From c630e2bf7a6cb84eec2005e2e66e35e0d88054cb Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Thu, 26 Jan 2023 15:19:50 +0100 Subject: 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. --- dashboard/app/api.go | 10 ++++-- dashboard/app/main_test.go | 81 ++++++++++++++++++++++++++++++++++++++++++++++ dashboard/app/util_test.go | 15 ++++++--- 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{ -- cgit mrf-deployment