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,52 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const test = require('node:test');
|
||||
const { createPatchBundleService } = require('../../src/services/patch-bundle-service');
|
||||
const { createAprAmprAdapterService, PINNED_UPSTREAM } = require('../../src/services/apr-ampr-adapter-service');
|
||||
|
||||
const digest = value => crypto.createHash('sha256').update(value).digest('hex');
|
||||
function fixture(options = {}) {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-apr-')); const source = path.join(root, 'source'); const artifacts = path.join(root, 'artifacts'); const workspace = path.join(root, 'workspace'); const staging = path.join(root, 'staging');
|
||||
fs.mkdirSync(path.join(source, 'sce_module'), { recursive: true }); fs.mkdirSync(artifacts, { recursive: true }); fs.mkdirSync(workspace, { recursive: true });
|
||||
fs.writeFileSync(path.join(source, 'sce_module', 'libSceAmpr.sprx'), 'OLD-AMPR'); fs.writeFileSync(path.join(source, 'ampr_emu.index'), 'OLD-INDEX'); fs.writeFileSync(path.join(source, 'asset.bin'), 'ASSET');
|
||||
const artifactPath = path.join(artifacts, 'libSceAmpr.sprx'); fs.writeFileSync(artifactPath, 'PINNED-AMPR');
|
||||
const patchService = createPatchBundleService({ sourceRoots: [source], bundleRoots: [workspace], stagingRoot: staging, now: () => 1_721_600_000_000 });
|
||||
const adapter = createAprAmprAdapterService({ patchService, sourceRoots: [source, staging], artifact: { path: artifactPath, sha256: digest('PINNED-AMPR'), version: '0.2.5.3' }, workspaceRoot: workspace, supportedFirmwares: ['9.60'], simulationMode: true, now: () => 1_721_600_000_000, hooks: options.hooks });
|
||||
const input = { sourceRoot: source, titleId: 'PPSA12345', version: '1.00', firmware: '9.60', loader: 'etaHEN', kstuffVersion: '1.07', storage: 'usb', format: 'folder', applicationId: 'apr-stage' };
|
||||
return { root, source, staging, adapter, input, close: () => fs.rmSync(root, { recursive: true, force: true }) };
|
||||
}
|
||||
|
||||
test('simulated supported workflow detects requirement evidence and pins capabilities', async t => {
|
||||
const f = fixture(); t.after(f.close);
|
||||
const check = f.adapter.preflight(f.input); assert.equal(check.supported, true); assert.equal(check.detection.required, true); assert.match(check.detection.evidence.sha256, /^[a-f0-9]{64}$/);
|
||||
assert.equal(check.adapter.adapterVersion, '1.0.3'); assert.equal(check.adapter.gameCompressorRevision, PINNED_UPSTREAM.gameCompressorRevision); assert.equal(check.adapter.capabilities.liveConsoleMutation, false); assert.equal(check.mountSettingsProposal.applied, false);
|
||||
const staged = await f.adapter.stage(f.input); assert.equal(staged.state, 'verified'); assert.equal(staged.index.state, 'current'); assert.deepEqual(staged.lifecycle, ['detected', 'preflight-passed', 'index-rebuilding', 'staged', 'verified']);
|
||||
assert.equal(fs.readFileSync(path.join(f.source, 'sce_module', 'libSceAmpr.sprx'), 'utf8'), 'OLD-AMPR');
|
||||
});
|
||||
|
||||
test('unsupported firmware, format and internal index bootstrap explain exact reasons', t => {
|
||||
const f = fixture(); t.after(f.close);
|
||||
const check = f.adapter.preflight({ ...f.input, firmware: '10.50', format: 'exfat' });
|
||||
assert.equal(check.supported, false); assert.ok(check.reasons.some(item => item.code === 'APR_FIRMWARE_UNSUPPORTED')); assert.ok(check.reasons.some(item => item.code === 'APR_FORMAT_UNSUPPORTED'));
|
||||
fs.unlinkSync(path.join(f.source, 'ampr_emu.index'));
|
||||
const internal = f.adapter.preflight({ ...f.input, storage: 'internal' }); assert.ok(internal.reasons.some(item => item.code === 'APR_LOCATION_UNSUPPORTED'));
|
||||
});
|
||||
|
||||
test('index rebuild is deterministic, verified and source mismatch fails in staging', async t => {
|
||||
const good = fixture(); t.after(good.close); const staged = await good.adapter.stage(good.input); const document = JSON.parse(fs.readFileSync(path.join(staged.outputRoot, 'ampr_emu.index'), 'utf8'));
|
||||
assert.equal(document.format, 'chimera-ampr-index-simulator-v1'); assert.equal(document.consoleCompatible, false); assert.equal(document.entries[0].path, 'asset.bin');
|
||||
const bad = fixture({ hooks: { beforeApply: ({ input }) => fs.writeFileSync(path.join(input.sourceRoot, 'sce_module', 'libSceAmpr.sprx'), 'CHANGED-AFTER-PREFLIGHT') } }); t.after(bad.close);
|
||||
await assert.rejects(bad.adapter.stage({ ...bad.input, applicationId: 'source-race' }), error => error.code === 'PATCH_SOURCE_MISMATCH');
|
||||
assert.equal(fs.existsSync(path.join(bad.staging, 'source-race')), false);
|
||||
});
|
||||
|
||||
test('adapter rollback restores original staged module and index with verified lifecycle', async t => {
|
||||
const f = fixture(); t.after(f.close); const staged = await f.adapter.stage(f.input); const result = await f.adapter.rollback(f.input.applicationId);
|
||||
assert.equal(result.state, 'rolled-back'); assert.equal(result.outputsVerified, true); assert.deepEqual(result.lifecycle, ['rollback-preflight', 'rollback-staged', 'rolled-back']);
|
||||
assert.equal(fs.readFileSync(path.join(staged.outputRoot, 'sce_module', 'libSceAmpr.sprx'), 'utf8'), 'OLD-AMPR'); assert.equal(fs.readFileSync(path.join(staged.outputRoot, 'ampr_emu.index'), 'utf8'), 'OLD-INDEX');
|
||||
});
|
||||
Reference in new issue
Block a user