diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2024-01-18 16:08:31 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2024-01-18 15:20:48 +0000 |
| commit | df0ec93c2662a5189ec2077aee2bf823e392bf25 (patch) | |
| tree | 7df2f1cbf0751082643a1d9e9fa15dd960eff5b0 | |
| parent | a5da85e3ce72a6f1362d33d098de56123034c2c1 (diff) | |
dashboard: wait for repro only when it makes sense
In case or build/boot/test errors there will never be a reproducer.
It's better to report them right away, without waiting.
| -rw-r--r-- | dashboard/app/jobs.go | 10 | ||||
| -rw-r--r-- | dashboard/app/reporting.go | 3 | ||||
| -rw-r--r-- | dashboard/app/reporting_test.go | 36 | ||||
| -rw-r--r-- | dashboard/app/util_test.go | 11 |
4 files changed, 56 insertions, 4 deletions
diff --git a/dashboard/app/jobs.go b/dashboard/app/jobs.go index 416f6ba1f..c5f50c013 100644 --- a/dashboard/app/jobs.go +++ b/dashboard/app/jobs.go @@ -223,11 +223,15 @@ func patchTestJobArgs(c context.Context, args *testJobArgs) error { return nil } +func crashNeedsRepro(title string) bool { + return !strings.Contains(title, "boot error:") && + !strings.Contains(title, "test error:") && + !strings.Contains(title, "build error") +} + func checkTestJob(args *testJobArgs) string { crash, bug := args.crash, args.bug - needRepro := !strings.Contains(crash.Title, "boot error:") && - !strings.Contains(crash.Title, "test error:") && - !strings.Contains(crash.Title, "build error") + needRepro := crashNeedsRepro(crash.Title) switch { case needRepro && crash.ReproC == 0 && crash.ReproSyz == 0: return "This crash does not have a reproducer. I cannot test it." diff --git a/dashboard/app/reporting.go b/dashboard/app/reporting.go index f2f4d7931..ccb7fa1ea 100644 --- a/dashboard/app/reporting.go +++ b/dashboard/app/reporting.go @@ -120,7 +120,8 @@ func needReport(c context.Context, typ string, state *ReportingState, bug *Bug) reporting, bugReporting = nil, nil return } - if bug.ReproLevel < ReproLevelC && timeSince(c, bug.FirstTime) < cfg.WaitForRepro { + if crashNeedsRepro(bug.Title) && bug.ReproLevel < ReproLevelC && + timeSince(c, bug.FirstTime) < cfg.WaitForRepro { status = fmt.Sprintf("%v: waiting for C repro", reporting.DisplayTitle) reporting, bugReporting = nil, nil return diff --git a/dashboard/app/reporting_test.go b/dashboard/app/reporting_test.go index 343310d15..c0d419418 100644 --- a/dashboard/app/reporting_test.go +++ b/dashboard/app/reporting_test.go @@ -1264,3 +1264,39 @@ func TestReportRevokedRepro(t *testing.T) { // Expect no further reports. client.pollBugs(0) } + +func TestWaitForRepro(t *testing.T) { + c := NewCtx(t) + defer c.Close() + + client := c.client + c.setWaitForRepro("test1", time.Hour*24) + + build := testBuild(1) + client.UploadBuild(build) + + // Normal crash witout repro. + client.ReportCrash(testCrash(build, 1)) + client.pollBugs(0) + c.advanceTime(time.Hour * 24) + client.pollBug() + + // A crash first without repro, then with it. + client.ReportCrash(testCrash(build, 2)) + c.advanceTime(time.Hour * 12) + client.pollBugs(0) + client.ReportCrash(testCrashWithRepro(build, 2)) + client.pollBug() + + // A crash with a reproducer. + c.advanceTime(time.Minute) + client.ReportCrash(testCrashWithRepro(build, 3)) + client.pollBug() + + // A crahs that will never have a reproducer. + c.advanceTime(time.Minute) + crash := testCrash(build, 4) + crash.Title = "upstream test error: abcd" + client.ReportCrash(crash) + client.pollBug() +} diff --git a/dashboard/app/util_test.go b/dashboard/app/util_test.go index 41b2032f0..9e180095b 100644 --- a/dashboard/app/util_test.go +++ b/dashboard/app/util_test.go @@ -274,6 +274,17 @@ func (c *Ctx) decommission(ns string) { } } +func (c *Ctx) setWaitForRepro(ns string, d time.Duration) { + c.transformContext = func(c context.Context) context.Context { + newConfig := replaceNamespaceConfig(c, ns, func(cfg *Config) *Config { + ret := *cfg + ret.WaitForRepro = d + return &ret + }) + return contextWithConfig(c, newConfig) + } +} + // GET sends admin-authorized HTTP GET request to the app. func (c *Ctx) GET(url string) ([]byte, error) { return c.AuthGET(AccessAdmin, url) |
