mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-22 02:27:44 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const { test } = require('node:test');
|
||||
const {
|
||||
MAX_LOCAL_RUN_STARTUP_RECOVERY_CANDIDATES,
|
||||
migrateLocalSqlitePath,
|
||||
openLocalSqliteRuntimeDatabase,
|
||||
} = require('../dist');
|
||||
|
||||
async function database(t) {
|
||||
const directory = fs.mkdtempSync(
|
||||
path.join(os.tmpdir(), 'ql3-local-startup-recovery-'),
|
||||
);
|
||||
t.after(() => fs.rmSync(directory, { recursive: true, force: true }));
|
||||
const databasePath = path.join(directory, 'qinglong3.sqlite');
|
||||
await migrateLocalSqlitePath({ databasePath, profile: 'edge' });
|
||||
const opened = await openLocalSqliteRuntimeDatabase({
|
||||
databasePath,
|
||||
profile: 'edge',
|
||||
});
|
||||
t.after(() => opened.close());
|
||||
return opened;
|
||||
}
|
||||
|
||||
function run(id, status, executionOwner = 'runtime') {
|
||||
return {
|
||||
id,
|
||||
projectId: 'default',
|
||||
taskId: `task-${id}`,
|
||||
taskRevision: `revision-${id}`,
|
||||
triggerType: 'manual',
|
||||
executionOrigin: 'manual',
|
||||
executionOwner,
|
||||
status,
|
||||
version: 0,
|
||||
eventSequence: 0,
|
||||
priority: 0,
|
||||
createdAtMs: 1,
|
||||
};
|
||||
}
|
||||
|
||||
function attempt(id, runId, status = 'running') {
|
||||
return {
|
||||
id,
|
||||
runId,
|
||||
attempt: 1,
|
||||
status,
|
||||
executorType: 'local_process',
|
||||
callbackSequence: 0,
|
||||
createdAtMs: 1,
|
||||
};
|
||||
}
|
||||
|
||||
test('finds only runtime-owned dispatching or running Runs', async (t) => {
|
||||
const opened = await database(t);
|
||||
await opened.runRepository.transaction(async (transaction) => {
|
||||
await transaction.insertRun(run('run-1', 'running'));
|
||||
await transaction.insertAttempt(attempt('attempt-1', 'run-1'));
|
||||
await transaction.insertRun(run('run-2', 'dispatching'));
|
||||
await transaction.insertRun(run('run-3', 'succeeded'));
|
||||
await transaction.insertRun(run('run-4', 'running', 'legacy'));
|
||||
});
|
||||
|
||||
const page = await opened.startupRecovery.inspectCandidates();
|
||||
assert.deepEqual(page, {
|
||||
candidates: [
|
||||
{
|
||||
runId: 'run-1',
|
||||
runStatus: 'running',
|
||||
activeAttemptCount: 1,
|
||||
},
|
||||
{
|
||||
runId: 'run-2',
|
||||
runStatus: 'dispatching',
|
||||
activeAttemptCount: 0,
|
||||
},
|
||||
],
|
||||
truncated: false,
|
||||
});
|
||||
});
|
||||
|
||||
test('returns a bounded deterministic page and explicit truncation', async (t) => {
|
||||
const opened = await database(t);
|
||||
await opened.runRepository.transaction(async (transaction) => {
|
||||
await transaction.insertRun(run('run-3', 'running'));
|
||||
await transaction.insertRun(run('run-1', 'running'));
|
||||
await transaction.insertRun(run('run-2', 'running'));
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
await opened.startupRecovery.inspectCandidates({ limit: 2 }),
|
||||
{
|
||||
candidates: [
|
||||
{
|
||||
runId: 'run-1',
|
||||
runStatus: 'running',
|
||||
activeAttemptCount: 0,
|
||||
},
|
||||
{
|
||||
runId: 'run-2',
|
||||
runStatus: 'running',
|
||||
activeAttemptCount: 0,
|
||||
},
|
||||
],
|
||||
truncated: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects invalid limits and shares repository close fencing', async (t) => {
|
||||
const opened = await database(t);
|
||||
await assert.rejects(
|
||||
opened.startupRecovery.inspectCandidates({ limit: 0 }),
|
||||
/limit must be between 1/,
|
||||
);
|
||||
await assert.rejects(
|
||||
opened.startupRecovery.inspectCandidates({
|
||||
limit: MAX_LOCAL_RUN_STARTUP_RECOVERY_CANDIDATES + 1,
|
||||
}),
|
||||
/limit must be between 1/,
|
||||
);
|
||||
await opened.close();
|
||||
await assert.rejects(
|
||||
opened.startupRecovery.inspectCandidates(),
|
||||
(error) =>
|
||||
error &&
|
||||
error.name === 'RunRepositoryOperationError' &&
|
||||
error.cause instanceof Error &&
|
||||
error.cause.message === 'Local SQLite Run repository is closed',
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user