64 lines
2.8 KiB
Diff
64 lines
2.8 KiB
Diff
--- a/server/media-cache.test.js
|
|
+++ b/server/media-cache.test.js
|
|
@@ -10,6 +10,8 @@
|
|
process.env.DB_PATH = join(root, 'test.db');
|
|
const dbmod = await import('./db.js');
|
|
const { createMediaCache, validateMedia, MediaSkip, HIGH, LOW, OPT_REV } = await import('./media-cache.js');
|
|
+const { initP2pSchema } = await import('./p2p-db.js');
|
|
+const { sha256File } = await import('./hash.js');
|
|
|
|
const fx = (name) => join(root, name);
|
|
const ff = (...args) => {
|
|
@@ -26,6 +28,7 @@
|
|
|
|
beforeAll(async () => {
|
|
await dbmod.initDb();
|
|
+ await initP2pSchema(); // adds media_cache.sha256
|
|
// 10 s 640x360 H.264 + AAC — the shape of a good cached copy.
|
|
ff('-f', 'lavfi', '-i', 'testsrc=size=640x360:rate=30:duration=10', '-f', 'lavfi', '-i', 'sine=frequency=440:duration=10',
|
|
'-c:v', 'libx264', '-preset', 'ultrafast', '-pix_fmt', 'yuv420p', '-c:a', 'aac', '-shortest', fx('good.mp4'));
|
|
@@ -102,6 +105,7 @@
|
|
download: async (id, out) => { calls.push(id); await sleep(30); copyFileSync(fx(state.fixture), out); return out; },
|
|
transcode: { enabled: false },
|
|
freeBytes: () => 100 * 1024 ** 3,
|
|
+ backfillDelayMs: -1,
|
|
...opts,
|
|
});
|
|
return { cache, dir, calls, state };
|
|
@@ -110,6 +114,35 @@
|
|
for (const r of await dbmod.listMedia()) await dbmod.deleteMedia(r.video_id);
|
|
}
|
|
|
|
+describe('content hashes (P2P cids)', () => {
|
|
+ test('a promoted copy stores the sha256 of its mp4 and reports it once', async () => {
|
|
+ await clearDb();
|
|
+ const seen = [];
|
|
+ const { cache, dir } = makeCache({ onReady: (i) => { seen.push(i); } });
|
|
+ await cache.init();
|
|
+ const row = await cache.ensureCached('hashAAAAAA1', { priority: HIGH });
|
|
+ const want = await sha256File(join(dir, `hashAAAAAA1.${row.gen}.mp4`));
|
|
+ expect((await dbmod.getMedia('hashAAAAAA1')).sha256).toBe(want);
|
|
+ expect(await until(() => seen.length === 1)).toBe(true);
|
|
+ expect(seen[0]).toMatchObject({ id: 'hashAAAAAA1', gen: row.gen, sha256: want, vcodec: 'h264' });
|
|
+ expect(seen[0].meta.title).toBe('T hashAAAAAA1');
|
|
+ });
|
|
+
|
|
+ test('backfill hashes ready copies that have no sha256 yet', async () => {
|
|
+ await clearDb();
|
|
+ const seen = [];
|
|
+ const { cache } = makeCache({ onReady: (i) => { seen.push(i); } });
|
|
+ await cache.init();
|
|
+ await cache.ensureCached('hashAAAAAA2', { priority: HIGH });
|
|
+ await dbmod.upsertMedia('hashAAAAAA2', { sha256: null });
|
|
+ seen.length = 0;
|
|
+ expect(await cache.backfillHashes()).toBe(1);
|
|
+ expect((await dbmod.getMedia('hashAAAAAA2')).sha256).toMatch(/^[0-9a-f]{64}$/);
|
|
+ expect(await until(() => seen.length === 1)).toBe(true);
|
|
+ expect(await cache.backfillHashes()).toBe(0); // nothing left
|
|
+ });
|
|
+});
|
|
+
|
|
describe('media cache jobs', () => {
|
|
test('fetches once, dedupes concurrent requests, then serves from disk', async () => {
|
|
await clearDb();
|