mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-21 01:00:24 +08:00
163 lines
4.0 KiB
JavaScript
163 lines
4.0 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const { test } = require('node:test');
|
|
|
|
const {
|
|
ClusterRunCancellationConvergenceCoordinator,
|
|
ClusterRunCancellationConvergenceUnavailableError,
|
|
normalizeClusterRunCancellationConvergencePageCommand,
|
|
normalizeClusterRunCancellationConvergencePageResult,
|
|
} = require('../dist/run/clusterRunCancellationConvergence');
|
|
|
|
test('normalizes one exact bounded convergence page command and result', () => {
|
|
assert.deepEqual(
|
|
normalizeClusterRunCancellationConvergencePageCommand({
|
|
limit: 2,
|
|
}),
|
|
{ limit: 2 },
|
|
);
|
|
assert.deepEqual(
|
|
normalizeClusterRunCancellationConvergencePageResult({
|
|
scanned: 2,
|
|
settledRuns: 2,
|
|
settledAttempts: 3,
|
|
blocked: 0,
|
|
hasMore: false,
|
|
}, 2),
|
|
{
|
|
scanned: 2,
|
|
settledRuns: 2,
|
|
settledAttempts: 3,
|
|
blocked: 0,
|
|
hasMore: false,
|
|
},
|
|
);
|
|
});
|
|
|
|
test('rejects widened and internally inconsistent page facts', () => {
|
|
assert.throws(() => normalizeClusterRunCancellationConvergencePageCommand({
|
|
limit: 1,
|
|
extra: true,
|
|
}));
|
|
assert.throws(() => normalizeClusterRunCancellationConvergencePageResult({
|
|
scanned: 1,
|
|
settledRuns: 2,
|
|
settledAttempts: 0,
|
|
blocked: 0,
|
|
hasMore: false,
|
|
}, 1));
|
|
assert.throws(() => normalizeClusterRunCancellationConvergencePageResult({
|
|
scanned: 1,
|
|
settledRuns: 1,
|
|
settledAttempts: 129,
|
|
blocked: 0,
|
|
hasMore: false,
|
|
}, 1));
|
|
});
|
|
|
|
test('coalesces callers and aggregates a bounded multi-page cycle', async () => {
|
|
const calls = [];
|
|
let release;
|
|
let page = 0;
|
|
const coordinator = new ClusterRunCancellationConvergenceCoordinator({
|
|
async convergePage(command) {
|
|
calls.push(command);
|
|
page += 1;
|
|
if (page === 1) await new Promise((resolve) => { release = resolve; });
|
|
return page === 1
|
|
? {
|
|
scanned: 2,
|
|
settledRuns: 2,
|
|
settledAttempts: 1,
|
|
blocked: 0,
|
|
hasMore: true,
|
|
}
|
|
: {
|
|
scanned: 1,
|
|
settledRuns: 1,
|
|
settledAttempts: 0,
|
|
blocked: 0,
|
|
hasMore: false,
|
|
};
|
|
},
|
|
}, {
|
|
pageSize: 2,
|
|
maxPages: 4,
|
|
});
|
|
|
|
const first = coordinator.reconcile();
|
|
const second = coordinator.reconcile();
|
|
assert.equal(first, second);
|
|
while (!release) await new Promise((resolve) => setImmediate(resolve));
|
|
release();
|
|
assert.deepEqual(await first, {
|
|
pages: 2,
|
|
scanned: 3,
|
|
settledRuns: 3,
|
|
settledAttempts: 1,
|
|
blocked: 0,
|
|
hasMore: false,
|
|
remaining: false,
|
|
stopReason: 'complete',
|
|
});
|
|
assert.equal(calls.length, 2);
|
|
assert.deepEqual(calls[0], { limit: 2 });
|
|
});
|
|
|
|
test('stops on blocked state and exposes page-limit continuation', async () => {
|
|
const blocked = new ClusterRunCancellationConvergenceCoordinator({
|
|
async convergePage() {
|
|
return {
|
|
scanned: 1,
|
|
settledRuns: 0,
|
|
settledAttempts: 0,
|
|
blocked: 1,
|
|
hasMore: true,
|
|
};
|
|
},
|
|
}, {});
|
|
assert.deepEqual(await blocked.reconcile(), {
|
|
pages: 1,
|
|
scanned: 1,
|
|
settledRuns: 0,
|
|
settledAttempts: 0,
|
|
blocked: 1,
|
|
hasMore: true,
|
|
remaining: true,
|
|
stopReason: 'blocked',
|
|
});
|
|
|
|
const limited = new ClusterRunCancellationConvergenceCoordinator({
|
|
async convergePage() {
|
|
return {
|
|
scanned: 1,
|
|
settledRuns: 1,
|
|
settledAttempts: 0,
|
|
blocked: 0,
|
|
hasMore: true,
|
|
};
|
|
},
|
|
}, {
|
|
pageSize: 1,
|
|
maxPages: 2,
|
|
});
|
|
assert.equal((await limited.reconcile()).stopReason, 'page_limit');
|
|
});
|
|
|
|
test('wraps malformed or stalled repositories as unavailable', async () => {
|
|
const coordinator = new ClusterRunCancellationConvergenceCoordinator({
|
|
async convergePage() {
|
|
return {
|
|
scanned: 0,
|
|
settledRuns: 0,
|
|
settledAttempts: 0,
|
|
blocked: 0,
|
|
hasMore: true,
|
|
};
|
|
},
|
|
}, {});
|
|
await assert.rejects(
|
|
coordinator.reconcile(),
|
|
ClusterRunCancellationConvergenceUnavailableError,
|
|
);
|
|
});
|