Files
ytplayer/plans/patches/009-media-cache-test.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();