Skip to content

Commit 4034aec

Browse files
authored
Rollup merge of #103681 - RalfJung:libtest-thread, r=thomcc
libtest: run all tests in their own thread, if supported by the host This reverts the threading changes of rust-lang/rust#56243, which made it so that with `-j1`, the test harness does not spawn any threads. Those changes were done to enable Miri to run the test harness, but Miri supports threads nowadays, so this is no longer needed. Using a thread for each test is useful because the thread's name can be set to the test's name which makes panic messages consistent between `-j1` and `-j2` runs and also a bit more readable. I did not revert the HashMap changes of rust-lang/rust#56243; using a deterministic map seems fine for the test harness and the more deterministic testing is the better. Fixes rust-lang/rust#59122 Fixes rust-lang/rust#70492
2 parents b2af3d1 + 708d5c8 commit 4034aec

File tree

3 files changed

+37
-54
lines changed

3 files changed

+37
-54
lines changed

Diff for: test/src/lib.rs

+28-30
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub mod test {
4040
cli::{parse_opts, TestOpts},
4141
filter_tests,
4242
helpers::metrics::{Metric, MetricMap},
43-
options::{Concurrent, Options, RunIgnored, RunStrategy, ShouldPanic},
43+
options::{Options, RunIgnored, RunStrategy, ShouldPanic},
4444
run_test, test_main, test_main_static,
4545
test_result::{TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk},
4646
time::{TestExecTime, TestTimeOptions},
@@ -85,7 +85,7 @@ use event::{CompletedTest, TestEvent};
8585
use helpers::concurrency::get_concurrency;
8686
use helpers::exit_code::get_exit_code;
8787
use helpers::shuffle::{get_shuffle_seed, shuffle_tests};
88-
use options::{Concurrent, RunStrategy};
88+
use options::RunStrategy;
8989
use test_result::*;
9090
use time::TestExecTime;
9191

@@ -267,6 +267,19 @@ where
267267
join_handle: Option<thread::JoinHandle<()>>,
268268
}
269269

270+
impl RunningTest {
271+
fn join(self, completed_test: &mut CompletedTest) {
272+
if let Some(join_handle) = self.join_handle {
273+
if let Err(_) = join_handle.join() {
274+
if let TrOk = completed_test.result {
275+
completed_test.result =
276+
TrFailedMsg("panicked after reporting success".to_string());
277+
}
278+
}
279+
}
280+
}
281+
}
282+
270283
// Use a deterministic hasher
271284
type TestMap =
272285
HashMap<TestId, RunningTest, BuildHasherDefault<collections::hash_map::DefaultHasher>>;
@@ -366,10 +379,10 @@ where
366379
let (id, test) = remaining.pop_front().unwrap();
367380
let event = TestEvent::TeWait(test.desc.clone());
368381
notify_about_test_event(event)?;
369-
let join_handle =
370-
run_test(opts, !opts.run_tests, id, test, run_strategy, tx.clone(), Concurrent::No);
371-
assert!(join_handle.is_none());
372-
let completed_test = rx.recv().unwrap();
382+
let join_handle = run_test(opts, !opts.run_tests, id, test, run_strategy, tx.clone());
383+
// Wait for the test to complete.
384+
let mut completed_test = rx.recv().unwrap();
385+
RunningTest { join_handle }.join(&mut completed_test);
373386

374387
let event = TestEvent::TeResult(completed_test);
375388
notify_about_test_event(event)?;
@@ -383,15 +396,8 @@ where
383396

384397
let event = TestEvent::TeWait(desc.clone());
385398
notify_about_test_event(event)?; //here no pad
386-
let join_handle = run_test(
387-
opts,
388-
!opts.run_tests,
389-
id,
390-
test,
391-
run_strategy,
392-
tx.clone(),
393-
Concurrent::Yes,
394-
);
399+
let join_handle =
400+
run_test(opts, !opts.run_tests, id, test, run_strategy, tx.clone());
395401
running_tests.insert(id, RunningTest { join_handle });
396402
timeout_queue.push_back(TimeoutEntry { id, desc, timeout });
397403
pending += 1;
@@ -423,14 +429,7 @@ where
423429

424430
let mut completed_test = res.unwrap();
425431
let running_test = running_tests.remove(&completed_test.id).unwrap();
426-
if let Some(join_handle) = running_test.join_handle {
427-
if let Err(_) = join_handle.join() {
428-
if let TrOk = completed_test.result {
429-
completed_test.result =
430-
TrFailedMsg("panicked after reporting success".to_string());
431-
}
432-
}
433-
}
432+
running_test.join(&mut completed_test);
434433

