@@ -99,6 +99,10 @@ mod formatters;
9999
100100use formatters:: { JsonFormatter , OutputFormatter , PrettyFormatter , TerseFormatter } ;
101101
102+ /// Whether to execute tests concurrently or not
103+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
104+ pub enum Concurrent { Yes , No }
105+
102106// The name of a test. By convention this follows the rules for rust
103107// paths; i.e., it should be a series of identifiers separated by double
104108// colons. This way if some test runner wants to arrange the tests
@@ -1073,8 +1077,12 @@ pub fn run_tests<F>(opts: &TestOpts, tests: Vec<TestDescAndFn>, mut callback: F)
10731077where
10741078 F : FnMut ( TestEvent ) -> io:: Result < ( ) > ,
10751079{
1076- use std:: collections:: HashMap ;
1080+ use std:: collections:: { self , HashMap } ;
1081+ use std:: hash:: BuildHasherDefault ;
10771082 use std:: sync:: mpsc:: RecvTimeoutError ;
1083+ // Use a deterministic hasher
1084+ type TestMap =
1085+ HashMap < TestDesc , Instant , BuildHasherDefault < collections:: hash_map:: DefaultHasher > > ;
10781086
10791087 let tests_len = tests. len ( ) ;
10801088
@@ -1113,9 +1121,9 @@ where
11131121
11141122 let ( tx, rx) = channel :: < MonitorMsg > ( ) ;
11151123
1116- let mut running_tests: HashMap < TestDesc , Instant > = HashMap :: new ( ) ;
1124+ let mut running_tests: TestMap = HashMap :: default ( ) ;
11171125
1118- fn get_timed_out_tests ( running_tests : & mut HashMap < TestDesc , Instant > ) -> Vec < TestDesc > {
1126+ fn get_timed_out_tests ( running_tests : & mut TestMap ) -> Vec < TestDesc > {
11191127 let now = Instant :: now ( ) ;
11201128 let timed_out = running_tests
11211129 . iter ( )
@@ -1133,7 +1141,7 @@ where
11331141 timed_out
11341142 } ;
11351143
1136- fn calc_timeout ( running_tests : & HashMap < TestDesc , Instant > ) -> Option < Duration > {
1144+ fn calc_timeout ( running_tests : & TestMap ) -> Option < Duration > {
11371145 running_tests. values ( ) . min ( ) . map ( |next_timeout| {
11381146 let now = Instant :: now ( ) ;
11391147 if * next_timeout >= now {
@@ -1148,7 +1156,7 @@ where
11481156 while !remaining. is_empty ( ) {
11491157 let test = remaining. pop ( ) . unwrap ( ) ;
11501158 callback ( TeWait ( test. desc . clone ( ) ) ) ?;
1151- run_test ( opts, !opts. run_tests , test, tx. clone ( ) ) ;
1159+ run_test ( opts, !opts. run_tests , test, tx. clone ( ) , Concurrent :: No ) ;
11521160 let ( test, result, stdout) = rx. recv ( ) . unwrap ( ) ;
11531161 callback ( TeResult ( test, result, stdout) ) ?;
11541162 }
@@ -1159,7 +1167,7 @@ where
11591167 let timeout = Instant :: now ( ) + Duration :: from_secs ( TEST_WARN_TIMEOUT_S ) ;
11601168 running_tests. insert ( test. desc . clone ( ) , timeout) ;
11611169 callback ( TeWait ( test. desc . clone ( ) ) ) ?; //here no pad
1162- run_test ( opts, !opts. run_tests , test, tx. clone ( ) ) ;
1170+ run_test ( opts, !opts. run_tests , test, tx. clone ( ) , Concurrent :: Yes ) ;
11631171 pending += 1 ;
11641172 }
11651173
@@ -1191,7 +1199,7 @@ where
11911199 // All benchmarks run at the end, in serial.
11921200 for b in filtered_benchs {
11931201 callback ( TeWait ( b. desc . clone ( ) ) ) ?;
1194- run_test ( opts, false , b, tx. clone ( ) ) ;
1202+ run_test ( opts, false , b, tx. clone ( ) , Concurrent :: No ) ;
11951203 let ( test, result, stdout) = rx. recv ( ) . unwrap ( ) ;
11961204 callback ( TeResult ( test, result, stdout) ) ?;
11971205 }
@@ -1393,6 +1401,7 @@ pub fn run_test(
13931401 force_ignore : bool ,
13941402 test : TestDescAndFn ,
13951403 monitor_ch : Sender < MonitorMsg > ,
1404+ concurrency : Concurrent ,
13961405) {
13971406 let TestDescAndFn { desc, testfn } = test;
13981407
@@ -1409,6 +1418,7 @@ pub fn run_test(
14091418 monitor_ch : Sender < MonitorMsg > ,
14101419 nocapture : bool ,
14111420 testfn : Box < dyn FnBox ( ) + Send > ,
1421+ concurrency : Concurrent ,
14121422 ) {
14131423 // Buffer for capturing standard I/O
14141424 let data = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
@@ -1443,7 +1453,7 @@ pub fn run_test(
14431453 // the test synchronously, regardless of the concurrency
14441454 // level.
14451455 let supports_threads = !cfg ! ( target_os = "emscripten" ) && !cfg ! ( target_arch = "wasm32" ) ;
1446- if supports_threads {
1456+ if concurrency == Concurrent :: Yes && supports_threads {
14471457 let cfg = thread:: Builder :: new ( ) . name ( name. as_slice ( ) . to_owned ( ) ) ;
14481458 cfg. spawn ( runtest) . unwrap ( ) ;
14491459 } else {
@@ -1464,13 +1474,14 @@ pub fn run_test(
14641474 }
14651475 DynTestFn ( f) => {
14661476 let cb = move || __rust_begin_short_backtrace ( f) ;
1467- run_test_inner ( desc, monitor_ch, opts. nocapture , Box :: new ( cb) )
1477+ run_test_inner ( desc, monitor_ch, opts. nocapture , Box :: new ( cb) , concurrency )
14681478 }
14691479 StaticTestFn ( f) => run_test_inner (
14701480 desc,
14711481 monitor_ch,
14721482 opts. nocapture ,
14731483 Box :: new ( move || __rust_begin_short_backtrace ( f) ) ,
1484+ concurrency,
14741485 ) ,
14751486 }
14761487}
@@ -1753,6 +1764,7 @@ mod tests {
17531764 use std:: sync:: mpsc:: channel;
17541765 use bench;
17551766 use Bencher ;
1767+ use Concurrent ;
17561768
17571769
17581770 fn one_ignored_one_unignored_test ( ) -> Vec < TestDescAndFn > {
@@ -1793,7 +1805,7 @@ mod tests {
17931805 testfn : DynTestFn ( Box :: new ( f) ) ,
17941806 } ;
17951807 let ( tx, rx) = channel ( ) ;
1796- run_test ( & TestOpts :: new ( ) , false , desc, tx) ;
1808+ run_test ( & TestOpts :: new ( ) , false , desc, tx, Concurrent :: No ) ;
17971809 let ( _, res, _) = rx. recv ( ) . unwrap ( ) ;
17981810 assert ! ( res != TrOk ) ;
17991811 }
@@ -1811,7 +1823,7 @@ mod tests {
18111823 testfn : DynTestFn ( Box :: new ( f) ) ,
18121824 } ;
18131825 let ( tx, rx) = channel ( ) ;
1814- run_test ( & TestOpts :: new ( ) , false , desc, tx) ;
1826+ run_test ( & TestOpts :: new ( ) , false , desc, tx, Concurrent :: No ) ;
18151827 let ( _, res, _) = rx. recv ( ) . unwrap ( ) ;
18161828 assert ! ( res == TrIgnored ) ;
18171829 }
@@ -1831,7 +1843,7 @@ mod tests {
18311843 testfn : DynTestFn ( Box :: new ( f) ) ,
18321844 } ;
18331845 let ( tx, rx) = channel ( ) ;
1834- run_test ( & TestOpts :: new ( ) , false , desc, tx) ;
1846+ run_test ( & TestOpts :: new ( ) , false , desc, tx, Concurrent :: No ) ;
18351847 let ( _, res, _) = rx. recv ( ) . unwrap ( ) ;
18361848 assert ! ( res == TrOk ) ;
18371849 }
@@ -1851,7 +1863,7 @@ mod tests {
18511863 testfn : DynTestFn ( Box :: new ( f) ) ,
18521864 } ;
18531865 let ( tx, rx) = channel ( ) ;
1854- run_test ( & TestOpts :: new ( ) , false , desc, tx) ;
1866+ run_test ( & TestOpts :: new ( ) , false , desc, tx, Concurrent :: No ) ;
18551867 let ( _, res, _) = rx. recv ( ) . unwrap ( ) ;
18561868 assert ! ( res == TrOk ) ;
18571869 }
@@ -1873,7 +1885,7 @@ mod tests {
18731885 testfn : DynTestFn ( Box :: new ( f) ) ,
18741886 } ;
18751887 let ( tx, rx) = channel ( ) ;
1876- run_test ( & TestOpts :: new ( ) , false , desc, tx) ;
1888+ run_test ( & TestOpts :: new ( ) , false , desc, tx, Concurrent :: No ) ;
18771889 let ( _, res, _) = rx. recv ( ) . unwrap ( ) ;
18781890 assert ! ( res == TrFailedMsg ( format!( "{} '{}'" , failed_msg, expected) ) ) ;
18791891 }
@@ -1891,7 +1903,7 @@ mod tests {
18911903 testfn : DynTestFn ( Box :: new ( f) ) ,
18921904 } ;
18931905 let ( tx, rx) = channel ( ) ;
1894- run_test ( & TestOpts :: new ( ) , false , desc, tx) ;
1906+ run_test ( & TestOpts :: new ( ) , false , desc, tx, Concurrent :: No ) ;
18951907 let ( _, res, _) = rx. recv ( ) . unwrap ( ) ;
18961908 assert ! ( res == TrFailed ) ;
18971909 }
0 commit comments