Files
qinglong/test/back/legacyCronExecutionSpec.test.cjs
T

112 lines
3.4 KiB
JavaScript

require('ts-node/register/transpile-only');
const assert = require('node:assert/strict');
const { test } = require('node:test');
const {
DEFAULT_LEGACY_TERMINATION_GRACE_MS,
buildLegacyCronExecutionSpec,
} = require('../../back/runtime/adapters/legacy/legacyCronExecutionSpec');
const {
InvalidExecutionSpecError,
} = require('../../back/runtime/domain/executorErrors');
function createInput(overrides = {}) {
return {
runId: '019f70f0-0000-7000-8000-000000000001',
attemptId: '019f70f0-0000-7000-8000-000000000002',
projectId: 'default',
taskRevision: 'legacy-revision-1',
cron: {
id: 7,
command: 'demo/script.js now',
},
realTime: false,
...overrides,
};
}
test('builds the minimal legacy task.sh shell contract', () => {
assert.deepEqual(buildLegacyCronExecutionSpec(createInput()), {
runId: '019f70f0-0000-7000-8000-000000000001',
attemptId: '019f70f0-0000-7000-8000-000000000002',
projectId: 'default',
taskId: 'legacy-cron:7',
taskRevision: 'legacy-revision-1',
command: {
kind: 'shell',
command: "real_time='false' no_tee='true' ID='7' task demo/script.js now",
shell: '/bin/bash',
},
environmentPolicy: 'inherit',
terminationGraceMs: DEFAULT_LEGACY_TERMINATION_GRACE_MS,
});
});
test('preserves existing task/ql commands instead of adding a second prefix', () => {
const task = buildLegacyCronExecutionSpec(
createInput({ cron: { id: 8, command: ' task script.py now ' } }),
);
const ql = buildLegacyCronExecutionSpec(
createInput({ cron: { id: 9, command: 'ql update' } }),
);
assert.match(task.command.command, / ID='8' task script\.py now$/);
assert.match(ql.command.command, / ID='9' ql update$/);
});
test('quotes paths, hook commands, and log values without changing shell boundaries', () => {
const spec = buildLegacyCronExecutionSpec(
createInput({
realTime: true,
realLogPath: "folder with space/run's.log",
noDelay: true,
timeoutMs: 60_000,
terminationGraceMs: 2_000,
resourcePolicy: {
memoryBytes: {
value: 128 * 1024 * 1024,
enforcement: 'best_effort',
},
},
cron: {
id: 10,
command: "scripts/job.py now -- 'user value'",
taskBefore: "echo 'before'\n echo second",
taskAfter: 'echo after;\n echo done',
workDirectory: "/data/project's worktree",
logName: 'custom log',
},
}),
);
assert.equal(
spec.command.command,
"real_log_path='folder with space/run'\\''s.log' no_delay='true' real_time='true' no_tee='true' ID='10' log_name='custom log' task_before='echo '\\''before'\\''; echo second' task_after='echo after; echo done' work_dir='/data/project'\\''s worktree' task scripts/job.py now -- 'user value'",
);
assert.equal(spec.timeoutMs, 60_000);
assert.equal(spec.terminationGraceMs, 2_000);
assert.deepEqual(spec.resourcePolicy, {
memoryBytes: {
value: 128 * 1024 * 1024,
enforcement: 'best_effort',
},
});
});
test('rejects invalid legacy ids and empty commands before execution', () => {
assert.throws(
() =>
buildLegacyCronExecutionSpec(
createInput({ cron: { id: 0, command: 'script.py' } }),
),
InvalidExecutionSpecError,
);
assert.throws(
() =>
buildLegacyCronExecutionSpec(
createInput({ cron: { id: 1, command: ' ' } }),
),
InvalidExecutionSpecError,
);
});