Live video on the AT Protocol
1import { bytesToMultibase } from "@atproto/crypto";
2import { ChildProcess } from "child_process";
3import fs from "fs/promises";
4import os from "os";
5import path from "path";
6import { privateKeyToAccount } from "viem/accounts";
7import getEnv from "../env";
8import makeNode from "../node";
9import { playbackTest } from "./playback-test";
10import { syncTest } from "./sync-test";
11import { E2ETest, TestEnv } from "./test-env";
12
13const allTests: Record<string, E2ETest> = {
14 playback: playbackTest,
15 sync: syncTest,
16};
17
18export const allTestNames = Object.keys(allTests);
19
20const randomPort = () => Math.floor(Math.random() * 20000) + 20000;
21
22export default async function runTests(
23 tests: string[],
24 duration: string,
25 privateKey: `0x${string}`,
26): Promise<boolean> {
27 const testFuncs = [];
28 for (const test of tests) {
29 if (!allTests[test]) {
30 throw new Error(`Test ${test} not found`);
31 }
32 testFuncs.push(allTests[test]);
33 }
34 try {
35 const results = await Promise.all(
36 testFuncs.map(async (test) => {
37 let testProc: ChildProcess | undefined;
38 try {
39 const { skipNode } = getEnv();
40 const hexKey = privateKey.slice(2); // Remove 0x prefix
41 const exportedKey = new Uint8Array(
42 hexKey.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)),
43 );
44 const multibaseKey = bytesToMultibase(exportedKey, "base58btc");
45 const account = privateKeyToAccount(privateKey);
46 const tmpDir = await fs.mkdtemp(
47 path.join(os.tmpdir(), "streamplace-test-"),
48 );
49
50 let testEnv: TestEnv = {
51 addr: "http://127.0.0.1:38080",
52 internalAddr: "http://127.0.0.1:39090",
53 privateKey: privateKey,
54 publicAddress: account.address.toLowerCase(),
55 testDuration: parseInt(duration),
56 multibaseKey,
57 env: {},
58 };
59 if (!skipNode) {
60 testEnv.env = {
61 SP_HTTP_ADDR: `127.0.0.1:${randomPort()}`,
62 SP_HTTP_INTERNAL_ADDR: `127.0.0.1:${randomPort()}`,
63 SP_DATA_DIR: tmpDir,
64 };
65 }
66 if (test.setup) {
67 testEnv = await test.setup(testEnv);
68 }
69 if (!skipNode) {
70 const { addr, internalAddr, proc } = await makeNode({
71 env: testEnv.env,
72 autoQuit: false,
73 });
74 testEnv.addr = addr;
75 testEnv.internalAddr = internalAddr;
76 testProc = proc;
77 }
78 return await test.test(testEnv);
79 } catch (e) {
80 console.error("error running test", e.message);
81 } finally {
82 if (testProc) {
83 testProc.kill("SIGTERM");
84 }
85 }
86 }),
87 );
88 const failures = results.filter((r) => r !== null);
89 if (failures.length > 0) {
90 console.error("tests failed", failures.join(", "));
91 return false;
92 }
93 return true;
94 } catch (e) {
95 console.error("error running tests", e.message);
96 return false;
97 }
98}