v86/tests/devices/wisp_network.js
Fabian 23411f337e use emulator.destroy() over emulator.stop() to properly remove v86 instances
emulator.stop sometimes works (when the GC can figure out that .start()
is unreachable and nothing can call into the instance). However, some
resources, such as any WebSocket connection, need to be closed manually.
2024-12-20 10:41:09 -07:00

179 lines
4.5 KiB
JavaScript
Executable file

#!/usr/bin/env -S node --experimental-websocket
"use strict";
process.on("unhandledRejection", exn => { throw exn; });
const TEST_RELEASE_BUILD = +process.env.TEST_RELEASE_BUILD;
const V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug"}.js`).V86;
const assert = require("assert").strict;
const SHOW_LOGS = false;
const tests =
[
{
name: "DHCP",
start: () =>
{
emulator.serial0_send("udhcpc\n");
emulator.serial0_send("echo -e done\\\\tudhcpc\n");
},
end_trigger: "done\tudhcpc",
end: (capture) =>
{
assert(/lease of 192.168.86.100 obtained/.test(capture), "lease of 192.168.86.100 obtained");
},
},
{
name: "ifconfig",
start: () =>
{
emulator.serial0_send("ifconfig\n");
emulator.serial0_send("echo -e done\\\\tifconfig\n");
},
end_trigger: "done\tifconfig",
end: (capture) =>
{
assert(/192.168.86.100/.test(capture), "192.168.86.100");
},
},
{
name: "route",
start: () =>
{
emulator.serial0_send("ip route\n");
emulator.serial0_send("echo -e done\\\\troute\n");
},
end_trigger: "done\troute",
end: (capture) =>
{
assert(/192.168.86.1/.test(capture), "192.168.86.100");
},
},
//{
// name: "arp -a",
// start: () =>
// {
// emulator.serial0_send("arp -a\n");
// emulator.serial0_send("echo -e done\\\\tarp\n");
// },
// end_trigger: "done\tarp",
// end: (capture) =>
// {
// assert(/.192.168.86.1. at 52:54:00:01:02:03 \[ether\] {2}on eth0/.test(capture), "(192.168.86.1) at 52:54:00:01:02:03 [ether] on eth0");
// },
//},
{
name: "Curl example.org",
allow_failure: true,
start: () =>
{
emulator.serial0_send("wget -T 10 -O - example.org\n");
emulator.serial0_send("echo -e done\\\\texample.org\n");
},
end_trigger: "done\texample.org",
end: (capture) =>
{
assert(/This domain is for use in illustrative examples in documents/.test(capture), "got example.org text");
},
},
];
const emulator = new V86({
bios: { url: __dirname + "/../../bios/seabios.bin" },
vga_bios: { url: __dirname + "/../../bios/vgabios.bin" },
cdrom: { url: __dirname + "/../../images/linux4.iso" },
autostart: true,
memory_size: 64 * 1024 * 1024,
disable_jit: +process.env.DISABLE_JIT,
network_relay_url: "wisps://wisp.mercurywork.shop/",
log_level: SHOW_LOGS ? 0x400000 : 0,
});
let test_num = 0;
let booted = false;
let line = "";
let capture = "";
let end_trigger;
emulator.bus.register("emulator-started", function()
{
console.log("Booting now, please stand by");
});
emulator.add_listener("serial0-output-byte", function(byte)
{
const chr = String.fromCharCode(byte);
if(chr < " " && chr !== "\n" && chr !== "\t" || chr > "~")
{
return;
}
let new_line = "";
if(chr === "\n")
{
console.log(" Captured: %s", line);
new_line = line;
capture += line + "\n";
line = "";
}
else
{
line += chr;
}
if(new_line === end_trigger)
{
let test_has_failed = false;
try {
tests[test_num].end(capture);
} catch(e) {
console.log(e);
test_has_failed = true;
}
if(!test_has_failed)
{
console.log("[+] Test #%d passed: %s", test_num, tests[test_num].name);
}
else
{
if(tests[test_num].allow_failure)
{
console.warn("[!] Test #%d failed: %s (failure allowed)", test_num, tests[test_num].name);
}
else
{
console.error("[-] Test #%d failed: %s", test_num, tests[test_num].name);
process.exit(1);
}
}
test_num++;
}
if(!booted && line.endsWith("~% ") || new_line === end_trigger)
{
booted = true;
if(test_num >= tests.length)
{
emulator.destroy();
console.log("Tests finished.");
}
else
{
console.log("Starting test #%d: %s", test_num, tests[test_num].name);
capture = "";
end_trigger = tests[test_num].end_trigger;
tests[test_num].start();
}
}
});