mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const { createHash } = require('node:crypto');
|
||||
const { test } = require('node:test');
|
||||
const {
|
||||
createRemoteWorkerArtifactUploadResponseBody,
|
||||
createRemoteWorkerCompletionResponseBody,
|
||||
parseRemoteWorkerArtifactUploadHeader,
|
||||
} = require('@qinglong/runtime-core/remote-worker-completion');
|
||||
const {
|
||||
WorkerRemoteArtifactHttpsUploader,
|
||||
WorkerRemoteCompletionHttpsError,
|
||||
WorkerRemoteExecutionHttpsCompletionClient,
|
||||
} = require('@qinglong/worker-runtime/completion-transport');
|
||||
|
||||
const SESSION_ID = '018f0000-0000-7000-8000-000000000001';
|
||||
const LEASE_TOKEN = 'worker_generated_lease_capability_0000000000000001';
|
||||
const LOG_ARTIFACT_ID = `wlog-${'a'.repeat(30)}`;
|
||||
const CALLBACK_DIGEST = 'b'.repeat(64);
|
||||
|
||||
function fence() {
|
||||
return {
|
||||
workerId: 'worker-1',
|
||||
workerSessionId: SESSION_ID,
|
||||
workerGeneration: 2,
|
||||
projectId: 'project-1',
|
||||
runId: 'run-1',
|
||||
attemptId: 'attempt-1',
|
||||
offerId: 'offer-1',
|
||||
leaseGeneration: 3,
|
||||
leaseToken: LEASE_TOKEN,
|
||||
expectedLeaseVersion: 4,
|
||||
};
|
||||
}
|
||||
|
||||
function uploadCommand(content) {
|
||||
return {
|
||||
...fence(),
|
||||
logArtifactId: LOG_ARTIFACT_ID,
|
||||
byteLength: content.byteLength,
|
||||
truncated: false,
|
||||
content: (async function* () { yield content; })(),
|
||||
};
|
||||
}
|
||||
|
||||
function completionCommand(content, overrides = {}) {
|
||||
return {
|
||||
...fence(),
|
||||
callbackSequence: 1,
|
||||
callbackTokenDigest: CALLBACK_DIGEST,
|
||||
result: {
|
||||
outcome: 'succeeded',
|
||||
startedAtMs: 100,
|
||||
finishedAtMs: 200,
|
||||
exitCode: 0,
|
||||
},
|
||||
artifact: {
|
||||
logArtifactId: LOG_ARTIFACT_ID,
|
||||
byteLength: content.byteLength,
|
||||
sha256: createHash('sha256').update(content).digest('hex'),
|
||||
truncated: false,
|
||||
},
|
||||
executorType: 'remote_worker',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
test('uploads one framed Artifact and verifies exact response authority', async () => {
|
||||
const content = Buffer.from('worker-log');
|
||||
let observed;
|
||||
const uploader = new WorkerRemoteArtifactHttpsUploader({
|
||||
client: {
|
||||
async postStream(request) {
|
||||
const chunks = [];
|
||||
for await (const chunk of request.body) chunks.push(Buffer.from(chunk));
|
||||
const envelope = Buffer.concat(chunks);
|
||||
const headerLength = envelope.readUInt32BE(0);
|
||||
const header = parseRemoteWorkerArtifactUploadHeader(
|
||||
envelope.subarray(4, 4 + headerLength),
|
||||
{ workerId: 'worker-1', workerSessionId: SESSION_ID },
|
||||
);
|
||||
observed = { request, envelope, header, headerLength };
|
||||
return Buffer.from(JSON.stringify(
|
||||
createRemoteWorkerArtifactUploadResponseBody({
|
||||
status: 'stored',
|
||||
projectId: 'project-1',
|
||||
runId: 'run-1',
|
||||
attemptId: 'attempt-1',
|
||||
logArtifactId: LOG_ARTIFACT_ID,
|
||||
byteLength: content.byteLength,
|
||||
sha256: createHash('sha256').update(content).digest('hex'),
|
||||
truncated: false,
|
||||
}),
|
||||
));
|
||||
},
|
||||
},
|
||||
});
|
||||
const result = await uploader.upload(uploadCommand(content));
|
||||
assert.equal(result.status, 'stored');
|
||||
assert.equal(result.sha256, createHash('sha256').update(content).digest('hex'));
|
||||
assert.equal(
|
||||
observed.request.path,
|
||||
`/api/v3/worker-ingress/workers/worker-1/sessions/${SESSION_ID}/artifacts`,
|
||||
);
|
||||
assert.equal(observed.request.byteLength, observed.envelope.byteLength);
|
||||
assert.deepEqual(
|
||||
observed.envelope.subarray(4 + observed.headerLength),
|
||||
content,
|
||||
);
|
||||
assert.equal(observed.header.leaseToken, LEASE_TOKEN);
|
||||
assert.equal(observed.header.logArtifactId, LOG_ARTIFACT_ID);
|
||||
});
|
||||
|
||||
test('rejects Artifact receipt authority drift', async () => {
|
||||
const content = Buffer.from('log');
|
||||
const uploader = new WorkerRemoteArtifactHttpsUploader({
|
||||
client: {
|
||||
async postStream(request) {
|
||||
for await (const _chunk of request.body) { /* consume */ }
|
||||
return Buffer.from(JSON.stringify(
|
||||
createRemoteWorkerArtifactUploadResponseBody({
|
||||
status: 'stored',
|
||||
projectId: 'project-other',
|
||||
runId: 'run-1',
|
||||
attemptId: 'attempt-1',
|
||||
logArtifactId: LOG_ARTIFACT_ID,
|
||||
byteLength: content.byteLength,
|
||||
sha256: 'c'.repeat(64),
|
||||
truncated: false,
|
||||
}),
|
||||
));
|
||||
},
|
||||
},
|
||||
});
|
||||
await assert.rejects(
|
||||
uploader.upload(uploadCommand(content)),
|
||||
(error) =>
|
||||
error instanceof WorkerRemoteCompletionHttpsError &&
|
||||
error.reason === 'response_invalid',
|
||||
);
|
||||
});
|
||||
|
||||
test('posts exact completion JSON and binds the response to the receipt', async () => {
|
||||
const content = Buffer.from('worker-log');
|
||||
let observed;
|
||||
const client = new WorkerRemoteExecutionHttpsCompletionClient({
|
||||
client: {
|
||||
async postJson(request) {
|
||||
observed = request;
|
||||
return Buffer.from(JSON.stringify(
|
||||
createRemoteWorkerCompletionResponseBody({
|
||||
status: 'applied',
|
||||
runId: 'run-1',
|
||||
attemptId: 'attempt-1',
|
||||
callbackSequence: 1,
|
||||
}),
|
||||
));
|
||||
},
|
||||
},
|
||||
});
|
||||
assert.deepEqual(await client.complete(completionCommand(content)), {
|
||||
status: 'applied',
|
||||
runId: 'run-1',
|
||||
attemptId: 'attempt-1',
|
||||
callbackSequence: 1,
|
||||
});
|
||||
assert.equal(
|
||||
observed.path,
|
||||
`/api/v3/worker-ingress/workers/worker-1/sessions/${SESSION_ID}/completion`,
|
||||
);
|
||||
assert.equal(observed.body.schema, 'qinglong/remote-worker-completion@v1');
|
||||
assert.equal('workerId' in observed.body, false);
|
||||
assert.equal('workerSessionId' in observed.body, false);
|
||||
assert.equal(observed.body.callbackTokenDigest, CALLBACK_DIGEST);
|
||||
assert.equal(observed.body.leaseToken, LEASE_TOKEN);
|
||||
});
|
||||
|
||||
test('rejects non-Worker execution and response authority drift', async () => {
|
||||
const content = Buffer.from('log');
|
||||
let calls = 0;
|
||||
const client = new WorkerRemoteExecutionHttpsCompletionClient({
|
||||
client: {
|
||||
async postJson() {
|
||||
calls += 1;
|
||||
return Buffer.from(JSON.stringify(
|
||||
createRemoteWorkerCompletionResponseBody({
|
||||
status: 'applied',
|
||||
runId: 'run-other',
|
||||
attemptId: 'attempt-1',
|
||||
callbackSequence: 1,
|
||||
}),
|
||||
));
|
||||
},
|
||||
},
|
||||
});
|
||||
await assert.rejects(
|
||||
client.complete(completionCommand(content, { executorType: 'local_process' })),
|
||||
(error) =>
|
||||
error instanceof WorkerRemoteCompletionHttpsError &&
|
||||
error.reason === 'request_invalid',
|
||||
);
|
||||
assert.equal(calls, 0);
|
||||
await assert.rejects(
|
||||
client.complete(completionCommand(content)),
|
||||
(error) =>
|
||||
error instanceof WorkerRemoteCompletionHttpsError &&
|
||||
error.reason === 'response_invalid',
|
||||
);
|
||||
assert.equal(calls, 1);
|
||||
});
|
||||
Reference in New Issue
Block a user