diff options
Diffstat (limited to 'dashboard')
| -rw-r--r-- | dashboard/app/jobs.go | 38 | ||||
| -rw-r--r-- | dashboard/app/jobs_test.go | 68 |
2 files changed, 94 insertions, 12 deletions
diff --git a/dashboard/app/jobs.go b/dashboard/app/jobs.go index 6d2efc75a..f97f443ad 100644 --- a/dashboard/app/jobs.go +++ b/dashboard/app/jobs.go @@ -95,17 +95,10 @@ func addTestJob(c context.Context, args *testJobArgs, now time.Time) error { args.repo, args.branch); reason != "" { return &BadTestRequestError{reason} } - manager := args.crash.Manager - for _, ns := range config.Namespaces { - if mgr, ok := ns.Managers[manager]; ok { - if mgr.RestrictedTestingRepo != "" && args.repo != mgr.RestrictedTestingRepo { - return &BadTestRequestError{mgr.RestrictedTestingReason} - } - if mgr.Decommissioned { - manager = mgr.DelegatedTo - } - break - } + manager, mgrConfig := activeManager(args.crash.Manager, args.bug.Namespace) + if mgrConfig != nil && mgrConfig.RestrictedTestingRepo != "" && + args.repo != mgrConfig.RestrictedTestingRepo { + return &BadTestRequestError{mgrConfig.RestrictedTestingReason} } patchID, err := putText(c, args.bug.Namespace, textPatch, args.patch, false) if err != nil { @@ -319,9 +312,14 @@ func handleRetestForBug(c context.Context, now time.Time, bug *Bug, bugKey *db.K if managerHasJob[crash.Manager] { continue } + // We could have decommissioned the original manager since then. + manager, _ := activeManager(crash.Manager, bug.Namespace) + if manager == "" { + continue + } // Take the last successful build -- the build on which this crash happened // might contain already obsolete repro and branch values. - build, err := lastManagerBuild(c, bug.Namespace, crash.Manager) + build, err := lastManagerBuild(c, bug.Namespace, manager) if err != nil { return err } @@ -1145,6 +1143,22 @@ func loadPendingJob(c context.Context, managers map[string]dashapi.ManagerJobs) return nil, nil, nil } +// activeManager determines the manager currently responsible for all bugs found by +// the specified manager. +func activeManager(manager, ns string) (string, *ConfigManager) { + nsConfig := config.Namespaces[ns] + if mgr, ok := nsConfig.Managers[manager]; ok { + if mgr.Decommissioned { + newMgr := nsConfig.Managers[mgr.DelegatedTo] + return mgr.DelegatedTo, &newMgr + } + return manager, &mgr + } + // This manager is not mentioned in the configuration, therefore it was + // definitely not decommissioned. + return manager, nil +} + func extJobID(jobKey *db.Key) string { return fmt.Sprintf("%v|%v", jobKey.Parent().StringID(), jobKey.IntID()) } diff --git a/dashboard/app/jobs_test.go b/dashboard/app/jobs_test.go index a473bc03b..961310724 100644 --- a/dashboard/app/jobs_test.go +++ b/dashboard/app/jobs_test.go @@ -488,6 +488,74 @@ func TestReproRetestJob(t *testing.T) { c.expectEQ(bug.StatusReason, dashapi.InvalidatedByRevokedRepro) } +func TestDelegatedManagerReproRetest(t *testing.T) { + c := NewCtx(t) + defer c.Close() + + client := c.client2 + oldManager := noFixBisectionManager + newManager := specialCCManager + + oldBuild := testBuild(1) + oldBuild.KernelRepo = "git://delegated.repo/git.git" + oldBuild.KernelBranch = "main" + oldBuild.Manager = oldManager + client.UploadBuild(oldBuild) + + crash := testCrash(oldBuild, 1) + crash.ReproOpts = []byte("repro opts") + crash.ReproSyz = []byte("repro syz") + crash.ReproC = []byte("repro C") + client.ReportCrash(crash) + sender := c.pollEmailBug().Sender + _, extBugID, err := email.RemoveAddrContext(sender) + c.expectOK(err) + + // Deprecate the oldManager. + mgrConfig := config.Namespaces["test2"].Managers[oldManager] + mgrConfig.Decommissioned = true + mgrConfig.DelegatedTo = newManager + config.Namespaces["test2"].Managers[oldManager] = mgrConfig + + // Upload a build for the new manager. + c.advanceTime(time.Minute) + build := testBuild(1) + build.ID = "new-build" + build.KernelRepo = "git://delegated.repo/new-git.git" + build.KernelBranch = "new-main" + build.KernelConfig = []byte{0xAB, 0xCD, 0xEF} + build.Manager = newManager + client.UploadBuild(build) + + // Wait until the bug is upstreamed. + c.advanceTime(20 * 24 * time.Hour) + c.pollEmailBug() + c.pollEmailBug() + + // Let's say that the C repro testing has failed. + c.advanceTime(config.Obsoleting.ReproRetestPeriod + time.Hour) + c.updRetestReproJobs() + + resp := client.pollSpecificJobs(build.Manager, dashapi.ManagerJobs{TestPatches: true}) + c.expectEQ(resp.Type, dashapi.JobTestPatch) + c.expectEQ(resp.KernelRepo, build.KernelRepo) + c.expectEQ(resp.KernelBranch, build.KernelBranch) + c.expectEQ(resp.KernelConfig, build.KernelConfig) + c.expectEQ(resp.Patch, []uint8(nil)) + + // Pretend that the C repro fails. + done := &dashapi.JobDoneReq{ + ID: resp.ID, + } + + client.expectOK(client.JobDone(done)) + + // If it has worked, the repro is revoked and the bug is obsoleted. + c.pollEmailBug() + bug, _, _ := c.loadBug(extBugID) + c.expectEQ(bug.HeadReproLevel, ReproLevelNone) +} + // Test on a restricted manager. func TestJobRestrictedManager(t *testing.T) { c := NewCtx(t) |
