go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/bisection/testfailureanalysis/status_updater_test.go (about) 1 // Copyright 2023 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package testfailureanalysis 16 17 import ( 18 "context" 19 "testing" 20 "time" 21 22 . "github.com/smartystreets/goconvey/convey" 23 "go.chromium.org/luci/bisection/model" 24 pb "go.chromium.org/luci/bisection/proto/v1" 25 "go.chromium.org/luci/bisection/util/testutil" 26 "go.chromium.org/luci/common/clock" 27 "go.chromium.org/luci/common/clock/testclock" 28 "go.chromium.org/luci/gae/impl/memory" 29 "go.chromium.org/luci/gae/service/datastore" 30 ) 31 32 func TestUpdateAnalysisStatus(t *testing.T) { 33 t.Parallel() 34 35 Convey("UpdateStatus", t, func() { 36 ctx := memory.Use(context.Background()) 37 cl := testclock.New(testclock.TestTimeUTC) 38 cl.Set(time.Unix(10000, 0).UTC()) 39 ctx = clock.Set(ctx, cl) 40 Convey("Update status ended", func() { 41 tfa := testutil.CreateTestFailureAnalysis(ctx, &testutil.TestFailureAnalysisCreationOption{ 42 Status: pb.AnalysisStatus_RUNNING, 43 RunStatus: pb.AnalysisRunStatus_STARTED, 44 }) 45 err := UpdateAnalysisStatus(ctx, tfa, pb.AnalysisStatus_FOUND, pb.AnalysisRunStatus_ENDED) 46 So(err, ShouldBeNil) 47 So(tfa.Status, ShouldEqual, pb.AnalysisStatus_FOUND) 48 So(tfa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_ENDED) 49 So(tfa.EndTime.Unix(), ShouldEqual, 10000) 50 }) 51 52 Convey("Update status started", func() { 53 tfa := testutil.CreateTestFailureAnalysis(ctx, &testutil.TestFailureAnalysisCreationOption{ 54 Status: pb.AnalysisStatus_CREATED, 55 RunStatus: pb.AnalysisRunStatus_ANALYSIS_RUN_STATUS_UNSPECIFIED, 56 }) 57 err := UpdateAnalysisStatus(ctx, tfa, pb.AnalysisStatus_CREATED, pb.AnalysisRunStatus_STARTED) 58 So(err, ShouldBeNil) 59 So(tfa.Status, ShouldEqual, pb.AnalysisStatus_CREATED) 60 So(tfa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_STARTED) 61 So(tfa.StartTime.Unix(), ShouldEqual, 10000) 62 }) 63 64 Convey("Do not update the start time of a started analysis", func() { 65 tfa := testutil.CreateTestFailureAnalysis(ctx, &testutil.TestFailureAnalysisCreationOption{ 66 Status: pb.AnalysisStatus_RUNNING, 67 RunStatus: pb.AnalysisRunStatus_STARTED, 68 StartTime: time.Unix(5000, 0).UTC(), 69 }) 70 err := UpdateAnalysisStatus(ctx, tfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_STARTED) 71 So(err, ShouldBeNil) 72 So(tfa.Status, ShouldEqual, pb.AnalysisStatus_SUSPECTFOUND) 73 So(tfa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_STARTED) 74 So(tfa.StartTime.Unix(), ShouldEqual, 5000) 75 }) 76 77 Convey("Ended analysis will not update", func() { 78 tfa := testutil.CreateTestFailureAnalysis(ctx, &testutil.TestFailureAnalysisCreationOption{ 79 Status: pb.AnalysisStatus_FOUND, 80 RunStatus: pb.AnalysisRunStatus_ENDED, 81 }) 82 err := UpdateAnalysisStatus(ctx, tfa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_CANCELED) 83 So(err, ShouldBeNil) 84 So(tfa.Status, ShouldEqual, pb.AnalysisStatus_FOUND) 85 So(tfa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_ENDED) 86 }) 87 88 Convey("Canceled analysis will not update", func() { 89 tfa := testutil.CreateTestFailureAnalysis(ctx, &testutil.TestFailureAnalysisCreationOption{ 90 Status: pb.AnalysisStatus_NOTFOUND, 91 RunStatus: pb.AnalysisRunStatus_CANCELED, 92 }) 93 err := UpdateAnalysisStatus(ctx, tfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 94 So(err, ShouldBeNil) 95 So(tfa.Status, ShouldEqual, pb.AnalysisStatus_NOTFOUND) 96 So(tfa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_CANCELED) 97 }) 98 }) 99 } 100 101 func TestUpdateNthSectionAnalysisStatus(t *testing.T) { 102 t.Parallel() 103 104 Convey("Update Nthsection Status", t, func() { 105 ctx := memory.Use(context.Background()) 106 cl := testclock.New(testclock.TestTimeUTC) 107 cl.Set(time.Unix(10000, 0).UTC()) 108 ctx = clock.Set(ctx, cl) 109 Convey("Update status ended", func() { 110 nsa := testutil.CreateTestNthSectionAnalysis(ctx, &testutil.TestNthSectionAnalysisCreationOption{ 111 Status: pb.AnalysisStatus_RUNNING, 112 RunStatus: pb.AnalysisRunStatus_STARTED, 113 }) 114 err := UpdateNthSectionAnalysisStatus(ctx, nsa, pb.AnalysisStatus_FOUND, pb.AnalysisRunStatus_ENDED) 115 So(err, ShouldBeNil) 116 So(nsa.Status, ShouldEqual, pb.AnalysisStatus_FOUND) 117 So(nsa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_ENDED) 118 So(nsa.EndTime.Unix(), ShouldEqual, 10000) 119 }) 120 121 Convey("Ended analysis will not update", func() { 122 nsa := testutil.CreateTestNthSectionAnalysis(ctx, &testutil.TestNthSectionAnalysisCreationOption{ 123 Status: pb.AnalysisStatus_FOUND, 124 RunStatus: pb.AnalysisRunStatus_ENDED, 125 }) 126 err := UpdateNthSectionAnalysisStatus(ctx, nsa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_CANCELED) 127 So(err, ShouldBeNil) 128 So(nsa.Status, ShouldEqual, pb.AnalysisStatus_FOUND) 129 So(nsa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_ENDED) 130 }) 131 132 Convey("Canceled analysis will not update", func() { 133 nsa := testutil.CreateTestNthSectionAnalysis(ctx, &testutil.TestNthSectionAnalysisCreationOption{ 134 Status: pb.AnalysisStatus_NOTFOUND, 135 RunStatus: pb.AnalysisRunStatus_CANCELED, 136 }) 137 err := UpdateNthSectionAnalysisStatus(ctx, nsa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 138 So(err, ShouldBeNil) 139 So(nsa.Status, ShouldEqual, pb.AnalysisStatus_NOTFOUND) 140 So(nsa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_CANCELED) 141 }) 142 }) 143 } 144 145 func TestUpdateStatusWhenError(t *testing.T) { 146 t.Parallel() 147 148 Convey("Update Status When Error", t, func() { 149 ctx := memory.Use(context.Background()) 150 cl := testclock.New(testclock.TestTimeUTC) 151 cl.Set(time.Unix(10000, 0).UTC()) 152 ctx = clock.Set(ctx, cl) 153 tfa := testutil.CreateTestFailureAnalysis(ctx, &testutil.TestFailureAnalysisCreationOption{ 154 Status: pb.AnalysisStatus_CREATED, 155 RunStatus: pb.AnalysisRunStatus_STARTED, 156 }) 157 nsa := testutil.CreateTestNthSectionAnalysis(ctx, &testutil.TestNthSectionAnalysisCreationOption{ 158 ParentAnalysisKey: datastore.KeyForObj(ctx, tfa), 159 Status: pb.AnalysisStatus_CREATED, 160 RunStatus: pb.AnalysisRunStatus_STARTED, 161 }) 162 163 Convey("No in progress rerun", func() { 164 err := UpdateAnalysisStatusWhenError(ctx, tfa) 165 So(err, ShouldBeNil) 166 So(datastore.Get(ctx, nsa), ShouldBeNil) 167 So(nsa.Status, ShouldEqual, pb.AnalysisStatus_ERROR) 168 So(nsa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_ENDED) 169 So(nsa.EndTime, ShouldEqual, time.Unix(10000, 0).UTC()) 170 171 So(datastore.Get(ctx, tfa), ShouldBeNil) 172 So(tfa.Status, ShouldEqual, pb.AnalysisStatus_ERROR) 173 So(tfa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_ENDED) 174 So(tfa.EndTime, ShouldEqual, time.Unix(10000, 0).UTC()) 175 }) 176 177 Convey("Have in progress rerun", func() { 178 testutil.CreateTestSingleRerun(ctx, &testutil.TestSingleRerunCreationOption{ 179 AnalysisKey: datastore.KeyForObj(ctx, tfa), 180 Type: model.RerunBuildType_NthSection, 181 Status: pb.RerunStatus_RERUN_STATUS_IN_PROGRESS, 182 }) 183 err := UpdateAnalysisStatusWhenError(ctx, tfa) 184 So(err, ShouldBeNil) 185 So(datastore.Get(ctx, nsa), ShouldBeNil) 186 // No change. 187 So(nsa.Status, ShouldEqual, pb.AnalysisStatus_CREATED) 188 So(datastore.Get(ctx, tfa), ShouldBeNil) 189 So(tfa.Status, ShouldEqual, pb.AnalysisStatus_CREATED) 190 }) 191 }) 192 }