go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/bisection/culpritverification/test_failure_verify_culprit.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 culpritverification performs culprit verification for test failures. 16 package culpritverification 17 18 import ( 19 "context" 20 21 "go.chromium.org/luci/bisection/model" 22 tpb "go.chromium.org/luci/bisection/task/proto" 23 "go.chromium.org/luci/bisection/testfailureanalysis/bisection" 24 "go.chromium.org/luci/bisection/testfailureanalysis/bisection/projectbisector" 25 "go.chromium.org/luci/bisection/util/datastoreutil" 26 "go.chromium.org/luci/bisection/util/loggingutil" 27 "go.chromium.org/luci/common/errors" 28 "go.chromium.org/luci/common/logging" 29 "go.chromium.org/luci/gae/service/datastore" 30 ) 31 32 func processTestFailureTask(ctx context.Context, task *tpb.TestFailureCulpritVerificationTask) error { 33 analysisID := task.AnalysisId 34 ctx = loggingutil.SetAnalysisID(ctx, analysisID) 35 logging.Infof(ctx, "Processing culprit verification for test failure bisection task") 36 // TODO(beining@): set analysis status on error. 37 // Retrieves analysis from datastore. 38 tfa, err := datastoreutil.GetTestFailureAnalysis(ctx, analysisID) 39 if err != nil { 40 return errors.Annotate(err, "get test failure analysis").Err() 41 } 42 43 // Retrieves suspect. 44 suspect, err := datastoreutil.GetSuspectForTestAnalysis(ctx, tfa) 45 if err != nil || suspect == nil { 46 return errors.Annotate(err, "couldn't get suspect").Err() 47 } 48 49 return verifyTestFailureSuspect(ctx, tfa, suspect) 50 } 51 52 func verifyTestFailureSuspect(ctx context.Context, tfa *model.TestFailureAnalysis, suspect *model.Suspect) error { 53 projectBisector, err := bisection.GetProjectBisector(ctx, tfa) 54 if err != nil { 55 return errors.Annotate(err, "get project bisector").Err() 56 } 57 // Get test failure bundle. 58 bundle, err := datastoreutil.GetTestFailureBundle(ctx, tfa) 59 if err != nil { 60 return errors.Annotate(err, "get test failure bundle").Err() 61 } 62 // Only rerun the non-diverged test failures. 63 tfs := bundle.NonDiverged() 64 commit := &suspect.GitilesCommit 65 option := projectbisector.RerunOption{ 66 FullRun: true, 67 } 68 suspectBuild, err := projectBisector.TriggerRerun(ctx, tfa, tfs, commit, option) 69 if err != nil { 70 return errors.Annotate(err, "trigger suspect rerun for commit %s", commit.Id).Err() 71 } 72 73 parentCommit, err := getParentCommit(ctx, commit) 74 if err != nil { 75 return errors.Annotate(err, "get parent commit for commit %s", commit.Id).Err() 76 } 77 parentBuild, err := projectBisector.TriggerRerun(ctx, tfa, tfs, parentCommit, option) 78 if err != nil { 79 return errors.Annotate(err, "trigger parent rerun for commit %s", parentCommit.Id).Err() 80 } 81 82 // Save rerun models. 83 options := bisection.CreateRerunModelOptions{ 84 TestFailureAnalysis: tfa, 85 SuspectKey: datastore.KeyForObj(ctx, suspect), 86 TestFailures: tfs, 87 Build: suspectBuild, 88 RerunType: model.RerunBuildType_CulpritVerification, 89 } 90 suspectRerun, err := bisection.CreateTestRerunModel(ctx, options) 91 if err != nil { 92 return errors.Annotate(err, "create test rerun model for suspect rerun").Err() 93 } 94 options.Build = parentBuild 95 parentRerun, err := bisection.CreateTestRerunModel(ctx, options) 96 if err != nil { 97 return errors.Annotate(err, "create test rerun model for parent rerun").Err() 98 } 99 100 // Update suspect. 101 return datastore.RunInTransaction(ctx, func(ctx context.Context) error { 102 e := datastore.Get(ctx, suspect) 103 if e != nil { 104 return e 105 } 106 suspect.VerificationStatus = model.SuspectVerificationStatus_UnderVerification 107 suspect.SuspectRerunBuild = datastore.KeyForObj(ctx, suspectRerun) 108 suspect.ParentRerunBuild = datastore.KeyForObj(ctx, parentRerun) 109 return datastore.Put(ctx, suspect) 110 }, nil) 111 }