@@ -748,6 +748,52 @@ fn test_nightly_finder_iterator() {
748
748
assert_eq ! ( start_date - chrono:: Duration :: days( 78 ) , iter. next( ) . unwrap( ) ) ;
749
749
}
750
750
751
+ fn install_and_test (
752
+ t : & Toolchain ,
753
+ cfg : & Config ,
754
+ client : & Client ,
755
+ dl_spec : & DownloadParams ) -> Result < Satisfies , InstallError >
756
+ {
757
+ match t. install ( & client, & dl_spec) {
758
+ Ok ( ( ) ) => {
759
+ eprintln ! ( "testing..." ) ;
760
+ let outcome = t. test ( & cfg) ;
761
+ // we want to fail, so a successful build doesn't satisfy us
762
+ let r = match outcome {
763
+ TestOutcome :: Baseline => Satisfies :: No ,
764
+ TestOutcome :: Regressed => Satisfies :: Yes ,
765
+ } ;
766
+ eprintln ! ( "RESULT: {}, ===> {}" , t, r) ;
767
+ if !cfg. args . preserve {
768
+ let _ = t. remove ( & dl_spec) ;
769
+ }
770
+ eprintln ! ( ) ;
771
+ Ok ( r)
772
+ }
773
+ Err ( error) => {
774
+ if !cfg. args . preserve {
775
+ let _ = t. remove ( & dl_spec) ;
776
+ }
777
+ Err ( error)
778
+ }
779
+ }
780
+ }
781
+
782
+ fn bisect_to_regression (
783
+ toolchains : & Vec < Toolchain > ,
784
+ cfg : & Config ,
785
+ client : & Client ,
786
+ dl_spec : & DownloadParams ) -> Result < usize , InstallError >
787
+ {
788
+ let found = least_satisfying ( & toolchains, |t| {
789
+ match install_and_test ( & t, & cfg, & client, & dl_spec) {
790
+ Ok ( r) => r,
791
+ Err ( _) => Satisfies :: Unknown ,
792
+ }
793
+ } ) ;
794
+ Ok ( found)
795
+ }
796
+
751
797
// nightlies branch of bisect execution
752
798
fn bisect_nightlies ( cfg : & Config , client : & Client ) -> Result < BisectionResult , Error > {
753
799
if cfg. args . alt {
@@ -781,6 +827,12 @@ fn bisect_nightlies(cfg: &Config, client: &Client) -> Result<BisectionResult, Er
781
827
782
828
let mut nightly_iter = NightlyFinderIter :: new ( nightly_date) ;
783
829
830
+ // this loop tests nightly toolchains to:
831
+ // (1) validate that start date does not have regression (if start date defined on CL)
832
+ // (2) identify a nightly date range for the bisection routine
833
+ //
834
+ // The tests here must be constrained to dates after 2015-10-20 (`end_at` date)
835
+ // because -std packages were not available prior
784
836
while nightly_date > end_at {
785
837
let mut t = Toolchain {
786
838
spec : ToolchainSpec :: Nightly { date : nightly_date } ,
@@ -792,51 +844,61 @@ fn bisect_nightlies(cfg: &Config, client: &Client) -> Result<BisectionResult, Er
792
844
if t. is_current_nightly ( ) {
793
845
eprintln ! ( "checking {} from the currently installed default nightly \
794
846
toolchain as the last failure", t) ;
795
- } else {
796
- eprintln ! ( "checking {}" , t) ;
797
847
}
798
- match t. install ( client, & dl_spec) {
799
- Ok ( ( ) ) => {
800
- eprintln ! ( "verifying the start of the range does not reproduce the regression" ) ;
801
- let outcome = t. test ( & cfg) ;
802
-
803
- if !cfg. args . preserve {
804
- let _ = t. remove ( & dl_spec) ;
805
- }
806
848
807
- if let TestOutcome :: Baseline = outcome {
808
- eprintln ! ( "confirmed {} does not reproduce the regression" , t) ;
849
+ match install_and_test ( & t, & cfg, & client, & dl_spec) {
850
+ Ok ( r) => {
851
+ // If Satisfies::No, then the regression was not identified in this nightly.
852
+ // Break out of the loop and use this as the start date for the
853
+ // bisection range
854
+ if let Satisfies :: No = r {
809
855
first_success = Some ( nightly_date) ;
810
856
break ;
811
857
} else if has_start {
812
- bail ! ( "the start of the range to test must not reproduce the regression" ) ;
858
+ // If this date was explicitly defined on CL & has regression,
859
+ // then this is an error in the test definition. The user must
860
+ // re-define the start date and try again
861
+ bail ! ( "the start of the range ({}) must not reproduce the regression" , t) ;
813
862
} else {
814
863
last_failure = nightly_date;
815
864
}
816
865
817
866
nightly_date = nightly_iter. next ( ) . unwrap ( ) ;
818
- }
867
+ } ,
819
868
Err ( InstallError :: NotFound { .. } ) => {
820
- // go back just one day, presumably missing nightly
869
+ // go back just one day, presumably missing a nightly
821
870
nightly_date = nightly_date - chrono:: Duration :: days ( 1 ) ;
822
- if !cfg. args . preserve {
823
- let _ = t. remove ( & dl_spec) ;
824
- }
871
+ eprintln ! ( "*** unable to install {}. roll back one day and try again..." , t) ;
825
872
if has_start {
826
873
bail ! ( "could not find {}" , t) ;
827
874
}
828
- }
829
- Err ( e) => {
830
- if !cfg. args . preserve {
831
- let _ = t. remove ( & dl_spec) ;
832
- }
833
- return Err ( e. into ( ) ) ;
834
- }
875
+ } ,
876
+ Err ( error) => return Err ( error. into ( ) ) ,
835
877
}
836
878
}
837
879
838
880
let first_success = first_success. ok_or ( format_err ! ( "could not find a nightly that built" ) ) ?;
839
881
882
+ // confirm that the end of the date range has the regression
883
+ let mut t_end = Toolchain {
884
+ spec : ToolchainSpec :: Nightly { date : last_failure } ,
885
+ host : cfg. args . host . clone ( ) ,
886
+ std_targets : vec ! [ cfg. args. host. clone( ) , cfg. target. clone( ) ] ,
887
+ } ;
888
+ t_end. std_targets . sort ( ) ;
889
+ t_end. std_targets . dedup ( ) ;
890
+
891
+ match install_and_test ( & t_end, & cfg, & client, & dl_spec) {
892
+ Ok ( r) => {
893
+ // If Satisfies::No, then the regression was not identified in this nightly.
894
+ // this is an error, abort with error message
895
+ if r == Satisfies :: No {
896
+ bail ! ( "the end of the range ({}) does not reproduce the regression" , t_end) ;
897
+ }
898
+ } ,
899
+ Err ( error) => return Err ( error. into ( ) ) ,
900
+ }
901
+
840
902
let toolchains = toolchains_between (
841
903
cfg,
842
904
ToolchainSpec :: Nightly {
@@ -845,32 +907,7 @@ fn bisect_nightlies(cfg: &Config, client: &Client) -> Result<BisectionResult, Er
845
907
ToolchainSpec :: Nightly { date : last_failure } ,
846
908
) ;
847
909
848
- // First success check has been performed above so it is not necessary
849
- // to repeat it within the least_satisfying function in the call here.
850
- // Set `start_check` to false to prevent a repeat check on the same
851
- // nightly in `least_satisfying`
852
- let found = least_satisfying ( & toolchains, false , |t| {
853
- match t. install ( & client, & dl_spec) {
854
- Ok ( ( ) ) => {
855
- let outcome = t. test ( & cfg) ;
856
- // we want to fail, so a successful build doesn't satisfy us
857
- let r = match outcome {
858
- TestOutcome :: Baseline => Satisfies :: No ,
859
- TestOutcome :: Regressed => Satisfies :: Yes ,
860
- } ;
861
- if !cfg. args . preserve {
862
- let _ = t. remove ( & dl_spec) ;
863
- }
864
- eprintln ! ( "tested {}, got {}" , t, r) ;
865
- r
866
- }
867
- Err ( err) => {
868
- let _ = t. remove ( & dl_spec) ;
869
- eprintln ! ( "failed to install {}: {:?}" , t, err) ;
870
- Satisfies :: Unknown
871
- }
872
- }
873
- } ) ;
910
+ let found = bisect_to_regression ( & toolchains, & cfg, client, & dl_spec) ?;
874
911
875
912
Ok ( BisectionResult {
876
913
dl_spec,
@@ -993,31 +1030,33 @@ fn bisect_ci_in_commits(
993
1030
} )
994
1031
. collect :: < Vec < _ > > ( ) ;
995
1032
996
- eprintln ! ( "testing commits" ) ;
997
- let found = least_satisfying ( & toolchains, true , |t| {
998
- eprintln ! ( "installing {}" , t) ;
999
- match t. install ( & client, & dl_spec) {
1000
- Ok ( ( ) ) => {
1001
- eprintln ! ( "testing {}" , t) ;
1002
- let outcome = t. test ( & cfg) ;
1003
- // we want to fail, so a successful build doesn't satisfy us
1004
- let r = match outcome {
1005
- TestOutcome :: Regressed => Satisfies :: Yes ,
1006
- TestOutcome :: Baseline => Satisfies :: No ,
1007
- } ;
1008
- eprintln ! ( "tested {}, got {}" , t, r) ;
1009
- if !cfg. args . preserve {
1010
- let _ = t. remove ( & dl_spec) ;
1033
+ if !toolchains. is_empty ( ) {
1034
+ // validate commit at start of range
1035
+ match install_and_test ( & toolchains[ 0 ] , & cfg, & client, & dl_spec) {
1036
+ Ok ( r) => {
1037
+ // If Satisfies::Yes, then the commit at the beginning of the range
1038
+ // has the regression, this is an error
1039
+ if r == Satisfies :: Yes {
1040
+ bail ! ( "the commit at the start of the range ({}) includes the regression" , & toolchains[ 0 ] ) ;
1011
1041
}
1012
- r
1013
- }
1014
- Err ( err) => {
1015
- let _ = t. remove ( & dl_spec) ;
1016
- eprintln ! ( "failed to install {}: {:?}" , t, err) ;
1017
- Satisfies :: Unknown
1018
- }
1042
+ } ,
1043
+ Err ( error) => return Err ( error. into ( ) ) ,
1019
1044
}
1020
- } ) ;
1045
+
1046
+ // validate commit at end of range
1047
+ match install_and_test ( & toolchains[ toolchains. len ( ) -1 ] , & cfg, & client, & dl_spec) {
1048
+ Ok ( r) => {
1049
+ // If Satisfies::No, then the regression was not identified at the end of the
1050
+ // commit range, this is an error
1051
+ if r == Satisfies :: No {
1052
+ bail ! ( "the commit at the end of the range ({}) does not reproduce the regression" , & toolchains[ toolchains. len( ) -1 ] ) ;
1053
+ }
1054
+ } ,
1055
+ Err ( error) => return Err ( error. into ( ) ) ,
1056
+ }
1057
+ }
1058
+
1059
+ let found = bisect_to_regression ( & toolchains, & cfg, client, & dl_spec) ?;
1021
1060
1022
1061
Ok ( BisectionResult {
1023
1062
searched : toolchains,
@@ -1038,7 +1077,7 @@ fn main() {
1038
1077
match err. downcast :: < ExitError > ( ) {
1039
1078
Ok ( ExitError ( code) ) => process:: exit ( code) ,
1040
1079
Err ( err) => {
1041
- eprintln ! ( "{}" , err) ;
1080
+ eprintln ! ( "ERROR: {}" , err) ;
1042
1081
process:: exit ( 1 ) ;
1043
1082
}
1044
1083
}
0 commit comments