@@ -748,6 +748,52 @@ fn test_nightly_finder_iterator() {
748748 assert_eq ! ( start_date - chrono:: Duration :: days( 78 ) , iter. next( ) . unwrap( ) ) ;
749749}
750750
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+
751797// nightlies branch of bisect execution
752798fn bisect_nightlies ( cfg : & Config , client : & Client ) -> Result < BisectionResult , Error > {
753799 if cfg. args . alt {
@@ -781,6 +827,12 @@ fn bisect_nightlies(cfg: &Config, client: &Client) -> Result<BisectionResult, Er
781827
782828 let mut nightly_iter = NightlyFinderIter :: new ( nightly_date) ;
783829
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
784836 while nightly_date > end_at {
785837 let mut t = Toolchain {
786838 spec : ToolchainSpec :: Nightly { date : nightly_date } ,
@@ -792,51 +844,61 @@ fn bisect_nightlies(cfg: &Config, client: &Client) -> Result<BisectionResult, Er
792844 if t. is_current_nightly ( ) {
793845 eprintln ! ( "checking {} from the currently installed default nightly \
794846 toolchain as the last failure", t) ;
795- } else {
796- eprintln ! ( "checking {}" , t) ;
797847 }
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- }
806848
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 {
809855 first_success = Some ( nightly_date) ;
810856 break ;
811857 } 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) ;
813862 } else {
814863 last_failure = nightly_date;
815864 }
816865
817866 nightly_date = nightly_iter. next ( ) . unwrap ( ) ;
818- }
867+ } ,
819868 Err ( InstallError :: NotFound { .. } ) => {
820- // go back just one day, presumably missing nightly
869+ // go back just one day, presumably missing a nightly
821870 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) ;
825872 if has_start {
826873 bail ! ( "could not find {}" , t) ;
827874 }
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 ( ) ) ,
835877 }
836878 }
837879
838880 let first_success = first_success. ok_or ( format_err ! ( "could not find a nightly that built" ) ) ?;
839881
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+
840902 let toolchains = toolchains_between (
841903 cfg,
842904 ToolchainSpec :: Nightly {
@@ -845,32 +907,7 @@ fn bisect_nightlies(cfg: &Config, client: &Client) -> Result<BisectionResult, Er
845907 ToolchainSpec :: Nightly { date : last_failure } ,
846908 ) ;
847909
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) ?;
874911
875912 Ok ( BisectionResult {
876913 dl_spec,
@@ -993,31 +1030,33 @@ fn bisect_ci_in_commits(
9931030 } )
9941031 . collect :: < Vec < _ > > ( ) ;
9951032
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 ] ) ;
10111041 }
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 ( ) ) ,
10191044 }
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) ?;
10211060
10221061 Ok ( BisectionResult {
10231062 searched : toolchains,
@@ -1038,7 +1077,7 @@ fn main() {
10381077 match err. downcast :: < ExitError > ( ) {
10391078 Ok ( ExitError ( code) ) => process:: exit ( code) ,
10401079 Err ( err) => {
1041- eprintln ! ( "{}" , err) ;
1080+ eprintln ! ( "ERROR: {}" , err) ;
10421081 process:: exit ( 1 ) ;
10431082 }
10441083 }
0 commit comments