go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/bisection/compilefailureanalysis/statusupdater/status_updater_test.go (about) 1 // Copyright 2022 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 statusupdater 16 17 import ( 18 "context" 19 "testing" 20 21 . "github.com/smartystreets/goconvey/convey" 22 "go.chromium.org/luci/bisection/model" 23 pb "go.chromium.org/luci/bisection/proto/v1" 24 "go.chromium.org/luci/bisection/util/testutil" 25 "go.chromium.org/luci/common/clock" 26 "go.chromium.org/luci/common/clock/testclock" 27 "go.chromium.org/luci/gae/impl/memory" 28 "go.chromium.org/luci/gae/service/datastore" 29 ) 30 31 func TestUpdateAnalysisStatus(t *testing.T) { 32 t.Parallel() 33 c := memory.Use(context.Background()) 34 testutil.UpdateIndices(c) 35 cl := testclock.New(testclock.TestTimeUTC) 36 c = clock.Set(c, cl) 37 38 Convey("UpdateAnalysisStatus", t, func() { 39 // No heuristic and nthsection 40 Convey("No heuristic and nthsection", func() { 41 cfa := createCompileFailureAnalysisModel(c, 1000) 42 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_ERROR, pb.AnalysisRunStatus_ENDED) 43 }) 44 45 Convey("Have culprit", func() { 46 cfa := createCompileFailureAnalysisModel(c, 1001) 47 suspect := &model.Suspect{} 48 So(datastore.Put(c, suspect), ShouldBeNil) 49 datastore.GetTestable(c).CatchupIndexes() 50 51 cfa.VerifiedCulprits = []*datastore.Key{datastore.KeyForObj(c, suspect)} 52 So(datastore.Put(c, cfa), ShouldBeNil) 53 datastore.GetTestable(c).CatchupIndexes() 54 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_FOUND, pb.AnalysisRunStatus_ENDED) 55 }) 56 57 Convey("No nth section, run finished", func() { 58 cfa := createCompileFailureAnalysisModel(c, 1002) 59 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 60 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 61 }) 62 63 Convey("nth section error, run finished", func() { 64 cfa := createCompileFailureAnalysisModel(c, 1003) 65 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 66 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_ERROR, pb.AnalysisRunStatus_ENDED) 67 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 68 }) 69 70 Convey("No nth section, heuristic suspect found, run finished", func() { 71 cfa := createCompileFailureAnalysisModel(c, 1004) 72 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 73 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 74 }) 75 76 Convey("No nth section, heuristic suspect found, run unfinished", func() { 77 cfa := createCompileFailureAnalysisModel(c, 1005) 78 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 79 createUnfinishedRerun(c, cfa) 80 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_STARTED) 81 }) 82 83 Convey("No heuristic, run finished", func() { 84 cfa := createCompileFailureAnalysisModel(c, 1006) 85 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 86 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 87 }) 88 89 Convey("Heuristic error, run finished", func() { 90 cfa := createCompileFailureAnalysisModel(c, 1007) 91 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 92 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_ERROR, pb.AnalysisRunStatus_ENDED) 93 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 94 }) 95 96 Convey("No heuristic, nthsection suspect found, run finished", func() { 97 cfa := createCompileFailureAnalysisModel(c, 1008) 98 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 99 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 100 }) 101 102 Convey("No heuristic, nthsection suspect found, run unfinished", func() { 103 cfa := createCompileFailureAnalysisModel(c, 1009) 104 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 105 createUnfinishedRerun(c, cfa) 106 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_STARTED) 107 }) 108 109 Convey("Heuristic and nthsection both error", func() { 110 cfa := createCompileFailureAnalysisModel(c, 1010) 111 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_ERROR, pb.AnalysisRunStatus_ENDED) 112 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_ERROR, pb.AnalysisRunStatus_ENDED) 113 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_ERROR, pb.AnalysisRunStatus_ENDED) 114 }) 115 116 Convey("Heuristic suspect found, nth section in progress", func() { 117 cfa := createCompileFailureAnalysisModel(c, 1011) 118 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 119 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 120 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_STARTED) 121 }) 122 123 Convey("Heuristic suspect found, nth section finished", func() { 124 cfa := createCompileFailureAnalysisModel(c, 1012) 125 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 126 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_ENDED) 127 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 128 }) 129 130 Convey("Nthsection suspect found, heuristic not found, verification running", func() { 131 cfa := createCompileFailureAnalysisModel(c, 1013) 132 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_ENDED) 133 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 134 createUnfinishedRerun(c, cfa) 135 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_STARTED) 136 }) 137 138 Convey("Nthsection suspect found, verification finished", func() { 139 cfa := createCompileFailureAnalysisModel(c, 1014) 140 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_ENDED) 141 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 142 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 143 }) 144 145 Convey("Nthsection in progress, heuristic in progress", func() { 146 cfa := createCompileFailureAnalysisModel(c, 1015) 147 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 148 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 149 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 150 }) 151 152 Convey("Nthsection not found, heuristic not found", func() { 153 cfa := createCompileFailureAnalysisModel(c, 1016) 154 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_ENDED) 155 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_ENDED) 156 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_ENDED) 157 }) 158 159 Convey("Heuristic not found, nth section running", func() { 160 cfa := createCompileFailureAnalysisModel(c, 1017) 161 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_ENDED) 162 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 163 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 164 }) 165 166 Convey("Heuristic running, nth section not found", func() { 167 cfa := createCompileFailureAnalysisModel(c, 1019) 168 createHeuristicAnalysis(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 169 createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_ENDED) 170 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 171 }) 172 173 Convey("No heuristic, nthsection suspect found, run finished, verification schedule", func() { 174 cfa := createCompileFailureAnalysisModel(c, 1020) 175 nsa := createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 176 suspect := &model.Suspect{ 177 ParentAnalysis: datastore.KeyForObj(c, nsa), 178 VerificationStatus: model.SuspectVerificationStatus_VerificationScheduled, 179 } 180 So(datastore.Put(c, suspect), ShouldBeNil) 181 datastore.GetTestable(c).CatchupIndexes() 182 checkUpdateAnalysisStatus(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_STARTED) 183 }) 184 }) 185 } 186 187 func TestUpdateStatus(t *testing.T) { 188 t.Parallel() 189 c := memory.Use(context.Background()) 190 cl := testclock.New(testclock.TestTimeUTC) 191 c = clock.Set(c, cl) 192 193 Convey("UpdateStatus", t, func() { 194 Convey("Ended analysis will not update", func() { 195 cfa := createCompileFailureAnalysisModelWithStatus(c, 1000, pb.AnalysisStatus_FOUND, pb.AnalysisRunStatus_ENDED) 196 err := UpdateStatus(c, cfa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_CANCELED) 197 So(err, ShouldBeNil) 198 So(cfa.Status, ShouldEqual, pb.AnalysisStatus_FOUND) 199 So(cfa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_ENDED) 200 }) 201 202 Convey("Canceled analysis will not update", func() { 203 cfa := createCompileFailureAnalysisModelWithStatus(c, 1001, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_CANCELED) 204 err := UpdateStatus(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 205 So(err, ShouldBeNil) 206 So(cfa.Status, ShouldEqual, pb.AnalysisStatus_NOTFOUND) 207 So(cfa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_CANCELED) 208 }) 209 210 Convey("Update status", func() { 211 cfa := createCompileFailureAnalysisModelWithStatus(c, 1001, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 212 err := UpdateStatus(c, cfa, pb.AnalysisStatus_FOUND, pb.AnalysisRunStatus_ENDED) 213 So(err, ShouldBeNil) 214 So(cfa.Status, ShouldEqual, pb.AnalysisStatus_FOUND) 215 So(cfa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_ENDED) 216 }) 217 }) 218 } 219 220 func TestUpdateNthSectionStatus(t *testing.T) { 221 t.Parallel() 222 c := memory.Use(context.Background()) 223 testutil.UpdateIndices(c) 224 cl := testclock.New(testclock.TestTimeUTC) 225 c = clock.Set(c, cl) 226 227 Convey("UpdateNthSectionStatus", t, func() { 228 Convey("Ended analysis will not update", func() { 229 cfa := createCompileFailureAnalysisModelWithStatus(c, 1000, pb.AnalysisStatus_FOUND, pb.AnalysisRunStatus_ENDED) 230 nsa := createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_SUSPECTFOUND, pb.AnalysisRunStatus_ENDED) 231 err := UpdateNthSectionStatus(c, nsa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_CANCELED) 232 So(err, ShouldBeNil) 233 So(nsa.Status, ShouldEqual, pb.AnalysisStatus_SUSPECTFOUND) 234 So(nsa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_ENDED) 235 }) 236 237 Convey("Canceled analysis will not update", func() { 238 cfa := createCompileFailureAnalysisModelWithStatus(c, 1001, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_CANCELED) 239 nsa := createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_NOTFOUND, pb.AnalysisRunStatus_CANCELED) 240 err := UpdateNthSectionStatus(c, nsa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 241 So(err, ShouldBeNil) 242 So(nsa.Status, ShouldEqual, pb.AnalysisStatus_NOTFOUND) 243 So(nsa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_CANCELED) 244 }) 245 246 Convey("Update status", func() { 247 cfa := createCompileFailureAnalysisModelWithStatus(c, 1002, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 248 nsa := createNthSectionAnalysis(c, cfa, pb.AnalysisStatus_RUNNING, pb.AnalysisRunStatus_STARTED) 249 err := UpdateNthSectionStatus(c, nsa, pb.AnalysisStatus_FOUND, pb.AnalysisRunStatus_ENDED) 250 So(err, ShouldBeNil) 251 So(nsa.Status, ShouldEqual, pb.AnalysisStatus_FOUND) 252 So(nsa.RunStatus, ShouldEqual, pb.AnalysisRunStatus_ENDED) 253 }) 254 }) 255 } 256 257 func createCompileFailureAnalysisModel(c context.Context, id int64) *model.CompileFailureAnalysis { 258 cfa := &model.CompileFailureAnalysis{ 259 Id: id, 260 } 261 So(datastore.Put(c, cfa), ShouldBeNil) 262 datastore.GetTestable(c).CatchupIndexes() 263 return cfa 264 } 265 266 func createCompileFailureAnalysisModelWithStatus(c context.Context, id int64, status pb.AnalysisStatus, runStatus pb.AnalysisRunStatus) *model.CompileFailureAnalysis { 267 cfa := &model.CompileFailureAnalysis{ 268 Id: id, 269 Status: status, 270 RunStatus: runStatus, 271 } 272 So(datastore.Put(c, cfa), ShouldBeNil) 273 datastore.GetTestable(c).CatchupIndexes() 274 return cfa 275 } 276 277 func createHeuristicAnalysis(c context.Context, cfa *model.CompileFailureAnalysis, status pb.AnalysisStatus, runStatus pb.AnalysisRunStatus) *model.CompileHeuristicAnalysis { 278 ha := &model.CompileHeuristicAnalysis{ 279 ParentAnalysis: datastore.KeyForObj(c, cfa), 280 Status: status, 281 RunStatus: runStatus, 282 } 283 So(datastore.Put(c, ha), ShouldBeNil) 284 datastore.GetTestable(c).CatchupIndexes() 285 return ha 286 } 287 288 func createNthSectionAnalysis(c context.Context, cfa *model.CompileFailureAnalysis, status pb.AnalysisStatus, runStatus pb.AnalysisRunStatus) *model.CompileNthSectionAnalysis { 289 nsa := &model.CompileNthSectionAnalysis{ 290 ParentAnalysis: datastore.KeyForObj(c, cfa), 291 Status: status, 292 RunStatus: runStatus, 293 } 294 So(datastore.Put(c, nsa), ShouldBeNil) 295 datastore.GetTestable(c).CatchupIndexes() 296 return nsa 297 } 298 299 func createUnfinishedRerun(c context.Context, cfa *model.CompileFailureAnalysis) { 300 rerun := &model.SingleRerun{ 301 Analysis: datastore.KeyForObj(c, cfa), 302 Status: pb.RerunStatus_RERUN_STATUS_IN_PROGRESS, 303 } 304 So(datastore.Put(c, rerun), ShouldBeNil) 305 datastore.GetTestable(c).CatchupIndexes() 306 } 307 308 func checkUpdateAnalysisStatus(c context.Context, cfa *model.CompileFailureAnalysis, expectedStatus pb.AnalysisStatus, expectedRunStatus pb.AnalysisRunStatus) { 309 err := UpdateAnalysisStatus(c, cfa) 310 So(err, ShouldBeNil) 311 So(cfa.Status, ShouldEqual, expectedStatus) 312 So(cfa.RunStatus, ShouldEqual, expectedRunStatus) 313 }