]> git.lizzy.rs Git - rust.git/blobdiff - library/test/src/lib.rs
Remove unsafe impl Send for CompletedTest & TestResult
[rust.git] / library / test / src / lib.rs
index 3ff79eaea49aba18fa749b91c12e600de52d8cbe..f9e65be9b0d40028ebfaff37963020756274b9f0 100644 (file)
@@ -353,12 +353,13 @@ fn calc_timeout(timeout_queue: &VecDeque<TimeoutEntry>) -> Option<Duration> {
             }
 
             let mut completed_test = res.unwrap();
-            let running_test = running_tests.remove(&completed_test.desc).unwrap();
-            if let Some(join_handle) = running_test.join_handle {
-                if let Err(_) = join_handle.join() {
-                    if let TrOk = completed_test.result {
-                        completed_test.result =
-                            TrFailedMsg("panicked after reporting success".to_string());
+            if let Some(running_test) = running_tests.remove(&completed_test.desc) {
+                if let Some(join_handle) = running_test.join_handle {
+                    if let Err(_) = join_handle.join() {
+                        if let TrOk = completed_test.result {
+                            completed_test.result =
+                                TrFailedMsg("panicked after reporting success".to_string());
+                        }
                     }
                 }
             }
@@ -396,8 +397,8 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
     };
 
     // Remove tests that don't match the test filter
-    if let Some(ref filter) = opts.filter {
-        filtered.retain(|test| matches_filter(test, filter));
+    if !opts.filters.is_empty() {
+        filtered.retain(|test| opts.filters.iter().any(|filter| matches_filter(test, filter)));
     }
 
     // Skip tests that match any of the skip filters
@@ -506,7 +507,18 @@ fn run_test_inner(
         let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_arch = "wasm32");
         if concurrency == Concurrent::Yes && supports_threads {
             let cfg = thread::Builder::new().name(name.as_slice().to_owned());
-            Some(cfg.spawn(runtest).unwrap())
+            let mut runtest = Arc::new(Mutex::new(Some(runtest)));
+            let runtest2 = runtest.clone();
+            match cfg.spawn(move || runtest2.lock().unwrap().take().unwrap()()) {
+                Ok(handle) => Some(handle),
+                Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
+                    // `ErrorKind::WouldBlock` means hitting the thread limit on some
+                    // platforms, so run the test synchronously here instead.
+                    Arc::get_mut(&mut runtest).unwrap().get_mut().unwrap().take().unwrap()();
+                    None
+                }
+                Err(e) => panic!("failed to spawn thread to run test: {}", e),
+            }
         } else {
             runtest();
             None