'use strict'; const assert = require('node:assert/strict'); const { test } = require('node:test'); const { ClusterRunManagementTransportAuthenticationError, ClusterRunManagementTransportRequestError, createClusterRunManagementTransport, normalizeClusterRunManagementCommand, } = require('@qinglong/cluster-admin/run-management-transport'); const NOW = 1_000_000; function principal(overrides = {}) { return { subject: { type: 'user', id: 'operator-1' }, authenticationId: 'oidc:run-management-1', authenticatedAtMs: 999_000, expiresAtMs: 1_100_000, assurance: 'multi_factor', ...overrides, }; } function command(overrides = {}) { return { schemaVersion: 1, operation: 'run.retry', request: { projectId: 'project-1', sourceRunId: 'source-run-1', requestId: 'request-1', auditEventId: '019f9300-0000-4000-8000-000000000001', failureAuditEventId: '019f9300-0000-4000-8000-000000000002', body: { schema: 'qinglong/run-manual-retry@v1', mutationId: '019f9300-0000-4000-8000-000000000003', expectedRunVersion: 7, expectedRunStatus: 'failed', }, ...overrides, }, }; } function retryResult() { return { status: 'accepted', projectId: 'project-1', sourceRunId: 'source-run-1', sourceRunStatus: 'failed', sourceRunVersion: 7, runId: '019f9300-0000-4000-8000-000000000010', retryOfRunId: 'source-run-1', taskId: 'task-1', taskRevision: `qltd:v1:1:${'a'.repeat(64)}`, attemptId: '019f9300-0000-4000-8000-000000000011', runStatus: 'queued', runVersion: 2, eventSequence: 2, executorType: 'remote_worker', executionRevisionDigest: 'b'.repeat(64), createdAtMs: NOW, }; } function stopCommand(overrides = {}) { return { schemaVersion: 1, operation: 'run.stop', request: { projectId: 'project-1', runId: 'run-1', requestId: 'request-stop-1', auditEventId: '019f9300-0000-4000-8000-000000000021', failureAuditEventId: '019f9300-0000-4000-8000-000000000022', body: { schema: 'qinglong/run-cancellation@v1', mutationId: '019f9300-0000-4000-8000-000000000023', }, ...overrides, }, }; } function stopResult() { return { status: 'accepted', projectId: 'project-1', runId: 'run-1', runStatus: 'running', runVersion: 5, eventSequence: 7, cancelRequestedAtMs: NOW, cancelReason: 'user', }; } function diagnosticResult() { return { projectId: 'project-1', runId: 'run-1', runStatus: 'running', runVersion: 6, eventSequence: 8, cancelRequestedAtMs: NOW - 1_000, cancelReason: 'user', operatorAction: 'rearm', dispatch: { attemptId: 'attempt-1', status: 'blocked', version: 3, dispatchCount: 1, lastResult: 'identity_mismatch', createdAtMs: NOW - 900, updatedAtMs: NOW - 800, }, }; } function summaryResult() { return { projectId: 'project-1', observedAtMs: NOW, assessment: 'attention_required', operatorAction: 'inspect', dispatches: { total: 5, pending: 1, leased: 1, retryWait: 1, dispatched: 1, blocked: 1, }, signals: { due: 1, expiredLease: 1 }, blockingResults: { identityMismatch: 1, pidMismatch: 0, unsupported: 0, invalid: 0, }, oldestBlockedAtMs: NOW - 800, }; } function blockedListResult() { return { projectId: 'project-1', snapshotAtMs: NOW, observedAtMs: NOW, items: [{ runId: 'run-1', blockedAtMs: NOW - 800 }], truncated: false, }; } function rearmResult() { return { status: 'rearmed', projectId: 'project-1', runId: 'run-1', attemptId: 'attempt-1', previousDispatchVersion: 3, dispatchVersion: 4, previousResult: 'identity_mismatch', retryDelayMs: 5_000, nextAttemptAtMs: NOW + 5_000, runVersion: 7, eventSequence: 9, }; } function inspectCommand(overrides = {}) { return { schemaVersion: 1, operation: 'run.cancellation.inspect', request: { projectId: 'project-1', runId: 'run-1', requestId: 'request-inspect-1', auditEventId: '019f9300-0000-4000-8000-000000000031', failureAuditEventId: '019f9300-0000-4000-8000-000000000032', body: { schema: 'qinglong/run-cancellation-dispatch-inspect@v1', }, ...overrides, }, }; } function summaryCommand(overrides = {}) { return { schemaVersion: 1, operation: 'run.cancellation.summary', request: { projectId: 'project-1', requestId: 'request-summary-1', auditEventId: '019f9300-0000-4000-8000-000000000051', failureAuditEventId: '019f9300-0000-4000-8000-000000000052', body: { schema: 'qinglong/run-cancellation-dispatch-summary-request@v1', }, ...overrides, }, }; } function blockedListCommand(overrides = {}) { return { schemaVersion: 1, operation: 'run.cancellation.blocked.list', request: { projectId: 'project-1', requestId: 'request-blocked-1', auditEventId: '019f9300-0000-4000-8000-000000000061', failureAuditEventId: '019f9300-0000-4000-8000-000000000062', body: { schema: 'qinglong/run-cancellation-dispatch-blocked-list-request@v1', after: null, }, ...overrides, }, }; } function rearmCommand(overrides = {}) { return { schemaVersion: 1, operation: 'run.cancellation.rearm', request: { projectId: 'project-1', runId: 'run-1', requestId: 'request-rearm-1', auditEventId: '019f9300-0000-4000-8000-000000000041', failureAuditEventId: '019f9300-0000-4000-8000-000000000042', body: { schema: 'qinglong/run-cancellation-dispatch-rearm-request@v1', mutationId: '019f9300-0000-4000-8000-000000000043', expectedDispatchVersion: 3, expectedLastResult: 'identity_mismatch', retryDelayMs: 5_000, }, ...overrides, }, }; } test('routes one exact strong User retry and emits the shared response', async () => { const calls = []; const transport = createClusterRunManagementTransport({ now: () => NOW, service: { async retry(request) { calls.push(request); return retryResult(); }, async stop() { return stopResult(); }, async summarizeCancellation() { return summaryResult(); }, async listBlockedCancellations() { return blockedListResult(); }, async inspectCancellation() { return diagnosticResult(); }, async rearmCancellation() { return rearmResult(); }, }, }); const result = await transport.execute(command(), { authenticate: async () => principal(), }); assert.equal(calls.length, 1); assert.equal(calls[0].mutationId, command().request.body.mutationId); assert.equal(calls[0].principal.assurance, 'multi_factor'); assert.deepEqual(result, { schemaVersion: 1, operation: 'run.retry', retry: { schema: 'qinglong/run-manual-retry@v1', ...retryResult(), }, }); }); test('routes one exact strong User stop and emits the shared response', async () => { const calls = []; const transport = createClusterRunManagementTransport({ now: () => NOW, service: { async retry() { return retryResult(); }, async stop(request) { calls.push(request); return stopResult(); }, async summarizeCancellation() { return summaryResult(); }, async listBlockedCancellations() { return blockedListResult(); }, async inspectCancellation() { return diagnosticResult(); }, async rearmCancellation() { return rearmResult(); }, }, }); const result = await transport.execute(stopCommand(), { authenticate: async () => principal({ assurance: 'hardware' }), }); assert.equal(calls.length, 1); assert.equal(calls[0].runId, 'run-1'); assert.equal(calls[0].mutationId, stopCommand().request.body.mutationId); assert.deepEqual(result, { schemaVersion: 1, operation: 'run.stop', stop: { schema: 'qinglong/run-cancellation@v1', ...stopResult(), }, }); }); test('rejects weak or non-User identity before service authority', async () => { let called = false; const transport = createClusterRunManagementTransport({ now: () => NOW, service: { async retry() { called = true; return retryResult(); }, async stop() { return stopResult(); }, async summarizeCancellation() { return summaryResult(); }, async listBlockedCancellations() { return blockedListResult(); }, async inspectCancellation() { return diagnosticResult(); }, async rearmCancellation() { return rearmResult(); }, }, }); await assert.rejects( transport.execute(command(), { authenticate: async () => principal({ assurance: 'single_factor' }), }), ClusterRunManagementTransportAuthenticationError, ); await assert.rejects( transport.execute(command(), { authenticate: async () => principal({ subject: { type: 'agent', id: 'agent-1' } }), }), ClusterRunManagementTransportAuthenticationError, ); assert.equal(called, false); }); test('routes bounded cancellation inspection without lease capability data', async () => { const calls = []; const transport = createClusterRunManagementTransport({ now: () => NOW, service: { async retry() { return retryResult(); }, async stop() { return stopResult(); }, async summarizeCancellation() { return summaryResult(); }, async listBlockedCancellations() { return blockedListResult(); }, async inspectCancellation(request) { calls.push(request); return diagnosticResult(); }, async rearmCancellation() { return rearmResult(); }, }, }); const result = await transport.execute(inspectCommand(), { authenticate: async () => principal(), }); assert.equal(calls[0].runId, 'run-1'); assert.deepEqual(result, { schemaVersion: 1, operation: 'run.cancellation.inspect', diagnostic: { schema: 'qinglong/run-cancellation-dispatch-diagnostic@v1', ...diagnosticResult(), }, }); assert.equal(JSON.stringify(result).includes('leaseOwner'), false); assert.equal(JSON.stringify(result).includes('leaseToken'), false); }); test('routes one Project-scoped cancellation summary without Run identity', async () => { const calls = []; const transport = createClusterRunManagementTransport({ now: () => NOW, service: { async retry() { return retryResult(); }, async stop() { return stopResult(); }, async summarizeCancellation(request) { calls.push(request); return summaryResult(); }, async listBlockedCancellations() { return blockedListResult(); }, async inspectCancellation() { return diagnosticResult(); }, async rearmCancellation() { return rearmResult(); }, }, }); const result = await transport.execute(summaryCommand(), { authenticate: async () => principal(), }); assert.equal(calls.length, 1); assert.equal(calls[0].projectId, 'project-1'); assert.equal(Object.hasOwn(calls[0], 'runId'), false); assert.deepEqual(result, { schemaVersion: 1, operation: 'run.cancellation.summary', summary: { schema: 'qinglong/run-cancellation-dispatch-summary@v1', ...summaryResult(), }, }); assert.equal(JSON.stringify(result).includes('attemptId'), false); assert.equal(JSON.stringify(result).includes('leaseOwner'), false); }); test('routes one fixed Project blocked page without dispatch internals', async () => { const calls = []; const transport = createClusterRunManagementTransport({ now: () => NOW, service: { async retry() { return retryResult(); }, async stop() { return stopResult(); }, async summarizeCancellation() { return summaryResult(); }, async listBlockedCancellations(request) { calls.push(request); return blockedListResult(); }, async inspectCancellation() { return diagnosticResult(); }, async rearmCancellation() { return rearmResult(); }, }, }); const result = await transport.execute(blockedListCommand(), { authenticate: async () => principal(), }); assert.equal(calls.length, 1); assert.equal(calls[0].projectId, 'project-1'); assert.equal(Object.hasOwn(calls[0], 'after'), false); assert.deepEqual(result, { schemaVersion: 1, operation: 'run.cancellation.blocked.list', page: { schema: 'qinglong/run-cancellation-dispatch-blocked-page@v1', ...blockedListResult(), }, }); for (const forbidden of [ 'attemptId', 'dispatchVersion', 'lastResult', 'leaseOwner', 'leaseToken', ]) { assert.equal(JSON.stringify(result).includes(forbidden), false); } }); test('routes an exact blocked cancellation rearm receipt', async () => { const calls = []; const transport = createClusterRunManagementTransport({ now: () => NOW, service: { async retry() { return retryResult(); }, async stop() { return stopResult(); }, async summarizeCancellation() { return summaryResult(); }, async listBlockedCancellations() { return blockedListResult(); }, async inspectCancellation() { return diagnosticResult(); }, async rearmCancellation(request) { calls.push(request); return rearmResult(); }, }, }); const result = await transport.execute(rearmCommand(), { authenticate: async () => principal({ assurance: 'hardware' }), }); assert.equal(calls[0].expectedDispatchVersion, 3); assert.equal(calls[0].expectedLastResult, 'identity_mismatch'); assert.deepEqual(result, { schemaVersion: 1, operation: 'run.cancellation.rearm', rearm: { schema: 'qinglong/run-cancellation-dispatch-rearm-receipt@v1', ...rearmResult(), }, }); }); test('rejects widened commands and ambiguous audit identity', () => { assert.throws( () => normalizeClusterRunManagementCommand({ ...command(), principal: principal(), }), ClusterRunManagementTransportRequestError, ); assert.throws( () => normalizeClusterRunManagementCommand( command({ failureAuditEventId: command().request.auditEventId }), ), ClusterRunManagementTransportRequestError, ); assert.throws( () => normalizeClusterRunManagementCommand( command({ body: { ...command().request.body, expectedRunStatus: 'lost' }, }), ), ClusterRunManagementTransportRequestError, ); assert.throws( () => normalizeClusterRunManagementCommand( stopCommand({ body: { ...stopCommand().request.body, mutationId: 'weak' }, }), ), ClusterRunManagementTransportRequestError, ); });