@@ -33,6 +33,7 @@ use std::{env, fs, vec};
33
33
use build_helper:: git:: { get_git_modified_files, get_git_untracked_files} ;
34
34
use camino:: { Utf8Path , Utf8PathBuf } ;
35
35
use getopts:: Options ;
36
+ use rayon:: iter:: { ParallelBridge , ParallelIterator } ;
36
37
use tracing:: * ;
37
38
use walkdir:: WalkDir ;
38
39
@@ -641,6 +642,18 @@ struct TestCollector {
641
642
poisoned : bool ,
642
643
}
643
644
645
+ impl TestCollector {
646
+ fn new ( ) -> Self {
647
+ TestCollector { tests : vec ! [ ] , found_path_stems : HashSet :: new ( ) , poisoned : false }
648
+ }
649
+
650
+ fn merge ( & mut self , mut other : Self ) {
651
+ self . tests . append ( & mut other. tests ) ;
652
+ self . found_path_stems . extend ( other. found_path_stems ) ;
653
+ self . poisoned |= other. poisoned ;
654
+ }
655
+ }
656
+
644
657
/// Creates test structures for every test/revision in the test suite directory.
645
658
///
646
659
/// This always inspects _all_ test files in the suite (e.g. all 17k+ ui tests),
@@ -659,10 +672,7 @@ pub(crate) fn collect_and_make_tests(config: Arc<Config>) -> Vec<CollectedTest>
659
672
let cache = HeadersCache :: load ( & config) ;
660
673
661
674
let cx = TestCollectorCx { config, cache, common_inputs_stamp, modified_tests } ;
662
- let mut collector =
663
- TestCollector { tests : vec ! [ ] , found_path_stems : HashSet :: new ( ) , poisoned : false } ;
664
-
665
- collect_tests_from_dir ( & cx, & mut collector, & cx. config . src_test_suite_root , Utf8Path :: new ( "" ) )
675
+ let collector = collect_tests_from_dir ( & cx, & cx. config . src_test_suite_root , Utf8Path :: new ( "" ) )
666
676
. unwrap_or_else ( |reason| {
667
677
panic ! ( "Could not read tests from {}: {reason}" , cx. config. src_test_suite_root)
668
678
} ) ;
@@ -768,25 +778,25 @@ fn modified_tests(config: &Config, dir: &Utf8Path) -> Result<Vec<Utf8PathBuf>, S
768
778
/// that will be handed over to libtest.
769
779
fn collect_tests_from_dir (
770
780
cx : & TestCollectorCx ,
771
- collector : & mut TestCollector ,
772
781
dir : & Utf8Path ,
773
782
relative_dir_path : & Utf8Path ,
774
- ) -> io:: Result < ( ) > {
783
+ ) -> io:: Result < TestCollector > {
775
784
// Ignore directories that contain a file named `compiletest-ignore-dir`.
776
785
if dir. join ( "compiletest-ignore-dir" ) . exists ( ) {
777
- return Ok ( ( ) ) ;
786
+ return Ok ( TestCollector :: new ( ) ) ;
778
787
}
779
788
780
789
// For run-make tests, a "test file" is actually a directory that contains an `rmake.rs`.
781
790
if cx. config . mode == Mode :: RunMake {
791
+ let mut collector = TestCollector :: new ( ) ;
782
792
if dir. join ( "rmake.rs" ) . exists ( ) {
783
793
let paths = TestPaths {
784
794
file : dir. to_path_buf ( ) ,
785
795
relative_dir : relative_dir_path. parent ( ) . unwrap ( ) . to_path_buf ( ) ,
786
796
} ;
787
- make_test ( cx, collector, & paths) ;
797
+ make_test ( cx, & mut collector, & paths) ;
788
798
// This directory is a test, so don't try to find other tests inside it.
789
- return Ok ( ( ) ) ;
799
+ return Ok ( collector ) ;
790
800
}
791
801
}
792
802
@@ -803,36 +813,47 @@ fn collect_tests_from_dir(
803
813
// subdirectories we find, except for `auxiliary` directories.
804
814
// FIXME: this walks full tests tree, even if we have something to ignore
805
815
// use walkdir/ignore like in tidy?
806
- for file in fs:: read_dir ( dir. as_std_path ( ) ) ? {
807
- let file = file?;
808
- let file_path = Utf8PathBuf :: try_from ( file. path ( ) ) . unwrap ( ) ;
809
- let file_name = file_path. file_name ( ) . unwrap ( ) ;
810
-
811
- if is_test ( file_name)
812
- && ( !cx. config . only_modified || cx. modified_tests . contains ( & file_path) )
813
- {
814
- // We found a test file, so create the corresponding libtest structures.
815
- debug ! ( %file_path, "found test file" ) ;
816
-
817
- // Record the stem of the test file, to check for overlaps later.
818
- let rel_test_path = relative_dir_path. join ( file_path. file_stem ( ) . unwrap ( ) ) ;
819
- collector. found_path_stems . insert ( rel_test_path) ;
820
-
821
- let paths =
822
- TestPaths { file : file_path, relative_dir : relative_dir_path. to_path_buf ( ) } ;
823
- make_test ( cx, collector, & paths) ;
824
- } else if file_path. is_dir ( ) {
825
- // Recurse to find more tests in a subdirectory.
826
- let relative_file_path = relative_dir_path. join ( file_name) ;
827
- if file_name != "auxiliary" {
828
- debug ! ( %file_path, "found directory" ) ;
829
- collect_tests_from_dir ( cx, collector, & file_path, & relative_file_path) ?;
816
+ fs:: read_dir ( dir. as_std_path ( ) ) ?
817
+ . par_bridge ( )
818
+ . map ( |file| {
819
+ let mut collector = TestCollector :: new ( ) ;
820
+ let file = file?;
821
+ let file_path = Utf8PathBuf :: try_from ( file. path ( ) ) . unwrap ( ) ;
822
+ let file_name = file_path. file_name ( ) . unwrap ( ) ;
823
+
824
+ if is_test ( file_name)
825
+ && ( !cx. config . only_modified || cx. modified_tests . contains ( & file_path) )
826
+ {
827
+ // We found a test file, so create the corresponding libtest structures.
828
+ debug ! ( %file_path, "found test file" ) ;
829
+
830
+ // Record the stem of the test file, to check for overlaps later.
831
+ let rel_test_path = relative_dir_path. join ( file_path. file_stem ( ) . unwrap ( ) ) ;
832
+ collector. found_path_stems . insert ( rel_test_path) ;
833
+
834
+ let paths =
835
+ TestPaths { file : file_path, relative_dir : relative_dir_path. to_path_buf ( ) } ;
836
+ make_test ( cx, & mut collector, & paths) ;
837
+ } else if file_path. is_dir ( ) {
838
+ // Recurse to find more tests in a subdirectory.
839
+ let relative_file_path = relative_dir_path. join ( file_name) ;
840
+ if file_name != "auxiliary" {
841
+ debug ! ( %file_path, "found directory" ) ;
842
+ collector. merge ( collect_tests_from_dir ( cx, & file_path, & relative_file_path) ?) ;
843
+ }
844
+ } else {
845
+ debug ! ( %file_path, "found other file/directory" ) ;
830
846
}
831
- } else {
832
- debug ! ( %file_path, "found other file/directory" ) ;
833
- }
834
- }
835
- Ok ( ( ) )
847
+ Ok ( collector)
848
+ } )
849
+ . reduce (
850
+ || Ok ( TestCollector :: new ( ) ) ,
851
+ |a, b| {
852
+ let mut a = a?;
853
+ a. merge ( b?) ;
854
+ Ok ( a)
855
+ } ,
856
+ )
836
857
}
837
858
838
859
/// Returns true if `file_name` looks like a proper test file name.
0 commit comments