@@ -574,22 +574,59 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
574
574
575
575
pub fn make_tests ( config : & Config ) -> Vec < test:: TestDescAndFn > {
576
576
debug ! ( "making tests from {:?}" , config. src_base. display( ) ) ;
577
+ let inputs = common_inputs_stamp ( config) ;
577
578
let mut tests = Vec :: new ( ) ;
578
579
collect_tests_from_dir (
579
580
config,
580
581
& config. src_base ,
581
582
& config. src_base ,
582
583
& PathBuf :: new ( ) ,
584
+ & inputs,
583
585
& mut tests,
584
586
) . expect ( & format ! ( "Could not read tests from {}" , config. src_base. display( ) ) ) ;
585
587
tests
586
588
}
587
589
590
+ /// Returns a stamp constructed from input files common to all test cases.
591
+ fn common_inputs_stamp ( config : & Config ) -> Stamp {
592
+ let rust_src_dir = config
593
+ . find_rust_src_root ( )
594
+ . expect ( "Could not find Rust source root" ) ;
595
+
596
+ let mut stamp = Stamp :: from_path ( & config. rustc_path ) ;
597
+
598
+ // Relevant pretty printer files
599
+ let pretty_printer_files = [
600
+ "src/etc/debugger_pretty_printers_common.py" ,
601
+ "src/etc/gdb_load_rust_pretty_printers.py" ,
602
+ "src/etc/gdb_rust_pretty_printing.py" ,
603
+ "src/etc/lldb_batchmode.py" ,
604
+ "src/etc/lldb_rust_formatters.py" ,
605
+ ] ;
606
+ for file in & pretty_printer_files {
607
+ let path = rust_src_dir. join ( file) ;
608
+ stamp. add_path ( & path) ;
609
+ }
610
+
611
+ stamp. add_dir ( & config. run_lib_path ) ;
612
+
613
+ if let Some ( ref rustdoc_path) = config. rustdoc_path {
614
+ stamp. add_path ( & rustdoc_path) ;
615
+ stamp. add_path ( & rust_src_dir. join ( "src/etc/htmldocck.py" ) ) ;
616
+ }
617
+
618
+ // Compiletest itself.
619
+ stamp. add_dir ( & rust_src_dir. join ( "src/tools/compiletest/" ) ) ;
620
+
621
+ stamp
622
+ }
623
+
588
624
fn collect_tests_from_dir (
589
625
config : & Config ,
590
626
base : & Path ,
591
627
dir : & Path ,
592
628
relative_dir_path : & Path ,
629
+ inputs : & Stamp ,
593
630
tests : & mut Vec < test:: TestDescAndFn > ,
594
631
) -> io:: Result < ( ) > {
595
632
// Ignore directories that contain a file named `compiletest-ignore-dir`.
@@ -602,7 +639,7 @@ fn collect_tests_from_dir(
602
639
file : dir. to_path_buf ( ) ,
603
640
relative_dir : relative_dir_path. parent ( ) . unwrap ( ) . to_path_buf ( ) ,
604
641
} ;
605
- tests. extend ( make_test ( config, & paths) ) ;
642
+ tests. extend ( make_test ( config, & paths, inputs ) ) ;
606
643
return Ok ( ( ) ) ;
607
644
}
608
645
@@ -627,12 +664,14 @@ fn collect_tests_from_dir(
627
664
file : file_path,
628
665
relative_dir : relative_dir_path. to_path_buf ( ) ,
629
666
} ;
630
- tests. extend ( make_test ( config, & paths) )
667
+ tests. extend ( make_test ( config, & paths, inputs ) )
631
668
} else if file_path. is_dir ( ) {
632
669
let relative_file_path = relative_dir_path. join ( file. file_name ( ) ) ;
633
670
if & file_name != "auxiliary" {
634
671
debug ! ( "found directory: {:?}" , file_path. display( ) ) ;
635
- collect_tests_from_dir ( config, base, & file_path, & relative_file_path, tests) ?;
672
+ collect_tests_from_dir (
673
+ config, base, & file_path, & relative_file_path,
674
+ inputs, tests) ?;
636
675
}
637
676
} else {
638
677
debug ! ( "found other file/directory: {:?}" , file_path. display( ) ) ;
@@ -655,7 +694,7 @@ pub fn is_test(file_name: &OsString) -> bool {
655
694
!invalid_prefixes. iter ( ) . any ( |p| file_name. starts_with ( p) )
656
695
}
657
696
658
- pub fn make_test ( config : & Config , testpaths : & TestPaths ) -> Vec < test:: TestDescAndFn > {
697
+ fn make_test ( config : & Config , testpaths : & TestPaths , inputs : & Stamp ) -> Vec < test:: TestDescAndFn > {
659
698
let early_props = if config. mode == Mode :: RunMake {
660
699
// Allow `ignore` directives to be in the Makefile.
661
700
EarlyProps :: from_file ( config, & testpaths. file . join ( "Makefile" ) )
@@ -685,19 +724,21 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> Vec<test::TestDescAn
685
724
revisions
686
725
. into_iter ( )
687
726
. map ( |revision| {
688
- // Debugging emscripten code doesn't make sense today
689
727
let ignore = early_props. ignore == Ignore :: Ignore
690
- || !up_to_date (
691
- config,
692
- testpaths,
693
- & early_props,
694
- revision. map ( |s| s. as_str ( ) ) ,
695
- )
728
+ // Debugging emscripten code doesn't make sense today
696
729
|| ( ( config. mode == DebugInfoGdbLldb || config. mode == DebugInfoCdb ||
697
730
config. mode == DebugInfoGdb || config. mode == DebugInfoLldb )
698
731
&& config. target . contains ( "emscripten" ) )
699
732
|| ( config. mode == DebugInfoGdb && !early_props. ignore . can_run_gdb ( ) )
700
- || ( config. mode == DebugInfoLldb && !early_props. ignore . can_run_lldb ( ) ) ;
733
+ || ( config. mode == DebugInfoLldb && !early_props. ignore . can_run_lldb ( ) )
734
+ // Ignore tests that already run and are up to date with respect to inputs.
735
+ || is_up_to_date (
736
+ config,
737
+ testpaths,
738
+ & early_props,
739
+ revision. map ( |s| s. as_str ( ) ) ,
740
+ inputs,
741
+ ) ;
701
742
test:: TestDescAndFn {
702
743
desc : test:: TestDesc {
703
744
name : make_test_name ( config, testpaths, revision) ,
@@ -716,98 +757,75 @@ fn stamp(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> Path
716
757
output_base_dir ( config, testpaths, revision) . join ( "stamp" )
717
758
}
718
759
719
- fn up_to_date (
760
+ fn is_up_to_date (
720
761
config : & Config ,
721
762
testpaths : & TestPaths ,
722
763
props : & EarlyProps ,
723
764
revision : Option < & str > ,
765
+ inputs : & Stamp ,
724
766
) -> bool {
725
767
let stamp_name = stamp ( config, testpaths, revision) ;
726
768
// Check hash.
727
769
let contents = match fs:: read_to_string ( & stamp_name) {
728
770
Ok ( f) => f,
729
771
Err ( ref e) if e. kind ( ) == ErrorKind :: InvalidData => panic ! ( "Can't read stamp contents" ) ,
730
- Err ( _) => return true ,
772
+ Err ( _) => return false ,
731
773
} ;
732
774
let expected_hash = runtest:: compute_stamp_hash ( config) ;
733
775
if contents != expected_hash {
734
- return true ;
776
+ return false ;
735
777
}
736
778
737
779
// Check timestamps.
738
- let rust_src_dir = config
739
- . find_rust_src_root ( )
740
- . expect ( "Could not find Rust source root" ) ;
741
- let stamp = Stamp :: from_path ( & stamp_name) ;
742
- let mut inputs = vec ! [ Stamp :: from_path( & testpaths. file) , Stamp :: from_path( & config. rustc_path) ] ;
743
- inputs. extend (
744
- props
745
- . aux
746
- . iter ( )
747
- . map ( |aux| {
748
- Stamp :: from_path ( & testpaths. file . parent ( ) . unwrap ( ) . join ( "auxiliary" ) . join ( aux) )
749
- } ) ,
750
- ) ;
751
- // Relevant pretty printer files
752
- let pretty_printer_files = [
753
- "src/etc/debugger_pretty_printers_common.py" ,
754
- "src/etc/gdb_load_rust_pretty_printers.py" ,
755
- "src/etc/gdb_rust_pretty_printing.py" ,
756
- "src/etc/lldb_batchmode.py" ,
757
- "src/etc/lldb_rust_formatters.py" ,
758
- ] ;
759
- inputs. extend ( pretty_printer_files. iter ( ) . map ( |pretty_printer_file| {
760
- Stamp :: from_path ( & rust_src_dir. join ( pretty_printer_file) )
761
- } ) ) ;
762
- inputs. extend ( Stamp :: from_dir ( & config. run_lib_path ) ) ;
763
- if let Some ( ref rustdoc_path) = config. rustdoc_path {
764
- inputs. push ( Stamp :: from_path ( & rustdoc_path) ) ;
765
- inputs. push ( Stamp :: from_path ( & rust_src_dir. join ( "src/etc/htmldocck.py" ) ) ) ;
780
+ let mut inputs = inputs. clone ( ) ;
781
+ inputs. add_path ( & testpaths. file ) ;
782
+
783
+ for aux in & props. aux {
784
+ let path = testpaths. file . parent ( )
785
+ . unwrap ( )
786
+ . join ( "auxiliary" )
787
+ . join ( aux) ;
788
+ inputs. add_path ( & path) ;
766
789
}
767
790
768
791
// UI test files.
769
- inputs . extend ( UI_EXTENSIONS . iter ( ) . map ( | extension| {
792
+ for extension in UI_EXTENSIONS {
770
793
let path = & expected_output_path ( testpaths, revision, & config. compare_mode , extension) ;
771
- Stamp :: from_path ( path)
772
- } ) ) ;
773
-
774
- // Compiletest itself.
775
- inputs. extend ( Stamp :: from_dir ( & rust_src_dir. join ( "src/tools/compiletest/" ) ) ) ;
794
+ inputs. add_path ( path) ;
795
+ }
776
796
777
- inputs. iter ( ) . any ( |input| input > & stamp )
797
+ inputs < Stamp :: from_path ( & stamp_name )
778
798
}
779
799
780
- #[ derive( Debug , PartialEq , PartialOrd , Ord , Eq ) ]
800
+ #[ derive( Clone , Debug , PartialEq , Eq , PartialOrd , Ord ) ]
781
801
struct Stamp {
782
802
time : SystemTime ,
783
- file : PathBuf ,
784
803
}
785
804
786
805
impl Stamp {
787
- fn from_path ( p : & Path ) -> Self {
788
- let time = fs:: metadata ( p)
806
+ fn from_path ( path : & Path ) -> Self {
807
+ let mut stamp = Stamp { time : SystemTime :: UNIX_EPOCH } ;
808
+ stamp. add_path ( path) ;
809
+ stamp
810
+ }
811
+
812
+ fn add_path ( & mut self , path : & Path ) {
813
+ let modified = fs:: metadata ( path)
789
814
. and_then ( |metadata| metadata. modified ( ) )
790
815
. unwrap_or ( SystemTime :: UNIX_EPOCH ) ;
791
-
792
- Stamp {
793
- time,
794
- file : p. into ( ) ,
795
- }
816
+ self . time = self . time . max ( modified) ;
796
817
}
797
818
798
- fn from_dir ( path : & Path ) -> impl Iterator < Item = Stamp > {
799
- WalkDir :: new ( path)
800
- . into_iter ( )
801
- . map ( |entry| entry. unwrap ( ) )
802
- . filter ( |entry| entry. file_type ( ) . is_file ( ) )
803
- . map ( |entry| {
804
- let time = ( || -> io:: Result < _ > { entry. metadata ( ) ?. modified ( ) } ) ( ) ;
805
-
806
- Stamp {
807
- time : time. unwrap_or ( SystemTime :: UNIX_EPOCH ) ,
808
- file : entry. path ( ) . into ( ) ,
809
- }
810
- } )
819
+ fn add_dir ( & mut self , path : & Path ) {
820
+ for entry in WalkDir :: new ( path) {
821
+ let entry = entry. unwrap ( ) ;
822
+ if entry. file_type ( ) . is_file ( ) {
823
+ let modified = entry. metadata ( ) . ok ( )
824
+ . and_then ( |metadata| metadata. modified ( ) . ok ( ) )
825
+ . unwrap_or ( SystemTime :: UNIX_EPOCH ) ;
826
+ self . time = self . time . max ( modified) ;
827
+ }
828
+ }
811
829
}
812
830
}
813
831
0 commit comments