Files
qinglong/packages/ql3-runtime-core/test/taskStart.test.cjs
T

109 lines
3.2 KiB
JavaScript

'use strict';
const assert = require('node:assert/strict');
const { test } = require('node:test');
const {
TASK_START_SCHEMA,
createTaskStartResponseBody,
normalizeTaskStartCommand,
normalizeTaskStartResult,
parseTaskStartRequestBody,
parseTaskStartResponseBody,
} = require('@qinglong/runtime-core/task-start');
const DIGEST = 'a'.repeat(64);
const EXECUTION_DIGEST = 'b'.repeat(64);
function command(overrides = {}) {
return {
projectId: 'project-1',
taskId: 'task-1',
mutationId: '019f7300-0000-7000-8000-000000000001',
expectedRevision: 3,
expectedContentDigest: DIGEST,
runId: '019f7300-0000-7000-8000-000000000002',
attemptId: '019f7300-0000-7000-8000-000000000003',
createdEventId: '019f7300-0000-7000-8000-000000000004',
queuedEventId: '019f7300-0000-7000-8000-000000000005',
subject: { type: 'user', id: 'user-1' },
policyFence: { projectVersion: 2, bindingVersion: 4 },
...overrides,
};
}
function result(overrides = {}) {
return {
status: 'accepted',
projectId: 'project-1',
taskId: 'task-1',
taskRevision: 3,
taskContentDigest: DIGEST,
runId: '019f7300-0000-7000-8000-000000000002',
attemptId: '019f7300-0000-7000-8000-000000000003',
runStatus: 'queued',
runVersion: 2,
eventSequence: 2,
executorType: 'local_process',
executionRevisionDigest: EXECUTION_DIGEST,
createdAtMs: 1_800_000_000_000,
...overrides,
};
}
test('accepts only the exact digest-fenced Task start wire body', () => {
const body = {
schema: TASK_START_SCHEMA,
mutationId: command().mutationId,
expectedRevision: 3,
expectedContentDigest: DIGEST,
};
assert.equal(TASK_START_SCHEMA, 'qinglong/task-start@v1');
assert.deepEqual(parseTaskStartRequestBody(body), body);
assert.throws(
() => parseTaskStartRequestBody({ ...body, command: '/bin/sh' }),
/shape is invalid/,
);
assert.throws(
() => parseTaskStartRequestBody({ ...body, mutationId: 'MUTATION' }),
/mutationId is invalid/,
);
assert.throws(
() => parseTaskStartRequestBody({ ...body, expectedContentDigest: 'A'.repeat(64) }),
/expectedContentDigest is invalid/,
);
});
test('normalizes complete server-owned identities and authorization fence', () => {
assert.deepEqual(normalizeTaskStartCommand(command()), command());
assert.throws(
() => normalizeTaskStartCommand(command({ policyFence: {
projectVersion: 2,
bindingVersion: null,
} })),
/authorization fence is incomplete/,
);
assert.throws(
() => normalizeTaskStartCommand(command({ runId: 'caller-run-id' })),
/runId is invalid/,
);
});
test('round-trips accepted and existing bounded receipts', () => {
assert.deepEqual(normalizeTaskStartResult(result()), result());
const existing = result({
status: 'existing',
executorType: 'remote_worker',
});
const body = createTaskStartResponseBody(existing);
assert.equal(body.schema, TASK_START_SCHEMA);
assert.deepEqual(parseTaskStartResponseBody(body), body);
assert.throws(
() => normalizeTaskStartResult(result({ runVersion: 3 })),
/result state is invalid/,
);
assert.throws(
() => parseTaskStartResponseBody({ ...body, command: {} }),
/shape is invalid/,
);
});