diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2026-01-15 12:50:59 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2026-01-15 12:26:32 +0000 |
| commit | e30f059fce4242956bd289e6690b150ddc6cd0d5 (patch) | |
| tree | f68cba31f5d79a20e4dea1fe7860595de652a987 | |
| parent | 41cfbc00ddb9f36db18d9e02ddd517d65ae1177c (diff) | |
dashboard: add a manuallyUpstreamed helper
This helper function can be used in the reporting filtering rules to
skip certain reporting stages depending on whether the previous stage(s)
have been manually upstreamed.
Add tests that it does have the intended effect.
Cc #6554.
| -rw-r--r-- | dashboard/app/app_test.go | 40 | ||||
| -rw-r--r-- | dashboard/app/reporting.go | 8 | ||||
| -rw-r--r-- | dashboard/app/reporting_test.go | 50 |
3 files changed, 98 insertions, 0 deletions
diff --git a/dashboard/app/app_test.go b/dashboard/app/app_test.go index d4c9f765f..96861dfa5 100644 --- a/dashboard/app/app_test.go +++ b/dashboard/app/app_test.go @@ -631,6 +631,44 @@ var testConfig = &GlobalConfig{ }, }, }, + "skip-stage": { + AccessLevel: AccessPublic, + Key: "publickeypublickeypublickey", + Clients: map[string]string{ + clientSkipStage: keySkipStage, + }, + Repos: []KernelRepo{ + { + URL: "git://syzkaller.org/access-public.git", + Branch: "access-public", + Alias: "access-public", + }, + }, + Reporting: []Reporting{ + { + Name: "reporting1", + DailyLimit: 1000, + Config: &TestConfig{Index: 1}, + Embargo: 4 * 24 * time.Hour, + }, + { + Name: "reporting2", + DailyLimit: 1000, + Config: &TestConfig{Index: 2}, + Filter: func(bug *Bug) FilterResult { + if bug.manuallyUpstreamed("reporting1") { + return FilterSkip + } + return FilterReport + }, + }, + { + Name: "reporting3", + DailyLimit: 1000, + Config: &TestConfig{Index: 3}, + }, + }, + }, }, } @@ -683,6 +721,8 @@ const ( keyTreeTests = "keyTreeTestskeyTreeTestskeyTreeTests" clientAI = "client-ai" keyAI = "clientaikeyclientaikeyclientaikey" + clientSkipStage = "client-skip-stage" + keySkipStage = "skipstagekeyskipstagekeyskipstagekey" restrictedManager = "restricted-manager" noFixBisectionManager = "no-fix-bisection-manager" diff --git a/dashboard/app/reporting.go b/dashboard/app/reporting.go index 61bee541d..ad55ac6c3 100644 --- a/dashboard/app/reporting.go +++ b/dashboard/app/reporting.go @@ -387,6 +387,14 @@ func (bug *Bug) managerConfig(c context.Context) *ConfigManager { return &mgr } +func (bug *Bug) manuallyUpstreamed(name string) bool { + reporting := bugReportingByName(bug, name) + if reporting == nil { + return false + } + return !reporting.Closed.IsZero() && !reporting.Auto +} + func createNotification(c context.Context, typ dashapi.BugNotif, public bool, text string, bug *Bug, reporting *Reporting, bugReporting *BugReporting) (*dashapi.BugNotification, error) { reportingConfig, err := json.Marshal(reporting.Config) diff --git a/dashboard/app/reporting_test.go b/dashboard/app/reporting_test.go index b1400c705..211797488 100644 --- a/dashboard/app/reporting_test.go +++ b/dashboard/app/reporting_test.go @@ -1417,3 +1417,53 @@ Blocks diff, Path `, msg.Body) } + +func TestSkipStage(t *testing.T) { + // The test ensures that manuallyUpstreamed works as intended in reporting filters. + c := NewCtx(t) + defer c.Close() + client := c.makeClient(clientSkipStage, keySkipStage, true) + + build := testBuild(1) + client.UploadBuild(build) + + { + // Normal scenario - manual upstreaming. + client.ReportCrash(testCrash(build, 1)) + rep := client.pollBug() + c.expectEQ(string(rep.Config), `{"Index":1}`) + c.client.updateBug(rep.ID, dashapi.BugStatusUpstream, "") + client.pollNotifs(0) + rep = client.pollBug() + c.expectEQ(string(rep.Config), `{"Index":3}`) + c.client.updateBug(rep.ID, dashapi.BugStatusInvalid, "") + } + + { + // Auto-upstreamed. + client.ReportCrash(testCrash(build, 2)) + rep := client.pollBug() + c.expectEQ(string(rep.Config), `{"Index":1}`) + c.advanceTime(5 * 24 * time.Hour) + notifs := client.pollNotifs(1) + reply, _ := client.ReportingUpdate(&dashapi.BugUpdate{ + ID: notifs[0].ID, + Status: dashapi.BugStatusUpstream, + Notification: true, + }) + c.expectEQ(reply.OK, true) + rep = client.pollBug() + c.expectEQ(string(rep.Config), `{"Index":2}`) + c.client.updateBug(rep.ID, dashapi.BugStatusInvalid, "") + } + + { + // Manually invalidated. + client.ReportCrash(testCrash(build, 3)) + rep := client.pollBug() + c.expectEQ(string(rep.Config), `{"Index":1}`) + c.client.updateBug(rep.ID, dashapi.BugStatusInvalid, "") + client.pollNotifs(0) + client.pollBugs(0) + } +} |
