Skip to content

Commit fc507ba

Browse files
committed
[debug commit]
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
1 parent f360b2b commit fc507ba

File tree

5 files changed

+123
-68
lines changed

5 files changed

+123
-68
lines changed

.github/workflows/ValidatePullRequest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767
- docs-pr
6868
- build-guests
6969
strategy:
70-
fail-fast: true
70+
fail-fast: false
7171
matrix:
7272
hypervisor: [hyperv, 'hyperv-ws2025', mshv3, kvm]
7373
cpu: [amd, intel]

src/hyperlight_host/src/sandbox/uninitialized.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,7 @@ mod tests {
773773
use hyperlight_testing::tracing_subscriber::TracingSubscriber;
774774
use tracing::Level;
775775
use tracing_core::Subscriber;
776+
use tracing_core::callsite::rebuild_interest_cache;
776777
use uuid::Uuid;
777778

778779
/// Helper to extract a string value from nested JSON: obj["span"]["attributes"][key]
@@ -793,19 +794,25 @@ mod tests {
793794
let subscriber = TracingSubscriber::new(Level::TRACE);
794795

795796
tracing::subscriber::with_default(subscriber.clone(), || {
797+
// Rebuild the global callsite interest cache so that all callsites
798+
// (including those already registered by other test threads with the
799+
// no-op subscriber) are re-evaluated against our TracingSubscriber.
800+
// Without this, a race condition can cause #[instrument] spans in
801+
// production code to be permanently disabled via Interest::never().
802+
rebuild_interest_cache();
803+
796804
let correlation_id = Uuid::new_v4().to_string();
797805
let _span = tracing::error_span!("test_trace_logs", %correlation_id).entered();
798806

799-
// Verify we're in span 1 with correct name
800-
let (span_id, span_meta) = subscriber
807+
// Verify we're in a span with correct name
808+
let (test_span_id, span_meta) = subscriber
801809
.current_span()
802810
.into_inner()
803811
.expect("Should be inside a span");
804-
assert_eq!(span_id.into_u64(), 1, "Should be in span 1");
805812
assert_eq!(span_meta.name(), "test_trace_logs");
806813

807814
// Verify correlation_id was recorded
808-
let span_data = subscriber.get_span(1);
815+
let span_data = subscriber.get_span(test_span_id.into_u64());
809816
let recorded_id =
810817
get_span_attr(&span_data, "correlation_id").expect("correlation_id not found");
811818
assert_eq!(recorded_id, correlation_id);
@@ -816,16 +823,31 @@ mod tests {
816823
let result = UninitializedSandbox::new(GuestBinary::FilePath(bad_path), None);
817824
assert!(result.is_err(), "Sandbox creation should fail");
818825

819-
// Verify we're still in span 1 (our test span)
820-
let (span_id, _) = subscriber
826+
// Verify we're still in our test span
827+
let (current_id, _) = subscriber
821828
.current_span()
822829
.into_inner()
823830
.expect("Should still be inside a span");
824-
assert_eq!(span_id.into_u64(), 1, "Should still be in span 1");
831+
assert_eq!(
832+
current_id.into_u64(),
833+
test_span_id.into_u64(),
834+
"Should still be in the test span"
835+
);
825836

826-
// Verify span 2 was created by UninitializedSandbox::new
827-
let inner_span_meta = subscriber.get_span_metadata(2);
828-
assert_eq!(inner_span_meta.name(), "new");
837+
// Verify a span named "new" was created by UninitializedSandbox::new
838+
// (look up by name rather than hardcoded ID to avoid fragility)
839+
let all_spans = subscriber.get_all_spans();
840+
let new_span_entry = all_spans
841+
.iter()
842+
.find(|&(&id, _)| {
843+
id != test_span_id.into_u64()
844+
&& subscriber.get_span_metadata(id).name() == "new"
845+
})
846+
.expect("Expected a span named 'new' from UninitializedSandbox::new");
847+
assert_eq!(
848+
subscriber.get_span_metadata(*new_span_entry.0).name(),
849+
"new"
850+
);
829851

830852
// Verify the error event was emitted
831853
let events = subscriber.get_events();

src/hyperlight_host/tests/integration_test.rs

Lines changed: 76 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ fn interrupt_host_call() {
6161
});
6262

6363
let result = sandbox.call::<i32>("CallHostSpin", ()).unwrap_err();
64-
assert!(matches!(result, HyperlightError::ExecutionCanceledByHost()));
64+
assert!(
65+
matches!(&result, HyperlightError::ExecutionCanceledByHost()),
66+
"unexpected error: {result:?}"
67+
);
6568
assert!(sandbox.poisoned());
6669

6770
// Restore from snapshot to clear poison
@@ -92,7 +95,10 @@ fn interrupt_in_progress_guest_call() {
9295
});
9396

9497
let res = sbox1.call::<i32>("Spin", ()).unwrap_err();
95-
assert!(matches!(res, HyperlightError::ExecutionCanceledByHost()));
98+
assert!(
99+
matches!(&res, HyperlightError::ExecutionCanceledByHost()),
100+
"unexpected error: {res:?}"
101+
);
96102
assert!(sbox1.poisoned());
97103

98104
// Restore from snapshot to clear poison
@@ -265,7 +271,10 @@ fn interrupt_moved_sandbox() {
265271
let thread = thread::spawn(move || {
266272
barrier2.wait();
267273
let res = sbox1.call::<i32>("Spin", ()).unwrap_err();
268-
assert!(matches!(res, HyperlightError::ExecutionCanceledByHost()));
274+
assert!(
275+
matches!(&res, HyperlightError::ExecutionCanceledByHost()),
276+
"unexpected error: {res:?}"
277+
);
269278
assert!(sbox1.poisoned());
270279
sbox1.restore(snapshot1.clone()).unwrap();
271280
assert!(!sbox1.poisoned());
@@ -281,7 +290,10 @@ fn interrupt_moved_sandbox() {
281290
});
282291

283292
let res = sbox2.call::<i32>("Spin", ()).unwrap_err();
284-
assert!(matches!(res, HyperlightError::ExecutionCanceledByHost()));
293+
assert!(
294+
matches!(&res, HyperlightError::ExecutionCanceledByHost()),
295+
"unexpected error: {res:?}"
296+
);
285297

286298
thread.join().expect("Thread should finish");
287299
thread2.join().expect("Thread should finish");
@@ -317,7 +329,10 @@ fn interrupt_custom_signal_no_and_retry_delay() {
317329

318330
for _ in 0..NUM_ITERS {
319331
let res = sbox1.call::<i32>("Spin", ()).unwrap_err();
320-
assert!(matches!(res, HyperlightError::ExecutionCanceledByHost()));
332+
assert!(
333+
matches!(&res, HyperlightError::ExecutionCanceledByHost()),
334+
"unexpected error: {res:?}"
335+
);
321336
assert!(sbox1.poisoned());
322337
// immediately reenter another guest function call after having being cancelled,
323338
// so that the vcpu is running again before the interruptor-thread has a chance to see that the vcpu is not running
@@ -355,7 +370,10 @@ fn interrupt_spamming_host_call() {
355370
.call::<i32>("HostCallLoop", "HostFunc1".to_string())
356371
.unwrap_err();
357372

358-
assert!(matches!(res, HyperlightError::ExecutionCanceledByHost()));
373+
assert!(
374+
matches!(&res, HyperlightError::ExecutionCanceledByHost()),
375+
"unexpected error: {res:?}"
376+
);
359377

360378
thread.join().expect("Thread should finish");
361379
});
@@ -368,8 +386,7 @@ fn print_four_args_c_guest() {
368386
"PrintFourArgs",
369387
("Test4".to_string(), 3_i32, 4_i64, "Tested".to_string()),
370388
);
371-
println!("{:?}", res);
372-
assert!(matches!(res, Ok(46)));
389+
assert!(matches!(&res, Ok(46)), "unexpected result: {res:?}");
373390
});
374391
}
375392

@@ -381,9 +398,9 @@ fn guest_abort() {
381398
let res = sbox1
382399
.call::<()>("GuestAbortWithCode", error_code as i32)
383400
.unwrap_err();
384-
println!("{:?}", res);
385401
assert!(
386-
matches!(res, HyperlightError::GuestAborted(code, message) if (code == error_code && message.is_empty()))
402+
matches!(&res, HyperlightError::GuestAborted(code, message) if (*code == error_code && message.is_empty())),
403+
"unexpected error: {res:?}"
387404
);
388405
});
389406
}
@@ -394,9 +411,9 @@ fn guest_abort_with_context1() {
394411
let res = sbox1
395412
.call::<()>("GuestAbortWithMessage", (25_i32, "Oh no".to_string()))
396413
.unwrap_err();
397-
println!("{:?}", res);
398414
assert!(
399-
matches!(res, HyperlightError::GuestAborted(code, context) if (code == 25 && context == "Oh no"))
415+
matches!(&res, HyperlightError::GuestAborted(code, context) if (*code == 25 && context == "Oh no")),
416+
"unexpected error: {res:?}"
400417
);
401418
});
402419
}
@@ -439,9 +456,9 @@ fn guest_abort_with_context2() {
439456
let res = sbox1
440457
.call::<()>("GuestAbortWithMessage", (60_i32, abort_message.to_string()))
441458
.unwrap_err();
442-
println!("{:?}", res);
443459
assert!(
444-
matches!(res, HyperlightError::GuestAborted(_, context) if context.contains("Guest abort buffer overflowed"))
460+
matches!(&res, HyperlightError::GuestAborted(_, context) if context.contains("Guest abort buffer overflowed")),
461+
"unexpected error: {res:?}"
445462
);
446463
});
447464
}
@@ -458,9 +475,9 @@ fn guest_abort_c_guest() {
458475
(75_i32, "This is a test error message".to_string()),
459476
)
460477
.unwrap_err();
461-
println!("{:?}", res);
462478
assert!(
463-
matches!(res, HyperlightError::GuestAborted(code, message) if (code == 75 && message == "This is a test error message") )
479+
matches!(&res, HyperlightError::GuestAborted(code, message) if (*code == 75 && message == "This is a test error message")),
480+
"unexpected error: {res:?}"
464481
);
465482
});
466483
}
@@ -472,9 +489,9 @@ fn guest_panic() {
472489
let res = sbox1
473490
.call::<()>("guest_panic", "Error... error...".to_string())
474491
.unwrap_err();
475-
println!("{:?}", res);
476492
assert!(
477-
matches!(res, HyperlightError::GuestAborted(code, context) if code == ErrorCode::UnknownError as u8 && context.contains("\nError... error..."))
493+
matches!(&res, HyperlightError::GuestAborted(code, context) if *code == ErrorCode::UnknownError as u8 && context.contains("\nError... error...")),
494+
"unexpected error: {res:?}"
478495
);
479496
});
480497
}
@@ -511,30 +528,37 @@ fn guest_malloc_abort() {
511528
let size = 20000000_i32; // some big number that should fail when allocated
512529

513530
let res = sbox1.call::<i32>("TestMalloc", size).unwrap_err();
514-
println!("{:?}", res);
515531
assert!(
516-
matches!(res, HyperlightError::GuestAborted(code, _) if code == ErrorCode::MallocFailed as u8)
532+
matches!(&res, HyperlightError::GuestAborted(code, _) if *code == ErrorCode::MallocFailed as u8),
533+
"unexpected error: {res:?}"
517534
);
518535
});
519536

