@@ -99,6 +99,10 @@ mod formatters;
99
99
100
100
use formatters:: { JsonFormatter , OutputFormatter , PrettyFormatter , TerseFormatter } ;
101
101
102
+ /// Whether to execute tests concurrently or not
103
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
104
+ pub enum Concurrent { Yes , No }
105
+
102
106
// The name of a test. By convention this follows the rules for rust
103
107
// paths; i.e., it should be a series of identifiers separated by double
104
108
// 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)
1073
1077
where
1074
1078
F : FnMut ( TestEvent ) -> io:: Result < ( ) > ,
1075
1079
{
1076
- use std:: collections:: HashMap ;
1080
+ use std:: collections:: { self , HashMap } ;
1081
+ use std:: hash:: BuildHasherDefault ;
1077
1082
use std:: sync:: mpsc:: RecvTimeoutError ;
1083
+ // Use a deterministic hasher
1084
+ type TestMap =
1085
+ HashMap < TestDesc , Instant , BuildHasherDefault < collections:: hash_map:: DefaultHasher > > ;
1078
1086
1079
1087
let tests_len = tests. len ( ) ;
1080
1088
@@ -1113,9 +1121,9 @@ where
1113
1121
1114
1122
let ( tx, rx) = channel :: < MonitorMsg > ( ) ;
1115
1123
1116
- let mut running_tests: HashMap < TestDesc , Instant > = HashMap :: new ( ) ;
1124
+ let mut running_tests: TestMap = HashMap :: default ( ) ;
1117
1125
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 > {
1119
1127
let now = Instant :: now ( ) ;
1120
1128
let timed_out = running_tests
1121
1129
. iter ( )
@@ -1133,7 +1141,7 @@ where
1133
1141
timed_out
1134
1142
} ;
1135
1143
1136
- fn calc_timeout ( running_tests : & HashMap < TestDesc , Instant > ) -> Option < Duration > {
1144
+ fn calc_timeout ( running_tests : & TestMap ) -> Option < Duration > {
1137
1145
running_tests. values ( ) . min ( ) . map ( |next_timeout| {
1138
1146
let now = Instant :: now ( ) ;
1139
1147
if * next_timeout >= now {
@@ -1148,7 +1156,7 @@ where
1148
1156
while !remaining. is_empty ( ) {
1149
1157
let test = remaining. pop ( ) . unwrap ( ) ;
1150
1158
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 ) ;
1152
1160
let ( test, result, stdout) = rx. recv ( ) . unwrap ( ) ;
1153
1161
callback ( TeResult ( test, result, stdout) ) ?;
1154
1162
}
@@ -1159,7 +1167,7 @@ where
1159
1167
let timeout = Instant :: now ( ) + Duration :: from_secs ( TEST_WARN_TIMEOUT_S ) ;
1160
1168
running_tests. insert ( test. desc . clone ( ) , timeout) ;
1161
1169
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 ) ;
1163
1171
pending += 1 ;
1164
1172
}
1165
1173
@@ -1191,7 +1199,7 @@ where
1191
1199
// All benchmarks run at the end, in serial.
1192
1200
for b in filtered_benchs {
1193
1201
callback ( TeWait ( b. desc . clone ( ) ) ) ?;
1194
- run_test ( opts, false , b, tx. clone ( ) ) ;
1202
+ run_test ( opts, false , b, tx. clone ( ) , Concurrent :: No ) ;
1195
1203
let ( test, result, stdout) = rx. recv ( ) . unwrap ( ) ;
1196
1204
callback ( TeResult ( test, result, stdout) ) ?;
1197
1205
}
@@ -1393,6 +1401,7 @@ pub fn run_test(
1393
1401
force_ignore : bool ,
1394
1402
test : TestDescAndFn ,
1395
1403
monitor_ch : Sender < MonitorMsg > ,
1404
+ concurrency : Concurrent ,
1396
1405
) {
1397
1406
let TestDescAndFn { desc, testfn } = test;
1398
1407
@@ -1409,6 +1418,7 @@ pub fn run_test(
1409
1418
monitor_ch : Sender < MonitorMsg > ,
1410
1419
nocapture : bool ,
1411
1420
testfn : Box < dyn FnBox ( ) + Send > ,
1421
+ concurrency : Concurrent ,
1412
1422
) {
1413
1423
// Buffer for capturing standard I/O
1414
1424
let data = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
@@ -1443,7 +1453,7 @@ pub fn run_test(
1443
1453
// the test synchronously, regardless of the concurrency
1444
1454
// level.
1445
1455
let supports_threads = !cfg ! ( target_os = "emscripten" ) && !cfg ! ( target_arch = "wasm32" ) ;
1446
- if supports_threads {
1456
+ if concurrency == Concurrent :: Yes && supports_threads {
1447
1457
let cfg = thread:: Builder :: new ( ) . name ( name. as_slice ( ) . to_owned ( ) ) ;
1448
1458
cfg. spawn ( runtest) . unwrap ( ) ;
1449
1459
} else {
@@ -1464,13 +1474,14 @@ pub fn run_test(
1464
1474
}
1465
1475
DynTestFn ( f) => {
1466
1476
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 )
1468
1478
}
1469
1479
StaticTestFn ( f) => run_test_inner (
1470
1480
desc,
1471
1481
monitor_ch,
1472
1482
opts. nocapture ,
1473
1483
Box :: new ( move || __rust_begin_short_backtrace ( f) ) ,
1484
+ concurrency,
1474
1485
) ,
1475
1486
}
1476
1487
}
@@ -1753,6 +1764,7 @@ mod tests {
1753
1764
use std:: sync:: mpsc:: channel;
1754
1765
use bench;
1755
1766
use Bencher ;
1767
+ use Concurrent ;
1756
1768
1757
1769
1758
1770
fn one_ignored_one_unignored_test ( ) -> Vec < TestDescAndFn > {
@@ -1793,7 +1805,7 @@ mod tests {
1793
1805
testfn : DynTestFn ( Box :: new ( f) ) ,
1794
1806
} ;
1795
1807
let ( tx, rx) = channel ( ) ;
1796
- run_test ( & TestOpts :: new ( ) , false , desc, tx) ;
1808
+ run_test ( & TestOpts :: new ( ) , false , desc, tx, Concurrent :: No ) ;
1797
1809
let ( _, res, _) = rx. recv ( ) . unwrap ( ) ;
1798
1810
assert ! ( res != TrOk ) ;
1799
1811
}
@@ -1811,7 +1823,7 @@ mod tests {
1811
1823
testfn : DynTestFn ( Box :: new ( f) ) ,
1812
1824
} ;
1813
1825
let ( tx, rx) = channel ( ) ;
1814
- run_test ( & TestOpts :: new ( ) , false , desc, tx) ;
1826
+ run_test ( & TestOpts :: new ( ) , false , desc, tx, Concurrent :: No ) ;
1815
1827
let ( _, res, _) = rx. recv ( ) . unwrap ( ) ;
1816
1828
assert ! ( res == TrIgnored ) ;
1817
1829
}
@@ -1831,7 +1843,7 @@ mod tests {
1831
1843
testfn : DynTestFn ( Box :: new ( f) ) ,
1832
1844
} ;
1833
1845
let ( tx, rx) = channel ( ) ;
1834
- run_test ( & TestOpts :: new ( ) , false , desc, tx) ;
1846
+ run_test ( & TestOpts :: new ( ) , false , desc, tx, Concurrent :: No ) ;
1835
1847
let ( _, res, _) = rx. recv ( ) . unwrap ( ) ;
1836
1848
assert ! ( res == TrOk ) ;
1837
1849
}
@@ -1851,7 +1863,7 @@ mod tests {
1851
1863
testfn : DynTestFn ( Box :: new ( f) ) ,
1852
1864
} ;
1853
1865
let ( tx, rx) = channel ( ) ;
1854
- run_test ( & TestOpts :: new ( ) , false , desc, tx) ;
1866
+ run_test ( & TestOpts :: new ( ) , false , desc, tx, Concurrent :: No ) ;
1855
1867
let ( _, res, _) = rx. recv ( ) . unwrap ( ) ;
1856
1868
assert ! ( res == TrOk ) ;
1857
1869
}
@@ -1873,7 +1885,7 @@ mod tests {
1873
1885
testfn : DynTestFn ( Box :: new ( f) ) ,
1874
1886
} ;
1875
1887
let ( tx, rx) = channel ( ) ;
1876
- run_test ( & TestOpts :: new ( ) , false , desc, tx) ;
1888
+ run_test ( & TestOpts :: new ( ) , false , desc, tx, Concurrent :: No ) ;
1877
1889
let ( _, res, _) = rx. recv ( ) . unwrap ( ) ;
1878
1890
assert ! ( res == TrFailedMsg ( format!( "{} '{}'" , failed_msg, expected) ) ) ;
1879
1891
}
@@ -1891,7 +1903,7 @@ mod tests {
1891
1903
testfn : DynTestFn ( Box :: new ( f) ) ,
1892
1904
} ;
1893
1905
let ( tx, rx) = channel ( ) ;
1894
- run_test ( & TestOpts :: new ( ) , false , desc, tx) ;
1906
+ run_test ( & TestOpts :: new ( ) , false , desc, tx, Concurrent :: No ) ;
1895
1907
let ( _, res, _) = rx. recv ( ) . unwrap ( ) ;
1896
1908
assert ! ( res == TrFailed ) ;
1897
1909
}
0 commit comments