aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2024-01-18 16:08:31 +0100
committerAleksandr Nogikh <nogikh@google.com>2024-01-18 15:20:48 +0000
commitdf0ec93c2662a5189ec2077aee2bf823e392bf25 (patch)
tree7df2f1cbf0751082643a1d9e9fa15dd960eff5b0
parenta5da85e3ce72a6f1362d33d098de56123034c2c1 (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.go10
-rw-r--r--dashboard/app/reporting.go3
-rw-r--r--dashboard/app/reporting_test.go36
-rw-r--r--dashboard/app/util_test.go11
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)