mirror of
https://github.com/jetkvm/kvm.git
synced 2026-05-21 05:20:35 +00:00
test(e2e): preserve remote agent diagnostics (#1457)
* test(e2e): lower s3 wake version gate * test(e2e): preserve device logs across restarts Capture failing device logs before later restarts can truncate last.log, and keep a rotated copy available during global teardown.
This commit is contained in:
@@ -21,6 +21,10 @@ export default async function globalTeardown() {
|
||||
|
||||
const logs: Record<string, string> = {
|
||||
"device-last.log": "cat /userdata/jetkvm/last.log",
|
||||
// Rotated by restartAppViaSSH — preserves the failing session's output
|
||||
// when a later test restarts the app before teardown captures logs.
|
||||
// sshExec(_, true) returns "" if the file is missing, so no shell guard needed.
|
||||
"device-prev.log": "cat /userdata/jetkvm/last.log.prev",
|
||||
"device-config.json": "cat /userdata/kvm_config.json",
|
||||
"device-dmesg.txt": "dmesg | tail -200",
|
||||
};
|
||||
|
||||
+5
-1
@@ -750,8 +750,12 @@ export async function restoreSSHDevState(state: SSHDevState): Promise<void> {
|
||||
export async function restartAppViaSSH(): Promise<void> {
|
||||
await sshExec("killall jetkvm_app", true);
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
// Rotate last.log into last.log.prev before respawning so a later teardown
|
||||
// can still recover the previous session's output if a subsequent restart
|
||||
// truncates the live log. Combined into one SSH call to save a round-trip.
|
||||
await sshExec(
|
||||
"setsid env LD_LIBRARY_PATH=/oem/usr/lib:/oem/lib /userdata/jetkvm/bin/jetkvm_app > /userdata/jetkvm/last.log 2>&1 &",
|
||||
"[ -s /userdata/jetkvm/last.log ] && mv /userdata/jetkvm/last.log /userdata/jetkvm/last.log.prev; " +
|
||||
"setsid env LD_LIBRARY_PATH=/oem/usr/lib:/oem/lib /userdata/jetkvm/bin/jetkvm_app > /userdata/jetkvm/last.log 2>&1 &",
|
||||
true,
|
||||
);
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
@@ -489,6 +489,24 @@ test.afterAll(async () => {
|
||||
if (sharedPage) await sharedPage.close();
|
||||
});
|
||||
|
||||
// Snapshot /userdata/jetkvm/last.log into the failing test's output dir before
|
||||
// any subsequent test reboots the device (RkLunch's `> last.log` at boot wipes
|
||||
// the log, and /oem is read-only so we can't change that). This makes the
|
||||
// capture race-free regardless of what later tests do.
|
||||
// Empty fixture destructure is required by Playwright; `_` would fail the
|
||||
// runtime "destructuring pattern" check.
|
||||
// oxlint-disable-next-line no-empty-pattern
|
||||
test.afterEach(async ({}, testInfo) => {
|
||||
if (!agent) return;
|
||||
if (testInfo.status === testInfo.expectedStatus) return;
|
||||
const log = await sshExec("cat /userdata/jetkvm/last.log", true);
|
||||
try {
|
||||
await testInfo.attach("device-last.log", { body: log, contentType: "text/plain" });
|
||||
} catch {
|
||||
// attach can throw if the worker is already tearing down; sshExec(_, true) won't.
|
||||
}
|
||||
});
|
||||
|
||||
test.describe("Remote Host Agent", () => {
|
||||
// ═══════════════════════════════════════════
|
||||
// KEYBOARD: TOGGLE KEYS + LED ROUND-TRIP
|
||||
@@ -2115,8 +2133,9 @@ test.describe("Remote Host Agent", () => {
|
||||
const postMountEvents = await waitForKeyboardReady(agent!, sharedPage);
|
||||
expect(postMountEvents.length, "keyboard should work after disk mount").toBeGreaterThan(0);
|
||||
|
||||
// Unmount
|
||||
await callJsonRpc(sharedPage, "unmountImage");
|
||||
// Unmount — Disk-mode unmount can hit the EBUSY rebind path plus NBD
|
||||
// disconnect drain, which routinely runs past the default 10s RPC timeout.
|
||||
await callJsonRpc(sharedPage, "unmountImage", {}, 30_000);
|
||||
const stateEnd = (await callJsonRpc(sharedPage, "getVirtualMediaState")) as null | object;
|
||||
expect(stateEnd).toBeNull();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user