@@ -32,15 +32,15 @@ extern crate test;
32
32
extern crate rustfix;
33
33
34
34
use common:: CompareMode ;
35
- use common:: { expected_output_path, UI_EXTENSIONS } ;
35
+ use common:: { expected_output_path, output_base_dir , output_relative_path , UI_EXTENSIONS } ;
36
36
use common:: { Config , TestPaths } ;
37
37
use common:: { DebugInfoGdb , DebugInfoLldb , Mode , Pretty } ;
38
38
use filetime:: FileTime ;
39
39
use getopts:: Options ;
40
40
use std:: env;
41
41
use std:: ffi:: OsString ;
42
42
use std:: fs;
43
- use std:: io;
43
+ use std:: io:: { self , Read } ;
44
44
use std:: path:: { Path , PathBuf } ;
45
45
use std:: process:: Command ;
46
46
use test:: ColorConfig ;
@@ -552,10 +552,9 @@ fn collect_tests_from_dir(
552
552
if name == * "Makefile" && config. mode == Mode :: RunMake {
553
553
let paths = TestPaths {
554
554
file : dir. to_path_buf ( ) ,
555
- base : base. to_path_buf ( ) ,
556
555
relative_dir : relative_dir_path. parent ( ) . unwrap ( ) . to_path_buf ( ) ,
557
556
} ;
558
- tests. push ( make_test ( config, & paths) ) ;
557
+ tests. extend ( make_test ( config, & paths) ) ;
559
558
return Ok ( ( ) ) ;
560
559
}
561
560
}
@@ -566,7 +565,7 @@ fn collect_tests_from_dir(
566
565
// sequential loop because otherwise, if we do it in the
567
566
// tests themselves, they race for the privilege of
568
567
// creating the directories and sometimes fail randomly.
569
- let build_dir = config . build_base . join ( & relative_dir_path) ;
568
+ let build_dir = output_relative_path ( config , relative_dir_path) ;
570
569
fs:: create_dir_all ( & build_dir) . unwrap ( ) ;
571
570
572
571
// Add each `.rs` file as a test, and recurse further on any
@@ -580,21 +579,12 @@ fn collect_tests_from_dir(
580
579
debug ! ( "found test file: {:?}" , file_path. display( ) ) ;
581
580
let paths = TestPaths {
582
581
file : file_path,
583
- base : base. to_path_buf ( ) ,
584
582
relative_dir : relative_dir_path. to_path_buf ( ) ,
585
583
} ;
586
- tests. push ( make_test ( config, & paths) )
584
+ tests. extend ( make_test ( config, & paths) )
587
585
} else if file_path. is_dir ( ) {
588
586
let relative_file_path = relative_dir_path. join ( file. file_name ( ) ) ;
589
- if & file_name == "auxiliary" {
590
- // `aux` directories contain other crates used for
591
- // cross-crate tests. Don't search them for tests, but
592
- // do create a directory in the build dir for them,
593
- // since we will dump intermediate output in there
594
- // sometimes.
595
- let build_dir = config. build_base . join ( & relative_file_path) ;
596
- fs:: create_dir_all ( & build_dir) . unwrap ( ) ;
597
- } else {
587
+ if & file_name != "auxiliary" {
598
588
debug ! ( "found directory: {:?}" , file_path. display( ) ) ;
599
589
collect_tests_from_dir ( config, base, & file_path, & relative_file_path, tests) ?;
600
590
}
@@ -617,7 +607,7 @@ pub fn is_test(file_name: &OsString) -> bool {
617
607
!invalid_prefixes. iter ( ) . any ( |p| file_name. starts_with ( p) )
618
608
}
619
609
620
- pub fn make_test ( config : & Config , testpaths : & TestPaths ) -> test:: TestDescAndFn {
610
+ pub fn make_test ( config : & Config , testpaths : & TestPaths ) -> Vec < test:: TestDescAndFn > {
621
611
let early_props = if config. mode == Mode :: RunMake {
622
612
// Allow `ignore` directives to be in the Makefile.
623
613
EarlyProps :: from_file ( config, & testpaths. file . join ( "Makefile" ) )
@@ -637,46 +627,68 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn
637
627
} ,
638
628
} ;
639
629
640
- // Debugging emscripten code doesn't make sense today
641
- let ignore = early_props. ignore || !up_to_date ( config, testpaths, & early_props)
642
- || ( config. mode == DebugInfoGdb || config. mode == DebugInfoLldb )
643
- && config. target . contains ( "emscripten" ) ;
644
-
645
- test:: TestDescAndFn {
646
- desc : test:: TestDesc {
647
- name : make_test_name ( config, testpaths) ,
648
- ignore,
649
- should_panic,
650
- allow_fail : false ,
651
- } ,
652
- testfn : make_test_closure ( config, testpaths) ,
653
- }
630
+ // Incremental tests are special, they inherently cannot be run in parallel.
631
+ // `runtest::run` will be responsible for iterating over revisions.
632
+ let revisions = if early_props. revisions . is_empty ( ) || config. mode == Mode :: Incremental {
633
+ vec ! [ None ]
634
+ } else {
635
+ early_props. revisions . iter ( ) . map ( |r| Some ( r) ) . collect ( )
636
+ } ;
637
+ revisions
638
+ . into_iter ( )
639
+ . map ( |revision| {
640
+ // Debugging emscripten code doesn't make sense today
641
+ let ignore = early_props. ignore
642
+ || !up_to_date (
643
+ config,
644
+ testpaths,
645
+ & early_props,
646
+ revision. map ( |s| s. as_str ( ) ) ,
647
+ )
648
+ || ( config. mode == DebugInfoGdb || config. mode == DebugInfoLldb )
649
+ && config. target . contains ( "emscripten" ) ;
650
+ test:: TestDescAndFn {
651
+ desc : test:: TestDesc {
652
+ name : make_test_name ( config, testpaths, revision) ,
653
+ ignore,
654
+ should_panic,
655
+ allow_fail : false ,
656
+ } ,
657
+ testfn : make_test_closure ( config, testpaths, revision) ,
658
+ }
659
+ } )
660
+ . collect ( )
654
661
}
655
662
656
- fn stamp ( config : & Config , testpaths : & TestPaths ) -> PathBuf {
657
- let mode_suffix = match config. compare_mode {
658
- Some ( ref mode) => format ! ( "-{}" , mode. to_str( ) ) ,
659
- None => format ! ( "" ) ,
660
- } ;
661
- let stamp_name = format ! (
662
- "{}-{}{}.stamp" ,
663
- testpaths. file. file_name( ) . unwrap( ) . to_str( ) . unwrap( ) ,
664
- config. stage_id,
665
- mode_suffix
666
- ) ;
667
- config
668
- . build_base
669
- . canonicalize ( )
670
- . unwrap_or_else ( |_| config. build_base . clone ( ) )
671
- . join ( & testpaths. relative_dir )
672
- . join ( stamp_name)
663
+ fn stamp ( config : & Config , testpaths : & TestPaths , revision : Option < & str > ) -> PathBuf {
664
+ output_base_dir ( config, testpaths, revision) . join ( "stamp" )
673
665
}
674
666
675
- fn up_to_date ( config : & Config , testpaths : & TestPaths , props : & EarlyProps ) -> bool {
667
+ fn up_to_date (
668
+ config : & Config ,
669
+ testpaths : & TestPaths ,
670
+ props : & EarlyProps ,
671
+ revision : Option < & str > ,
672
+ ) -> bool {
673
+ let stamp_name = stamp ( config, testpaths, revision) ;
674
+ // Check hash.
675
+ let mut f = match fs:: File :: open ( & stamp_name) {
676
+ Ok ( f) => f,
677
+ Err ( _) => return true ,
678
+ } ;
679
+ let mut contents = String :: new ( ) ;
680
+ f. read_to_string ( & mut contents)
681
+ . expect ( "Can't read stamp contents" ) ;
682
+ let expected_hash = runtest:: compute_stamp_hash ( config) ;
683
+ if contents != expected_hash {
684
+ return true ;
685
+ }
686
+
687
+ // Check timestamps.
676
688
let rust_src_dir = config
677
689
. find_rust_src_root ( )
678
690
. expect ( "Could not find Rust source root" ) ;
679
- let stamp = mtime ( & stamp ( config , testpaths ) ) ;
691
+ let stamp = mtime ( & stamp_name ) ;
680
692
let mut inputs = vec ! [ mtime( & testpaths. file) , mtime( & config. rustc_path) ] ;
681
693
for aux in props. aux . iter ( ) {
682
694
inputs. push ( mtime ( & testpaths
@@ -714,16 +726,8 @@ fn up_to_date(config: &Config, testpaths: &TestPaths, props: &EarlyProps) -> boo
714
726
715
727
// UI test files.
716
728
for extension in UI_EXTENSIONS {
717
- for revision in & props. revisions {
718
- let path =
719
- & expected_output_path ( testpaths, Some ( revision) , & config. compare_mode , extension) ;
720
- inputs. push ( mtime ( path) ) ;
721
- }
722
-
723
- if props. revisions . is_empty ( ) {
724
- let path = & expected_output_path ( testpaths, None , & config. compare_mode , extension) ;
725
- inputs. push ( mtime ( path) ) ;
726
- }
729
+ let path = & expected_output_path ( testpaths, revision, & config. compare_mode , extension) ;
730
+ inputs. push ( mtime ( path) ) ;
727
731
}
728
732
729
733
inputs. iter ( ) . any ( |input| * input > stamp)
@@ -735,7 +739,11 @@ fn mtime(path: &Path) -> FileTime {
735
739
. unwrap_or_else ( |_| FileTime :: zero ( ) )
736
740
}
737
741
738
- pub fn make_test_name ( config : & Config , testpaths : & TestPaths ) -> test:: TestName {
742
+ fn make_test_name (
743
+ config : & Config ,
744
+ testpaths : & TestPaths ,
745
+ revision : Option < & String > ,
746
+ ) -> test:: TestName {
739
747
// Convert a complete path to something like
740
748
//
741
749
// run-pass/foo/bar/baz.rs
@@ -747,17 +755,25 @@ pub fn make_test_name(config: &Config, testpaths: &TestPaths) -> test::TestName
747
755
None => format ! ( "" ) ,
748
756
} ;
749
757
test:: DynTestName ( format ! (
750
- "[{}{}] {}" ,
758
+ "[{}{}] {}{} " ,
751
759
config. mode,
752
760
mode_suffix,
753
- path. display( )
761
+ path. display( ) ,
762
+ revision. map_or( "" . to_string( ) , |rev| format!( "#{}" , rev) )
754
763
) )
755
764
}
756
765
757
- pub fn make_test_closure ( config : & Config , testpaths : & TestPaths ) -> test:: TestFn {
766
+ fn make_test_closure (
767
+ config : & Config ,
768
+ testpaths : & TestPaths ,
769
+ revision : Option < & String > ,
770
+ ) -> test:: TestFn {
758
771
let config = config. clone ( ) ;
759
772
let testpaths = testpaths. clone ( ) ;
760
- test:: DynTestFn ( Box :: new ( move || runtest:: run ( config, & testpaths) ) )
773
+ let revision = revision. cloned ( ) ;
774
+ test:: DynTestFn ( Box :: new ( move || {
775
+ runtest:: run ( config, & testpaths, revision. as_ref ( ) . map ( |s| s. as_str ( ) ) )
776
+ } ) )
761
777
}
762
778
763
779
/// Returns (Path to GDB, GDB Version, GDB has Rust Support)
0 commit comments