mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-23 03:18:09 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const { test } = require('node:test');
|
||||
|
||||
const {
|
||||
createTaskDefinitionRecord,
|
||||
} = require('@qinglong/runtime-core/task-definition');
|
||||
const { createTriggerRecord } = require('@qinglong/runtime-core/trigger');
|
||||
const {
|
||||
ClusterAutomationManagementTransportAuthenticationError,
|
||||
ClusterAutomationManagementTransportRequestError,
|
||||
createClusterAutomationManagementTransport,
|
||||
} = require('@qinglong/cluster-admin/automation-management-transport');
|
||||
|
||||
const principal = Object.freeze({
|
||||
subject: Object.freeze({ type: 'user', id: 'operator-a' }),
|
||||
authenticationId: 'session-operator-a',
|
||||
authenticatedAtMs: 900,
|
||||
expiresAtMs: 10_000,
|
||||
assurance: 'hardware',
|
||||
});
|
||||
const taskCommand = Object.freeze({
|
||||
projectId: 'project-a',
|
||||
taskId: 'task-a',
|
||||
expectedRevision: null,
|
||||
mutationId: '123e4567-e89b-42d3-a456-426614174000',
|
||||
name: 'Sensitive task name',
|
||||
kind: 'script',
|
||||
spec: {
|
||||
schema: 'qinglong/script@v1',
|
||||
config: { source: 'sensitive script body' },
|
||||
},
|
||||
labels: {},
|
||||
enabled: true,
|
||||
occurredAtMs: 1_000,
|
||||
});
|
||||
const triggerCommand = Object.freeze({
|
||||
projectId: 'project-a',
|
||||
triggerId: 'trigger-a',
|
||||
expectedRevision: null,
|
||||
mutationId: '123e4567-e89b-42d3-a456-426614174002',
|
||||
taskId: 'task-a',
|
||||
taskRevision: 1,
|
||||
taskContentDigest: 'a'.repeat(64),
|
||||
spec: {
|
||||
schema: 'qinglong/cron@v1',
|
||||
config: {
|
||||
expression: '*/5 * * * *',
|
||||
timezone: 'UTC',
|
||||
misfirePolicy: 'fire_once',
|
||||
},
|
||||
},
|
||||
enabled: true,
|
||||
occurredAtMs: 1_000,
|
||||
});
|
||||
|
||||
test('routes strong User Task/Trigger publications and returns only low-sensitive summaries', async () => {
|
||||
const calls = [];
|
||||
const transport = createClusterAutomationManagementTransport({
|
||||
service: {
|
||||
async publishTask(request) {
|
||||
calls.push(['task', request]);
|
||||
return {
|
||||
status: 'created',
|
||||
definition: createTaskDefinitionRecord(request.command, 900),
|
||||
};
|
||||
},
|
||||
async publishTrigger(request) {
|
||||
calls.push(['trigger', request]);
|
||||
return {
|
||||
status: 'created',
|
||||
trigger: createTriggerRecord(request.command, 900),
|
||||
};
|
||||
},
|
||||
async inspectTask(request) {
|
||||
calls.push(['task-inspect', request]);
|
||||
return createTaskDefinitionRecord(taskCommand, 900);
|
||||
},
|
||||
async listTasks(request) {
|
||||
calls.push(['task-list', request]);
|
||||
return {
|
||||
definitions: [createTaskDefinitionRecord(taskCommand, 900)],
|
||||
truncated: true,
|
||||
next: { taskId: 'task-a' },
|
||||
};
|
||||
},
|
||||
async inspectTrigger(request) {
|
||||
calls.push(['trigger-inspect', request]);
|
||||
return null;
|
||||
},
|
||||
async listTriggers(request) {
|
||||
calls.push(['trigger-list', request]);
|
||||
return {
|
||||
triggers: [createTriggerRecord(triggerCommand, 900)],
|
||||
truncated: false,
|
||||
};
|
||||
},
|
||||
},
|
||||
now: () => 1_100,
|
||||
});
|
||||
const authentication = { async authenticate() { return principal; } };
|
||||
const task = await transport.execute(
|
||||
{
|
||||
schemaVersion: 1,
|
||||
operation: 'task.publish',
|
||||
request: { requestId: 'request-task', command: taskCommand },
|
||||
},
|
||||
authentication,
|
||||
);
|
||||
const trigger = await transport.execute(
|
||||
{
|
||||
schemaVersion: 1,
|
||||
operation: 'trigger.publish',
|
||||
request: { requestId: 'request-trigger', command: triggerCommand },
|
||||
},
|
||||
authentication,
|
||||
);
|
||||
const taskInspection = await transport.execute(
|
||||
{
|
||||
schemaVersion: 1,
|
||||
operation: 'task.inspect',
|
||||
request: {
|
||||
requestId: 'request-task-inspect',
|
||||
auditEventId: '123e4567-e89b-42d3-a456-426614174010',
|
||||
projectId: 'project-a',
|
||||
taskId: 'task-a',
|
||||
},
|
||||
},
|
||||
authentication,
|
||||
);
|
||||
const taskList = await transport.execute(
|
||||
{
|
||||
schemaVersion: 1,
|
||||
operation: 'task.list',
|
||||
request: {
|
||||
requestId: 'request-task-list',
|
||||
auditEventId: '123e4567-e89b-42d3-a456-426614174011',
|
||||
projectId: 'project-a',
|
||||
limit: 1,
|
||||
},
|
||||
},
|
||||
authentication,
|
||||
);
|
||||
const triggerInspection = await transport.execute(
|
||||
{
|
||||
schemaVersion: 1,
|
||||
operation: 'trigger.inspect',
|
||||
request: {
|
||||
requestId: 'request-trigger-inspect',
|
||||
auditEventId: '123e4567-e89b-42d3-a456-426614174012',
|
||||
projectId: 'project-a',
|
||||
triggerId: 'trigger-a',
|
||||
},
|
||||
},
|
||||
authentication,
|
||||
);
|
||||
const triggerList = await transport.execute(
|
||||
{
|
||||
schemaVersion: 1,
|
||||
operation: 'trigger.list',
|
||||
request: {
|
||||
requestId: 'request-trigger-list',
|
||||
auditEventId: '123e4567-e89b-42d3-a456-426614174013',
|
||||
projectId: 'project-a',
|
||||
limit: 1,
|
||||
},
|
||||
},
|
||||
authentication,
|
||||
);
|
||||
assert.deepEqual(calls.map(([kind]) => kind), [
|
||||
'task',
|
||||
'trigger',
|
||||
'task-inspect',
|
||||
'task-list',
|
||||
'trigger-inspect',
|
||||
'trigger-list',
|
||||
]);
|
||||
assert.deepEqual(calls.map(([, request]) => request.principal), [
|
||||
principal,
|
||||
principal,
|
||||
principal,
|
||||
principal,
|
||||
principal,
|
||||
principal,
|
||||
]);
|
||||
assert.equal(task.task.contentDigest.length, 64);
|
||||
assert.equal(trigger.trigger.taskContentDigest, 'a'.repeat(64));
|
||||
assert.equal(taskInspection.status, 'found');
|
||||
assert.equal(taskList.next.taskId, 'task-a');
|
||||
assert.equal(triggerInspection.status, 'absent');
|
||||
assert.equal(triggerList.next, null);
|
||||
const serialized = JSON.stringify([
|
||||
task,
|
||||
trigger,
|
||||
taskInspection,
|
||||
taskList,
|
||||
triggerInspection,
|
||||
triggerList,
|
||||
]);
|
||||
assert.doesNotMatch(serialized, /Sensitive|script body|expression|authenticationId|mutationId/);
|
||||
});
|
||||
|
||||
test('rejects malformed envelopes and weak identities before service authority', async () => {
|
||||
let calls = 0;
|
||||
const transport = createClusterAutomationManagementTransport({
|
||||
service: {
|
||||
async publishTask() { calls += 1; },
|
||||
async publishTrigger() { calls += 1; },
|
||||
async inspectTask() { calls += 1; },
|
||||
async listTasks() { calls += 1; },
|
||||
async inspectTrigger() { calls += 1; },
|
||||
async listTriggers() { calls += 1; },
|
||||
},
|
||||
now: () => 1_100,
|
||||
});
|
||||
await assert.rejects(
|
||||
transport.execute(
|
||||
{ schemaVersion: 1, operation: 'task.publish', request: {}, extra: true },
|
||||
{ async authenticate() { return principal; } },
|
||||
),
|
||||
ClusterAutomationManagementTransportRequestError,
|
||||
);
|
||||
await assert.rejects(
|
||||
transport.execute(
|
||||
{
|
||||
schemaVersion: 1,
|
||||
operation: 'task.publish',
|
||||
request: { requestId: 'request-task', command: taskCommand },
|
||||
},
|
||||
{ async authenticate() { return { ...principal, assurance: 'single_factor' }; } },
|
||||
),
|
||||
ClusterAutomationManagementTransportAuthenticationError,
|
||||
);
|
||||
assert.equal(calls, 0);
|
||||
});
|
||||
Reference in New Issue
Block a user