diff options
| author | Zubin Mithra <zsm@chromium.org> | 2019-08-27 15:06:58 -0700 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2019-08-28 15:34:44 -0700 |
| commit | cd626f3ba9f85027426d4fbed73e79e523e8e138 (patch) | |
| tree | 7fa491ebe2f5cb428095e5e40fe9abc08da7d0e6 | |
| parent | 40203c152e000af463142886c75e346fbaaae7a7 (diff) | |
dashboard/app: retry BisectFix if crash still occurs on ToT
If a crash occurs on ToT when doing fix bisection, retry the job after
30 days. Add TestBisectFixRetry() to ensure that jobs are retried after
30 days if bisection results in crash on ToT.
| -rw-r--r-- | dashboard/app/jobs.go | 11 | ||||
| -rw-r--r-- | dashboard/app/jobs_test.go | 64 |
2 files changed, 75 insertions, 0 deletions
diff --git a/dashboard/app/jobs.go b/dashboard/app/jobs.go index 9f8dab51e..b8846cc59 100644 --- a/dashboard/app/jobs.go +++ b/dashboard/app/jobs.go @@ -507,6 +507,9 @@ func doneJob(c context.Context, req *dashapi.JobDoneReq) error { } else { bug.BisectFix = result } + // If the crash still occurs on HEAD, update the bug's LastTime so that it will be + // retried after 30 days. + crashesOnHead(c, bug, job, req, now) if _, err := db.Put(c, bugKey, bug); err != nil { return fmt.Errorf("failed to put bug: %v", err) } @@ -536,6 +539,14 @@ func doneJob(c context.Context, req *dashapi.JobDoneReq) error { return db.RunInTransaction(c, tx, &db.TransactionOptions{XG: true, Attempts: 30}) } +func crashesOnHead(c context.Context, bug *Bug, job *Job, req *dashapi.JobDoneReq, now time.Time) { + if job.Type != JobBisectFix || req.Error != nil || len(req.Commits) != 0 || len(req.CrashLog) == 0 { + return + } + bug.BisectFix = BisectNot + bug.LastTime = now +} + func pollCompletedJobs(c context.Context, typ string) ([]*dashapi.BugReport, error) { var jobs []*Job keys, err := db.NewQuery("Job"). diff --git a/dashboard/app/jobs_test.go b/dashboard/app/jobs_test.go index 54f2a679f..d52f93b30 100644 --- a/dashboard/app/jobs_test.go +++ b/dashboard/app/jobs_test.go @@ -405,3 +405,67 @@ func TestBisectFixJob(t *testing.T) { } c.client2.expectOK(c.client2.JobDone(done)) } + +// Test that JobBisectFix jobs are re-tried if crash occurs on ToT +func TestBisectFixRetry(t *testing.T) { + c := NewCtx(t) + defer c.Close() + + // Upload a crash report + build := testBuild(1) + c.client2.UploadBuild(build) + crash := testCrashWithRepro(build, 1) + c.client2.ReportCrash(crash) + c.client2.pollEmailBug() + + // Receive the JobBisectCause + resp := c.client2.pollJobs(build.Manager) + c.client2.expectNE(resp.ID, "") + c.client2.expectEQ(resp.Type, dashapi.JobBisectCause) + done := &dashapi.JobDoneReq{ + ID: resp.ID, + Error: []byte("testBisectFixRetry:JobBisectCause"), + } + c.client2.expectOK(c.client2.JobDone(done)) + + // Advance time by 30 days and read out any notification emails + { + c.advanceTime(30 * 24 * time.Hour) + msg := c.client2.pollEmailBug() + c.expectEQ(msg.Subject, "title1") + c.expectTrue(strings.Contains(msg.Body, "Sending this report upstream.")) + + msg = c.client2.pollEmailBug() + c.expectEQ(msg.Subject, "title1") + c.expectTrue(strings.Contains(msg.Body, "syzbot found the following crash")) + } + + // Ensure that we get a JobBisectFix. We send back a crashlog, no error, no commits + resp = c.client2.pollJobs(build.Manager) + c.client2.expectNE(resp.ID, "") + c.client2.expectEQ(resp.Type, dashapi.JobBisectFix) + done = &dashapi.JobDoneReq{ + Build: dashapi.Build{ + ID: "build1", + }, + ID: resp.ID, + CrashLog: []byte("this is a crashlog"), + CrashReport: []byte("this is a crashreport"), + } + c.client2.expectOK(c.client2.JobDone(done)) + + // Advance time by 30 days. No notification emails + { + c.advanceTime(30 * 24 * time.Hour) + } + + // Ensure that we get a JobBisectFix retry + resp = c.client2.pollJobs(build.Manager) + c.client2.expectNE(resp.ID, "") + c.client2.expectEQ(resp.Type, dashapi.JobBisectFix) + done = &dashapi.JobDoneReq{ + ID: resp.ID, + Error: []byte("testBisectFixRetry:JobBisectFix"), + } + c.client2.expectOK(c.client2.JobDone(done)) +} |
