import { TEST_DIR } from "../setup.ts"; import { assertEquals } from "@std/assert"; import { sweepGeneratedMedia } from "../../lib/ffmpeg.ts"; const UPLOADS = `${TEST_DIR}/uploads`; async function write(path: string, ageMs = 0): Promise { const full = `${UPLOADS}/${path}`; await Deno.mkdir(full.slice(0, full.lastIndexOf("/")), { recursive: true }); await Deno.writeTextFile(full, "x"); if (ageMs > 0) { const at = new Date(Date.now() - ageMs); await Deno.utime(full, at, at); } } const exists = (path: string) => Deno.stat(`${UPLOADS}/${path}`).then(() => true, () => false); Deno.test("sweepGeneratedMedia: takes the copies of gone uploads, the old previews and abandoned temporary files", async () => { const HOURS = 60 * 60_000; const kept = [ // An upload and its copies, in each format. "avatars/u1", "scaled/avatars/u1.w128.webp", "scaled/avatars/u1.w640.png", // A custom thumbnail is an upload; a still and a waveform go with their // dump, not here. "thumbnails/d1-custom", "scaled/thumbnails/d1-custom.w960.webp", "thumbnails/d1.jpg", "thumbnails/d1.waveform.json", // Being written right now. "scaled/avatars/u1.w320.webp.1234.tmp", "scaled/tmp/fresh", "thumbnails/d1.jpg.1234.tmp", ]; const swept = [ // Their upload is gone. "scaled/avatars/u2.w128.webp", "scaled/dumps/d2.w960.jpg", // The name the previews of image dumps had. "thumbnails/d1.preview.jpg", "thumbnails/d3.preview.png", ]; const abandoned = [ "scaled/avatars/u1.w960.webp.5678.tmp", "scaled/tmp/stale", "scaled/tmp/stale.webp", "thumbnails/d1.waveform.json.5678.tmp", ]; for (const path of [...kept, ...swept]) await write(path); for (const path of abandoned) await write(path, 2 * HOURS); assertEquals(await sweepGeneratedMedia(), swept.length + abandoned.length); for (const path of kept) assertEquals(await exists(path), true, path); for (const path of [...swept, ...abandoned]) { assertEquals(await exists(path), false, path); } // Nothing left to take. assertEquals(await sweepGeneratedMedia(), 0); });