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,62 @@
|
||||
'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 database = require('../../src/database');
|
||||
const { createStorageInventoryService } = require('../../src/services/storage-inventory-service');
|
||||
const { createGuidedGameMoveService } = require('../../src/services/guided-game-move-service');
|
||||
|
||||
async function fixture(t) {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-guided-move-'));
|
||||
database.configure({ dataDir: root, logger: { info() {}, warn() {}, error() {} } });
|
||||
await database.initialize();
|
||||
t.after(() => { database.close(); fs.rmSync(root, { recursive: true, force: true }); });
|
||||
const observedAt = Date.now();
|
||||
const storage = createStorageInventoryService({ db: database, now: () => observedAt });
|
||||
const inventory = storage.observe({ scope: 'console', adapterId: 'sentinel', source: 'sentinel-test', observedAt, completeCoverage: true, devices: [
|
||||
{ stableFingerprint: 'internal', displayName: 'Internal', volumes: [{ stableVolumeKey: 'internal', mountPath: '/user/app', capacityBytes: 2000, freeBytes: 1000, capabilities: { canInstall: true } }] },
|
||||
{ stableFingerprint: 'm2', displayName: 'M.2 SSD', volumes: [{ stableVolumeKey: 'm2', mountPath: '/mnt/m2', capacityBytes: 3000, freeBytes: 2000, capabilities: { canInstall: true } }] },
|
||||
] });
|
||||
const sourceVolumeId = inventory.devices.find(item => item.stableFingerprint === 'internal').volumes[0].id;
|
||||
const destinationVolumeId = inventory.devices.find(item => item.stableFingerprint === 'm2').volumes[0].id;
|
||||
database.runMutatingSqlWithParams("INSERT INTO titles (platform, title_id, name, sort_name) VALUES ('ps5', 'PPSA00001', 'Move Test', 'Move Test')", {});
|
||||
const titleDbId = Number(database.runQuery('SELECT last_insert_rowid() AS id')[0].id);
|
||||
database.runMutatingSqlWithParams(`INSERT INTO console_installs (title_id, console_profile_id, volume_id, remote_location_key, install_state, last_seen_at) VALUES (@titleId, 'ps5', @volumeId, 'source', 'observed', @seenAt)`, { titleId: titleDbId, volumeId: sourceVolumeId, seenAt: observedAt });
|
||||
return { service: createGuidedGameMoveService({ db: database, now: () => observedAt, uuid: () => 'plan-1' }), titleDbId, sourceVolumeId, destinationVolumeId, observedAt };
|
||||
}
|
||||
|
||||
test('guided plan validates source, destination, capacity and returns exact manual steps', async t => {
|
||||
const f = await fixture(t);
|
||||
const plan = f.service.create({ titleId: 'PPSA00001', sourceVolumeId: f.sourceVolumeId, destinationVolumeId: f.destinationVolumeId, requiredBytes: 500 });
|
||||
assert.equal(plan.status, 'planned');
|
||||
assert.equal(plan.beforeSnapshot.length, 1);
|
||||
assert.ok(plan.steps.some(step => step.includes('Settings > Storage > Games and Apps')));
|
||||
assert.ok(plan.steps.some(step => step.includes('Do not delete the source')));
|
||||
assert.equal(plan.sourceDeletionInitiated, false);
|
||||
assert.throws(() => f.service.create({ titleId: 'PPSA00001', sourceVolumeId: f.sourceVolumeId, destinationVolumeId: f.destinationVolumeId, requiredBytes: 2500 }), /no longer eligible.*insufficient-capacity/i);
|
||||
});
|
||||
|
||||
test('after-scan reconciliation links snapshots and reports the location diff', async t => {
|
||||
const f = await fixture(t);
|
||||
f.service.create({ titleId: 'PPSA00001', sourceVolumeId: f.sourceVolumeId, destinationVolumeId: f.destinationVolumeId, requiredBytes: 500 });
|
||||
database.runMutatingSqlWithParams(`INSERT INTO console_installs (title_id, console_profile_id, volume_id, remote_location_key, install_state, last_seen_at) VALUES (@titleId, 'ps5', @volumeId, 'destination', 'observed', @seenAt)`, { titleId: f.titleDbId, volumeId: f.destinationVolumeId, seenAt: f.observedAt + 1 });
|
||||
const result = f.service.reconcile('plan-1');
|
||||
assert.equal(result.status, 'completed');
|
||||
assert.equal(result.diff.destinationObserved, true);
|
||||
assert.equal(result.diff.sourceStillObserved, true);
|
||||
assert.equal(result.diff.sourceDeletionInitiated, false);
|
||||
assert.equal(result.afterSnapshot.length, 2);
|
||||
});
|
||||
|
||||
test('cancel changes only plan state and exposes no delete operation', async t => {
|
||||
const f = await fixture(t);
|
||||
f.service.create({ titleId: 'PPSA00001', sourceVolumeId: f.sourceVolumeId, destinationVolumeId: f.destinationVolumeId, requiredBytes: 500 });
|
||||
const cancelled = f.service.cancel('plan-1');
|
||||
assert.equal(cancelled.status, 'cancelled');
|
||||
assert.equal(cancelled.sourceDeletionInitiated, false);
|
||||
assert.equal(typeof f.service.delete, 'undefined');
|
||||
assert.throws(() => f.service.reconcile('plan-1'), /cancelled/i);
|
||||
});
|
||||
Reference in new issue
Block a user