mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): version worker support tier admission
This commit is contained in:
@@ -20,6 +20,8 @@ function worker() {
|
||||
const snapshot = canonicalRemoteWorkerCapabilities({
|
||||
architecture: 'arm64',
|
||||
executors: ['remote-worker'],
|
||||
protocolVersion: '1.0.0',
|
||||
supportTier: 'tier1',
|
||||
operatingSystem: 'linux',
|
||||
runtimes: [{ name: 'node', version: '24.18.0' }],
|
||||
labels: { region: 'cn-east', tier: 'edge' },
|
||||
@@ -90,7 +92,10 @@ test('rejects non-canonical snapshots and reports bounded mismatch classes', ()
|
||||
const value = worker();
|
||||
const reordered = {
|
||||
...value,
|
||||
capabilitiesJson: JSON.stringify({ executors: ['remote-worker'], architecture: 'arm64' }),
|
||||
capabilitiesJson: JSON.stringify({
|
||||
executors: ['remote-worker'], architecture: 'arm64',
|
||||
protocolVersion: '1.0.0', supportTier: 'tier1',
|
||||
}),
|
||||
};
|
||||
reordered.capabilitiesHash = require('node:crypto')
|
||||
.createHash('sha256')
|
||||
@@ -102,7 +107,7 @@ test('rejects non-canonical snapshots and reports bounded mismatch classes', ()
|
||||
);
|
||||
const decision = evaluateRemoteWorkerPlacement(
|
||||
value,
|
||||
{ required: { architectures: ['x64'], labels: { region: 'eu' } } },
|
||||
{ required: { architectures: ['amd64'], labels: { region: 'eu' } } },
|
||||
20_000,
|
||||
);
|
||||
assert.deepEqual(decision.mismatches, ['architecture', 'label']);
|
||||
|
||||
@@ -36,6 +36,8 @@ test('uses pinned SemVer for remote runtime range admission', () => {
|
||||
const candidate = worker({
|
||||
architecture: 'arm64',
|
||||
executors: ['remote-worker'],
|
||||
protocolVersion: '1.0.0',
|
||||
supportTier: 'tier1',
|
||||
runtimes: [{ name: 'node', version: '24.18.0' }],
|
||||
});
|
||||
|
||||
@@ -54,3 +56,51 @@ test('uses pinned SemVer for remote runtime range admission', () => {
|
||||
/versionRange is not semver/,
|
||||
);
|
||||
});
|
||||
|
||||
test('defaults to Tier 1 protocol v1 and requires explicit legacy placement', () => {
|
||||
const legacy = worker({
|
||||
architecture: 'arm/v6', executors: ['remote-worker'],
|
||||
protocolVersion: '1.0.0', supportTier: 'legacy-only',
|
||||
});
|
||||
assert.deepEqual(evaluateRemoteWorkerPlacement(legacy, {}, 500), {
|
||||
matches: false, score: 0, mismatches: ['support_tier'],
|
||||
});
|
||||
assert.deepEqual(evaluateRemoteWorkerPlacement(
|
||||
legacy, { required: { supportTiers: ['legacy-only'] } }, 500,
|
||||
), { matches: true, score: 0, mismatches: [] });
|
||||
const incompatible = worker({
|
||||
architecture: 'arm64', executors: ['remote-worker'],
|
||||
protocolVersion: '2.0.0', supportTier: 'tier1',
|
||||
});
|
||||
assert.deepEqual(evaluateRemoteWorkerPlacement(incompatible, {}, 500), {
|
||||
matches: false, score: 0, mismatches: ['protocol_version'],
|
||||
});
|
||||
});
|
||||
|
||||
test('rejects unversioned capabilities and unknown support policy', () => {
|
||||
assert.throws(() => canonicalRemoteWorkerCapabilities({
|
||||
architecture: 'arm64', executors: ['remote-worker'],
|
||||
}), /shape is invalid/);
|
||||
assert.throws(() => normalizeRemoteWorkerPlacement({
|
||||
required: { supportTiers: ['unsupported'] },
|
||||
}), /supportTier is unknown/);
|
||||
assert.throws(() => normalizeRemoteWorkerPlacement({
|
||||
required: { protocolVersionRange: 'not-a-range' },
|
||||
}), /protocolVersionRange is not semver/);
|
||||
assert.throws(() => canonicalRemoteWorkerCapabilities({
|
||||
architecture: 'arm/v7', executors: ['remote-worker'],
|
||||
protocolVersion: '1.0.0', supportTier: 'tier1',
|
||||
}), /does not belong to supportTier/);
|
||||
});
|
||||
|
||||
test('keeps Worker architecture tiers aligned with the release identity', () => {
|
||||
const { REMOTE_WORKER_ARCHITECTURES_BY_SUPPORT_TIER } =
|
||||
require('../dist/remote-execution/remoteWorkerCompatibility');
|
||||
const release = require('../../../ql3-release.json');
|
||||
assert.deepEqual(REMOTE_WORKER_ARCHITECTURES_BY_SUPPORT_TIER, {
|
||||
tier1: release.architectureSupport.tier1,
|
||||
candidate: release.architectureSupport.candidates,
|
||||
experimental: release.architectureSupport.experimentalBlocked,
|
||||
'legacy-only': release.architectureSupport.legacyOnly,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ const {
|
||||
} = require('../dist');
|
||||
|
||||
function capabilities() {
|
||||
const json = '{"architecture":"arm64","executors":["remote-worker"]}';
|
||||
const json = '{"architecture":"arm64","executors":["remote-worker"],"protocolVersion":"1.0.0","supportTier":"tier1"}';
|
||||
return {
|
||||
json,
|
||||
hash: createHash('sha256').update(json).digest('hex'),
|
||||
@@ -42,6 +42,10 @@ test('rejects forged capabilities, partial status capacity and invalid time', ()
|
||||
() => assertWorkerCapabilitiesSnapshot(snapshot.json, '0'.repeat(64)),
|
||||
InvalidWorkerSessionValueError,
|
||||
);
|
||||
const unversioned = '{"architecture":"arm64","executors":["remote-worker"]}';
|
||||
assert.throws(() => assertWorkerCapabilitiesSnapshot(
|
||||
unversioned, createHash('sha256').update(unversioned).digest('hex'),
|
||||
), /compatibility contract is invalid/);
|
||||
assert.throws(
|
||||
() =>
|
||||
assertWorkerSessionRecord({
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const { createHash } = require('node:crypto');
|
||||
const { test } = require('node:test');
|
||||
const {
|
||||
createWorkerSessionHeartbeatRequestBody,
|
||||
@@ -21,9 +22,10 @@ const authority = Object.freeze({
|
||||
workerId: 'edge-1',
|
||||
sessionId: '018f5c64-9b9d-7f1a-8c2d-1234567890ac',
|
||||
});
|
||||
const capabilitiesJson = '{}';
|
||||
const capabilitiesHash =
|
||||
'44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a';
|
||||
const capabilitiesJson =
|
||||
'{"architecture":"arm64","executors":["remote-worker"],"protocolVersion":"1.0.0","supportTier":"tier1"}';
|
||||
const capabilitiesHash = createHash('sha256')
|
||||
.update(capabilitiesJson).digest('hex');
|
||||
|
||||
function record(overrides = {}) {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user