aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dashboard/app/jobs.go57
-rw-r--r--dashboard/app/jobs_test.go21
2 files changed, 44 insertions, 34 deletions
diff --git a/dashboard/app/jobs.go b/dashboard/app/jobs.go
index dce164bfc..db821b4c8 100644
--- a/dashboard/app/jobs.go
+++ b/dashboard/app/jobs.go
@@ -302,7 +302,9 @@ func handleRetestForBug(c context.Context, now time.Time, bug *Bug, bugKey *db.K
if managerHasJob[crash.Manager] {
continue
}
- build, err := loadBuild(c, bug.Namespace, crash.BuildID)
+ // Take the last successful build -- the build on which this crash happened
+ // might contain already obsolete repro and branch values.
+ build, err := lastManagerBuild(c, bug.Namespace, crash.Manager)
if err != nil {
return err
}
@@ -567,42 +569,38 @@ func createJobResp(c context.Context, job *Job, jobKey *db.Key) (*dashapi.JobPol
// miss the situation when some actual user sends a patch testing request without
// patch.
func isRetestReproJob(job *Job, build *Build) bool {
- return job.Type == JobTestPatch &&
+ return (job.Type == JobTestPatch || job.Type == JobBisectFix) &&
job.Patch == 0 &&
job.KernelRepo == build.KernelRepo &&
job.KernelBranch == build.KernelBranch
}
-func handleRetestedRepro(c context.Context, now time.Time, job *Job, jobKey *db.Key, req *dashapi.JobDoneReq) error {
+func handleRetestedRepro(c context.Context, now time.Time, job *Job, jobKey *db.Key,
+ lastBuild *Build, req *dashapi.JobDoneReq) error {
bugKey := jobKey.Parent()
crashKey := db.NewKey(c, "Crash", "", job.CrashID, bugKey)
crash := new(Crash)
if err := db.Get(c, crashKey, crash); err != nil {
return fmt.Errorf("failed to get crash: %v", crashKey)
}
- build, err := loadBuild(c, job.Namespace, crash.BuildID)
- if err != nil {
- return fmt.Errorf("failed to query build: %w", err)
- }
- if !isRetestReproJob(job, build) {
- return nil
- }
bug := new(Bug)
if err := db.Get(c, bugKey, bug); err != nil {
return fmt.Errorf("failed to get bug: %v", bugKey)
}
- if !config.Namespaces[bug.Namespace].RetestRepros {
- return nil
- }
+ allTitles := gatherCrashTitles(req)
// Update the crash.
crash.LastReproRetest = now
- allTitles := gatherCrashTitles(req)
- if req.Error == nil && len(allTitles) == 0 {
- // If there was any crash at all, the repro is still not worth discarding.
- // Also, if repro testing itself failed, it might be just a temporary issue.
- crash.ReproIsRevoked = true
+ if req.Error == nil && !crash.ReproIsRevoked {
+ // If repro testing itself failed, it might be just a temporary issue.
+ if job.Type == JobTestPatch {
+ // If there was any crash at all, the repro is still not worth discarding.
+ crash.ReproIsRevoked = len(allTitles) == 0
+ } else if job.Type == JobBisectFix {
+ // More than one commit is suspected => repro stopped working at some point.
+ crash.ReproIsRevoked = len(req.Commits) > 0
+ }
}
- crash.UpdateReportingPriority(build, bug)
+ crash.UpdateReportingPriority(lastBuild, bug)
if _, err := db.Put(c, crashKey, crash); err != nil {
return fmt.Errorf("failed to put crash: %v", err)
}
@@ -652,6 +650,16 @@ func doneJob(c context.Context, req *dashapi.JobDoneReq) error {
if err != nil {
return err
}
+ // Datastore prohibits cross-group queries even inside XG transactions.
+ // So we have to query last build for the manager before the transaction.
+ job := new(Job)
+ if err := db.Get(c, jobKey, job); err != nil {
+ return fmt.Errorf("job %v: failed to get job: %v", jobID, err)
+ }
+ lastBuild, err := lastManagerBuild(c, job.Namespace, job.Manager)
+ if err != nil {
+ return err
+ }
now := timeNow(c)
tx := func(c context.Context) error {
job := new(Job)
@@ -661,8 +669,8 @@ func doneJob(c context.Context, req *dashapi.JobDoneReq) error {
if !job.Finished.IsZero() {
return fmt.Errorf("job %v: already finished", jobID)
}
- if job.Type == JobTestPatch {
- err := handleRetestedRepro(c, now, job, jobKey, req)
+ if isRetestReproJob(job, lastBuild) {
+ err := handleRetestedRepro(c, now, job, jobKey, lastBuild, req)
if err != nil {
return fmt.Errorf("job %v: failed to handle retested repro, %w", jobID, err)
}
@@ -749,13 +757,6 @@ func updateBugBisection(c context.Context, job *Job, jobKey *db.Key, req *dashap
if _, err := db.Put(c, bugKey, bug); err != nil {
return fmt.Errorf("failed to put bug: %v", err)
}
- // The repro is not working on the HEAD commit anymore, update the repro status.
- if job.Type == JobBisectFix && req.Error == nil && len(req.Commits) > 0 {
- err := handleRetestedRepro(c, now, job, jobKey, req)
- if err != nil {
- return err
- }
- }
_, bugReporting, _, _, _ := currentReporting(c, bug)
// The bug is either already closed or not yet reported in the current reporting,
// either way we don't need to report it. If it wasn't reported, it will be reported
diff --git a/dashboard/app/jobs_test.go b/dashboard/app/jobs_test.go
index 31e4eafea..8bb9ec464 100644
--- a/dashboard/app/jobs_test.go
+++ b/dashboard/app/jobs_test.go
@@ -374,12 +374,12 @@ func TestReproRetestJob(t *testing.T) {
c := NewCtx(t)
defer c.Close()
- build := testBuild(1)
- build.KernelRepo = "git://mygit.com/git.git"
- build.KernelBranch = "main"
- c.client2.UploadBuild(build)
+ oldBuild := testBuild(1)
+ oldBuild.KernelRepo = "git://mygit.com/git.git"
+ oldBuild.KernelBranch = "main"
+ c.client2.UploadBuild(oldBuild)
- crash := testCrash(build, 1)
+ crash := testCrash(oldBuild, 1)
crash.ReproOpts = []byte("repro opts")
crash.ReproSyz = []byte("repro syz")
c.client2.ReportCrash(crash)
@@ -387,11 +387,20 @@ func TestReproRetestJob(t *testing.T) {
_, extBugID, err := email.RemoveAddrContext(sender)
c.expectOK(err)
- crash2 := testCrash(build, 1)
+ crash2 := testCrash(oldBuild, 1)
crash2.ReproOpts = []byte("repro opts")
crash2.ReproSyz = []byte("repro syz")
crash2.ReproC = []byte("repro C")
c.client2.ReportCrash(crash2)
+
+ // Upload a newer build.
+ c.advanceTime(time.Minute)
+ build := testBuild(1)
+ build.ID = "new-build"
+ build.KernelRepo = "git://mygit.com/new-git.git"
+ build.KernelBranch = "new-main"
+ c.client2.UploadBuild(build)
+
// Wait until the bug is upstreamed.
c.advanceTime(15 * 24 * time.Hour)
c.pollEmailBug()