520537
// allocate a vector (on heap) that is bigger than the heap
521538
let heap_size = 0x4000;
522539
let size_to_allocate = 0x10000;
523-
assert!(size_to_allocate > heap_size);
540+
assert!(
541+
size_to_allocate > heap_size,
542+
"precondition: size_to_allocate ({size_to_allocate}) must be > heap_size ({heap_size})"
543+
);
524544

525545
let mut cfg = SandboxConfiguration::default();
526546
cfg.set_heap_size(heap_size);
527547
with_rust_sandbox_cfg(cfg, |mut sbox2| {
528-
let res = sbox2.call::<i32>(
529-
"CallMalloc", // uses the rust allocator to allocate a vector on heap
530-
size_to_allocate as i32,
548+
let err = sbox2
549+
.call::<i32>(
550+
"CallMalloc", // uses the rust allocator to allocate a vector on heap
551+
size_to_allocate as i32,
552+
)
553+
.unwrap_err();
554+
assert!(
555+
matches!(
556+
&err,
557+
// OOM memory errors in rust allocator are panics. Our panic handler returns ErrorCode::UnknownError on panic
558+
HyperlightError::GuestAborted(code, msg) if *code == ErrorCode::UnknownError as u8 && msg.contains("memory allocation of ")
559+
),
560+
"unexpected error: {err:?}"
531561
);
532-
println!("{:?}", res);
533-
assert!(matches!(
534-
res.unwrap_err(),
535-
// OOM memory errors in rust allocator are panics. Our panic handler returns ErrorCode::UnknownError on panic
536-
HyperlightError::GuestAborted(code, msg) if code == ErrorCode::UnknownError as u8 && msg.contains("memory allocation of ")
537-
));
538562
});
539563
}
540564

