Skip to content

Commit 3af058e

Browse files
committed
libtest: run all tests in their own thread, if supported by the host
1 parent cdd7afe commit 3af058e

File tree

7 files changed

+42
-59
lines changed

7 files changed

+42
-59
lines changed

library/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

@@ -235,6 +235,19 @@ where
235235
join_handle: Option<thread::JoinHandle<()>>,
236236
}
237237

238+
impl RunningTest {
239+
fn join(self, completed_test: &mut CompletedTest) {
240+
if let Some(join_handle) = self.join_handle {
241+
if let Err(_) = join_handle.join() {
242+
if let TrOk = completed_test.result {
243+
completed_test.result =
244+
TrFailedMsg("panicked after reporting success".to_string());
245+
}
246+
}
247+
}
248+
}
249+
}
250+
238251
// Use a deterministic hasher
239252
type TestMap =
240253
HashMap<TestId, RunningTest, BuildHasherDefault<collections::hash_map::DefaultHasher>>;
@@ -328,10 +341,10 @@ where
328341
let (id, test) = remaining.pop_front().unwrap();
329342
let event = TestEvent::TeWait(test.desc.clone());
330343
notify_about_test_event(event)?;
331-
let join_handle =
332-
run_test(opts, !opts.run_tests, id, test, run_strategy, tx.clone(), Concurrent::No);
333-
assert!(join_handle.is_none());
334-
let completed_test = rx.recv().unwrap();
344+
let join_handle = run_test(opts, !opts.run_tests, id, test, run_strategy, tx.clone());
345+
// Wait for the test to complete.
346+
let mut completed_test = rx.recv().unwrap();
347+
RunningTest { join_handle }.join(&mut completed_test);
335348

336349
let event = TestEvent::TeResult(completed_test);
337350
notify_about_test_event(event)?;
@@ -345,15 +358,8 @@ where
345358

346359
let event = TestEvent::TeWait(desc.clone());
347360
notify_about_test_event(event)?; //here no pad
348-
let join_handle = run_test(
349-
opts,
350-
!opts.run_tests,
351-
id,
352-
test,
353-
run_strategy,
354-
tx.clone(),
355-
Concurrent::Yes,
356-
);
361+
let join_handle =
362+
run_test(opts, !opts.run_tests, id, test, run_strategy, tx.clone());
357363
running_tests.insert(id, RunningTest { join_handle });
358364
timeout_queue.push_back(TimeoutEntry { id, desc, timeout });
359365
pending += 1;
@@ -385,14 +391,7 @@ where
385391

386392
let mut completed_test = res.unwrap();
387393
let running_test = running_tests.remove(&completed_test.id).unwrap();
388-
if let Some(join_handle) = running_test.join_handle {
389-
if let Err(_) = join_handle.join() {
390-
if let TrOk = completed_test.result {
391-
completed_test.result =
392-
TrFailedMsg("panicked after reporting success".to_string());
393-
}
394-
}
395-
}
394+
running_test.join(&mut completed_test);
396395

397396
let event = TestEvent::TeResult(completed_test);
398397
notify_about_test_event(event)?;
@@ -405,8 +404,10 @@ where
405404
for (id, b) in filtered_benchs {
406405
let event = TestEvent::TeWait(b.desc.clone());
407406
notify_about_test_event(event)?;
408-
run_test(opts, false, id, b, run_strategy, tx.clone(), Concurrent::No);
409-
let completed_test = rx.recv().unwrap();
407+
let join_handle = run_test(opts, false, id, b, run_strategy, tx.clone());
408+
// Wait for the test to complete.
409+
let mut completed_test = rx.recv().unwrap();
410+
RunningTest { join_handle }.join(&mut completed_test);
410411

411412
let event = TestEvent::TeResult(completed_test);
412413
notify_about_test_event(event)?;
@@ -480,7 +481,6 @@ pub fn run_test(
480481
test: TestDescAndFn,
481482
strategy: RunStrategy,
482483
monitor_ch: Sender<CompletedTest>,
483-
concurrency: Concurrent,
484484
) -> Option<thread::JoinHandle<()>> {
485485
let TestDescAndFn { desc, testfn } = test;
486486

@@ -498,7 +498,6 @@ pub fn run_test(
498498
struct TestRunOpts {
499499
pub strategy: RunStrategy,
500500
pub nocapture: bool,
501-
pub concurrency: Concurrent,
502501
pub time: Option<time::TestTimeOptions>,
503502
}
504503

@@ -509,7 +508,6 @@ pub fn run_test(
509508
testfn: Box<dyn FnOnce() -> Result<(), String> + Send>,
510509
opts: TestRunOpts,
511510
) -> Option<thread::JoinHandle<()>> {
512-
let concurrency = opts.concurrency;
513511
let name = desc.name.clone();
514512

515513
let runtest = move || match opts.strategy {
@@ -536,7 +534,7 @@ pub fn run_test(
536534
// the test synchronously, regardless of the concurrency
537535
// level.
538536
let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_family = "wasm");
539-
if concurrency == Concurrent::Yes && supports_threads {
537+
if supports_threads {
540538
let cfg = thread::Builder::new().name(name.as_slice().to_owned());
541539
let mut runtest = Arc::new(Mutex::new(Some(runtest)));
542540
let runtest2 = runtest.clone();
@@ -557,7 +555,7 @@ pub fn run_test(
557555
}
558556

559557
let test_run_opts =
560-
TestRunOpts { strategy, nocapture: opts.nocapture, concurrency, time: opts.time_options };
558+
TestRunOpts { strategy, nocapture: opts.nocapture, time: opts.time_options };
561559

562560
match testfn {
563561
DynBenchFn(benchfn) => {

library/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 {

library/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

src/test/run-make-fulldeps/libtest-json/output-default.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{ "type": "test", "event": "started", "name": "a" }
33
{ "type": "test", "name": "a", "event": "ok" }
44
{ "type": "test", "event": "started", "name": "b" }
5-
{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
5+
{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'b' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
66
{ "type": "test", "event": "started", "name": "c" }
77
{ "type": "test", "name": "c", "event": "ok" }
88
{ "type": "test", "event": "started", "name": "d" }

src/test/run-make-fulldeps/libtest-json/output-stdout-success.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
{ "type": "test", "event": "started", "name": "a" }
33
{ "type": "test", "name": "a", "event": "ok", "stdout": "print from successful test\n" }
44
{ "type": "test", "event": "started", "name": "b" }
5-
{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
5+
{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'b' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
66
{ "type": "test", "event": "started", "name": "c" }
7-
{ "type": "test", "name": "c", "event": "ok", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:15:5\n" }
7+
{ "type": "test", "name": "c", "event": "ok", "stdout": "thread 'c' panicked at 'assertion failed: false', f.rs:15:5\n" }
88
{ "type": "test", "event": "started", "name": "d" }
99
{ "type": "test", "name": "d", "event": "ignored", "message": "msg" }
1010
{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }

src/test/ui/test-attrs/test-thread-capture.run.stdout

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ fee
1010
fie
1111
foe
1212
fum
13-
thread 'main' panicked at 'explicit panic', $DIR/test-thread-capture.rs:32:5
13+
thread 'thready_fail' panicked at 'explicit panic', $DIR/test-thread-capture.rs:32:5
1414
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
1515

1616

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
thread 'main' panicked at 'explicit panic', $DIR/test-thread-nocapture.rs:32:5
1+
thread 'thready_fail' panicked at 'explicit panic', $DIR/test-thread-nocapture.rs:32:5
22
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

0 commit comments

Comments
 (0)