Files

129 lines
3.8 KiB
JavaScript

const assert = require('node:assert/strict');
const { test } = require('node:test');
const {
InvalidRunManualRetryError,
RUN_MANUAL_RETRY_SCHEMA,
RunManualRetryRateLimitedError,
createRunManualRetryResponseBody,
normalizeRunManualRetryCommand,
parseRunManualRetryRequestBody,
} = require('../dist/run/manual-retry/runManualRetry.js');
const IDS = Object.freeze({
mutationId: '019f9000-0000-4000-8000-000000000001',
runId: '019f9000-0000-4000-8000-000000000002',
attemptId: '019f9000-0000-4000-8000-000000000003',
createdEventId: '019f9000-0000-4000-8000-000000000004',
queuedEventId: '019f9000-0000-4000-8000-000000000005',
auditEventId: '019f9000-0000-4000-8000-000000000006',
});
function command(overrides = {}) {
return {
projectId: 'project-1',
sourceRunId: 'source-run-1',
mutationId: IDS.mutationId,
expectedRunVersion: 7,
expectedRunStatus: 'failed',
runId: IDS.runId,
attemptId: IDS.attemptId,
createdEventId: IDS.createdEventId,
queuedEventId: IDS.queuedEventId,
auditEventId: IDS.auditEventId,
requestId: 'run-retry-request-1',
principal: {
subject: { type: 'user', id: 'operator-1' },
authenticationId: 'local_console:proof-1',
authenticatedAtMs: 10_000,
expiresAtMs: 20_000,
assurance: 'local_console',
},
policyFence: { projectVersion: 2, bindingVersion: 3 },
...overrides,
};
}
test('normalizes one strongly authorized terminal Run retry command', () => {
const request = parseRunManualRetryRequestBody({
schema: RUN_MANUAL_RETRY_SCHEMA,
mutationId: IDS.mutationId,
expectedRunVersion: 7,
expectedRunStatus: 'timed_out',
});
assert.equal(request.expectedRunStatus, 'timed_out');
const normalized = normalizeRunManualRetryCommand(command());
assert.equal(normalized.principal.assurance, 'local_console');
assert.equal(Object.isFrozen(normalized), true);
});
test('rejects reopened states, weak principals and widened commands', () => {
assert.throws(
() =>
parseRunManualRetryRequestBody({
schema: RUN_MANUAL_RETRY_SCHEMA,
mutationId: IDS.mutationId,
expectedRunVersion: 7,
expectedRunStatus: 'lost',
}),
InvalidRunManualRetryError,
);
assert.throws(
() =>
normalizeRunManualRetryCommand(
command({
principal: { ...command().principal, assurance: 'single_factor' },
}),
),
/strong User/,
);
assert.throws(
() => normalizeRunManualRetryCommand({ ...command(), hidden: true }),
InvalidRunManualRetryError,
);
});
test('publishes only the bounded new-Run retry result', () => {
assert.deepEqual(
createRunManualRetryResponseBody({
status: 'accepted',
projectId: 'project-1',
sourceRunId: 'source-run-1',
sourceRunStatus: 'failed',
sourceRunVersion: 7,
runId: IDS.runId,
retryOfRunId: 'source-run-1',
taskId: 'task-1',
taskRevision: `v1:${'a'.repeat(64)}`,
attemptId: IDS.attemptId,
runStatus: 'queued',
runVersion: 2,
eventSequence: 2,
executorType: 'local_process',
executionRevisionDigest: 'b'.repeat(64),
createdAtMs: 11_000,
}),
{
schema: RUN_MANUAL_RETRY_SCHEMA,
status: 'accepted',
projectId: 'project-1',
sourceRunId: 'source-run-1',
sourceRunStatus: 'failed',
sourceRunVersion: 7,
runId: IDS.runId,
retryOfRunId: 'source-run-1',
taskId: 'task-1',
taskRevision: `v1:${'a'.repeat(64)}`,
attemptId: IDS.attemptId,
runStatus: 'queued',
runVersion: 2,
eventSequence: 2,
executorType: 'local_process',
executionRevisionDigest: 'b'.repeat(64),
createdAtMs: 11_000,
},
);
assert.equal(new RunManualRetryRateLimitedError(250).retryAfterMs, 250);
assert.throws(() => new RunManualRetryRateLimitedError(0));
});