test(aws-lambda): a site stores and hands out each video's probe

This commit is contained in:
Miguel Angel Simon Sierra
2026-10-24 04:59:43 -04:00
parent 56678f1ba5
commit e5874903ab
2 changed files with 66 additions and 2 deletions
+50 -1
View File
@@ -6,7 +6,7 @@ import { join } from "node:path";
import { createHash } from "node:crypto";
import type { S3Client } from "@aws-sdk/client-s3";
import { AUDIO_SIDECAR_MIN_BYTES } from "@hyperframes/producer/distributed";
import { audioSidecarUri } from "../contentStore.js";
import { audioSidecarUri, probeFactsUri } from "../contentStore.js";
import { parseSiteManifest } from "../siteManifest.js";
import { asS3Client, FakeS3 } from "./__fixtures__/fakeS3.js";
import { deploySite } from "./deploySite.js";
@@ -275,3 +275,52 @@ describe.skipIf(!HAS_FFMPEG)("deploySite audio sidecars", { timeout: 60_000 }, (
expect(notices[0]).toContain("ffmpeg");
});
});
describe.skipIf(!HAS_FFMPEG)("deploySite probe facts", { timeout: 60_000 }, () => {
function addVideo(): void {
const made = spawnSync(FFMPEG, [
...["-v", "error", "-y", "-f", "lavfi", "-i", "testsrc2=size=64x64:rate=25:duration=2"],
...["-c:v", "mpeg4", join(projectDir, "assets", "take.mp4")],
]);
expect(made.status).toBe(0);
}
it("stores each video's ffprobe JSON beside it, and leaves the site's file list as it was", async () => {
addVideo();
const s3 = new FakeS3();
const site = await deploySite({ projectDir, bucketName: "test-bucket", s3: asS3Client(s3) });
const take = parseSiteManifest(
s3.bodies.get(`test-bucket/sites/${site.siteId}/files.json`)?.toString() ?? "",
).find((file) => file.path === "assets/take.mp4");
const facts = probeFactsUri("test-bucket", take?.sha256 ?? "").replace("s3://", "");
expect(JSON.parse(s3.bodies.get(facts)?.toString() ?? "{}").streams[0].codec_type).toBe("video");
expect(sitePaths(s3, site.siteId)).toEqual([
"assets/style.css",
"assets/take.mp4",
"index.html",
]);
});
it("deploys the same site with no probe stored when there is no ffprobe, and says so", async () => {
addVideo();
const notices: string[] = [];
const before = process.env.HYPERFRAMES_FFPROBE_PATH;
process.env.HYPERFRAMES_FFPROBE_PATH = join(scratch, "no-such-ffprobe");
const s3 = new FakeS3();
try {
await deploySite({
projectDir,
bucketName: "test-bucket",
s3: asS3Client(s3),
onNotice: (message) => notices.push(message),
});
} finally {
if (before === undefined) delete process.env.HYPERFRAMES_FFPROBE_PATH;
else process.env.HYPERFRAMES_FFPROBE_PATH = before;
}
expect([...s3.existing].filter((id) => id.endsWith(".probe.v1.json"))).toEqual([]);
expect(notices.some((message) => message.includes("ffprobe"))).toBe(true);
});
});
+16 -1
View File
@@ -3,7 +3,7 @@ import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { S3Client } from "@aws-sdk/client-s3";
import { audioSidecarUri, contentStoreUri } from "./contentStore.js";
import { audioSidecarUri, contentStoreUri, probeFactsUri } from "./contentStore.js";
import { FakeS3 } from "./sdk/__fixtures__/fakeS3.js";
import { downloadSiteFiles, serializeSiteManifest, siteManifestUri } from "./siteManifest.js";
@@ -70,4 +70,19 @@ describe("downloadSiteFiles", () => {
expect(remote["takes/camera.mov"]?.url).toBeString();
expect(remote["takes/camera.mov"]?.audioSidecarUrl).toBeUndefined();
});
it("hands a remote video's stored probe along with it, when one is stored", async () => {
const fake = new FakeS3();
const manifestUri = siteWithVideo(fake);
fake.existing.add(probeFactsUri("bucket", VIDEO_SHA).replace("s3://", ""));
const remote = await downloadSiteFiles(
clientOver(fake),
manifestUri,
join(dir, "project"),
true,
);
expect(remote["takes/camera.mov"]?.probeFactsUrl).toContain(`${VIDEO_SHA}.probe.v1.json`);
});
});