Initial curated chimera source from a8ae5b1db07fb49926c94585e2718e5130330974
This commit is contained in:
commit
c737a37f71
531 files changed
+119270
No files matched your search
@@ -0,0 +1,84 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const test = require('node:test');
|
||||
const initSqlJs = require('sql.js');
|
||||
const migration = require('../../src/database/migrations/0017-create-ps5-system-backup-inventory');
|
||||
const { createExperimentalBarAdapter, createSqliteSystemBackupRepository, createSystemBackupInventoryService } = require('../../src/services/system-backup-recovery-lab-service');
|
||||
|
||||
async function harness(t) {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-ch0907-')); t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
||||
const SQL = await initSqlJs(); const db = new SQL.Database(); migration.up(db); let id = 0;
|
||||
const repository = createSqliteSystemBackupRepository({ db, now: () => 1784721600000 + id, idFactory: () => `artifact-${++id}` });
|
||||
return { db, root, repository, service: createSystemBackupInventoryService({ repository, allowedRoots: [root] }) };
|
||||
}
|
||||
|
||||
function writeCandidate(root, name, byte = 0x5a) { const file = path.join(root, name); fs.writeFileSync(file, Buffer.alloc(4096, byte)); return file; }
|
||||
const readyMetadata = { label: 'Original PS5 backup', backupSystemSoftwareVersion: '9.60', targetSystemSoftwareVersion: '10.00', usbFilesystem: 'exFAT', accountBound: true, targetAccountConfirmed: true, destructiveRestoreAcknowledged: true };
|
||||
|
||||
test('register opens and hashes the original artifact read-only without changing bytes or metadata', async t => {
|
||||
const context = await harness(t); const file = writeCandidate(context.root, 'original.bar'); const before = fs.statSync(file); const bytes = fs.readFileSync(file);
|
||||
const record = await context.service.register({ filePath: file, metadata: readyMetadata }); const after = fs.statSync(file);
|
||||
assert.equal(record.readOnlyVerified, true); assert.equal(record.sizeBytes, bytes.length); assert.match(record.sha256, /^[a-f0-9]{64}$/);
|
||||
assert.deepEqual(fs.readFileSync(file), bytes); assert.equal(after.size, before.size); assert.equal(after.mtimeMs, before.mtimeMs);
|
||||
assert.equal(record.integrityStatus, 'candidate'); assert.equal(record.immutable, true);
|
||||
assert.throws(() => context.db.run("UPDATE ps5_system_backup_artifacts SET display_name = 'changed'"), /immutable/i);
|
||||
});
|
||||
|
||||
test('same content is registered as a duplicate without collapsing provenance', async t => {
|
||||
const context = await harness(t); const first = await context.service.register({ filePath: writeCandidate(context.root, 'first.bar'), metadata: readyMetadata });
|
||||
const second = await context.service.register({ filePath: writeCandidate(context.root, 'copy.backup'), metadata: readyMetadata });
|
||||
assert.notEqual(second.id, first.id); assert.equal(second.sha256, first.sha256); assert.equal(second.duplicateOf, first.id); assert.equal(context.service.list().length, 2);
|
||||
});
|
||||
|
||||
test('unsupported and corrupt artifacts are recorded but never reported restore-ready', async t => {
|
||||
const context = await harness(t); const unsupported = await context.service.register({ filePath: writeCandidate(context.root, 'notes.txt'), metadata: readyMetadata });
|
||||
const corruptPath = path.join(context.root, 'empty.bar'); fs.writeFileSync(corruptPath, Buffer.alloc(0)); const corrupt = await context.service.register({ filePath: corruptPath, metadata: readyMetadata });
|
||||
assert.equal(unsupported.integrityStatus, 'unsupported'); assert.equal(unsupported.officialChecklist.status, 'blocked');
|
||||
assert.equal(corrupt.integrityStatus, 'corrupt'); assert.equal(corrupt.officialChecklist.status, 'blocked');
|
||||
});
|
||||
|
||||
test('official checklist gates filesystem, firmware, account and destructive warning', async t => {
|
||||
const context = await harness(t); const ready = await context.service.register({ filePath: writeCandidate(context.root, 'ready.bar'), metadata: readyMetadata });
|
||||
assert.equal(ready.officialChecklist.status, 'ready'); assert.match(ready.officialChecklist.officialRoute, /Restore Your PS5/);
|
||||
const blocked = await context.service.register({ filePath: writeCandidate(context.root, 'older-target.bar', 0x61), metadata: { ...readyMetadata, targetSystemSoftwareVersion: '9.00', usbFilesystem: 'ntfs', targetAccountConfirmed: false } });
|
||||
assert.equal(blocked.officialChecklist.status, 'blocked');
|
||||
assert.ok(blocked.officialChecklist.checks.some(check => check.id === 'system-software' && check.state === 'blocked'));
|
||||
assert.ok(blocked.officialChecklist.checks.some(check => check.id === 'usb-filesystem' && check.state === 'blocked'));
|
||||
assert.equal(ready.claims.trophyContents, 'excluded-by-official-guidance'); assert.equal(ready.claims.directTrophyRecovery, false); assert.equal(ready.claims.directSaveRecovery, false);
|
||||
});
|
||||
|
||||
test('managed root aliases are canonicalized before checking the resolved artifact', async t => {
|
||||
const context = await harness(t);
|
||||
const physical = path.join(context.root, 'physical'); fs.mkdirSync(physical);
|
||||
const alias = path.join(context.root, 'managed-alias'); fs.symlinkSync(physical, alias, 'junction');
|
||||
const file = writeCandidate(physical, 'original.bar'); const before = fs.statSync(file);
|
||||
const service = createSystemBackupInventoryService({ repository: context.repository, allowedRoots: [alias, path.join(context.root, 'unavailable-root')] });
|
||||
const record = await service.register({ filePath: path.join(alias, 'original.bar') });
|
||||
assert.equal(record.sourcePath, await fs.promises.realpath(file));
|
||||
assert.equal(record.sizeBytes, before.size); assert.equal(fs.statSync(file).mtimeMs, before.mtimeMs);
|
||||
assert.equal(record.readOnlyVerified, true);
|
||||
await assert.rejects(service.register({ filePath: file }), error => error.code === 'RECOVERY_LAB_PATH');
|
||||
});
|
||||
|
||||
test('an internal directory link cannot escape its selected managed root', async t => {
|
||||
const context = await harness(t);
|
||||
const managed = path.join(context.root, 'managed'); fs.mkdirSync(managed);
|
||||
const outside = path.join(context.root, 'outside'); fs.mkdirSync(outside);
|
||||
writeCandidate(outside, 'outside.bar');
|
||||
fs.symlinkSync(outside, path.join(managed, 'escape'), 'junction');
|
||||
const service = createSystemBackupInventoryService({ repository: context.repository, allowedRoots: [managed, outside] });
|
||||
await assert.rejects(service.register({ filePath: path.join(managed, 'escape', 'outside.bar') }), error => error.code === 'RECOVERY_LAB_PATH');
|
||||
assert.equal(context.repository.list().length, 0);
|
||||
});
|
||||
|
||||
test('experimental BAR adapter is capability-based WIP and fails closed', async () => {
|
||||
const adapter = createExperimentalBarAdapter(); const status = adapter.status();
|
||||
assert.equal(status.state, 'wip'); assert.equal(status.available, false); assert.deepEqual(status.capabilities, ['read-header', 'compare-sha256']);
|
||||
assert.ok(status.limitations.includes('no-restore')); assert.equal(adapter.assess({ integrityStatus: 'candidate' }).candidate, true);
|
||||
await assert.rejects(adapter.extract({}), error => error.code === 'RECOVERY_LAB_WIP');
|
||||
await assert.rejects(adapter.restore({}), error => error.code === 'RECOVERY_LAB_WIP');
|
||||
});
|
||||
Reference in new issue
Block a user