diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2022-12-22 11:35:38 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2023-01-11 13:14:11 +0100 |
| commit | 96166539c4c242fccd41c7316b7080377dca428b (patch) | |
| tree | f1d80628667c9daa66d80b6c0f8df7ea5cc72de4 /dashboard | |
| parent | 48bc529a18de54dddab161d995fc3abd85a670a8 (diff) | |
dashboard: support the only_manager filter
The manager= filter limits the dashboard output only to the bugs that
happened on the specified manager (but not exclusively there).
Introduce the only_manager= filter to only show the bugs that happened
ONLY on the specified manager.
Diffstat (limited to 'dashboard')
| -rw-r--r-- | dashboard/app/main.go | 37 | ||||
| -rw-r--r-- | dashboard/app/main_test.go | 77 |
2 files changed, 105 insertions, 9 deletions
diff --git a/dashboard/app/main.go b/dashboard/app/main.go index a74ee39df..1448796c6 100644 --- a/dashboard/app/main.go +++ b/dashboard/app/main.go @@ -299,12 +299,16 @@ func handleMain(c context.Context, w http.ResponseWriter, r *http.Request) error return err } accessLevel := accessLevel(c, r) - manager := r.FormValue("manager") + onlyManager := r.FormValue("only_manager") + manager := onlyManager + if manager == "" { + manager = r.FormValue("manager") + } managers, err := loadManagers(c, accessLevel, hdr.Namespace, manager) if err != nil { return err } - groups, err := fetchNamespaceBugs(c, accessLevel, hdr.Namespace, manager) + groups, err := fetchNamespaceBugs(c, accessLevel, hdr.Namespace, manager, onlyManager != "") if err != nil { return err } @@ -360,6 +364,8 @@ type TerminalBug struct { ShowPatch bool ShowPatched bool ShowStats bool + Manager string + OneManager bool } func handleTerminalBugList(c context.Context, w http.ResponseWriter, r *http.Request, typ *TerminalBug) error { @@ -369,16 +375,22 @@ func handleTerminalBugList(c context.Context, w http.ResponseWriter, r *http.Req return err } hdr.Subpage = typ.Subpage - manager := r.FormValue("manager") + onlyManager := r.FormValue("only_manager") + if onlyManager != "" { + typ.Manager = onlyManager + typ.OneManager = true + } else { + typ.Manager = r.FormValue("manager") + } extraBugs := []*Bug{} if typ.Status == BugStatusFixed { // Mix in bugs that have pending fixes. - extraBugs, err = fetchFixPendingBugs(c, hdr.Namespace, manager) + extraBugs, err = fetchFixPendingBugs(c, hdr.Namespace, typ.Manager) if err != nil { return err } } - bugs, stats, err := fetchTerminalBugs(c, accessLevel, hdr.Namespace, manager, typ, extraBugs) + bugs, stats, err := fetchTerminalBugs(c, accessLevel, hdr.Namespace, typ, extraBugs) if err != nil { return err } @@ -796,7 +808,8 @@ func fetchFixPendingBugs(c context.Context, ns, manager string) ([]*Bug, error) return rawBugs, nil } -func fetchNamespaceBugs(c context.Context, accessLevel AccessLevel, ns, manager string) ([]*uiBugGroup, error) { +func fetchNamespaceBugs(c context.Context, accessLevel AccessLevel, ns, + manager string, oneManager bool) ([]*uiBugGroup, error) { bugs, err := loadVisibleBugs(c, accessLevel, ns, manager) if err != nil { return nil, err @@ -820,6 +833,9 @@ func fetchNamespaceBugs(c context.Context, accessLevel AccessLevel, ns, manager dups = append(dups, bug) continue } + if oneManager && len(bug.HappenedOn) > 1 { + continue + } uiBug := createUIBug(c, bug, state, managers) if len(uiBug.Commits) != 0 { // Don't show "fix pending" bugs on the main page. @@ -914,12 +930,12 @@ func loadVisibleBugs(c context.Context, accessLevel AccessLevel, ns, manager str } func fetchTerminalBugs(c context.Context, accessLevel AccessLevel, - ns, manager string, typ *TerminalBug, extraBugs []*Bug) (*uiBugGroup, *uiBugStats, error) { + ns string, typ *TerminalBug, extraBugs []*Bug) (*uiBugGroup, *uiBugStats, error) { bugs, _, err := loadAllBugs(c, func(query *db.Query) *db.Query { query = query.Filter("Namespace=", ns). Filter("Status=", typ.Status) - if manager != "" { - query = query.Filter("HappenedOn=", manager) + if typ.Manager != "" { + query = query.Filter("HappenedOn=", typ.Manager) } return query }) @@ -955,6 +971,9 @@ func fetchTerminalBugs(c context.Context, accessLevel AccessLevel, if accessLevel < bug.sanitizeAccess(accessLevel) { continue } + if typ.OneManager && len(bug.HappenedOn) > 1 { + continue + } uiBug := createUIBug(c, bug, state, managers) res.Bugs = append(res.Bugs, uiBug) stats.Record(bug, &bug.Reporting[uiBug.ReportingIndex]) diff --git a/dashboard/app/main_test.go b/dashboard/app/main_test.go new file mode 100644 index 000000000..1629bab31 --- /dev/null +++ b/dashboard/app/main_test.go @@ -0,0 +1,77 @@ +// Copyright 2023 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +package main + +import ( + "bytes" + "testing" + + "github.com/google/syzkaller/dashboard/dashapi" +) + +func TestOnlyManagerFilter(t *testing.T) { + c := NewCtx(t) + defer c.Close() + + client := c.client + build1 := testBuild(1) + client.UploadBuild(build1) + build2 := testBuild(2) + client.UploadBuild(build2) + + crash1 := testCrash(build1, 1) + crash1.Title = "only the first manager" + client.ReportCrash(crash1) + + crash2 := testCrash(build2, 2) + crash2.Title = "only the second manager" + client.ReportCrash(crash2) + + crashBoth1 := testCrash(build1, 3) + crashBoth1.Title = "both managers" + client.ReportCrash(crashBoth1) + + crashBoth2 := testCrash(build2, 4) + crashBoth2.Title = "both managers" + client.ReportCrash(crashBoth2) + + // 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, crashBoth1.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?only_manager="+build1.Manager) + c.expectOK(err) + for _, title := range []string{crash2.Title, crashBoth1.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", crash1.Title) + } + + // Invalidate all these bugs. + polledBugs := client.pollBugs(3) + 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?only_manager="+build2.Manager) + c.expectOK(err) + for _, title := range []string{crash1.Title, crashBoth1.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) + } +} |
