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,289 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const { test } = require('node:test');
|
||||
|
||||
const {
|
||||
buildEvidenceReport,
|
||||
canonicalDigest,
|
||||
normalizeManifest,
|
||||
parseArguments,
|
||||
validateServiceStartEvidenceReport,
|
||||
} = require('../../scripts/ql3-physical-edge-evidence.cjs');
|
||||
const {
|
||||
buildServiceStartReport,
|
||||
normalizeServiceStartManifest,
|
||||
normalizeSession,
|
||||
} = require('../../scripts/ql3-physical-edge-service-start.cjs');
|
||||
|
||||
const deviceBootId = '019f0000-0000-4000-8000-000000000002';
|
||||
const packages = [
|
||||
'@qinglong/local-admin',
|
||||
'@qinglong/local-application',
|
||||
'@qinglong/local-command-file',
|
||||
'@qinglong/local-execution',
|
||||
'@qinglong/local-process',
|
||||
'@qinglong/local-secret',
|
||||
'@qinglong/local-sqlite',
|
||||
'@qinglong/runtime-core',
|
||||
'croner',
|
||||
'semver',
|
||||
];
|
||||
|
||||
function baseManifest() {
|
||||
return normalizeManifest({
|
||||
schemaVersion: 1,
|
||||
evidenceClass: 'physical_edge_candidate',
|
||||
profile: 'edge',
|
||||
deviceId: 'router-a1',
|
||||
deviceModel: 'router-a1-model',
|
||||
soc: 'arm-soc',
|
||||
storageMedium: 'emmc',
|
||||
expectedArchitecture: 'arm64',
|
||||
memoryBytes: {
|
||||
minimum: 128 * 1024 * 1024,
|
||||
maximum: 512 * 1024 * 1024,
|
||||
},
|
||||
expectedFilesystem: 'ext4',
|
||||
});
|
||||
}
|
||||
|
||||
function observed() {
|
||||
return {
|
||||
platform: 'linux',
|
||||
architecture: 'arm64',
|
||||
bootId: deviceBootId,
|
||||
bootAgeMs: 15_000,
|
||||
dataFilesystem: 'ext4',
|
||||
nodeExecutable: '/usr/bin/node',
|
||||
nodeSha256: 'd'.repeat(64),
|
||||
nodeVersion: 'v24.18.0',
|
||||
virtualizationIndicators: [],
|
||||
};
|
||||
}
|
||||
|
||||
function physicalObserved() {
|
||||
return {
|
||||
platform: 'linux',
|
||||
architecture: 'arm64',
|
||||
node: 'v24.18.0',
|
||||
bootId: deviceBootId,
|
||||
kernel: '6.6.0',
|
||||
distribution: { id: 'openwrt', versionId: '24.10' },
|
||||
libc: 'musl-ld-musl-aarch64.so.1',
|
||||
cpuModel: 'test-cpu',
|
||||
cpuCount: 1,
|
||||
totalMemoryBytes: 256 * 1024 * 1024,
|
||||
observedModel: 'router-a1-model',
|
||||
dataPath: '/mnt/ql3-evidence',
|
||||
dataFilesystem: 'ext4',
|
||||
dataMountOptions: ['rw', 'noatime'],
|
||||
dataBytes: 4 * 1024 * 1024 * 1024,
|
||||
dataAvailableBytes: 2 * 1024 * 1024 * 1024,
|
||||
virtualizationIndicators: [],
|
||||
};
|
||||
}
|
||||
|
||||
function artifact() {
|
||||
return {
|
||||
artifactSha256: 'a'.repeat(64),
|
||||
artifactMetadataSha256: 'b'.repeat(64),
|
||||
artifactFiles: 627,
|
||||
artifactBytes: 5_045_360,
|
||||
entrypointSha256: 'c'.repeat(64),
|
||||
packages,
|
||||
};
|
||||
}
|
||||
|
||||
function serviceManifest() {
|
||||
return normalizeServiceStartManifest({
|
||||
schemaVersion: 1,
|
||||
evidenceClass: 'physical_edge_service_start_candidate',
|
||||
profile: 'edge',
|
||||
deviceId: 'router-a1',
|
||||
serviceManager: 'systemd',
|
||||
expectedArchitecture: 'arm64',
|
||||
expectedFilesystem: 'ext4',
|
||||
expectedArtifactSha256: 'a'.repeat(64),
|
||||
expectedArtifactFiles: 627,
|
||||
expectedArtifactBytes: 5_045_360,
|
||||
expectedNodeSha256: 'd'.repeat(64),
|
||||
maximumBootToActiveMs: 180_000,
|
||||
maximumServiceStartBootAgeMs: 60_000,
|
||||
maximumServiceStartToActiveMs: 30_000,
|
||||
});
|
||||
}
|
||||
|
||||
function serviceReport() {
|
||||
const sessionId = '019f0000-0000-4000-8000-000000000020';
|
||||
const dataPath = '/mnt/ql3-evidence';
|
||||
const deploymentRoot = `${dataPath}/.ql3-service-start-deployment-${sessionId}`;
|
||||
const toolRoot = `${deploymentRoot}/physical-service-start`;
|
||||
const serviceName = 'qinglong3-physical-019f0000';
|
||||
const sessionBody = {
|
||||
schemaVersion: 1,
|
||||
evidenceClass: 'physical_edge_service_start_session',
|
||||
sessionId,
|
||||
manifestDigest: canonicalDigest(serviceManifest()),
|
||||
uid: 1000,
|
||||
preparedAt: '2026-07-29T08:00:00.000Z',
|
||||
artifact: artifact(),
|
||||
environment: {
|
||||
...observed(),
|
||||
bootId: '019f0000-0000-4000-8000-000000000001',
|
||||
},
|
||||
paths: {
|
||||
dataPath,
|
||||
toolRoot,
|
||||
deploymentRoot,
|
||||
artifactRoot: '/opt/qinglong3-release',
|
||||
applicationEntrypoint:
|
||||
'/opt/qinglong3-release/node_modules/@qinglong/local-application/dist/cli.js',
|
||||
applicationConfig: `${deploymentRoot}/local-application.json`,
|
||||
wrapper: `${toolRoot}/boot-probe.sh`,
|
||||
wrapperStartRecord: `${toolRoot}/wrapper-start.record`,
|
||||
nodeRecord: `${toolRoot}/node.record`,
|
||||
activeRecord: `${toolRoot}/active.record`,
|
||||
eventLog: `${toolRoot}/events.jsonl`,
|
||||
stderrLog: `${toolRoot}/stderr.log`,
|
||||
fifo: `${toolRoot}/events.fifo`,
|
||||
},
|
||||
service: {
|
||||
kind: 'systemd',
|
||||
serviceName,
|
||||
managerExecutable: '/usr/bin/systemctl',
|
||||
managerSha256: 'e'.repeat(64),
|
||||
enableExecutable: '/usr/bin/systemctl',
|
||||
enableSha256: 'e'.repeat(64),
|
||||
descriptorSource: `${deploymentRoot}/service/qinglong3.service`,
|
||||
descriptorDestination: `/etc/systemd/system/${serviceName}.service`,
|
||||
descriptorMode: 0o644,
|
||||
descriptorSha256: 'f'.repeat(64),
|
||||
wrapperSha256: '1'.repeat(64),
|
||||
installArguments: [
|
||||
'-o',
|
||||
'root',
|
||||
'-g',
|
||||
'root',
|
||||
'-m',
|
||||
'644',
|
||||
`${deploymentRoot}/service/qinglong3.service`,
|
||||
`/etc/systemd/system/${serviceName}.service`,
|
||||
],
|
||||
enableArguments: ['enable', serviceName],
|
||||
},
|
||||
};
|
||||
const session = normalizeSession({
|
||||
...sessionBody,
|
||||
sha256: canonicalDigest(sessionBody),
|
||||
});
|
||||
return buildServiceStartReport({
|
||||
manifest: serviceManifest(),
|
||||
session,
|
||||
observed: {
|
||||
after: observed(),
|
||||
artifact: artifact(),
|
||||
process: {
|
||||
bootId: deviceBootId,
|
||||
wrapperPid: 101,
|
||||
wrapperStartTicks: 1200,
|
||||
nodePid: 102,
|
||||
nodeStartTicks: 1201,
|
||||
},
|
||||
service: {
|
||||
kind: 'systemd',
|
||||
serviceName,
|
||||
managerExecutable: '/usr/bin/systemctl',
|
||||
managerSha256: 'e'.repeat(64),
|
||||
descriptorSha256: 'f'.repeat(64),
|
||||
mainPid: 101,
|
||||
},
|
||||
},
|
||||
measurements: {
|
||||
serviceStartBootAgeMs: 12_000,
|
||||
activeBootAgeMs: 13_250,
|
||||
bootToActiveMs: 13_250,
|
||||
serviceStartToActiveMs: 1_250,
|
||||
activeEventOrdinal: 2,
|
||||
},
|
||||
outcomes: {
|
||||
activeEventCount: 1,
|
||||
aiStatus: 'deployment_excluded',
|
||||
descriptorInstalled: true,
|
||||
serviceActive: true,
|
||||
serviceEnabled: true,
|
||||
wrapperProcessIdentityMatched: true,
|
||||
nodeProcessIdentityMatched: true,
|
||||
stderrBytes: 0,
|
||||
},
|
||||
generatedAt: '2026-07-29T08:01:00.000Z',
|
||||
});
|
||||
}
|
||||
|
||||
test('accepts the service-start importer path', () => {
|
||||
assert.equal(
|
||||
parseArguments([
|
||||
'--manifest=/mnt/data/manifest.json',
|
||||
'--data-path=/mnt/data',
|
||||
'--service-start-evidence=/mnt/data/service-start.json',
|
||||
]).serviceStartEvidencePath,
|
||||
'/mnt/data/service-start.json',
|
||||
);
|
||||
assert.throws(
|
||||
() =>
|
||||
parseArguments([
|
||||
'--manifest=/mnt/data/manifest.json',
|
||||
'--data-path=/mnt/data',
|
||||
'--service-start-evidence=service-start.json',
|
||||
]),
|
||||
/serviceStartEvidencePath must be absolute/,
|
||||
);
|
||||
});
|
||||
|
||||
test('validates same-device current-boot service evidence', () => {
|
||||
assert.deepEqual(
|
||||
validateServiceStartEvidenceReport(
|
||||
serviceReport(),
|
||||
baseManifest(),
|
||||
observed(),
|
||||
),
|
||||
[],
|
||||
);
|
||||
assert.notDeepEqual(
|
||||
validateServiceStartEvidenceReport(serviceReport(), baseManifest(), {
|
||||
...observed(),
|
||||
bootId: '019f0000-0000-4000-8000-000000000099',
|
||||
}),
|
||||
[],
|
||||
);
|
||||
});
|
||||
|
||||
test('refines but does not erase the broad power-on startup gate', () => {
|
||||
const report = buildEvidenceReport({
|
||||
manifest: baseManifest(),
|
||||
observed: physicalObserved(),
|
||||
workloads: {},
|
||||
supplementalEvidence: [serviceReport()],
|
||||
generatedAt: '2026-07-29T08:02:00.000Z',
|
||||
});
|
||||
assert.ok(
|
||||
report.qualification.collectedEvidence.includes(
|
||||
'kernel_boot_to_init_managed_native_application_active',
|
||||
),
|
||||
);
|
||||
assert.ok(
|
||||
report.qualification.remainingRequiredEvidence.includes(
|
||||
'firmware_and_bootloader_power_on_to_linux_kernel_clock',
|
||||
),
|
||||
);
|
||||
assert.ok(
|
||||
report.qualification.remainingRequiredEvidence.includes(
|
||||
'direct_release_unit_without_evidence_wrapper',
|
||||
),
|
||||
);
|
||||
assert.equal(
|
||||
report.qualification.remainingRequiredEvidence.includes(
|
||||
'cold_start_and_first_ready',
|
||||
),
|
||||
false,
|
||||
);
|
||||
assert.equal(report.supported, false);
|
||||
});
|
||||
Reference in New Issue
Block a user