import assert from 'node:assert/strict'; import {copyFileSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync} from 'node:fs'; import {spawnSync} from 'node:child_process'; import {createHash} from 'node:crypto'; import {join, relative} from 'node:path'; const root = process.cwd(); const dir = mkdtempSync(join(root, 'reports/os-implementation/K1415-device-driver-match-local-')); const sha = path => createHash('sha256').update(readFileSync(path)).digest('hex'); const artifact = path => ({path: relative(root, path), sha256: sha(path)}); const copy = (source, target) => { mkdirSync(join(target, '..'), {recursive: true}); copyFileSync(join(root, source), target); return artifact(target); }; const sourceRoot = join(dir, 'source'); const model = join(sourceRoot, 'os-device-registry/src/lib.rs'); const fixture = join(sourceRoot, 'kernel/tests/os/device_registry.rs'); const contract = join(sourceRoot, 'kernel/DEVICE_REGISTRY_DRIVER_MATCH_CONTRACT.md'); const noStdRoot = join(sourceRoot, 'no-std-root.rs'); mkdirSync(sourceRoot, {recursive: true}); writeFileSync(noStdRoot, '#![no_std]\n#[path = "os-device-registry/src/lib.rs"]\npub mod device_registry;\n'); const sources = { model: copy('os-device-registry/src/lib.rs', model), fixture: copy('kernel/tests/os/device_registry.rs', fixture), contract: copy('kernel/DEVICE_REGISTRY_DRIVER_MATCH_CONTRACT.md', contract), noStdRoot: artifact(noStdRoot), reference: copy('kernel/src/virtio_mmio.rs', join(sourceRoot, 'kernel/src/virtio_mmio.rs')), harness: artifact(join(root, 'scripts/os-acceptance/device-driver-match-local.mjs')), }; const predecessor = artifact(join(root, 'reports/os-implementation/K1410-device-resources-matrix-check-4NOnUt/report.json')); const run = (name, program, args, expected) => { const result = spawnSync(program, args, {cwd: root, encoding: 'utf8'}); const log = join(dir, `${name}.log`); writeFileSync(log, `${result.stdout ?? ''}${result.stderr ?? ''}`); assert.equal(result.status, expected, `${name}: expected exit ${expected}, observed ${result.status}; ${artifact(log).path}`); return {exitCode: result.status, log: artifact(log)}; }; const binary = join(dir, 'device-driver-match-tests'); const tests = { compile: run('host-compile', 'rustc', ['--edition=2024', '--test', fixture, '-o', binary], 0), green: run('host-tests', binary, [], 0), target: run('aarch64-no-std-check', 'rustc', ['--edition=2024', '--crate-type=lib', '--target=aarch64-unknown-none', '--emit=metadata', noStdRoot, '-o', join(dir, 'model.rmeta')], 0), }; const greenText = readFileSync(join(dir, 'host-tests.log'), 'utf8'); assert.match(greenText, /os_device_registry_driver_match_positive \.\.\. ok/); assert.match(greenText, /os_device_registry_driver_match_negative \.\.\. ok/); assert.match(greenText, /4 passed; 0 failed/); const mutantRoot = join(dir, 'mutant'); const mutantModel = join(mutantRoot, 'os-device-registry/src/lib.rs'); const mutantFixture = join(mutantRoot, 'kernel/tests/os/device_registry.rs'); copy('kernel/tests/os/device_registry.rs', mutantFixture); mkdirSync(join(mutantModel, '..'), {recursive: true}); const original = readFileSync(model, 'utf8'); const guard = 'rule.device_id == identity.device_id && rule.class == identity.class'; assert.equal(original.split(guard).length, 2, 'device and class match must both be checked'); writeFileSync(mutantModel, original.replace(guard, 'rule.device_id == identity.device_id')); const mutant = artifact(mutantModel); const mutantBinary = join(dir, 'device-driver-match-mutant-tests'); tests.mutantCompile = run('mutant-compile', 'rustc', ['--edition=2024', '--test', mutantFixture, '-o', mutantBinary], 0); tests.red = run('mutant-tests', mutantBinary, [], 101); const redText = readFileSync(join(dir, 'mutant-tests.log'), 'utf8'); assert.match(redText, /os_device_registry_driver_match_negative \.\.\. FAILED/); assert.match(redText, /assertion .*failed|assertion `left == right` failed/); const report = { schema: 'turkos-k1415-device-driver-match-local/v1', status: 'K1411_K1414_LOCAL_VALIDATED', guestAccepted: false, productAccepted: false, predecessor, sources, mutant, tests: {...tests, greenCount: 4, mutationRejected: true}, scope: 'Exact VirtIO MMIO vendor, DeviceID, and normalized class matching gates publication of the driver binding and resource claim. Unsupported class, mismatched class, vendor, and transport are rejected without state changes. Four host tests and AArch64 no_std compilation pass. A removed class-equality guard is rejected by the negative test. Guest acceptance and product Image integration remain open at K1415.', }; const reportPath = join(dir, 'report.json'); writeFileSync(reportPath, JSON.stringify(report, null, 2) + '\n'); console.log(JSON.stringify({status: report.status, report: relative(root, reportPath), tests: report.tests.greenCount, mutationRejected: report.tests.mutationRejected}));