@@ -572,10 +596,13 @@ fn guest_panic_no_alloc() {
572596
panic!("panic on OOM caused stack overflow, this implies allocation in panic handler");
573597
}
574598

575-
assert!(matches!(
576-
res,
577-
HyperlightError::GuestAborted(code, msg) if code == ErrorCode::UnknownError as u8 && msg.contains("memory allocation of ") && msg.contains("bytes failed")
578-
));
599+
assert!(
600+
matches!(
601+
&res,
602+
HyperlightError::GuestAborted(code, msg) if *code == ErrorCode::UnknownError as u8 && msg.contains("memory allocation of ") && msg.contains("bytes failed")
603+
),
604+
"unexpected error: {res:?}"
605+
);
579606
});
580607
}
581608

@@ -590,7 +617,8 @@ fn dynamic_stack_allocate_c_guest() {
590617
.call::<i32>("StackAllocate", 0x800_0000_i32)
591618
.unwrap_err();
592619
assert!(
593-
matches!(res, HyperlightError::GuestAborted(code, _) if code == ErrorCode::MallocFailed as u8)
620+
matches!(&res, HyperlightError::GuestAborted(code, _) if *code == ErrorCode::MallocFailed as u8),
621+
"unexpected error: {res:?}"
594622
);
595623
});
596624
}
@@ -610,7 +638,8 @@ fn static_stack_allocate_overflow() {
610638
with_all_sandboxes(|mut sbox1| {
611639
let res = sbox1.call::<i32>("LargeVar", ()).unwrap_err();
612640
assert!(
613-
matches!(res, HyperlightError::GuestAborted(code, _) if code == ErrorCode::MallocFailed as u8)
641+
matches!(&res, HyperlightError::GuestAborted(code, _) if *code == ErrorCode::MallocFailed as u8),
642+
"unexpected error: {res:?}"
614643
);
615644
});
616645
}
@@ -630,7 +659,8 @@ fn guard_page_check_2() {
630659
with_rust_sandbox(|mut sbox1| {
631660
let res = sbox1.call::<()>("InfiniteRecursion", ()).unwrap_err();
632661
assert!(
633-
matches!(res, HyperlightError::GuestAborted(code, _) if code == ErrorCode::MallocFailed as u8)
662+
matches!(&res, HyperlightError::GuestAborted(code, _) if *code == ErrorCode::MallocFailed as u8),
663+
"unexpected error: {res:?}"
634664
);
635665
});
636666
}
@@ -663,15 +693,12 @@ fn recursive_stack_allocate_overflow() {
663693

664694
let res = sbox1.call::<()>("StackOverflow", iterations).unwrap_err();
665695
assert!(
666-
matches!(res, HyperlightError::GuestAborted(code, _) if code == ErrorCode::MallocFailed as u8)
696+
matches!(&res, HyperlightError::GuestAborted(code, _) if *code == ErrorCode::MallocFailed as u8),
697+
"unexpected error: {res:?}"
667698
);
668699
});
669700
}
670701

