@@ -596,7 +596,9 @@ impl<T: Write> ConsoleTestState<T> {
596596 }
597597
598598 pub fn write_timeout ( & mut self , desc : & TestDesc ) -> io:: Result < ( ) > {
599- self . write_plain ( & format ! ( "test {} has been running for over {} seconds\n " , desc. name, TEST_WARN_TIMEOUT_S ) )
599+ self . write_plain ( & format ! ( "test {} has been running for over {} seconds\n " ,
600+ desc. name,
601+ TEST_WARN_TIMEOUT_S ) )
600602 }
601603
602604 pub fn write_log ( & mut self , test : & TestDesc , result : & TestResult ) -> io:: Result < ( ) > {
@@ -879,7 +881,28 @@ fn run_tests<F>(opts: &TestOpts, tests: Vec<TestDescAndFn>, mut callback: F) ->
879881
880882 let ( tx, rx) = channel :: < MonitorMsg > ( ) ;
881883
882- let mut running_tests: HashMap < TestDesc , Duration > = HashMap :: new ( ) ;
884+ let mut running_tests: HashMap < TestDesc , Instant > = HashMap :: new ( ) ;
885+
886+ fn get_timed_out_tests ( running_tests : & mut HashMap < TestDesc , Instant > ) -> Vec < TestDesc > {
887+ let now = Instant :: now ( ) ;
888+ let timed_out = running_tests. iter ( )
889+ . filter_map ( |( desc, timeout) | if & now >= timeout { Some ( desc. clone ( ) ) } else { None } )
890+ . collect ( ) ;
891+ for test in & timed_out {
892+ running_tests. remove ( test) ;
893+ }
894+ timed_out
895+ } ;
896+
897+ fn calc_timeout ( running_tests : & HashMap < TestDesc , Instant > ) -> Option < Duration > {
898+ running_tests. values ( ) . min ( ) . map ( |next_timeout| {
899+ let now = Instant :: now ( ) ;
900+ if * next_timeout >= now {
901+ * next_timeout - now
902+ } else {
903+ Duration :: new ( 0 , 0 )
904+ } } )
905+ } ;
883906
884907 while pending > 0 || !remaining. is_empty ( ) {
885908 while pending < concurrency && !remaining. is_empty ( ) {
@@ -890,38 +913,26 @@ fn run_tests<F>(opts: &TestOpts, tests: Vec<TestDescAndFn>, mut callback: F) ->
890913 // that hang forever.
891914 callback ( TeWait ( test. desc . clone ( ) , test. testfn . padding ( ) ) ) ?;
892915 }
893- running_tests. insert ( test. desc . clone ( ) , Duration :: from_secs ( TEST_WARN_TIMEOUT_S ) ) ;
916+ let timeout = Instant :: now ( ) + Duration :: from_secs ( TEST_WARN_TIMEOUT_S ) ;
917+ running_tests. insert ( test. desc . clone ( ) , timeout) ;
894918 run_test ( opts, !opts. run_tests , test, tx. clone ( ) ) ;
895919 pending += 1 ;
896920 }
897921
898922 let mut res;
899- if let Some ( min_timeout) = running_tests. values ( ) . min ( ) . cloned ( ) {
900- loop {
901- let before = Instant :: now ( ) ;
902- res = rx. recv_timeout ( min_timeout) ;
903- let elapsed = Instant :: now ( ) - before;
904-
905- let mut to_remove = Vec :: new ( ) ;
906- for ( desc, time_left) in & mut running_tests {
907- if * time_left >= elapsed {
908- * time_left -= elapsed;
909- } else {
910- to_remove. push ( desc. clone ( ) ) ;
911- callback ( TeTimeout ( desc. clone ( ) ) ) ?;
912- }
913- }
914-
915- for rem in to_remove {
916- running_tests. remove ( & rem) ;
923+ loop {
924+ if let Some ( timeout) = calc_timeout ( & running_tests) {
925+ res = rx. recv_timeout ( timeout) ;
926+ for test in get_timed_out_tests ( & mut running_tests) {
927+ callback ( TeTimeout ( test) ) ?;
917928 }
918-
919929 if res != Err ( RecvTimeoutError :: Timeout ) {
920930 break ;
921931 }
932+ } else {
933+ res = rx. recv ( ) . map_err ( |_| RecvTimeoutError :: Disconnected ) ;
934+ break ;
922935 }
923- } else {
924- res = rx. recv ( ) . map_err ( |_| RecvTimeoutError :: Disconnected ) ;
925936 }
926937
927938 let ( desc, result, stdout) = res. unwrap ( ) ;
0 commit comments