test: harden database qualification startup and cleanup evidence
MariaDB persistence qualification / mariadb (push) Failing after 7s

This commit is contained in:
cesnimda
2026-10-24 14:04:57 +02:00
parent 2b26953d6f
commit 5ac11549b2
16 changed files with 228 additions and 15 deletions
@@ -5,6 +5,11 @@ import { setTimeout as sleep } from 'node:timers/promises';
export const durationMs = 15 * 60 * 1000;
export const paceMs = 500;
export function persistedCareerProfile(profile) {
// StructuredCvProfileJson.SerializePersisted omits null properties; CV overrides are a separate contract.
return JSON.parse(JSON.stringify(profile, (_key, value) => value === null ? undefined : value));
}
export function summarize(rows) {
const values = rows.filter(row => !row.error && row.status === 200).map(row => row.ms).sort((a, b) => a - b);
const percentile = p => values.length ? values[Math.ceil(values.length * p) - 1] : null;
@@ -25,6 +30,10 @@ export function assertMembership(actual, expected) {
if (process.argv.includes('--self-test')) {
assert.equal(durationMs, 900000);
assert.equal(paceMs, 500);
const profile = { contact: { fullName: 'Synthetic', phone: null }, metadata: { fields: {}, updatedAtUtc: null }, values: [null, '', 0, false] };
assert.deepEqual(persistedCareerProfile(profile), { contact: { fullName: 'Synthetic' }, metadata: { fields: {} }, values: [null, '', 0, false] });
assert.equal(profile.contact.phone, null);
assert.notDeepEqual(persistedCareerProfile(profile), persistedCareerProfile({ ...profile, contact: { fullName: 'Changed' } }));
assert.deepEqual(summarize([]), { attempts: 0, failures: 0, p50Ms: null, p95Ms: null, p99Ms: null, maxMs: null });
const rows = Array.from({ length: 100 }, (_, i) => ({ ms: i + 1, status: 200 }));
assert.deepEqual(summarize([...rows, { ms: 999, status: 500 }, { ms: 999, error: 'timeout' }]),
@@ -8,7 +8,10 @@ if (process.env.PLAYWRIGHT_STATIC_EXPORT !== 'true' || process.env.PLAYWRIGHT_PR
}
const artifacts = path.resolve('../.artifacts/p9-requal-01/performance');
const cwd = path.resolve(__dirname, '../../../../../job-tracker-ui');
const servers = Array.isArray(base.webServer) ? base.webServer : [base.webServer!];
export default defineConfig({ ...base, testDir: '.', testMatch: 'sustained.spec.ts', workers: 1, retries: 0,
webServer: servers.map(server => ({ ...server, cwd })),
timeout: 18 * 60 * 1000, outputDir: path.join(artifacts, 'test-results'),
reporter: [['list'], ['json', { outputFile: path.join(artifacts, 'playwright-results.json') }]],
});
@@ -1,7 +1,7 @@
import { test, expect, type APIRequestContext } from '../../../../../job-tracker-ui/node_modules/@playwright/test';
import os from 'node:os';
import { performance } from 'node:perf_hooks';
import { durationMs, paceMs, waitUntil, summarize, assertMembership } from './metrics.mjs';
import { durationMs, paceMs, waitUntil, summarize, assertMembership, persistedCareerProfile } from './metrics.mjs';
import { snapshot, sql } from './mariadb-proof.mjs';
const api = 'http://localhost:5302/api';
@@ -53,7 +53,8 @@ test('P9-REQUAL-01 real MariaDB: 15 minutes, 250 applications, two paced readers
const initialProfile = await (await page.request.get(`${api}/career/profile`)).json();
expect((await page.request.put(`${api}/career/profile`, { headers: owner.headers,
data: { expectedVersion: initialProfile.revision, profile } })).status()).toBe(200);
const savedProfile = (await (await page.request.get(`${api}/career/profile`)).json()).profile;
const savedResponse = await (await page.request.get(`${api}/career/profile`)).json();
const savedProfile = savedResponse.profile;
expect(savedProfile.jobs).toHaveLength(8);
expect(savedProfile.jobs.map((job: { start: string; end: string; bullets: string[] }) => ({ start: job.start, end: job.end, bullets: job.bullets })))
.toEqual(profile.jobs.map(job => ({ start: job.start, end: job.end, bullets: job.bullets })));
@@ -62,10 +63,11 @@ test('P9-REQUAL-01 real MariaDB: 15 minutes, 250 applications, two paced readers
expect(cv.status()).toBe(200);
const cvId = (await cv.json()).id;
const before = await snapshot(owner.id);
evidence.before = before;
assertMembership(before.ids, ids);
expect(before.ownerCount).toBe(250); expect(before.deletedCount).toBe(0);
expect(JSON.parse(before.profile)).toEqual(savedProfile);
evidence.before = before;
expect(before.revision).toBe(savedResponse.revision);
expect(JSON.parse(before.profile)).toEqual(persistedCareerProfile(savedProfile));
await Promise.all(readers.map(reader => login(reader, email)));
await page.addInitScript(() => localStorage.setItem('uiLanguage', 'en'));
await context.route('**/*', route => {