Skip to content

Commit 8cf3f18

Browse files
committed
refactor(cli): remove duplicate createMockClient, use shared test-utils
Address code review feedback: checkup.test.ts now imports createMockClient from test-utils.ts instead of having its own duplicate implementation. - Added versionRows option to shared MockClientOptions - Updated all test calls to use new signature - Reduced checkup.test.ts by ~110 lines
1 parent e21bab1 commit 8cf3f18

2 files changed

Lines changed: 58 additions & 168 deletions

File tree

cli/test/checkup.test.ts

Lines changed: 53 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { resolve } from "path";
44
// Import from source directly since we're using Bun
55
import * as checkup from "../lib/checkup";
66
import * as api from "../lib/checkup-api";
7+
import { createMockClient } from "./test-utils";
78

89

910
function runCli(args: string[], env: Record<string, string> = {}) {
@@ -19,111 +20,6 @@ function runCli(args: string[], env: Record<string, string> = {}) {
1920
};
2021
}
2122

22-
// Mock client for testing report generators
23-
interface MockClientOptions {
24-
settingsRows?: any[]; // Settings metric rows (tag_setting_name, tag_setting_value, etc.)
25-
databaseSizesRows?: any[];
26-
dbStatsRows?: any[]; // db_stats metric rows (numbackends, xact_commit, etc.)
27-
connectionStatesRows?: any[];
28-
uptimeRows?: any[];
29-
invalidIndexesRows?: any[];
30-
unusedIndexesRows?: any[];
31-
redundantIndexesRows?: any[];
32-
}
33-
34-
function createMockClient(versionRows: any[], _legacySettingsRows: any[], options: MockClientOptions = {}) {
35-
const {
36-
settingsRows = [],
37-
databaseSizesRows = [],
38-
dbStatsRows = [],
39-
connectionStatesRows = [],
40-
uptimeRows = [],
41-
invalidIndexesRows = [],
42-
unusedIndexesRows = [],
43-
redundantIndexesRows = [],
44-
} = options;
45-
46-
return {
47-
query: async (sql: string) => {
48-
// Version query (simple inline - used by getPostgresVersion)
49-
if (sql.includes("server_version") && sql.includes("server_version_num") && sql.includes("pg_settings") && !sql.includes("tag_setting_name")) {
50-
return { rows: versionRows };
51-
}
52-
// Settings metric query (from metrics.yml - has tag_setting_name, tag_setting_value)
53-
if (sql.includes("tag_setting_name") && sql.includes("tag_setting_value") && sql.includes("pg_settings")) {
54-
return { rows: settingsRows };
55-
}
56-
// Database sizes (simple inline - lists all databases)
57-
if (sql.includes("pg_database") && sql.includes("pg_database_size") && sql.includes("datistemplate")) {
58-
return { rows: databaseSizesRows };
59-
}
60-
// db_size metric (current database size from metrics.yml)
61-
if (sql.includes("pg_database_size(current_database())") && sql.includes("size_b")) {
62-
return { rows: [{ tag_datname: "testdb", size_b: "1073741824" }] };
63-
}
64-
// db_stats metric (from metrics.yml)
65-
if (sql.includes("pg_stat_database") && sql.includes("xact_commit") && sql.includes("pg_control_system")) {
66-
return { rows: dbStatsRows };
67-
}
68-
// Stats reset metric (from metrics.yml)
69-
if (sql.includes("stats_reset") && sql.includes("pg_stat_database") && sql.includes("seconds_since_reset")) {
70-
return { rows: [{
71-
tag_database_name: "testdb",
72-
stats_reset_epoch: "1704067200",
73-
seconds_since_reset: "2592000" // 30 days in seconds
74-
}] };
75-
}
76-
// Postmaster startup time (simple inline - used by getStatsReset)
77-
if (sql.includes("pg_postmaster_start_time") && sql.includes("postmaster_startup_epoch")) {
78-
return { rows: [{
79-
postmaster_startup_epoch: "1704067200",
80-
postmaster_startup_time: "2024-01-01 00:00:00+00"
81-
}] };
82-
}
83-
// Connection states (simple inline)
84-
if (sql.includes("pg_stat_activity") && sql.includes("state") && sql.includes("group by")) {
85-
return { rows: connectionStatesRows };
86-
}
87-
// Uptime info (simple inline)
88-
if (sql.includes("pg_postmaster_start_time()") && sql.includes("uptime") && !sql.includes("postmaster_startup_epoch")) {
89-
return { rows: uptimeRows };
90-
}
91-
// Invalid indexes (H001) - from metrics.yml
92-
if (sql.includes("indisvalid = false") && sql.includes("fk_indexes")) {
93-
return { rows: invalidIndexesRows };
94-
}
95-
// Unused indexes (H002) - from metrics.yml
96-
if (sql.includes("Never Used Indexes") && sql.includes("idx_scan = 0")) {
97-
return { rows: unusedIndexesRows };
98-
}
99-
// Redundant indexes (H004) - from metrics.yml
100-
if (sql.includes("redundant_indexes_grouped") && sql.includes("columns like")) {
101-
return { rows: redundantIndexesRows };
102-
}
103-
// D004: pg_stat_statements extension check
104-
if (sql.includes("pg_extension") && sql.includes("pg_stat_statements")) {
105-
return { rows: [] }; // Extension not installed by default
106-
}
107-
// D004: pg_stat_kcache extension check
108-
if (sql.includes("pg_extension") && sql.includes("pg_stat_kcache")) {
109-
return { rows: [] }; // Extension not installed by default
110-
}
111-
// G001: Memory settings query
112-
if (sql.includes("pg_size_bytes") && sql.includes("shared_buffers") && sql.includes("work_mem")) {
113-
return { rows: [{
114-
shared_buffers_bytes: "134217728",
115-
wal_buffers_bytes: "4194304",
116-
work_mem_bytes: "4194304",
117-
maintenance_work_mem_bytes: "67108864",
118-
effective_cache_size_bytes: "4294967296",
119-
max_connections: 100,
120-
}] };
121-
}
122-
throw new Error(`Unexpected query: ${sql}`);
123-
},
124-
};
125-
}
126-
12723
// Unit tests for parseVersionNum
12824
describe("parseVersionNum", () => {
12925
test("parses PG 16.3 version number", () => {
@@ -259,10 +155,12 @@ describe("formatBytes", () => {
259155
// Mock client tests for report generators
260156
describe("Report generators with mock client", () => {
261157
test("getPostgresVersion extracts version info", async () => {
262-
const mockClient = createMockClient([
263-
{ name: "server_version", setting: "16.3" },
264-
{ name: "server_version_num", setting: "160003" },
265-
], []);
158+
const mockClient = createMockClient({
159+
versionRows: [
160+
{ name: "server_version", setting: "16.3" },
161+
{ name: "server_version_num", setting: "160003" },
162+
],
163+
});
266164

267165
const version = await checkup.getPostgresVersion(mockClient as any);
268166
expect(version.version).toBe("16.3");
@@ -272,7 +170,7 @@ describe("Report generators with mock client", () => {
272170
});
273171

274172
test("getSettings transforms rows to keyed object", async () => {
275-
const mockClient = createMockClient([], [], {
173+
const mockClient = createMockClient({
276174
settingsRows: [
277175
{
278176
tag_setting_name: "shared_buffers",
@@ -308,10 +206,12 @@ describe("Report generators with mock client", () => {
308206
});
309207

310208
test("generateA002 creates report with version data", async () => {
311-
const mockClient = createMockClient([
312-
{ name: "server_version", setting: "16.3" },
313-
{ name: "server_version_num", setting: "160003" },
314-
], []);
209+
const mockClient = createMockClient({
210+
versionRows: [
211+
{ name: "server_version", setting: "16.3" },
212+
{ name: "server_version_num", setting: "160003" },
213+
],
214+
});
315215

316216
const report = await checkup.generateA002(mockClient as any, "test-node");
317217
expect(report.checkId).toBe("A002");
@@ -323,27 +223,24 @@ describe("Report generators with mock client", () => {
323223
});
324224

325225
test("generateA003 creates report with settings and version", async () => {
326-
const mockClient = createMockClient(
327-
[
226+
const mockClient = createMockClient({
227+
versionRows: [
328228
{ name: "server_version", setting: "16.3" },
329229
{ name: "server_version_num", setting: "160003" },
330230
],
331-
[],
332-
{
333-
settingsRows: [
334-
{
335-
tag_setting_name: "shared_buffers",
336-
tag_setting_value: "16384",
337-
tag_unit: "8kB",
338-
tag_category: "Resource Usage / Memory",
339-
tag_vartype: "integer",
340-
is_default: 1,
341-
setting_normalized: "134217728",
342-
unit_normalized: "bytes",
343-
},
344-
],
345-
}
346-
);
231+
settingsRows: [
232+
{
233+
tag_setting_name: "shared_buffers",
234+
tag_setting_value: "16384",
235+
tag_unit: "8kB",
236+
tag_category: "Resource Usage / Memory",
237+
tag_vartype: "integer",
238+
is_default: 1,
239+
setting_normalized: "134217728",
240+
unit_normalized: "bytes",
241+
},
242+
],
243+
});
347244

348245
const report = await checkup.generateA003(mockClient as any, "test-node");
349246
expect(report.checkId).toBe("A003");
@@ -355,10 +252,12 @@ describe("Report generators with mock client", () => {
355252
});
356253

357254
test("generateA013 creates report with minor version data", async () => {
358-
const mockClient = createMockClient([
359-
{ name: "server_version", setting: "16.3" },
360-
{ name: "server_version_num", setting: "160003" },
361-
], []);
255+
const mockClient = createMockClient({
256+
versionRows: [
257+
{ name: "server_version", setting: "16.3" },
258+
{ name: "server_version_num", setting: "160003" },
259+
],
260+
});
362261

363262
const report = await checkup.generateA013(mockClient as any, "test-node");
364263
expect(report.checkId).toBe("A013");
@@ -370,13 +269,11 @@ describe("Report generators with mock client", () => {
370269
});
371270

372271
test("generateAllReports returns reports for all checks", async () => {
373-
const mockClient = createMockClient(
374-
[
272+
const mockClient = createMockClient({
273+
versionRows: [
375274
{ name: "server_version", setting: "16.3" },
376275
{ name: "server_version_num", setting: "160003" },
377276
],
378-
[],
379-
{
380277
settingsRows: [
381278
{
382279
tag_setting_name: "shared_buffers",
@@ -437,7 +334,7 @@ describe("Report generators with mock client", () => {
437334
// Tests for A007 (Altered settings)
438335
describe("A007 - Altered settings", () => {
439336
test("getAlteredSettings returns non-default settings", async () => {
440-
const mockClient = createMockClient([], [], {
337+
const mockClient = createMockClient({
441338
settingsRows: [
442339
{ tag_setting_name: "shared_buffers", tag_setting_value: "256MB", tag_unit: "", tag_category: "Resource Usage / Memory", tag_vartype: "string", is_default: 0, setting_normalized: null, unit_normalized: null },
443340
{ tag_setting_name: "work_mem", tag_setting_value: "64MB", tag_unit: "", tag_category: "Resource Usage / Memory", tag_vartype: "string", is_default: 0, setting_normalized: null, unit_normalized: null },
@@ -454,13 +351,11 @@ describe("A007 - Altered settings", () => {
454351
});
455352

456353
test("generateA007 creates report with altered settings", async () => {
457-
const mockClient = createMockClient(
458-
[
354+
const mockClient = createMockClient({
355+
versionRows: [
459356
{ name: "server_version", setting: "16.3" },
460357
{ name: "server_version_num", setting: "160003" },
461358
],
462-
[],
463-
{
464359
settingsRows: [
465360
{ tag_setting_name: "max_connections", tag_setting_value: "200", tag_unit: "", tag_category: "Connections and Authentication", tag_vartype: "integer", is_default: 0, setting_normalized: null, unit_normalized: null },
466361
],
@@ -481,7 +376,7 @@ describe("A007 - Altered settings", () => {
481376
// Tests for A004 (Cluster information)
482377
describe("A004 - Cluster information", () => {
483378
test("getDatabaseSizes returns database sizes", async () => {
484-
const mockClient = createMockClient([], [], {
379+
const mockClient = createMockClient({
485380
databaseSizesRows: [
486381
{ datname: "postgres", size_bytes: "1073741824" },
487382
{ datname: "mydb", size_bytes: "536870912" },
@@ -496,7 +391,7 @@ describe("A004 - Cluster information", () => {
496391
});
497392

498393
test("getClusterInfo returns cluster metrics", async () => {
499-
const mockClient = createMockClient([], [], {
394+
const mockClient = createMockClient({
500395
dbStatsRows: [{
501396
numbackends: 10,
502397
xact_commit: 1000,
@@ -535,13 +430,11 @@ describe("A004 - Cluster information", () => {
535430
});
536431

537432
test("generateA004 creates report with cluster info and database sizes", async () => {
538-
const mockClient = createMockClient(
539-
[
433+
const mockClient = createMockClient({
434+
versionRows: [
540435
{ name: "server_version", setting: "16.3" },
541436
{ name: "server_version_num", setting: "160003" },
542437
],
543-
[],
544-
{
545438
databaseSizesRows: [
546439
{ datname: "postgres", size_bytes: "1073741824" },
547440
],
@@ -585,7 +478,7 @@ describe("A004 - Cluster information", () => {
585478
// Tests for H001 (Invalid indexes)
586479
describe("H001 - Invalid indexes", () => {
587480
test("getInvalidIndexes returns invalid indexes", async () => {
588-
const mockClient = createMockClient([], [], {
481+
const mockClient = createMockClient({
589482
invalidIndexesRows: [
590483
{ schema_name: "public", table_name: "users", index_name: "users_email_idx", relation_name: "users", index_size_bytes: "1048576", supports_fk: false },
591484
],
@@ -603,13 +496,11 @@ describe("H001 - Invalid indexes", () => {
603496
});
604497

605498
test("generateH001 creates report with invalid indexes", async () => {
606-
const mockClient = createMockClient(
607-
[
499+
const mockClient = createMockClient({
500+
versionRows: [
608501
{ name: "server_version", setting: "16.3" },
609502
{ name: "server_version_num", setting: "160003" },
610503
],
611-
[],
612-
{
613504
invalidIndexesRows: [
614505
{ schema_name: "public", table_name: "orders", index_name: "orders_status_idx", relation_name: "orders", index_size_bytes: "2097152", supports_fk: false },
615506
],
@@ -639,7 +530,7 @@ describe("H001 - Invalid indexes", () => {
639530
// Tests for H002 (Unused indexes)
640531
describe("H002 - Unused indexes", () => {
641532
test("getUnusedIndexes returns unused indexes", async () => {
642-
const mockClient = createMockClient([], [], {
533+
const mockClient = createMockClient({
643534
unusedIndexesRows: [
644535
{
645536
schema_name: "public",
@@ -667,13 +558,11 @@ describe("H002 - Unused indexes", () => {
667558
});
668559

669560
test("generateH002 creates report with unused indexes", async () => {
670-
const mockClient = createMockClient(
671-
[
561+
const mockClient = createMockClient({
562+
versionRows: [
672563
{ name: "server_version", setting: "16.3" },
673564
{ name: "server_version_num", setting: "160003" },
674565
],
675-
[],
676-
{
677566
unusedIndexesRows: [
678567
{
679568
schema_name: "public",
@@ -712,7 +601,7 @@ describe("H002 - Unused indexes", () => {
712601
// Tests for H004 (Redundant indexes)
713602
describe("H004 - Redundant indexes", () => {
714603
test("getRedundantIndexes returns redundant indexes", async () => {
715-
const mockClient = createMockClient([], [], {
604+
const mockClient = createMockClient({
716605
redundantIndexesRows: [
717606
{
718607
schema_name: "public",
@@ -752,13 +641,11 @@ describe("H004 - Redundant indexes", () => {
752641
});
753642

754643
test("generateH004 creates report with redundant indexes", async () => {
755-
const mockClient = createMockClient(
756-
[
644+
const mockClient = createMockClient({
645+
versionRows: [
757646
{ name: "server_version", setting: "16.3" },
758647
{ name: "server_version_num", setting: "160003" },
759648
],
760-
[],
761-
{
762649
redundantIndexesRows: [
763650
{
764651
schema_name: "public",

0 commit comments

Comments
 (0)