@@ -62,6 +62,7 @@ pub mod test {
6262}
6363
6464use std:: {
65+ collections:: VecDeque ,
6566 env, io,
6667 io:: prelude:: Write ,
6768 panic:: { self , catch_unwind, AssertUnwindSafe , PanicInfo } ,
@@ -211,14 +212,18 @@ where
211212 use std:: sync:: mpsc:: RecvTimeoutError ;
212213
213214 struct RunningTest {
214- timeout : Instant ,
215215 join_handle : Option < thread:: JoinHandle < ( ) > > ,
216216 }
217217
218218 // Use a deterministic hasher
219219 type TestMap =
220220 HashMap < TestDesc , RunningTest , BuildHasherDefault < collections:: hash_map:: DefaultHasher > > ;
221221
222+ struct TimeoutEntry {
223+ desc : TestDesc ,
224+ timeout : Instant ,
225+ }
226+
222227 let tests_len = tests. len ( ) ;
223228
224229 let mut filtered_tests = filter_tests ( opts, tests) ;
@@ -262,25 +267,28 @@ where
262267 } ;
263268
264269 let mut running_tests: TestMap = HashMap :: default ( ) ;
270+ let mut timeout_queue: VecDeque < TimeoutEntry > = VecDeque :: new ( ) ;
265271
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 > {
267276 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+ }
278286 }
279287 timed_out
280288 }
281289
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 , .. } | {
284292 let now = Instant :: now ( ) ;
285293 if next_timeout >= now { next_timeout - now } else { Duration :: new ( 0 , 0 ) }
286294 } )
@@ -305,7 +313,7 @@ where
305313 let timeout = time:: get_default_test_timeout ( ) ;
306314 let desc = test. desc . clone ( ) ;
307315
308- let event = TestEvent :: TeWait ( test . desc . clone ( ) ) ;
316+ let event = TestEvent :: TeWait ( desc. clone ( ) ) ;
309317 notify_about_test_event ( event) ?; //here no pad
310318 let join_handle = run_test (
311319 opts,
@@ -315,15 +323,16 @@ where
315323 tx. clone ( ) ,
316324 Concurrent :: Yes ,
317325 ) ;
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 } ) ;
319328 pending += 1 ;
320329 }
321330
322331 let mut res;
323332 loop {
324- if let Some ( timeout) = calc_timeout ( & running_tests ) {
333+ if let Some ( timeout) = calc_timeout ( & timeout_queue ) {
325334 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 ) {
327336 let event = TestEvent :: TeTimeout ( test) ;
328337 notify_about_test_event ( event) ?;
329338 }
0 commit comments