Skip to content

Commit d9812ce

Browse files
committed
test: address staging-perf live review findings
Tighten the spec docstrings so the V1 regression scope and the V2 baseline scope are each called out explicitly. The V1 spec now says PUT/DELETE are the phases that exercise the batched-diff hydration path, with POST kept as a baseline smoke. The V2 spec now explains that v2/staging is served by a separate controller from the v1 fix and that this job is an SLA baseline for that path. Reject parseIntEnv(0) so STAGING_PERF_*_ROW_COUNT=0 or BUDGET_MS=0 cannot collapse the test into a silent no-op pass. Enforce the v2 paginationSchema's 1000-row cap on STAGING_PERF_V2_ROW_COUNT so a clamped single-page response can never look like data loss. In the new v2 staging-perf job, point the post-run mirror-DB dump at cadt_mirror_test (the DB the job actually configures) instead of cadt_mirror_test_v2, which was never populated. Add a matching mirror-DB dump step to the new v1 staging-perf job so a mirror regression there is debuggable from the run log without re-running. Reframe the commit-message scope so v1 is the phase that guards the batched-diff fix and v2 is an independent baseline.
1 parent 3216e6b commit d9812ce

3 files changed

Lines changed: 66 additions & 11 deletions

File tree

.github/workflows/tests.yaml

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,10 +1494,10 @@ jobs:
14941494
service mariadb status || echo "MariaDB service status check failed"
14951495
echo ""
14961496
echo "Checking mirror database tables..."
1497-
mysql -u cadt_test -pcadt_test_password -e "USE cadt_mirror_test_v2; SHOW TABLES;" 2>/dev/null || echo "Could not list tables (DB may not have been created yet)"
1497+
mysql -u cadt_test -pcadt_test_password -e "USE cadt_mirror_test; SHOW TABLES;" 2>/dev/null || echo "Could not list tables (DB may not have been created yet)"
14981498
echo ""
14991499
echo "Record counts in mirror tables:"
1500-
mysql -u cadt_test -pcadt_test_password cadt_mirror_test_v2 -e "
1500+
mysql -u cadt_test -pcadt_test_password cadt_mirror_test -e "
15011501
SELECT 'project_mirror' as table_name, COUNT(*) as count FROM project_mirror UNION ALL
15021502
SELECT 'methodology_mirror', COUNT(*) FROM methodology_mirror UNION ALL
15031503
SELECT 'program_mirror', COUNT(*) FROM program_mirror UNION ALL
@@ -1970,6 +1970,36 @@ jobs:
19701970
echo "########################################################"
19711971
npm run test:v1:live:staging:perf
19721972
1973+
- name: Show MySQL mirror database status
1974+
if: always()
1975+
shell: bash
1976+
run: |
1977+
echo "=========================================="
1978+
echo "MySQL/MariaDB Mirror Database Status"
1979+
echo "=========================================="
1980+
echo ""
1981+
echo "Checking MariaDB service status..."
1982+
service mariadb status || echo "MariaDB service status check failed"
1983+
echo ""
1984+
echo "Checking mirror database tables..."
1985+
mysql -u cadt_test -pcadt_test_password -e "USE cadt_mirror_test; SHOW TABLES;" 2>/dev/null || echo "Could not list tables (DB may not have been created yet)"
1986+
echo ""
1987+
echo "Record counts in mirror tables:"
1988+
mysql -u cadt_test -pcadt_test_password cadt_mirror_test -e "
1989+
SELECT 'project_mirror' as table_name, COUNT(*) as count FROM project_mirror UNION ALL
1990+
SELECT 'methodology_mirror', COUNT(*) FROM methodology_mirror UNION ALL
1991+
SELECT 'program_mirror', COUNT(*) FROM program_mirror UNION ALL
1992+
SELECT 'unit_mirror', COUNT(*) FROM unit_mirror UNION ALL
1993+
SELECT 'issuance_mirror', COUNT(*) FROM issuance_mirror UNION ALL
1994+
SELECT 'verification_mirror', COUNT(*) FROM verification_mirror UNION ALL
1995+
SELECT 'validation_mirror', COUNT(*) FROM validation_mirror UNION ALL
1996+
SELECT 'location_mirror', COUNT(*) FROM location_mirror UNION ALL
1997+
SELECT 'estimation_mirror', COUNT(*) FROM estimation_mirror UNION ALL
1998+
SELECT 'rating_mirror', COUNT(*) FROM rating_mirror UNION ALL
1999+
SELECT 'label_mirror', COUNT(*) FROM label_mirror UNION ALL
2000+
SELECT 'stakeholder_mirror', COUNT(*) FROM stakeholder_mirror;
2001+
" 2>/dev/null || echo "Could not count records (tables may not exist)"
2002+
19732003
- name: Show CADT logs after tests
19742004
if: always()
19752005
shell: bash

