From c096576adb204ffe1ffcee884dd2077090fcc842 Mon Sep 17 00:00:00 2001 From: danbugs Date: Tue, 19 May 2026 23:31:49 +0000 Subject: [PATCH 1/4] feat: enforce script timeout in Hyperlight runner Use hyperlight-unikraft v0.6.0 which adds run_code_with_timeout() with cancellable host sleep. When script_timeout is set in the config, the runner uses the timeout variant; otherwise run_code() is used as before. Signed-off-by: danbugs --- src/wxc_common/Cargo.toml | 2 +- src/wxc_common/src/hyperlight_runner.rs | 14 +++++++++++++- src/wxc_e2e_tests/tests/e2e_windows.rs | 6 ++++++ test_configs/hyperlight_timeout.json | 7 +++++++ 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 test_configs/hyperlight_timeout.json diff --git a/src/wxc_common/Cargo.toml b/src/wxc_common/Cargo.toml index 74671e7b4..41fe6236b 100644 --- a/src/wxc_common/Cargo.toml +++ b/src/wxc_common/Cargo.toml @@ -21,7 +21,7 @@ getrandom = { workspace = true } semver = "1" [target.'cfg(target_arch = "x86_64")'.dependencies] -hyperlight-unikraft-host = { git = "https://github.com/hyperlight-dev/hyperlight-unikraft", tag = "v0.5.0", optional = true } +hyperlight-unikraft-host = { git = "https://github.com/hyperlight-dev/hyperlight-unikraft", tag = "v0.6.0", optional = true } [target.'cfg(target_os = "windows")'.dependencies] windows = { workspace = true } diff --git a/src/wxc_common/src/hyperlight_runner.rs b/src/wxc_common/src/hyperlight_runner.rs index 1dcd86dc9..a2c235972 100644 --- a/src/wxc_common/src/hyperlight_runner.rs +++ b/src/wxc_common/src/hyperlight_runner.rs @@ -536,7 +536,19 @@ impl ScriptRunner for HyperlightScriptRunner { } }; - match rt.run_code(&request.script_code) { + let result = if request.script_timeout > 0 { + let timeout = + std::time::Duration::from_millis(u64::from(request.script_timeout)); + logger.log_line(&format!( + "hyperlight: timeout set to {}ms", + request.script_timeout + )); + rt.run_code_with_timeout(&request.script_code, timeout) + } else { + rt.run_code(&request.script_code) + }; + + match result { Ok(timing) => { logger.log_line(&format!( "hyperlight: run ok (restore={:.1}ms call={:.1}ms exit={})", diff --git a/src/wxc_e2e_tests/tests/e2e_windows.rs b/src/wxc_e2e_tests/tests/e2e_windows.rs index d90f84fa6..78191b3dd 100644 --- a/src/wxc_e2e_tests/tests/e2e_windows.rs +++ b/src/wxc_e2e_tests/tests/e2e_windows.rs @@ -622,6 +622,12 @@ fn hyperlight_suite() { expected_exit: 0, output_contains: Some("BLOCKED"), }, + HyperlightCase { + config: "hyperlight_timeout.json", + description: "time.sleep(120) killed by 5s timeout", + expected_exit: -1, + output_contains: Some("timed out"), + }, ]; let mut failures = Vec::new(); diff --git a/test_configs/hyperlight_timeout.json b/test_configs/hyperlight_timeout.json new file mode 100644 index 000000000..b19c0467e --- /dev/null +++ b/test_configs/hyperlight_timeout.json @@ -0,0 +1,7 @@ +{ + "process": { + "commandLine": "import time; time.sleep(120); print('should not reach here')", + "timeout": 5000 + }, + "containment": "hyperlight" +} From ffb1e00f12f3888184fb79b7f0265ec05e5afd3f Mon Sep 17 00:00:00 2001 From: danbugs Date: Tue, 19 May 2026 23:43:23 +0000 Subject: [PATCH 2/4] fix: update Cargo.lock for v0.6.0 and reduce test timeout to 1s Signed-off-by: danbugs --- src/Cargo.lock | 4 ++-- src/wxc_e2e_tests/tests/e2e_windows.rs | 2 +- test_configs/hyperlight_timeout.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index bdc094c57..91bfe10fa 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -843,8 +843,8 @@ dependencies = [ [[package]] name = "hyperlight-unikraft-host" -version = "0.5.0" -source = "git+https://github.com/hyperlight-dev/hyperlight-unikraft?tag=v0.5.0#ca05c5af35f1728bbce94e17677a18200b7247a6" +version = "0.6.0" +source = "git+https://github.com/hyperlight-dev/hyperlight-unikraft?tag=v0.6.0#d8524a99ad4855c7c9f1d0c17381b884386596b0" dependencies = [ "anyhow", "base64", diff --git a/src/wxc_e2e_tests/tests/e2e_windows.rs b/src/wxc_e2e_tests/tests/e2e_windows.rs index 78191b3dd..0a2db1f31 100644 --- a/src/wxc_e2e_tests/tests/e2e_windows.rs +++ b/src/wxc_e2e_tests/tests/e2e_windows.rs @@ -624,7 +624,7 @@ fn hyperlight_suite() { }, HyperlightCase { config: "hyperlight_timeout.json", - description: "time.sleep(120) killed by 5s timeout", + description: "time.sleep(120) killed by 1s timeout", expected_exit: -1, output_contains: Some("timed out"), }, diff --git a/test_configs/hyperlight_timeout.json b/test_configs/hyperlight_timeout.json index b19c0467e..6d6a31a10 100644 --- a/test_configs/hyperlight_timeout.json +++ b/test_configs/hyperlight_timeout.json @@ -1,7 +1,7 @@ { "process": { "commandLine": "import time; time.sleep(120); print('should not reach here')", - "timeout": 5000 + "timeout": 1000 }, "containment": "hyperlight" } From 9f02238a68977bce09773b8259a12419b7e8f4ee Mon Sep 17 00:00:00 2001 From: danbugs Date: Tue, 19 May 2026 23:44:05 +0000 Subject: [PATCH 3/4] fix: update GHCR image tag to v0.6.0 Signed-off-by: danbugs --- src/wxc_common/src/hyperlight_runner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wxc_common/src/hyperlight_runner.rs b/src/wxc_common/src/hyperlight_runner.rs index a2c235972..f0f1ad26e 100644 --- a/src/wxc_common/src/hyperlight_runner.rs +++ b/src/wxc_common/src/hyperlight_runner.rs @@ -201,7 +201,7 @@ pub fn setup(force: bool, logger: &mut Logger) -> Result { let opts = pyhl::InstallOptions { home: &home, source: pyhl::InstallSource::Ghcr { - tag: Some("v0.5.0"), + tag: Some("v0.6.0"), }, mounts: &[], network: None, From 2377a78225b7b9a39cbd67569240177fb5af75cb Mon Sep 17 00:00:00 2001 From: danbugs Date: Tue, 19 May 2026 23:48:12 +0000 Subject: [PATCH 4/4] style: rustfmt Signed-off-by: danbugs --- src/wxc_common/src/hyperlight_runner.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wxc_common/src/hyperlight_runner.rs b/src/wxc_common/src/hyperlight_runner.rs index f0f1ad26e..ed048d5cd 100644 --- a/src/wxc_common/src/hyperlight_runner.rs +++ b/src/wxc_common/src/hyperlight_runner.rs @@ -537,8 +537,7 @@ impl ScriptRunner for HyperlightScriptRunner { }; let result = if request.script_timeout > 0 { - let timeout = - std::time::Duration::from_millis(u64::from(request.script_timeout)); + let timeout = std::time::Duration::from_millis(u64::from(request.script_timeout)); logger.log_line(&format!( "hyperlight: timeout set to {}ms", request.script_timeout