435434
let event = TestEvent::TeResult(completed_test);
436435
notify_about_test_event(event)?;
@@ -443,8 +442,10 @@ where
443442
for (id, b) in filtered.benchs {
444443
let event = TestEvent::TeWait(b.desc.clone());
445444
notify_about_test_event(event)?;
446-
run_test(opts, false, id, b, run_strategy, tx.clone(), Concurrent::No);
447-
let completed_test = rx.recv().unwrap();
445+
let join_handle = run_test(opts, false, id, b, run_strategy, tx.clone());
446+
// Wait for the test to complete.
447+
let mut completed_test = rx.recv().unwrap();
448+
RunningTest { join_handle }.join(&mut completed_test);
448449

449450
let event = TestEvent::TeResult(completed_test);
450451
notify_about_test_event(event)?;
@@ -520,7 +521,6 @@ pub fn run_test(
520521
test: TestDescAndFn,
521522
strategy: RunStrategy,
522523
monitor_ch: Sender<CompletedTest>,
523-
concurrency: Concurrent,
524524
) -> Option<thread::JoinHandle<()>> {
525525
let TestDescAndFn { desc, testfn } = test;
526526

@@ -538,7 +538,6 @@ pub fn run_test(
538538
struct TestRunOpts {
539539
pub strategy: RunStrategy,
540540
pub nocapture: bool,
541-
pub concurrency: Concurrent,
542541
pub time: Option<time::TestTimeOptions>,
543542
}
544543

@@ -549,7 +548,6 @@ pub fn run_test(
549548
testfn: Box<dyn FnOnce() -> Result<(), String> + Send>,
550549
opts: TestRunOpts,
551550
) -> Option<thread::JoinHandle<()>> {
552-
let concurrency = opts.concurrency;
553551
let name = desc.name.clone();
554552

555553
let runtest = move || match opts.strategy {
@@ -576,7 +574,7 @@ pub fn run_test(
576574
// the test synchronously, regardless of the concurrency
577575
// level.
578576
let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_family = "wasm");
579-
if concurrency == Concurrent::Yes && supports_threads {
577+
if supports_threads {
580578
let cfg = thread::Builder::new().name(name.as_slice().to_owned());
581579
let mut runtest = Arc::new(Mutex::new(Some(runtest)));
582580
let runtest2 = runtest.clone();
@@ -597,7 +595,7 @@ pub fn run_test(
597595
}
598596

599597
let test_run_opts =
600-
TestRunOpts { strategy, nocapture: opts.nocapture, concurrency, time: opts.time_options };
598+
TestRunOpts { strategy, nocapture: opts.nocapture, time: opts.time_options };
601599

602600
match testfn {
603601
DynBenchFn(benchfn) => {

Diff for: test/src/options.rs

-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
//! Enums denoting options for test execution.
22
3-
/// Whether to execute tests concurrently or not
4-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
5-
pub enum Concurrent {
6-
Yes,
7-
No,
8-
}
9-
103
/// Number of times to run a benchmarked function
114
#[derive(Clone, PartialEq, Eq)]
125
pub enum BenchMode {

Diff for: test/src/tests.rs

+9-17
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ pub fn do_not_run_ignored_tests() {
102102
testfn: DynTestFn(Box::new(f)),
103103
};
104104
let (tx, rx) = channel();
105-
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
105+
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx);
106106
let result = rx.recv().unwrap().result;
107107
assert_ne!(result, TrOk);
108108
}
@@ -125,7 +125,7 @@ pub fn ignored_tests_result_in_ignored() {
125125
testfn: DynTestFn(Box::new(f)),
126126
};
127127
let (tx, rx) = channel();
128-
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
128+
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx);
129129
let result = rx.recv().unwrap().result;
130130
assert_eq!(result, TrIgnored);
131131
}
@@ -150,7 +150,7 @@ fn test_should_panic() {
150150
testfn: DynTestFn(Box::new(f)),
151151
};
152152
let (tx, rx) = channel();
153-
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
153+
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx);
154154
let result = rx.recv().unwrap().result;
155155
assert_eq!(result, TrOk);
156156
}
@@ -175,7 +175,7 @@ fn test_should_panic_good_message() {
175175
testfn: DynTestFn(Box::new(f)),
176176
};
177177
let (tx, rx) = channel();
178-
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
178+
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx);
179179
let result = rx.recv().unwrap().result;
180180
assert_eq!(result, TrOk);
181181
}
@@ -205,7 +205,7 @@ fn test_should_panic_bad_message() {
205205
testfn: DynTestFn(Box::new(f)),
206206
};
207207
let (tx, rx) = channel();
208-
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
208+
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx);
209209
let result = rx.recv().unwrap().result;
210210
assert_eq!(result, TrFailedMsg(failed_msg.to_string()));
211211
}
@@ -239,7 +239,7 @@ fn test_should_panic_non_string_message_type() {
239239
testfn: DynTestFn(Box::new(f)),
240240
};
241241
let (tx, rx) = channel();
242-
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
242+
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx);
243243
let result = rx.recv().unwrap().result;
244244
assert_eq!(result, TrFailedMsg(failed_msg));
245245
}
@@ -267,15 +267,7 @@ fn test_should_panic_but_succeeds() {
267267
testfn: DynTestFn(Box::new(f)),
268268
};
269269
let (tx, rx) = channel();
270-
run_test(
271-
&TestOpts::new(),
272-
false,
273-
TestId(0),
274-
desc,
275-
RunStrategy::InProcess,
276-
tx,
277-
Concurrent::No,
278-
);
270+
run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx);
279271
let result = rx.recv().unwrap().result;
280272
assert_eq!(
281273
result,
@@ -306,7 +298,7 @@ fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {
306298

307299
let test_opts = TestOpts { time_options, ..TestOpts::new() };
308300
let (tx, rx) = channel();
309-
run_test(&test_opts, false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
301+
run_test(&test_opts, false, TestId(0), desc, RunStrategy::InProcess, tx);
310302
let exec_time = rx.recv().unwrap().exec_time;
311303
exec_time
312304
}
@@ -345,7 +337,7 @@ fn time_test_failure_template(test_type: TestType) -> TestResult {
345337

346338
let test_opts = TestOpts { time_options: Some(time_options), ..TestOpts::new() };
347339
let (tx, rx) = channel();
348-
run_test(&test_opts, false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
340+
run_test(&test_opts, false, TestId(0), desc, RunStrategy::InProcess, tx);
349341
let result = rx.recv().unwrap().result;
350342

351343
result

0 commit comments

Comments
 (0)