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