tests/v1/live-api/staging-perf.live.spec.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
* - commits + waits for the existing datalayer submission path to
1010
* succeed (no tight SLA on the commit path itself).
1111
*
12+
* PUT and DELETE are the phases that exercise the batched-diff hydration
13+
* path (Project/Unit/Issuance findAll IN) the staging.model.js fix
14+
* targets. POST short-circuits on INSERT and is kept as a baseline smoke
15+
* on the unpaginated GET shape + commit round-trip.
16+
*
1217
* Tunables (env overrides for tuning after live runs):
1318
* STAGING_PERF_V1_ROW_COUNT default 100
1419
* STAGING_PERF_V1_BUDGET_MS default 3000
@@ -36,8 +41,10 @@ const parseIntEnv = (name, fallback) => {
3641
const raw = process.env[name];
3742
if (raw === undefined || raw === '') return fallback;
3843
const parsed = Number.parseInt(raw, 10);
39-
if (Number.isNaN(parsed) || parsed < 0) {
40-
throw new Error(`Invalid ${name}=${raw}; expected non-negative integer`);
44+
// Zero would collapse ROW_COUNT / BUDGET_MS / COMMIT_TIMEOUT_MS to no-ops
45+
// or always-fail, so reject <= 0 explicitly.
46+
if (Number.isNaN(parsed) || parsed <= 0) {
47+
throw new Error(`Invalid ${name}=${raw}; expected positive integer`);
4148
}
4249
return parsed;
4350
};

tests/v2/live-api/staging-perf.live.spec.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@
44
* Mirrors tests/v1/live-api/staging-perf.live.spec.js against the V2 API.
55
* For POST / PUT / DELETE phases this:
66
* - stages a configurable batch (default 100 projects),
7-
* - times a single GET /v2/staging (paginated, matches how the app
8-
* actually consumes the endpoint) before committing,
7+
* - times a single GET /v2/staging with limit >= ROW_COUNT so the whole
8+
* batch lands in one request (single-request SLA, not a paginated
9+
* browse) before committing,
910
* - asserts status 200, expected staged row count, and response time
1011
* under the configured budget,
1112
* - commits + waits for the existing datalayer submission path to
1213
* succeed (no tight SLA on the commit path itself).
1314
*
15+
* V2 staging is served by src/controllers/v2/staging-v2.controller.js,
16+
* which is a separate code path from the V1 staging controller. This
17+
* spec is a baseline SLA for that V2 path independent of any batched-
18+
* diff work on V1; it will be useful as a regression guard once the
19+
* equivalent batching lands on V2.
20+
*
1421
* Tunables (env overrides for tuning after live runs):
1522
* STAGING_PERF_V2_ROW_COUNT default 100
1623
* STAGING_PERF_V2_BUDGET_MS default 2000
@@ -38,19 +45,30 @@ const parseIntEnv = (name, fallback) => {
3845
const raw = process.env[name];
3946
if (raw === undefined || raw === '') return fallback;
4047
const parsed = Number.parseInt(raw, 10);
41-
if (Number.isNaN(parsed) || parsed < 0) {
42-
throw new Error(`Invalid ${name}=${raw}; expected non-negative integer`);
48+
// Zero would collapse ROW_COUNT / BUDGET_MS / COMMIT_TIMEOUT_MS to no-ops
49+
// or always-fail, so reject <= 0 explicitly.
50+
if (Number.isNaN(parsed) || parsed <= 0) {
51+
throw new Error(`Invalid ${name}=${raw}; expected positive integer`);
4352
}
4453
return parsed;
4554
};
4655

56+
// V2 paginationSchema caps `limit` at 1000 (src/validations/v2/pagination-v2.validations.js).
57+
// Staying at or below that keeps the single-request SLA valid; bumping ROW_COUNT higher
58+
// would require paging across multiple GETs and rethinking the budget.
59+
const MAX_STAGING_PAGE_LIMIT = 1000;
60+
4761
const ROW_COUNT = parseIntEnv('STAGING_PERF_V2_ROW_COUNT', 100);
62+
if (ROW_COUNT > MAX_STAGING_PAGE_LIMIT) {
63+
throw new Error(
64+
`STAGING_PERF_V2_ROW_COUNT=${ROW_COUNT} exceeds the V2 pagination limit ` +
65+
`(${MAX_STAGING_PAGE_LIMIT}); the single-GET SLA would return a clamped page.`,
66+
);
67+
}
4868
const BUDGET_MS = parseIntEnv('STAGING_PERF_V2_BUDGET_MS', 2000);
4969
const COMMIT_TIMEOUT_MS = parseIntEnv('STAGING_PERF_V2_COMMIT_TIMEOUT_MS', 1_200_000);
5070

51-
// Pagination limit must be >= ROW_COUNT so a single GET fetches every row
52-
// we staged; that keeps the perf assertion a true single-request SLA.
53-
const STAGING_PAGE_LIMIT = Math.max(ROW_COUNT, 1000);
71+
const STAGING_PAGE_LIMIT = MAX_STAGING_PAGE_LIMIT;
5472

5573
const SPEC_TIMEOUT_MS = COMMIT_TIMEOUT_MS * 3 + 600_000;
5674

0 commit comments

Comments
 (0)