mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-04-23 04:16:29 +02:00
162 lines
3.8 KiB
JavaScript
162 lines
3.8 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* OpenVPN E2E Test Harness
|
|
*
|
|
* This script:
|
|
* 1. Skips unless explicitly enabled via DONUTBROWSER_RUN_OPENVPN_E2E=1
|
|
* 2. Builds the Rust vpn_integration test binary without running it
|
|
* 3. Runs the OpenVPN e2e test binary under sudo
|
|
*
|
|
* Usage: DONUTBROWSER_RUN_OPENVPN_E2E=1 node scripts/openvpn-test-harness.mjs
|
|
*/
|
|
|
|
import { spawn } from "child_process";
|
|
import path from "path";
|
|
import { fileURLToPath } from "url";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const ROOT_DIR = path.resolve(__dirname, "..");
|
|
const SRC_TAURI_DIR = path.join(ROOT_DIR, "src-tauri");
|
|
const TEST_NAME = "test_openvpn_traffic_flows_through_donut_proxy";
|
|
|
|
function log(message) {
|
|
console.log(`[openvpn-harness] ${message}`);
|
|
}
|
|
|
|
function error(message) {
|
|
console.error(`[openvpn-harness] ERROR: ${message}`);
|
|
}
|
|
|
|
function shouldRun() {
|
|
if (process.env.DONUTBROWSER_RUN_OPENVPN_E2E !== "1") {
|
|
log("Skipping OpenVPN e2e test because DONUTBROWSER_RUN_OPENVPN_E2E is not set");
|
|
return false;
|
|
}
|
|
|
|
if (process.platform !== "linux") {
|
|
log(`Skipping OpenVPN e2e test on unsupported platform: ${process.platform}`);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
async function buildTestBinary() {
|
|
log("Building OpenVPN e2e test binary...");
|
|
|
|
return new Promise((resolve, reject) => {
|
|
let executablePath = "";
|
|
let stdoutBuffer = "";
|
|
|
|
const proc = spawn(
|
|
"cargo",
|
|
[
|
|
"test",
|
|
"--test",
|
|
"vpn_integration",
|
|
TEST_NAME,
|
|
"--no-run",
|
|
"--message-format=json",
|
|
],
|
|
{
|
|
cwd: SRC_TAURI_DIR,
|
|
env: process.env,
|
|
stdio: ["ignore", "pipe", "pipe"],
|
|
}
|
|
);
|
|
|
|
const parseBuffer = (flush = false) => {
|
|
const lines = stdoutBuffer.split("\n");
|
|
const completeLines = flush ? lines : lines.slice(0, -1);
|
|
stdoutBuffer = flush ? "" : lines.at(-1) ?? "";
|
|
|
|
for (const line of completeLines.filter(Boolean)) {
|
|
try {
|
|
const message = JSON.parse(line);
|
|
if (message.reason === "compiler-artifact" && message.executable) {
|
|
executablePath = message.executable;
|
|
}
|
|
} catch {
|
|
// Ignore non-JSON lines.
|
|
}
|
|
}
|
|
};
|
|
|
|
proc.stdout.on("data", (data) => {
|
|
stdoutBuffer += data.toString();
|
|
parseBuffer();
|
|
});
|
|
|
|
proc.stderr.on("data", (data) => {
|
|
process.stderr.write(data);
|
|
});
|
|
|
|
proc.on("error", (err) => {
|
|
reject(err);
|
|
});
|
|
|
|
proc.on("close", (code) => {
|
|
parseBuffer(true);
|
|
|
|
if (code !== 0) {
|
|
reject(new Error(`cargo test --no-run exited with code ${code}`));
|
|
return;
|
|
}
|
|
|
|
if (!executablePath) {
|
|
reject(new Error("Could not determine the vpn_integration test binary path"));
|
|
return;
|
|
}
|
|
|
|
resolve(path.isAbsolute(executablePath) ? executablePath : path.resolve(SRC_TAURI_DIR, executablePath));
|
|
});
|
|
});
|
|
}
|
|
|
|
async function runOpenVpnE2e(executablePath) {
|
|
log("Running OpenVPN e2e test under sudo...");
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const proc = spawn(
|
|
"sudo",
|
|
[
|
|
"--preserve-env=CI,GITHUB_ACTIONS,VPN_TEST_OVPN_HOST,VPN_TEST_OVPN_PORT,DONUTBROWSER_RUN_OPENVPN_E2E",
|
|
executablePath,
|
|
TEST_NAME,
|
|
"--exact",
|
|
"--nocapture",
|
|
],
|
|
{
|
|
cwd: SRC_TAURI_DIR,
|
|
env: process.env,
|
|
stdio: "inherit",
|
|
}
|
|
);
|
|
|
|
proc.on("error", (err) => {
|
|
reject(err);
|
|
});
|
|
|
|
proc.on("close", (code) => {
|
|
resolve(code ?? 1);
|
|
});
|
|
});
|
|
}
|
|
|
|
async function main() {
|
|
if (!shouldRun()) {
|
|
process.exit(0);
|
|
}
|
|
|
|
try {
|
|
const executablePath = await buildTestBinary();
|
|
const exitCode = await runOpenVpnE2e(executablePath);
|
|
process.exit(exitCode);
|
|
} catch (err) {
|
|
error(err instanceof Error ? err.message : String(err));
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
main();
|