Files
qinglong/packages/ql3-local-sqlite/test/pluginPackageLifecycleCrashMatrix.test.cjs

108 lines
3.2 KiB
JavaScript

const assert = require('node:assert/strict');
const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');
const { spawnSync } = require('node:child_process');
const { test } = require('node:test');
const {
CRASH_POINTS,
setupScenario,
verifyScenario,
} = require('./fixtures/pluginPackageLifecycleCrashMatrixFixture.cjs');
const FIXTURE_PATH = path.join(
__dirname,
'fixtures',
'pluginPackageLifecycleCrashMatrixFixture.cjs',
);
test(
'survives the Plugin Package lifecycle crash matrix',
{ timeout: 240_000 },
async (context) => {
const reports = [];
for (const profile of ['edge', 'standalone']) {
for (const action of ['disable', 'enable']) {
for (const [pointName, point] of Object.entries(CRASH_POINTS)) {
const directory = fs.mkdtempSync(
path.join(
os.tmpdir(),
`ql3-package-lifecycle-${profile}-${action}-`,
),
);
context.after(() => {
fs.rmSync(directory, { recursive: true, force: true });
});
const databasePath = path.join(directory, 'runtime.sqlite');
const markerPath = path.join(directory, 'crash-marker.json');
const event = await setupScenario({ action, databasePath, profile });
const crashed = spawnSync(
process.execPath,
[
FIXTURE_PATH,
'crash',
databasePath,
markerPath,
pointName,
profile,
action,
],
{ encoding: 'utf8', timeout: 30_000 },
);
assert.equal(
crashed.error,
undefined,
`${profile}/${action}/${pointName}: ${crashed.error?.message}`,
);
assert.equal(
crashed.signal,
'SIGKILL',
`${profile}/${action}/${pointName}: status=${crashed.status}, stderr=${crashed.stderr}`,
);
const marker = JSON.parse(fs.readFileSync(markerPath, 'utf8'));
assert.deepEqual(marker, {
schema:
'qinglong/sqlite-plugin-package-lifecycle-crash-marker@v1',
action,
point: pointName,
pid: marker.pid,
});
reports.push(
await verifyScenario({
action,
databasePath,
event,
pointName,
profile,
}),
);
assert.equal(reports.at(-1).durableAfterCrash, point.durable);
}
}
}
assert.equal(reports.length, 32);
assert.equal(
reports.filter(({ crashBeforeCommit }) => crashBeforeCommit).length,
28,
);
assert.equal(
reports.filter(({ durableAfterCrash }) => durableAfterCrash).length,
4,
);
assert.deepEqual(
[...new Set(reports.map(({ journalMode }) => journalMode))].sort(),
['delete', 'wal'],
);
assert.ok(reports.every(({ synchronous }) => synchronous === 2));
assert.ok(
reports.every(
({ exactReplay, integrityCheck, foreignKeyCheck }) =>
exactReplay &&
integrityCheck === 'ok' &&
foreignKeyCheck === 'ok',
),
);
},
);