@@ -510,6 +510,7 @@ pub fn make_tests(config: &Config) -> Vec<test::TestDescAndFn> {
510510 & config. src_base ,
511511 & PathBuf :: new ( ) ,
512512 & mut tests,
513+ true ,
513514 ) . unwrap ( ) ;
514515 tests
515516}
@@ -520,6 +521,7 @@ fn collect_tests_from_dir(
520521 dir : & Path ,
521522 relative_dir_path : & Path ,
522523 tests : & mut Vec < test:: TestDescAndFn > ,
524+ tests_in_dir : bool ,
523525) -> io:: Result < ( ) > {
524526 // Ignore directories that contain a file
525527 // `compiletest-ignore-dir`.
@@ -535,7 +537,7 @@ fn collect_tests_from_dir(
535537 base : base. to_path_buf ( ) ,
536538 relative_dir : relative_dir_path. parent ( ) . unwrap ( ) . to_path_buf ( ) ,
537539 } ;
538- tests. push ( make_test ( config, & paths) ) ;
540+ tests. extend ( make_test ( config, & paths) ) ;
539541 return Ok ( ( ) ) ;
540542 }
541543 }
@@ -556,14 +558,23 @@ fn collect_tests_from_dir(
556558 let file = file?;
557559 let file_path = file. path ( ) ;
558560 let file_name = file. file_name ( ) ;
559- if is_test ( & file_name) {
561+ if tests_in_dir && is_test ( & file_name) {
560562 debug ! ( "found test file: {:?}" , file_path. display( ) ) ;
563+
564+ let relative_file_path = relative_dir_path. join ( file_path. file_stem ( ) . unwrap ( ) ) ;
565+ let build_dir = config. build_base . join ( & relative_file_path) ;
566+ fs:: create_dir_all ( & build_dir) . unwrap ( ) ;
567+
561568 let paths = TestPaths {
562569 file : file_path,
563570 base : base. to_path_buf ( ) ,
564571 relative_dir : relative_dir_path. to_path_buf ( ) ,
565572 } ;
566- tests. push ( make_test ( config, & paths) )
573+ tests. extend ( make_test ( config, & paths) )
574+ } else if file_path. is_file ( ) {
575+ let relative_file_path = relative_dir_path. join ( file_path. file_stem ( ) . unwrap ( ) ) ;
576+ let build_dir = config. build_base . join ( & relative_file_path) ;
577+ fs:: create_dir_all ( & build_dir) . unwrap ( ) ;
567578 } else if file_path. is_dir ( ) {
568579 let relative_file_path = relative_dir_path. join ( file. file_name ( ) ) ;
569580 if & file_name == "auxiliary" {
@@ -572,11 +583,17 @@ fn collect_tests_from_dir(
572583 // do create a directory in the build dir for them,
573584 // since we will dump intermediate output in there
574585 // sometimes.
575- let build_dir = config. build_base . join ( & relative_file_path) ;
576- fs:: create_dir_all ( & build_dir) . unwrap ( ) ;
586+ collect_tests_from_dir (
587+ config,
588+ base,
589+ & file_path,
590+ & relative_file_path,
591+ tests,
592+ false ,
593+ ) ?;
577594 } else {
578595 debug ! ( "found directory: {:?}" , file_path. display( ) ) ;
579- collect_tests_from_dir ( config, base, & file_path, & relative_file_path, tests) ?;
596+ collect_tests_from_dir ( config, base, & file_path, & relative_file_path, tests, true ) ?;
580597 }
581598 } else {
582599 debug ! ( "found other file/directory: {:?}" , file_path. display( ) ) ;
@@ -597,7 +614,7 @@ pub fn is_test(file_name: &OsString) -> bool {
597614 !invalid_prefixes. iter ( ) . any ( |p| file_name. starts_with ( p) )
598615}
599616
600- pub fn make_test ( config : & Config , testpaths : & TestPaths ) -> test:: TestDescAndFn {
617+ pub fn make_test ( config : & Config , testpaths : & TestPaths ) -> Vec < test:: TestDescAndFn > {
601618 let early_props = EarlyProps :: from_file ( config, & testpaths. file ) ;
602619
603620 // The `should-fail` annotation doesn't apply to pretty tests,
@@ -617,14 +634,41 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn
617634 || ( config. mode == DebugInfoGdb || config. mode == DebugInfoLldb )
618635 && config. target . contains ( "emscripten" ) ;
619636
620- test:: TestDescAndFn {
621- desc : test:: TestDesc {
622- name : make_test_name ( config, testpaths) ,
623- ignore,
624- should_panic,
625- allow_fail : false ,
626- } ,
627- testfn : make_test_closure ( config, testpaths) ,
637+ // This is going to create a directory structure containing the test relative dir, joined with
638+ // the revision if any and as last the stage.
639+ // i.e.
640+ // run-pass/borrowck/two-phase-baseline/lxl/stage1-x86_64-unknown-linux-gnu
641+ // This is done here to create directories in advance, avoiding race conditions over the file
642+ // system.
643+ let dir = config. build_base . join ( & testpaths. relative_dir )
644+ . join ( PathBuf :: from ( & testpaths. file . file_stem ( ) . unwrap ( ) ) ) ;
645+
646+ if early_props. revisions . is_empty ( ) {
647+ fs:: create_dir_all ( & dir) . unwrap ( ) ;
648+
649+ vec ! [ test:: TestDescAndFn {
650+ desc: test:: TestDesc {
651+ name: make_test_name( config, testpaths, None ) ,
652+ ignore,
653+ should_panic,
654+ allow_fail: false ,
655+ } ,
656+ testfn: make_test_closure( config, testpaths, None ) ,
657+ } ]
658+ } else {
659+ early_props. revisions . iter ( ) . map ( |revision| {
660+ fs:: create_dir_all ( dir. join ( revision) ) . unwrap ( ) ;
661+
662+ test:: TestDescAndFn {
663+ desc : test:: TestDesc {
664+ name : make_test_name ( config, testpaths, Some ( revision) ) ,
665+ ignore,
666+ should_panic,
667+ allow_fail : false ,
668+ } ,
669+ testfn : make_test_closure ( config, testpaths, Some ( revision) ) ,
670+ }
671+ } ) . collect ( )
628672 }
629673}
630674
@@ -698,20 +742,34 @@ fn mtime(path: &Path) -> FileTime {
698742 . unwrap_or_else ( |_| FileTime :: zero ( ) )
699743}
700744
701- pub fn make_test_name ( config : & Config , testpaths : & TestPaths ) -> test:: TestName {
745+ pub fn make_test_name (
746+ config : & Config ,
747+ testpaths : & TestPaths ,
748+ revision : Option < & str > ,
749+ ) -> test:: TestName {
702750 // Convert a complete path to something like
703751 //
704752 // run-pass/foo/bar/baz.rs
705753 let path = PathBuf :: from ( config. src_base . file_name ( ) . unwrap ( ) )
706754 . join ( & testpaths. relative_dir )
707755 . join ( & testpaths. file . file_name ( ) . unwrap ( ) ) ;
708- test:: DynTestName ( format ! ( "[{}] {}" , config. mode, path. display( ) ) )
756+ test:: DynTestName ( format ! (
757+ "[{}] {}{}" ,
758+ config. mode,
759+ path. display( ) ,
760+ revision. map_or( "" . to_string( ) , |rev| format!( "#{}" , rev) )
761+ ) )
709762}
710763
711- pub fn make_test_closure ( config : & Config , testpaths : & TestPaths ) -> test:: TestFn {
764+ pub fn make_test_closure (
765+ config : & Config ,
766+ testpaths : & TestPaths ,
767+ revision : Option < & str > ,
768+ ) -> test:: TestFn {
712769 let config = config. clone ( ) ;
713770 let testpaths = testpaths. clone ( ) ;
714- test:: DynTestFn ( Box :: new ( move || runtest:: run ( config, & testpaths) ) )
771+ let revision = revision. map ( |r| r. to_string ( ) ) ;
772+ test:: DynTestFn ( Box :: new ( move || runtest:: run ( config, & testpaths, revision) ) )
715773}
716774
717775/// Returns (Path to GDB, GDB Version, GDB has Rust Support)
0 commit comments