Live video on the AT Protocol
at eli/optional-convergence 119 lines 3.9 kB view raw
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 { resumeLoopTest } from "./resume-loop-test"; 11import { serverRestartTest } from "./server-restart-test"; 12import { E2ETest, TestEnv } from "./test-env"; 13import { randomPort } from "./util"; 14 15const allTests: Record<string, E2ETest> = { 16 playback: playbackTest, 17 // sync: syncTest, 18 resume: resumeLoopTest, 19 serverRestart: serverRestartTest, 20}; 21 22export const allTestNames = Object.keys(allTests); 23 24const series = process.env.STREAMPLACE_TEST_SERIES === "true"; 25 26export default async function runTests( 27 tests: string[], 28 duration: string, 29 privateKey: `0x${string}`, 30): Promise<boolean> { 31 const testsToRun = []; 32 for (const test of tests) { 33 if (!allTests[test]) { 34 throw new Error(`Test ${test} not found`); 35 } 36 testsToRun.push(test); 37 } 38 try { 39 const results: string[] = []; 40 const funcs: (() => Promise<void>)[] = []; 41 for (const testName of testsToRun) { 42 const test = allTests[testName]; 43 console.log(`============ running test ${testName} ============`); 44 let testProc: ChildProcess | undefined; 45 const testFunc = ((test) => { 46 return async () => { 47 try { 48 const { skipNode } = getEnv(); 49 const hexKey = privateKey.slice(2); // Remove 0x prefix 50 const exportedKey = new Uint8Array( 51 hexKey.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)), 52 ); 53 const multibaseKey = bytesToMultibase(exportedKey, "base58btc"); 54 const account = privateKeyToAccount(privateKey); 55 const tmpDir = await fs.mkdtemp( 56 path.join(os.tmpdir(), "streamplace-test-"), 57 ); 58 59 let testEnv: TestEnv = { 60 addr: "http://127.0.0.1:38080", 61 internalAddr: "http://127.0.0.1:39090", 62 privateKey: privateKey, 63 publicAddress: account.address.toLowerCase(), 64 testDuration: parseInt(duration), 65 multibaseKey, 66 env: {}, 67 }; 68 if (!skipNode) { 69 testEnv.env = { 70 SP_HTTP_ADDR: `127.0.0.1:${randomPort()}`, 71 SP_HTTP_INTERNAL_ADDR: `127.0.0.1:${randomPort()}`, 72 SP_RTMP_ADDR: `127.0.0.1:${randomPort()}`, 73 SP_DATA_DIR: tmpDir, 74 }; 75 } 76 if (test.setup) { 77 testEnv = await test.setup(testEnv); 78 } 79 if (!skipNode) { 80 const { addr, internalAddr, proc } = await makeNode({ 81 env: testEnv.env, 82 autoQuit: false, 83 }); 84 testEnv.addr = addr; 85 testEnv.internalAddr = internalAddr; 86 testProc = proc; 87 } 88 const result = await test.test(testEnv); 89 results.push(result); 90 } catch (e) { 91 console.error("error running test", e.message); 92 results.push(e.message); 93 } finally { 94 if (testProc) { 95 testProc.kill("SIGTERM"); 96 } 97 } 98 }; 99 })(test); 100 funcs.push(testFunc); 101 } 102 if (series) { 103 for (const func of funcs) { 104 await func(); 105 } 106 } else { 107 await Promise.all(funcs.map((f) => f())); 108 } 109 const failures = results.filter((r) => r !== null); 110 if (failures.length > 0) { 111 console.error("tests failed", failures.join(", ")); 112 return false; 113 } 114 return true; 115 } catch (e) { 116 console.error("error running tests", e.message); 117 return false; 118 } 119}