Clean up some tests

This commit is contained in:
Fabian 2024-08-29 13:52:33 +02:00
parent 56498d6ce2
commit fcdd110cb7
8 changed files with 162 additions and 526 deletions

View file

@ -162,7 +162,7 @@ FS.prototype.HandleEvent = function(id) {
this.events = newevents;
};
FS.prototype.load_from_json = function(fs, done)
FS.prototype.load_from_json = function(fs)
{
dbg_assert(fs, "Invalid fs passed to load_from_json");
@ -183,8 +183,6 @@ FS.prototype.load_from_json = function(fs, done)
//{
// this.Check();
//}
done && done();
};
FS.prototype.LoadRecursive = function(data, parentid)

View file

@ -1179,10 +1179,9 @@ V86.prototype.serial_set_clear_to_send = function(serial, status)
* @param {string} path Path for the mount point
* @param {string|undefined} baseurl
* @param {string|undefined} basefs As a JSON string
* @param {function(Object)=} callback
* @export
*/
V86.prototype.mount_fs = async function(path, baseurl, basefs, callback)
V86.prototype.mount_fs = async function(path, baseurl, basefs)
{
let file_storage = new MemoryFileStorage();
@ -1191,39 +1190,26 @@ V86.prototype.mount_fs = async function(path, baseurl, basefs, callback)
file_storage = new ServerFileStorageWrapper(file_storage, baseurl);
}
const newfs = new FS(file_storage, this.fs9p.qidcounter);
const mount = () =>
{
const idx = this.fs9p.Mount(path, newfs);
if(!callback)
{
return;
}
if(idx === -ENOENT)
{
callback(new FileNotFoundError());
}
else if(idx === -EEXIST)
{
callback(new FileExistsError());
}
else if(idx < 0)
{
dbg_assert(false, "Unexpected error code: " + (-idx));
callback(new Error("Failed to mount. Error number: " + (-idx)));
}
else
{
callback(null);
}
};
if(baseurl)
{
dbg_assert(typeof basefs === "object", "Filesystem: basefs must be a JSON object");
newfs.load_from_json(basefs, () => mount());
newfs.load_from_json(basefs);
}
else
const idx = this.fs9p.Mount(path, newfs);
if(idx === -ENOENT)
{
mount();
throw new FileNotFoundError();
}
else if(idx === -EEXIST)
{
throw new FileExistsError();
}
else if(idx < 0)
{
dbg_assert(false, "Unexpected error code: " + (-idx));
throw new Error("Failed to mount. Error number: " + (-idx));
}
};
@ -1354,7 +1340,6 @@ V86.prototype.automatically = function(steps)
};
run(steps);
};
/**

View file

@ -48,7 +48,7 @@ else
emulator.bus.register("emulator-started", function()
{
console.error("Booting now, please stand by");
console.log("Booting now, please stand by");
start_time = Date.now();
});

View file

@ -9,28 +9,11 @@ const V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug
const assert = require("assert").strict;
const SHOW_LOGS = false;
const STOP_ON_FIRST_FAILURE = false;
function log_pass(msg, ...args)
{
console.log(`\x1b[92m[+] ${msg}\x1b[0m`, ...args);
}
function log_warn(msg, ...args)
{
console.error(`\x1b[93m[!] ${msg}\x1b[0m`, ...args);
}
function log_fail(msg, ...args)
{
console.error(`\x1b[91m[-] ${msg}\x1b[0m`, ...args);
}
const tests =
[
{
name: "DHCP",
timeout: 60,
start: () =>
{
emulator.serial0_send("udhcpc\n");
@ -44,7 +27,6 @@ const tests =
},
{
name: "ifconfig",
timeout: 60,
start: () =>
{
emulator.serial0_send("ifconfig\n");
@ -58,7 +40,6 @@ const tests =
},
{
name: "route",
timeout: 60,
start: () =>
{
emulator.serial0_send("ip route\n");
@ -72,7 +53,6 @@ const tests =
},
{
name: "ping 1.2.3.4",
timeout: 60,
start: () =>
{
emulator.serial0_send("ping -c 2 1.2.3.4\n");
@ -86,7 +66,6 @@ const tests =
},
{
name: "arp -a",
timeout: 60,
start: () =>
{
emulator.serial0_send("arp -a\n");
@ -100,7 +79,6 @@ const tests =
},
{
name: "Curl mocked.example.org",
timeout: 60,
allow_failure: true,
start: () =>
{
@ -115,7 +93,6 @@ const tests =
},
{
name: "Curl example.org",
timeout: 60,
allow_failure: true,
start: () =>
{
@ -131,10 +108,6 @@ const tests =
];
let test_num = 0;
let test_timeout = 0;
const failed_tests = [];
const emulator = new V86({
bios: { url: __dirname + "/../../bios/seabios.bin" },
vga_bios: { url: __dirname + "/../../bios/vgabios.bin" },
@ -162,152 +135,15 @@ emulator.add_listener("emulator-ready", function () {
};
});
let ran_command = false;
let test_num = 0;
let booted = false;
let line = "";
let capturing = false;
let capture = "";
let next_trigger;
let next_trigger_handler;
function start_timeout()
{
if(tests[test_num].timeout)
{
test_timeout = setTimeout(() =>
{
log_fail("Test #%d (%s) took longer than %s sec. Timing out and terminating.", test_num, tests[test_num].name, tests[test_num].timeout);
process.exit(1);
}, tests[test_num].timeout * 1000);
}
}
function begin()
{
start_timeout();
console.log("\nPreparing test #%d: %s", test_num, tests[test_num].name);
start_test();
}
function start_test()
{
console.log("Starting test #%d: %s", test_num, tests[test_num].name);
capture = "";
tests[test_num].start();
if(tests[test_num].capture_trigger)
{
next_trigger = tests[test_num].capture_trigger;
next_trigger_handler = start_capture;
}
else
{
next_trigger = tests[test_num].end_trigger;
next_trigger_handler = end_test;
}
start_capture();
}
function start_capture()
{
console.log("Capturing...");
capture = "";
capturing = true;
next_trigger = tests[test_num].end_trigger;
next_trigger_handler = end_test;
}
function end_test()
{
capturing = false;
if(tests[test_num].timeout)
{
clearTimeout(test_timeout);
}
let test_has_failed = false;
try {
tests[test_num].end(capture);
} catch(e) {
console.log(e);
test_has_failed = true;
}
if(!test_has_failed)
{
log_pass("Test #%d passed: %s", test_num, tests[test_num].name);
}
else
{
if(tests[test_num].allow_failure)
{
log_warn("Test #%d failed: %s (failure allowed)", test_num, tests[test_num].name);
}
else
{
log_fail("Test #%d failed: %s", test_num, tests[test_num].name);
if(STOP_ON_FIRST_FAILURE)
{
finish_tests();
}
}
test_has_failed = false;
}
test_num++;
if(test_num < tests.length)
{
begin();
}
else
{
finish_tests();
}
}
function finish_tests()
{
emulator.stop();
console.log("\nTests finished.");
if(failed_tests.length === 0)
{
console.log("All tests passed");
}
else
{
let unallowed_failure = false;
console.error("Failed %d out of %d tests:", failed_tests.length, tests.length);
for(const num of failed_tests)
{
if(tests[num].allow_failure)
{
log_warn("#%d %s (failure allowed)", num, tests[num].name);
}
else
{
unallowed_failure = true;
log_fail("#%d %s", num, tests[num].name);
}
}
if(unallowed_failure)
{
process.exit(1);
}
}
}
let end_trigger;
emulator.bus.register("emulator-started", function()
{
console.error("Booting now, please stand by");
console.log("Booting now, please stand by");
});
emulator.add_listener("serial0-output-byte", function(byte)
@ -319,11 +155,11 @@ emulator.add_listener("serial0-output-byte", function(byte)
}
let new_line = "";
let is_new_line = false;
if(chr === "\n")
{
is_new_line = true;
console.log(" Captured: %s", line);
new_line = line;
capture += line + "\n";
line = "";
}
else
@ -331,22 +167,57 @@ emulator.add_listener("serial0-output-byte", function(byte)
line += chr;
}
if(!ran_command && line.endsWith("~% "))
if(new_line === end_trigger)
{
ran_command = true;
begin();
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++;
}
else if(new_line === next_trigger)
if(!booted && line.endsWith("~% ") || new_line === end_trigger)
{
next_trigger_handler();
}
else if(is_new_line && capturing)
{
capture += new_line + "\n";
console.log(" Captured: %s", new_line);
}
else if(is_new_line)
{
console.log(" Serial: %s", new_line);
booted = true;
if(test_num >= tests.length)
{
emulator.stop();
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();
}
}
});

View file

@ -12,28 +12,13 @@ const testfsjson = require("./testfs.json");
const SHOW_LOGS = false;
const STOP_ON_FIRST_FAILURE = false;
function log_pass(msg, ...args)
{
console.log(`\x1b[92m[+] ${msg}\x1b[0m`, ...args);
}
function log_warn(msg, ...args)
{
console.error(`\x1b[93m[!] ${msg}\x1b[0m`, ...args);
}
function log_fail(msg, ...args)
{
console.error(`\x1b[91m[-] ${msg}\x1b[0m`, ...args);
}
function assert_equal(actual, expected, message)
{
if(actual !== expected)
{
log_warn("Failed assert equal (Test: %s). %s", tests[test_num].name, message || "");
log_warn("Expected:\n" + expected);
log_warn("Actual:\n" + actual);
console.warn("Failed assert equal (Test: %s). %s", tests[test_num].name, message || "");
console.warn("Expected:\n" + expected);
console.warn("Actual:\n" + actual);
test_fail();
}
}
@ -42,8 +27,8 @@ function assert_not_equal(actual, expected, message)
{
if(actual === expected)
{
log_warn("Failed assert not equal (Test: %s). %s", tests[test_num].name, message || "");
log_warn("Expected something different than:\n" + expected);
console.warn("Failed assert not equal (Test: %s). %s", tests[test_num].name, message || "");
console.warn("Expected something different than:\n" + expected);
test_fail();
}
}
@ -164,7 +149,7 @@ const tests =
assert_equal(data.length, 512 * 1024);
if(data.find(v => v !== 0))
{
log_warn("Fail: Incorrect data. Expected all zeros.");
console.warn("Fail: Incorrect data. Expected all zeros.");
test_fail();
}
done();
@ -663,7 +648,7 @@ const tests =
const outputs = capture.split("\n").map(output => output.split(/\s+/));
if(outputs.length < 3)
{
log_warn("Wrong format: %s", capture);
console.warn("Wrong format: %s", capture);
test_fail();
done();
return;
@ -732,7 +717,7 @@ const tests =
if(outputs.length < 3)
{
log_warn("Wrong format (expected 3 rows): %s", capture);
console.warn("Wrong format (expected 3 rows): %s", capture);
test_fail();
done();
return;
@ -1567,96 +1552,46 @@ let capture = "";
let next_trigger;
let next_trigger_handler;
function start_timeout()
async function prepare_test()
{
console.log("\nPreparing test #%d: %s", test_num, tests[test_num].name);
if(tests[test_num].timeout)
{
test_timeout = setTimeout(() =>
{
log_fail("Test #%d (%s) took longer than %s sec. Timing out and terminating.", test_num, tests[test_num].name, tests[test_num].timeout);
console.error("[-] Test #%d (%s) took longer than %s sec. Timing out and terminating.", test_num, tests[test_num].name, tests[test_num].timeout);
process.exit(1);
}, tests[test_num].timeout * 1000);
}
}
function nuke_fs()
{
start_timeout();
console.log("\nPreparing test #%d: %s", test_num, tests[test_num].name);
console.log(" Nuking /mnt");
emulator.fs9p.RecursiveDelete("");
reload_fsjson();
}
function reload_fsjson()
{
if(tests[test_num].use_fsjson)
{
console.log(" Reloading files from json");
emulator.fs9p.load_from_json(testfsjson, () => do_mounts());
emulator.fs9p.load_from_json(testfsjson);
}
else
{
do_mounts();
}
}
function do_mounts()
{
console.log(" Configuring mounts");
if(tests[test_num].mounts && tests[test_num].mounts.length > 0)
{
premount(0);
function premount(mount_num)
for(const { path, baseurl, basefs } of tests[test_num].mounts)
{
const path = tests[test_num].mounts[mount_num].path;
emulator.serial0_send("mkdir -p /mnt" + path + "\n");
emulator.serial0_send("rmdir /mnt" + path + "\n");
emulator.serial0_send("echo done-premount\n");
next_trigger = "done-premount";
next_trigger_handler = () => mount(mount_num);
}
function mount(mount_num)
{
const { path, baseurl, basefs } = tests[test_num].mounts[mount_num];
emulator.mount_fs(path, baseurl, basefs, err =>
{
if(err)
{
log_warn("Failed to mount fs required for test %s: %s",
tests[test_num].name, err);
test_fail();
}
if(mount_num + 1 < tests[test_num].mounts.length)
{
premount(mount_num + 1);
}
else
{
if(test_has_failed)
{
report_test();
}
else
{
load_files();
}
}
});
await async function() {
return new Promise((resolve, reject) => {
emulator.serial0_send("mkdir -p /mnt" + path + "\n");
emulator.serial0_send("rmdir /mnt" + path + "\n");
emulator.serial0_send("echo done-premount\n");
next_trigger = "done-premount";
next_trigger_handler = resolve;
});
}();
emulator.mount_fs(path, baseurl, basefs);
}
}
else
{
load_files();
}
}
async function load_files()
{
console.log(" Loading additional files");
if(tests[test_num].files)
{
@ -1664,29 +1599,9 @@ async function load_files()
for(const f of tests[test_num].files)
{
await emulator.create_file(f.file, f.data);
remaining--;
if(!remaining)
{
if(test_has_failed)
{
report_test();
}
else
{
start_test();
}
}
}
}
else
{
start_test();
}
}
function start_test()
{
console.log("Starting test #%d: %s", test_num, tests[test_num].name);
capture = "";
@ -1731,17 +1646,17 @@ function report_test()
{
if(!test_has_failed)
{
log_pass("Test #%d passed: %s", test_num, tests[test_num].name);
console.log("[+] Test #%d passed: %s", test_num, tests[test_num].name);
}
else
{
if(tests[test_num].allow_failure)
{
log_warn("Test #%d failed: %s (failure allowed)", test_num, tests[test_num].name);
console.warn("Test #%d failed: %s (failure allowed)", test_num, tests[test_num].name);
}
else
{
log_fail("Test #%d failed: %s", test_num, tests[test_num].name);
console.error("[-] Test #%d failed: %s", test_num, tests[test_num].name);
if(STOP_ON_FIRST_FAILURE)
{
@ -1755,7 +1670,7 @@ function report_test()
if(test_num < tests.length)
{
nuke_fs();
prepare_test();
}
else
{
@ -1776,17 +1691,17 @@ function finish_tests()
{
let unallowed_failure = false;
console.error("Failed %d out of %d tests:", failed_tests.length, tests.length);
console.error("[-] Failed %d out of %d tests:", failed_tests.length, tests.length);
for(const num of failed_tests)
{
if(tests[num].allow_failure)
{
log_warn("#%d %s (failure allowed)", num, tests[num].name);
console.warn("#%d %s (failure allowed)", num, tests[num].name);
}
else
{
unallowed_failure = true;
log_fail("#%d %s", num, tests[num].name);
console.error("[-] #%d %s", num, tests[num].name);
}
}
if(unallowed_failure)
@ -1798,7 +1713,7 @@ function finish_tests()
emulator.bus.register("emulator-started", function()
{
console.error("Booting now, please stand by");
console.log("Booting now, please stand by");
});
emulator.add_listener("serial0-output-byte", function(byte)
@ -1825,7 +1740,7 @@ emulator.add_listener("serial0-output-byte", function(byte)
if(!ran_command && line.endsWith("~% "))
{
ran_command = true;
nuke_fs();
prepare_test();
}
else if(new_line === next_trigger)
{

View file

@ -9,28 +9,11 @@ const V86 = require(`../../build/${TEST_RELEASE_BUILD ? "libv86" : "libv86-debug
const assert = require("assert").strict;
const SHOW_LOGS = false;
const STOP_ON_FIRST_FAILURE = false;
function log_pass(msg, ...args)
{
console.log(`\x1b[92m[+] ${msg}\x1b[0m`, ...args);
}
function log_warn(msg, ...args)
{
console.error(`\x1b[93m[!] ${msg}\x1b[0m`, ...args);
}
function log_fail(msg, ...args)
{
console.error(`\x1b[91m[-] ${msg}\x1b[0m`, ...args);
}
const tests =
[
{
name: "DHCP",
timeout: 60,
start: () =>
{
emulator.serial0_send("udhcpc\n");
@ -44,7 +27,6 @@ const tests =
},
{
name: "ifconfig",
timeout: 60,
start: () =>
{
emulator.serial0_send("ifconfig\n");
@ -58,7 +40,6 @@ const tests =
},
{
name: "route",
timeout: 60,
start: () =>
{
emulator.serial0_send("ip route\n");
@ -72,7 +53,6 @@ const tests =
},
//{
// name: "arp -a",
// timeout: 60,
// start: () =>
// {
// emulator.serial0_send("arp -a\n");
@ -86,7 +66,6 @@ const tests =
//},
{
name: "Curl example.org",
timeout: 60,
allow_failure: true,
start: () =>
{
@ -102,10 +81,6 @@ const tests =
];
let test_num = 0;
let test_timeout = 0;
const failed_tests = [];
const emulator = new V86({
bios: { url: __dirname + "/../../bios/seabios.bin" },
vga_bios: { url: __dirname + "/../../bios/vgabios.bin" },
@ -117,157 +92,15 @@ const emulator = new V86({
log_level: SHOW_LOGS ? 0x400000 : 0,
});
emulator.add_listener("emulator-ready", function () {
});
let ran_command = false;
let test_num = 0;
let booted = false;
let line = "";
let capturing = false;
let capture = "";
let next_trigger;
let next_trigger_handler;
function start_timeout()
{
if(tests[test_num].timeout)
{
test_timeout = setTimeout(() =>
{
log_fail("Test #%d (%s) took longer than %s sec. Timing out and terminating.", test_num, tests[test_num].name, tests[test_num].timeout);
process.exit(1);
}, tests[test_num].timeout * 1000);
}
}
function begin()
{
start_timeout();
console.log("\nPreparing test #%d: %s", test_num, tests[test_num].name);
start_test();
}
function start_test()
{
console.log("Starting test #%d: %s", test_num, tests[test_num].name);
capture = "";
tests[test_num].start();
if(tests[test_num].capture_trigger)
{
next_trigger = tests[test_num].capture_trigger;
next_trigger_handler = start_capture;
}
else
{
next_trigger = tests[test_num].end_trigger;
next_trigger_handler = end_test;
}
start_capture();
}
function start_capture()
{
console.log("Capturing...");
capture = "";
capturing = true;
next_trigger = tests[test_num].end_trigger;
next_trigger_handler = end_test;
}
function end_test()
{
capturing = false;
if(tests[test_num].timeout)
{
clearTimeout(test_timeout);
}
let test_has_failed = false;
try {
tests[test_num].end(capture);
} catch(e) {
console.log(e);
test_has_failed = true;
}
if(!test_has_failed)
{
log_pass("Test #%d passed: %s", test_num, tests[test_num].name);
}
else
{
if(tests[test_num].allow_failure)
{
log_warn("Test #%d failed: %s (failure allowed)", test_num, tests[test_num].name);
}
else
{
log_fail("Test #%d failed: %s", test_num, tests[test_num].name);
if(STOP_ON_FIRST_FAILURE)
{
finish_tests();
}
}
test_has_failed = false;
}
test_num++;
if(test_num < tests.length)
{
begin();
}
else
{
finish_tests();
}
}
function finish_tests()
{
emulator.stop();
emulator.destroy();
console.log("\nTests finished.");
if(failed_tests.length === 0)
{
console.log("All tests passed");
}
else
{
let unallowed_failure = false;
console.error("Failed %d out of %d tests:", failed_tests.length, tests.length);
for(const num of failed_tests)
{
if(tests[num].allow_failure)
{
log_warn("#%d %s (failure allowed)", num, tests[num].name);
}
else
{
unallowed_failure = true;
log_fail("#%d %s", num, tests[num].name);
}
}
if(unallowed_failure)
{
process.exit(1);
}
}
}
let end_trigger;
emulator.bus.register("emulator-started", function()
{
console.error("Booting now, please stand by");
console.log("Booting now, please stand by");
});
emulator.add_listener("serial0-output-byte", function(byte)
@ -279,11 +112,11 @@ emulator.add_listener("serial0-output-byte", function(byte)
}
let new_line = "";
let is_new_line = false;
if(chr === "\n")
{
is_new_line = true;
console.log(" Captured: %s", line);
new_line = line;
capture += line + "\n";
line = "";
}
else
@ -291,22 +124,57 @@ emulator.add_listener("serial0-output-byte", function(byte)
line += chr;
}
if(!ran_command && line.endsWith("~% "))
if(new_line === end_trigger)
{
ran_command = true;
begin();
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++;
}
else if(new_line === next_trigger)
if(!booted && line.endsWith("~% ") || new_line === end_trigger)
{
next_trigger_handler();
}
else if(is_new_line && capturing)
{
capture += new_line + "\n";
console.log(" Captured: %s", new_line);
}
else if(is_new_line)
{
console.log(" Serial: %s", new_line);
booted = true;
if(test_num >= tests.length)
{
emulator.stop();
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();
}
}
});

View file

@ -23,7 +23,7 @@ var emulator = new V86({
emulator.bus.register("emulator-started", function()
{
console.error("Booting now, please stand by");
console.log("Booting now, please stand by");
emulator.create_file("test-jit", test_executable);
});

View file

@ -23,7 +23,6 @@ var emulator = new V86({
emulator.bus.register("emulator-started", function()
{
console.error("Booting now, please stand by");
emulator.create_file("test-i386", test_executable);
});