mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
require('ts-node/register/transpile-only');
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const { test } = require('node:test');
|
||||
const {
|
||||
PrimaryCancellationSupervisor,
|
||||
} = require('../../back/runtime/application/primaryCancellationSupervisor');
|
||||
|
||||
function summary(overrides = {}) {
|
||||
return {
|
||||
scanned: 1,
|
||||
claimed: 1,
|
||||
terminationRequested: 1,
|
||||
alreadyExited: 0,
|
||||
pending: 0,
|
||||
ambiguous: 0,
|
||||
blocked: 0,
|
||||
deferred: 0,
|
||||
alreadyResolved: 0,
|
||||
notEligible: 0,
|
||||
failed: 0,
|
||||
truncated: false,
|
||||
unsafeAttemptOverflow: false,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
test('paginates a bounded cancellation recovery cycle and aggregates results', async () => {
|
||||
const calls = [];
|
||||
const pages = [
|
||||
summary({
|
||||
scanned: 2,
|
||||
claimed: 1,
|
||||
pending: 1,
|
||||
truncated: true,
|
||||
nextCursor: { requestedAtMs: 100, runId: 'run-2' },
|
||||
}),
|
||||
summary({
|
||||
scanned: 2,
|
||||
claimed: 2,
|
||||
terminationRequested: 0,
|
||||
alreadyExited: 1,
|
||||
blocked: 1,
|
||||
}),
|
||||
];
|
||||
const supervisor = new PrimaryCancellationSupervisor({
|
||||
async dispatchBatch(options) {
|
||||
calls.push(options);
|
||||
return pages.shift();
|
||||
},
|
||||
});
|
||||
|
||||
const result = await supervisor.runCycle({ pageSize: 2, maxPages: 4 });
|
||||
assert.deepEqual(calls, [
|
||||
{ limit: 2 },
|
||||
{ cursor: { requestedAtMs: 100, runId: 'run-2' }, limit: 2 },
|
||||
]);
|
||||
assert.deepEqual(result, {
|
||||
pages: 2,
|
||||
scanned: 4,
|
||||
claimed: 3,
|
||||
terminationRequested: 1,
|
||||
alreadyExited: 1,
|
||||
pending: 1,
|
||||
ambiguous: 0,
|
||||
blocked: 1,
|
||||
deferred: 0,
|
||||
alreadyResolved: 0,
|
||||
notEligible: 0,
|
||||
failed: 0,
|
||||
stopReason: 'complete',
|
||||
remaining: false,
|
||||
});
|
||||
});
|
||||
|
||||
test('stops at the page limit and exposes a resume cursor', async () => {
|
||||
let page = 0;
|
||||
const supervisor = new PrimaryCancellationSupervisor({
|
||||
async dispatchBatch() {
|
||||
page += 1;
|
||||
return summary({
|
||||
truncated: true,
|
||||
nextCursor: { requestedAtMs: 100 + page, runId: `run-${page}` },
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const result = await supervisor.runCycle({ pageSize: 1, maxPages: 2 });
|
||||
assert.equal(result.pages, 2);
|
||||
assert.equal(result.stopReason, 'page_limit');
|
||||
assert.equal(result.remaining, true);
|
||||
assert.deepEqual(result.nextCursor, {
|
||||
requestedAtMs: 102,
|
||||
runId: 'run-2',
|
||||
});
|
||||
|
||||
const resumedCalls = [];
|
||||
const resumed = new PrimaryCancellationSupervisor({
|
||||
async dispatchBatch(options) {
|
||||
resumedCalls.push(options);
|
||||
return summary();
|
||||
},
|
||||
});
|
||||
await resumed.runCycle({ cursor: result.nextCursor, pageSize: 1 });
|
||||
assert.deepEqual(resumedCalls, [
|
||||
{
|
||||
cursor: { requestedAtMs: 102, runId: 'run-2' },
|
||||
limit: 1,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test('fails closed when attempt rows overflow or pagination cannot advance', async () => {
|
||||
const unsafe = new PrimaryCancellationSupervisor({
|
||||
async dispatchBatch() {
|
||||
return summary({
|
||||
scanned: 0,
|
||||
claimed: 0,
|
||||
terminationRequested: 0,
|
||||
truncated: true,
|
||||
unsafeAttemptOverflow: true,
|
||||
});
|
||||
},
|
||||
});
|
||||
const unsafeResult = await unsafe.runCycle();
|
||||
assert.equal(unsafeResult.stopReason, 'unsafe_attempt_overflow');
|
||||
assert.equal(unsafeResult.remaining, true);
|
||||
|
||||
const stalled = new PrimaryCancellationSupervisor({
|
||||
async dispatchBatch() {
|
||||
return summary({ truncated: true });
|
||||
},
|
||||
});
|
||||
const stalledResult = await stalled.runCycle();
|
||||
assert.equal(stalledResult.stopReason, 'cursor_stalled');
|
||||
assert.equal(stalledResult.remaining, true);
|
||||
});
|
||||
|
||||
test('rejects unbounded cycle settings', async () => {
|
||||
const supervisor = new PrimaryCancellationSupervisor({
|
||||
async dispatchBatch() {
|
||||
throw new Error('must not run');
|
||||
},
|
||||
});
|
||||
await assert.rejects(supervisor.runCycle({ pageSize: 65 }), RangeError);
|
||||
await assert.rejects(supervisor.runCycle({ maxPages: 65 }), RangeError);
|
||||
});
|
||||
Reference in New Issue
Block a user