aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2023-01-26 15:19:50 +0100
committerAleksandr Nogikh <wp32pw@gmail.com>2023-01-27 17:31:25 +0100
commitc630e2bf7a6cb84eec2005e2e66e35e0d88054cb (patch)
tree4ac778adfd375a6fc46389ee36240384753558d5
parente40567a5893b3aa8372771183a9a2ee9f075895a (diff)
dashboard: test subsystem filtering
In order to do that, we need to tweak the subsystem extraction code. Use context values, as this should simplify the flow.
-rw-r--r--dashboard/app/api.go10
-rw-r--r--dashboard/app/main_test.go81
-rw-r--r--dashboard/app/util_test.go15
3 files changed, 100 insertions, 6 deletions
diff --git a/dashboard/app/api.go b/dashboard/app/api.go
index 2980e4234..bdb7354bf 100644
--- a/dashboard/app/api.go
+++ b/dashboard/app/api.go
@@ -758,7 +758,7 @@ func reportCrash(c context.Context, build *Build, req *dashapi.Crash) (*Bug, err
bug.NumCrashes%20 == 0 ||
!stringInList(bug.MergedTitles, req.Title)
if save {
- newSubsystems = detectCrashSubsystems(req, build)
+ newSubsystems = detectCrashSubsystems(c, req, build)
log.Infof(c, "determined subsystems: %q", newSubsystems)
if err := saveCrash(c, ns, req, bug, bugKey, build, assets); err != nil {
return nil, err
@@ -821,7 +821,13 @@ func parseCrashAssets(c context.Context, req *dashapi.Crash) ([]Asset, error) {
return assets, nil
}
-func detectCrashSubsystems(req *dashapi.Crash, build *Build) []string {
+const overrideSubsystemsKey = "set_subsystems"
+
+func detectCrashSubsystems(c context.Context, req *dashapi.Crash, build *Build) []string {
+ val, ok := c.Value(overrideSubsystemsKey).([]string)
+ if ok {
+ return val
+ }
if build.OS == targets.Linux {
extractor := subsystem.MakeLinuxSubsystemExtractor()
return extractor.Extract(&subsystem.Crash{
diff --git a/dashboard/app/main_test.go b/dashboard/app/main_test.go
index 1629bab31..d344f4ce2 100644
--- a/dashboard/app/main_test.go
+++ b/dashboard/app/main_test.go
@@ -75,3 +75,84 @@ func TestOnlyManagerFilter(t *testing.T) {
t.Fatalf("%#v is not contained on the invalid bugs page", crash2.Title)
}
}
+
+func TestSubsystemFilterMain(t *testing.T) {
+ c := NewCtx(t)
+ defer c.Close()
+
+ subsystemA, subsystemB := "subsystemA", "subsystemB"
+
+ client := c.client
+ build := testBuild(1)
+ client.UploadBuild(build)
+
+ crash1 := testCrash(build, 1)
+ crash1.Title = "first bug"
+ c.contextVars[overrideSubsystemsKey] = []string{subsystemA}
+ client.ReportCrash(crash1)
+
+ crash2 := testCrash(build, 2)
+ c.contextVars[overrideSubsystemsKey] = []string{subsystemB}
+ crash2.Title = "second bug"
+ client.ReportCrash(crash2)
+
+ client.pollBugs(2)
+ // Make sure all those bugs are present on the main page.
+ reply, err := c.AuthGET(AccessAdmin, "/test1")
+ c.expectOK(err)
+ for _, title := range []string{crash1.Title, crash2.Title} {
+ if !bytes.Contains(reply, []byte(title)) {
+ t.Fatalf("%#v is not contained on the main page", title)
+ }
+ }
+ // Check that filtering on the main page works.
+ reply, err = c.AuthGET(AccessAdmin, "/test1?subsystem="+subsystemA)
+ c.expectOK(err)
+ for _, title := range []string{crash2.Title} {
+ if bytes.Contains(reply, []byte(title)) {
+ t.Fatalf("%#v is contained on the main page", title)
+ }
+ }
+ if !bytes.Contains(reply, []byte(crash1.Title)) {
+ t.Fatalf("%#v is not contained on the main page", crash2.Title)
+ }
+}
+
+func TestSubsystemFilterTerminal(t *testing.T) {
+ c := NewCtx(t)
+ defer c.Close()
+
+ subsystemA, subsystemB := "subsystemA", "subsystemB"
+
+ client := c.client
+ build := testBuild(1)
+ client.UploadBuild(build)
+
+ crash1 := testCrash(build, 1)
+ crash1.Title = "first bug"
+ c.contextVars[overrideSubsystemsKey] = []string{subsystemA}
+ client.ReportCrash(crash1)
+
+ crash2 := testCrash(build, 2)
+ c.contextVars[overrideSubsystemsKey] = []string{subsystemB}
+ crash2.Title = "second bug"
+ client.ReportCrash(crash2)
+
+ // Invalidate all these bugs.
+ polledBugs := client.pollBugs(2)
+ for _, bug := range polledBugs {
+ client.updateBug(bug.ID, dashapi.BugStatusInvalid, "")
+ }
+
+ // Verify that the filtering works on the invalid bugs page.
+ reply, err := c.AuthGET(AccessAdmin, "/test1/invalid?subsystem="+subsystemB)
+ c.expectOK(err)
+ for _, title := range []string{crash1.Title} {
+ if bytes.Contains(reply, []byte(title)) {
+ t.Fatalf("%#v is contained on the invalid bugs page", title)
+ }
+ }
+ if !bytes.Contains(reply, []byte(crash2.Title)) {
+ t.Fatalf("%#v is not contained on the invalid bugs page", crash2.Title)
+ }
+}
diff --git a/dashboard/app/util_test.go b/dashboard/app/util_test.go
index af9bbc2e3..d01fb0d27 100644
--- a/dashboard/app/util_test.go
+++ b/dashboard/app/util_test.go
@@ -38,6 +38,7 @@ type Ctx struct {
ctx context.Context
mockedTime time.Time
emailSink chan *aemail.Message
+ contextVars map[interface{}]interface{}
client *apiClient
client2 *apiClient
publicClient *apiClient
@@ -67,10 +68,11 @@ func NewCtx(t *testing.T) *Ctx {
t.Fatal(err)
}
c := &Ctx{
- t: t,
- inst: inst,
- mockedTime: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
- emailSink: make(chan *aemail.Message, 100),
+ t: t,
+ inst: inst,
+ mockedTime: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
+ contextVars: make(map[interface{}]interface{}),
+ emailSink: make(chan *aemail.Message, 100),
}
c.client = c.makeClient(client1, password1, true)
c.client2 = c.makeClient(client2, password2, true)
@@ -374,6 +376,11 @@ type apiClient struct {
func (c *Ctx) makeClient(client, key string, failOnErrors bool) *apiClient {
doer := func(r *http.Request) (*http.Response, error) {
r = registerRequest(r, c)
+ newCtx := r.Context()
+ for key, val := range c.contextVars {
+ newCtx = context.WithValue(newCtx, key, val)
+ }
+ r = r.WithContext(newCtx)
w := httptest.NewRecorder()
http.DefaultServeMux.ServeHTTP(w, r)
res := &http.Response{