671-
// assert!(
672-
// matches!(res, HyperlightError::GuestAborted(code, _) if code == ErrorCode::MallocFailed as u8)
673-
// );
674-
675702
// Check that log messages are emitted correctly from the guest
676703
// This test is ignored as it sets a logger and therefore maybe impacted by other tests running concurrently
677704
// or it may impact other tests.
@@ -774,13 +801,11 @@ fn test_if_guest_is_able_to_get_bool_return_values_from_host() {
774801
let res = sbox3
775802
.call::<bool>("GuestRetrievesBoolValue", (i, i))
776803
.unwrap();
777-
println!("{:?}", res);
778804
assert!(!res);
779805
} else {
780806
let res = sbox3
781807
.call::<bool>("GuestRetrievesBoolValue", (i, i))
782808
.unwrap();
783-
println!("{:?}", res);
784809
assert!(res);
785810
}
786811
}
@@ -799,7 +824,6 @@ fn test_if_guest_is_able_to_get_float_return_values_from_host() {
799824
let res = sbox3
800825
.call::<f32>("GuestRetrievesFloatValue", (1.34_f32, 1.34_f32))
801826
.unwrap();
802-
println!("{:?}", res);
803827
assert_eq!(res, 2.68_f32);
804828
});
805829
}
@@ -816,7 +840,6 @@ fn test_if_guest_is_able_to_get_double_return_values_from_host() {
816840
let res = sbox3
817841
.call::<f64>("GuestRetrievesDoubleValue", (1.34_f64, 1.34_f64))
818842
.unwrap();
819-
println!("{:?}", res);
820843
assert_eq!(res, 2.68_f64);
821844
});
822845
}
@@ -835,7 +858,6 @@ fn test_if_guest_is_able_to_get_string_return_values_from_host() {
835858
let res = sbox3
836859
.call::<String>("GuestRetrievesStringValue", ())
837860
.unwrap();
838-
println!("{:?}", res);
839861
assert_eq!(
840862
res,
841863
"Guest Function, string added by Host Function".to_string()
@@ -1550,10 +1572,13 @@ fn interrupt_infinite_moving_loop_stress_test() {
15501572

15511573
// If the guest entered before calling kill, then we know for a fact the call should have been canceled since kill() was NOT premature.
15521574
if entered_before_kill {
1553-
assert!(matches!(
1554-
sandbox_res,
1555-
Err(HyperlightError::ExecutionCanceledByHost())
1556-
));
1575+
assert!(
1576+
matches!(
1577+
&sandbox_res,
1578+
Err(HyperlightError::ExecutionCanceledByHost())
1579+
),
1580+
"unexpected result: {sandbox_res:?}"
1581+
);
15571582
}
15581583

15591584
// If we did NOT enter the guest before calling kill, then the call may or may not have been canceled depending on timing.

0 commit comments

Comments
 (0)