ai-chatbot/scripts/qa/video-upscale-service.cjs

104 lines
3.3 KiB
JavaScript

// Real authenticated GPU API smoke test. Inputs must be the documented synthetic one-second clips.
const fs = require("node:fs"),
crypto = require("node:crypto"),
assert = require("node:assert/strict");
const { execFileSync } = require("node:child_process");
const base = process.env.VIDEO_UPSCALE_QA_URL,
token = process.env.VIDEO_UPSCALE_QA_TOKEN,
source = process.env.VIDEO_UPSCALE_QA_SOURCE;
if (!base || !token || !source)
throw Error(
"Set VIDEO_UPSCALE_QA_URL, VIDEO_UPSCALE_QA_TOKEN and VIDEO_UPSCALE_QA_SOURCE"
);
const sha = (s) => crypto.createHash("sha256").update(s).digest("hex"),
headers = {
authorization: "Bearer " + token,
"content-type": "application/json",
};
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
(async () => {
const request = async (route, body) => {
const r = await fetch(base + route, {
method: body ? "POST" : "GET",
headers,
body: body && JSON.stringify(body),
signal: AbortSignal.timeout(15000),
});
return { status: r.status, body: await r.json() };
};
assert.equal((await fetch(base + "/health")).status, 401);
const input = {
id: sha("upscale-qa-" + crypto.randomUUID()),
tenant: sha("isolated-qa"),
plan: { url: source, resolution: "4K" },
};
assert.equal((await request("/v1/upscales", input)).status, 202);
assert.equal((await request("/v1/upscales", input)).status, 200);
assert.equal(
(
await request("/v1/upscales", {
...input,
plan: { ...input.plan, resolution: "2K" },
})
).status,
409
);
const host = process.env.VIDEO_UPSCALE_QA_SSH_HOST,
control = process.env.VIDEO_UPSCALE_QA_SSH_CONTROL;
if (host) {
for (let i = 0; i < 30; i++) {
if ((await request("/v1/upscales/" + input.id)).body.status === "running")
break;
await wait(100);
}
execFileSync(
"ssh",
[
...(control ? ["-S", control] : []),
"-o",
"BatchMode=yes",
host,
"systemctl restart video-upscale",
],
{ timeout: 30000, stdio: "pipe" }
);
await wait(1500);
assert.equal((await request("/v1/upscales", input)).status, 200);
}
let result;
for (let i = 0; i < 240; i++) {
result = (await request("/v1/upscales/" + input.id)).body;
if (["succeeded", "failed"].includes(result.status)) break;
await wait(2000);
}
assert.equal(result.status, "succeeded", JSON.stringify(result));
assert.equal(result.result.width, 3840);
assert.equal(result.result.height, 2160);
assert.equal(result.result.frames, 2);
assert.equal(result.result.audio, true);
if (host) assert.equal(result.attempts, 2);
const response = await fetch(base + "/v1/upscales/" + input.id + "/video", {
headers,
});
assert(response.ok);
fs.mkdirSync(".qa/video-upscale-service", { recursive: true });
fs.writeFileSync(
".qa/video-upscale-service/result.mp4",
Buffer.from(await response.arrayBuffer())
);
assert.equal(
(await fetch(base + "/v1/upscales/" + input.id + "/video")).status,
401
);
fs.writeFileSync(
".qa/video-upscale-service/report.json",
JSON.stringify(result, null, 2)
);
console.log(
"PASS: GPU upscale, authenticated download, idempotency, conflicting parameters, restart recovery, dimensions/frame count/audio"
);
})().catch((e) => {
console.error(e);
process.exitCode = 1;
});