'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); const os = require('os'); const path = require('path'); const { createConversionService } = require('../../src/services/conversion-service'); function waitFor(predicate, timeoutMs = 15000) { const started = Date.now(); return new Promise((resolve, reject) => { const poll = () => { const value = predicate(); if (value) return resolve(value); if (Date.now() - started > timeoutMs) return reject(new Error('Timed out waiting for conversion job.')); setTimeout(poll, 25); }; poll(); }); } test('Docker conversion queue builds a real FFPFSC image', async () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-conversion-')); const source = path.join(root, 'games', 'CUSA00001'); const tmp = path.join(root, 'tmp'); const exports = path.join(root, 'exports'); fs.mkdirSync(path.join(source, 'sce_sys'), { recursive: true }); fs.mkdirSync(tmp, { recursive: true }); fs.mkdirSync(exports, { recursive: true }); fs.writeFileSync(path.join(source, 'eboot.bin'), Buffer.alloc(128 * 1024, 0x42)); fs.writeFileSync(path.join(source, 'sce_sys', 'param.sfo'), 'fixture'); const settings = { get: (key, fallback) => key === 'conv.outputDir' ? exports : fallback }; const service = createConversionService({ settings, paths: { root, tmp }, ftp: { isConnected: () => false, hasCredentials: () => false }, logger: { error() {} }, resolvePath: value => path.resolve(String(value)), }); try { const added = service.add({ game_id: 'CUSA00001', game_name: 'Fixture', game_path: source, mode: 'ffpfsc' }); service.start(); const completed = await waitFor(() => service.list().find(job => job.id === added.id && ['done', 'error'].includes(job.status))); assert.equal(completed.status, 'done', completed.error || 'conversion failed'); assert.equal(completed.progress.percent, 100); assert.equal(fs.existsSync(completed.output_file), true); assert.equal(fs.statSync(completed.output_file).size > 64 * 1024, true); const image = fs.readFileSync(completed.output_file); assert.equal(image.readBigUInt64LE(0), 2n); assert.equal(image.readBigUInt64LE(8), 20130315n); assert.throws(() => service.add({ game_id: 'CUSA00002', game_path: source, mode: 'ffpkg' }), /Windows-worker/); } finally { fs.rmSync(root, { recursive: true, force: true }); } });