@@ -85,8 +85,11 @@ pub(crate) fn maybe_time_and_emit_host_call<T, F: FnOnce() -> T>(
85
85
86
86
#[ cfg( test) ]
87
87
mod tests {
88
+ use std:: thread;
89
+ use std:: time:: Duration ;
90
+
88
91
use hyperlight_testing:: simple_guest_as_string;
89
- use metrics:: Key ;
92
+ use metrics:: { with_local_recorder , Key } ;
90
93
use metrics_util:: CompositeKey ;
91
94
92
95
use super :: * ;
@@ -95,24 +98,24 @@ mod tests {
95
98
use crate :: { GuestBinary , UninitializedSandbox } ;
96
99
97
100
#[ test]
98
- #[ ignore = "This test needs to be run separately to avoid having other tests interfere with it" ]
99
101
fn test_metrics_are_emitted ( ) {
100
- // Set up the recorder and snapshotter
101
102
let recorder = metrics_util:: debugging:: DebuggingRecorder :: new ( ) ;
102
103
let snapshotter = recorder. snapshotter ( ) ;
103
-
104
- // we cannot use with_local_recorder, since that won't capture the metrics
105
- // emitted by the hypervisor-thread (which is all of them)
106
- recorder. install ( ) . unwrap ( ) ;
107
-
108
- let snapshot = {
104
+ let snapshot = with_local_recorder ( & recorder, || {
109
105
let uninit = UninitializedSandbox :: new (
110
106
GuestBinary :: FilePath ( simple_guest_as_string ( ) . unwrap ( ) ) ,
111
107
None ,
112
108
)
113
109
. unwrap ( ) ;
114
110
115
111
let mut multi = uninit. evolve ( Noop :: default ( ) ) . unwrap ( ) ;
112
+ let interrupt_handle = multi. interrupt_handle ( ) ;
113
+
114
+ // interrupt the guest function call to "Spin" after 1 second
115
+ let thread = thread:: spawn ( move || {
116
+ thread:: sleep ( Duration :: from_secs ( 1 ) ) ;
117
+ assert ! ( interrupt_handle. kill( ) ) ;
118
+ } ) ;
116
119
117
120
multi
118
121
. call_guest_function_by_name :: < i32 > ( "PrintOutput" , "Hello" . to_string ( ) )
@@ -121,9 +124,10 @@ mod tests {
121
124
multi
122
125
. call_guest_function_by_name :: < i32 > ( "Spin" , ( ) )
123
126
. unwrap_err ( ) ;
127
+ thread. join ( ) . unwrap ( ) ;
124
128
125
129
snapshotter. snapshot ( )
126
- } ;
130
+ } ) ;
127
131
128
132
// Convert snapshot into a hashmap for easier lookup
129
133
#[ expect( clippy:: mutable_key_type) ]
@@ -132,27 +136,17 @@ mod tests {
132
136
cfg_if:: cfg_if! {
133
137
if #[ cfg( feature = "function_call_metrics" ) ] {
134
138
use metrics:: Label ;
135
- // Verify that the histogram metrics are recorded correctly
136
- assert_eq!( snapshot. len( ) , 4 , "Expected two metrics in the snapshot" ) ;
137
139
138
- // 1. Host print duration
139
- let histogram_key = CompositeKey :: new(
140
- metrics_util:: MetricKind :: Histogram ,
141
- Key :: from_parts(
142
- METRIC_HOST_FUNC_DURATION ,
143
- vec![ Label :: new( "function_name" , "HostPrint" ) ] ,
144
- ) ,
145
- ) ;
146
- let histogram_value = & snapshot. get( & histogram_key) . unwrap( ) . 2 ;
147
- assert!(
148
- matches!(
149
- histogram_value,
150
- metrics_util:: debugging:: DebugValue :: Histogram ( histogram) if histogram. len( ) == 1
151
- ) ,
152
- "Histogram metric does not match expected value"
153
- ) ;
140
+ let expected_num_metrics = if cfg!( all( feature = "seccomp" , target_os = "linux" ) ) {
141
+ 3 // if seccomp enabled, the host call duration metric is emitted on a separate thread which this local recorder doesn't capture
142
+ } else {
143
+ 4
144
+ } ;
154
145
155
- // 2. Guest call duration
146
+ // Verify that the histogram metrics are recorded correctly
147
+ assert_eq!( snapshot. len( ) , expected_num_metrics) ;
148
+
149
+ // 1. Guest call duration
156
150
let histogram_key = CompositeKey :: new(
157
151
metrics_util:: MetricKind :: Histogram ,
158
152
Key :: from_parts(
@@ -169,7 +163,7 @@ mod tests {
169
163
"Histogram metric does not match expected value"
170
164
) ;
171
165
172
- // 3 . Guest cancellation
166
+ // 2 . Guest cancellation
173
167
let counter_key = CompositeKey :: new(
174
168
metrics_util:: MetricKind :: Counter ,
175
169
Key :: from_name( METRIC_GUEST_CANCELLATION ) ,
@@ -179,7 +173,7 @@ mod tests {
179
173
metrics_util:: debugging:: DebugValue :: Counter ( 1 )
180
174
) ;
181
175
182
- // 4 . Guest call duration
176
+ // 3 . Guest call duration
183
177
let histogram_key = CompositeKey :: new(
184
178
metrics_util:: MetricKind :: Histogram ,
185
179
Key :: from_parts(
@@ -195,9 +189,28 @@ mod tests {
195
189
) ,
196
190
"Histogram metric does not match expected value"
197
191
) ;
192
+
193
+ if !cfg!( all( feature = "seccomp" , target_os = "linux" ) ) {
194
+ // 4. Host call duration
195
+ let histogram_key = CompositeKey :: new(
196
+ metrics_util:: MetricKind :: Histogram ,
197
+ Key :: from_parts(
198
+ METRIC_HOST_FUNC_DURATION ,
199
+ vec![ Label :: new( "function_name" , "HostPrint" ) ] ,
200
+ ) ,
201
+ ) ;
202
+ let histogram_value = & snapshot. get( & histogram_key) . unwrap( ) . 2 ;
203
+ assert!(
204
+ matches!(
205
+ histogram_value,
206
+ metrics_util:: debugging:: DebugValue :: Histogram ( histogram) if histogram. len( ) == 1
207
+ ) ,
208
+ "Histogram metric does not match expected value"
209
+ ) ;
210
+ }
198
211
} else {
199
212
// Verify that the counter metrics are recorded correctly
200
- assert_eq!( snapshot. len( ) , 1 , "Expected two metrics in the snapshot" ) ;
213
+ assert_eq!( snapshot. len( ) , 1 ) ;
201
214
202
215
let counter_key = CompositeKey :: new(
203
216
metrics_util:: MetricKind :: Counter ,
0 commit comments