@@ -62,6 +62,7 @@ pub mod test {
62
62
}
63
63
64
64
use std:: {
65
+ collections:: VecDeque ,
65
66
env, io,
66
67
io:: prelude:: Write ,
67
68
panic:: { self , catch_unwind, AssertUnwindSafe , PanicInfo } ,
@@ -211,14 +212,18 @@ where
211
212
use std:: sync:: mpsc:: RecvTimeoutError ;
212
213
213
214
struct RunningTest {
214
- timeout : Instant ,
215
215
join_handle : Option < thread:: JoinHandle < ( ) > > ,
216
216
}
217
217
218
218
// Use a deterministic hasher
219
219
type TestMap =
220
220
HashMap < TestDesc , RunningTest , BuildHasherDefault < collections:: hash_map:: DefaultHasher > > ;
221
221
222
+ struct TimeoutEntry {
223
+ desc : TestDesc ,
224
+ timeout : Instant ,
225
+ }
226
+
222
227
let tests_len = tests. len ( ) ;
223
228
224
229
let mut filtered_tests = filter_tests ( opts, tests) ;
@@ -262,25 +267,28 @@ where
262
267
} ;
263
268
264
269
let mut running_tests: TestMap = HashMap :: default ( ) ;
270
+ let mut timeout_queue: VecDeque < TimeoutEntry > = VecDeque :: new ( ) ;
265
271
266
- fn get_timed_out_tests ( running_tests : & mut TestMap ) -> Vec < TestDesc > {
272
+ fn get_timed_out_tests (
273
+ running_tests : & TestMap ,
274
+ timeout_queue : & mut VecDeque < TimeoutEntry > ,
275
+ ) -> Vec < TestDesc > {
267
276
let now = Instant :: now ( ) ;
268
- let timed_out = running_tests
269
- . iter ( )
270
- . filter_map (
271
- |( desc, running_test) | {
272
- if now >= running_test. timeout { Some ( desc. clone ( ) ) } else { None }
273
- } ,
274
- )
275
- . collect ( ) ;
276
- for test in & timed_out {
277
- running_tests. remove ( test) ;
277
+ let mut timed_out = Vec :: new ( ) ;
278
+ while let Some ( timeout_entry) = timeout_queue. front ( ) {
279
+ if now < timeout_entry. timeout {
280
+ break ;
281
+ }
282
+ let timeout_entry = timeout_queue. pop_front ( ) . unwrap ( ) ;
283
+ if running_tests. contains_key ( & timeout_entry. desc ) {
284
+ timed_out. push ( timeout_entry. desc ) ;
285
+ }
278
286
}
279
287
timed_out
280
288
}
281
289
282
- fn calc_timeout ( running_tests : & TestMap ) -> Option < Duration > {
283
- running_tests . values ( ) . map ( |running_test| running_test . timeout ) . min ( ) . map ( |next_timeout | {
290
+ fn calc_timeout ( timeout_queue : & VecDeque < TimeoutEntry > ) -> Option < Duration > {
291
+ timeout_queue . front ( ) . map ( |& TimeoutEntry { timeout : next_timeout , .. } | {
284
292
let now = Instant :: now ( ) ;
285
293
if next_timeout >= now { next_timeout - now } else { Duration :: new ( 0 , 0 ) }
286
294
} )
@@ -305,7 +313,7 @@ where
305
313
let timeout = time:: get_default_test_timeout ( ) ;
306
314
let desc = test. desc . clone ( ) ;
307
315
308
- let event = TestEvent :: TeWait ( test . desc . clone ( ) ) ;
316
+ let event = TestEvent :: TeWait ( desc. clone ( ) ) ;
309
317
notify_about_test_event ( event) ?; //here no pad
310
318
let join_handle = run_test (
311
319
opts,
@@ -315,15 +323,16 @@ where
315
323
tx. clone ( ) ,
316
324
Concurrent :: Yes ,
317
325
) ;
318
- running_tests. insert ( desc, RunningTest { timeout, join_handle } ) ;
326
+ running_tests. insert ( desc. clone ( ) , RunningTest { join_handle } ) ;
327
+ timeout_queue. push_back ( TimeoutEntry { desc, timeout } ) ;
319
328
pending += 1 ;
320
329
}
321
330
322
331
let mut res;
323
332
loop {
324
- if let Some ( timeout) = calc_timeout ( & running_tests ) {
333
+ if let Some ( timeout) = calc_timeout ( & timeout_queue ) {
325
334
res = rx. recv_timeout ( timeout) ;
326
- for test in get_timed_out_tests ( & mut running_tests ) {
335
+ for test in get_timed_out_tests ( & running_tests , & mut timeout_queue ) {
327
336
let event = TestEvent :: TeTimeout ( test) ;
328
337
notify_about_test_event ( event) ?;
329
338
}
0 commit comments