diff options
| author | Cheng-Min Chiang <chmnchiang@google.com> | 2020-09-02 17:23:49 -0700 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2020-09-14 15:00:02 +0200 |
| commit | 9eff3337ee5c407d4156eccb7bdea4d666e492fc (patch) | |
| tree | a1e61c38d1d4f47bc7017a8e5c8e9d9b06fce6d8 | |
| parent | df4f5a9c4a22ded414b447d4d790c53d4d2a86e2 (diff) | |
dashboard/app: send machine information to dashboard
- Change syz-manager so that it will send machine info the first time a
crash occurs.
- Add a field in entities.Crash to store machine info.
- Add a field in dashapi.BugReport to store machine info.
- Change the HTML template and struct uiCrash to display machine info.
- Add a test to make sure that the link to machine info appears on the
webpage.
Update #466
| -rw-r--r-- | dashboard/app/api.go | 3 | ||||
| -rw-r--r-- | dashboard/app/entities.go | 2 | ||||
| -rw-r--r-- | dashboard/app/jobs.go | 31 | ||||
| -rw-r--r-- | dashboard/app/main.go | 30 | ||||
| -rw-r--r-- | dashboard/app/reporting.go | 42 | ||||
| -rw-r--r-- | dashboard/app/reporting_test.go | 45 | ||||
| -rw-r--r-- | dashboard/app/templates.html | 1 | ||||
| -rw-r--r-- | dashboard/dashapi/dashapi.go | 3 | ||||
| -rw-r--r-- | syz-manager/manager.go | 13 |
9 files changed, 117 insertions, 53 deletions
diff --git a/dashboard/app/api.go b/dashboard/app/api.go index f30c87174..12f3c7e1c 100644 --- a/dashboard/app/api.go +++ b/dashboard/app/api.go @@ -810,6 +810,9 @@ func saveCrash(c context.Context, ns string, req *dashapi.Crash, bugKey *db.Key, if crash.ReproC, err = putText(c, ns, textReproC, req.ReproC, false); err != nil { return err } + if crash.MachineInfo, err = putText(c, ns, textMachineInfo, req.MachineInfo, false); err != nil { + return err + } crashKey := db.NewIncompleteKey(c, "Crash", bugKey) if _, err = db.Put(c, crashKey, crash); err != nil { return fmt.Errorf("failed to put crash: %v", err) diff --git a/dashboard/app/entities.go b/dashboard/app/entities.go index ef54c8565..d00d90f11 100644 --- a/dashboard/app/entities.go +++ b/dashboard/app/entities.go @@ -131,6 +131,7 @@ type Crash struct { ReproOpts []byte `datastore:",noindex"` ReproSyz int64 // reference to ReproSyz text entity ReproC int64 // reference to ReproC text entity + MachineInfo int64 // Reference to MachineInfo text entity. // Custom crash priority for reporting (greater values are higher priority). // For example, a crash in mainline kernel has higher priority than a crash in a side branch. // For historical reasons this is called ReportLen. @@ -232,6 +233,7 @@ const ( textCrashReport = "CrashReport" textReproSyz = "ReproSyz" textReproC = "ReproC" + textMachineInfo = "MachineInfo" textKernelConfig = "KernelConfig" textPatch = "Patch" textLog = "Log" diff --git a/dashboard/app/jobs.go b/dashboard/app/jobs.go index e46684b21..6d5fd3ff3 100644 --- a/dashboard/app/jobs.go +++ b/dashboard/app/jobs.go @@ -668,21 +668,22 @@ func createBugReportForJob(c context.Context, job *Job, jobKey *db.Key, config i } kernelRepo := kernelRepoInfo(build) rep := &dashapi.BugReport{ - Type: typ, - Config: reportingConfig, - JobID: extJobID(jobKey), - ExtID: job.ExtID, - CC: append(job.CC, kernelRepo.CC...), - Log: crashLog, - LogLink: externalLink(c, textCrashLog, job.CrashLog), - Report: report, - ReportLink: externalLink(c, textCrashReport, job.CrashReport), - ReproCLink: externalLink(c, textReproC, crash.ReproC), - ReproSyzLink: externalLink(c, textReproSyz, crash.ReproSyz), - CrashTitle: job.CrashTitle, - Error: jobError, - ErrorLink: externalLink(c, textError, job.Error), - PatchLink: externalLink(c, textPatch, job.Patch), + Type: typ, + Config: reportingConfig, + JobID: extJobID(jobKey), + ExtID: job.ExtID, + CC: append(job.CC, kernelRepo.CC...), + Log: crashLog, + LogLink: externalLink(c, textCrashLog, job.CrashLog), + Report: report, + ReportLink: externalLink(c, textCrashReport, job.CrashReport), + ReproCLink: externalLink(c, textReproC, crash.ReproC), + ReproSyzLink: externalLink(c, textReproSyz, crash.ReproSyz), + MachineInfoLink: externalLink(c, textMachineInfo, crash.MachineInfo), + CrashTitle: job.CrashTitle, + Error: jobError, + ErrorLink: externalLink(c, textError, job.Error), + PatchLink: externalLink(c, textPatch, job.Patch), } if job.Type == JobBisectCause || job.Type == JobBisectFix { rep.Maintainers = append(crash.Maintainers, kernelRepo.Maintainers...) diff --git a/dashboard/app/main.go b/dashboard/app/main.go index 9c6144082..422cebd9c 100644 --- a/dashboard/app/main.go +++ b/dashboard/app/main.go @@ -165,13 +165,14 @@ type uiBug struct { } type uiCrash struct { - Manager string - Time time.Time - Maintainers string - LogLink string - ReportLink string - ReproSyzLink string - ReproCLink string + Manager string + Time time.Time + Maintainers string + LogLink string + ReportLink string + ReproSyzLink string + ReproCLink string + MachineInfoLink string *uiBuild } @@ -917,13 +918,14 @@ func loadFixBisectionsForBug(c context.Context, bug *Bug) ([]*uiCrash, error) { func makeUICrash(crash *Crash, build *Build) *uiCrash { ui := &uiCrash{ - Manager: crash.Manager, - Time: crash.Time, - Maintainers: strings.Join(crash.Maintainers, ", "), - LogLink: textLink(textCrashLog, crash.Log), - ReportLink: textLink(textCrashReport, crash.Report), - ReproSyzLink: textLink(textReproSyz, crash.ReproSyz), - ReproCLink: textLink(textReproC, crash.ReproC), + Manager: crash.Manager, + Time: crash.Time, + Maintainers: strings.Join(crash.Maintainers, ", "), + LogLink: textLink(textCrashLog, crash.Log), + ReportLink: textLink(textCrashReport, crash.Report), + ReproSyzLink: textLink(textReproSyz, crash.ReproSyz), + ReproCLink: textLink(textReproC, crash.ReproC), + MachineInfoLink: textLink(textMachineInfo, crash.MachineInfo), } if build != nil { ui.uiBuild = makeUIBuild(build) diff --git a/dashboard/app/reporting.go b/dashboard/app/reporting.go index 23703c78b..dc32fbbe8 100644 --- a/dashboard/app/reporting.go +++ b/dashboard/app/reporting.go @@ -391,6 +391,10 @@ func createBugReport(c context.Context, bug *Bug, crash *Crash, crashKey *db.Key if err != nil { return nil, err } + machineInfo, _, err := getText(c, textMachineInfo, crash.MachineInfo) + if err != nil { + return nil, err + } if len(reproSyz) != 0 { buf := new(bytes.Buffer) buf.WriteString(syzReproPrefix) @@ -411,24 +415,26 @@ func createBugReport(c context.Context, bug *Bug, crash *Crash, crashKey *db.Key kernelRepo := kernelRepoInfo(build) rep := &dashapi.BugReport{ - Type: typ, - Config: reportingConfig, - ExtID: bugReporting.ExtID, - First: bugReporting.Reported.IsZero(), - Moderation: reporting.moderation, - Log: crashLog, - LogLink: externalLink(c, textCrashLog, crash.Log), - Report: report, - ReportLink: externalLink(c, textCrashReport, crash.Report), - CC: kernelRepo.CC, - Maintainers: append(crash.Maintainers, kernelRepo.Maintainers...), - ReproC: reproC, - ReproCLink: externalLink(c, textReproC, crash.ReproC), - ReproSyz: reproSyz, - ReproSyzLink: externalLink(c, textReproSyz, crash.ReproSyz), - CrashID: crashKey.IntID(), - NumCrashes: bug.NumCrashes, - HappenedOn: managersToRepos(c, bug.Namespace, bug.HappenedOn), + Type: typ, + Config: reportingConfig, + ExtID: bugReporting.ExtID, + First: bugReporting.Reported.IsZero(), + Moderation: reporting.moderation, + Log: crashLog, + LogLink: externalLink(c, textCrashLog, crash.Log), + Report: report, + ReportLink: externalLink(c, textCrashReport, crash.Report), + CC: kernelRepo.CC, + Maintainers: append(crash.Maintainers, kernelRepo.Maintainers...), + ReproC: reproC, + ReproCLink: externalLink(c, textReproC, crash.ReproC), + ReproSyz: reproSyz, + ReproSyzLink: externalLink(c, textReproSyz, crash.ReproSyz), + MachineInfo: machineInfo, + MachineInfoLink: externalLink(c, textMachineInfo, crash.MachineInfo), + CrashID: crashKey.IntID(), + NumCrashes: bug.NumCrashes, + HappenedOn: managersToRepos(c, bug.Namespace, bug.HappenedOn), } if bugReporting.CC != "" { rep.CC = append(rep.CC, strings.Split(bugReporting.CC, "|")...) diff --git a/dashboard/app/reporting_test.go b/dashboard/app/reporting_test.go index 427f3bf15..1bb985b55 100644 --- a/dashboard/app/reporting_test.go +++ b/dashboard/app/reporting_test.go @@ -5,6 +5,7 @@ package main import ( "fmt" + "regexp" "testing" "time" @@ -460,3 +461,47 @@ func TestReportingFilter(t *testing.T) { rep4 := c.client.pollBug() c.expectEQ(string(rep4.Config), `{"Index":2}`) } + +func TestMachineInfo(t *testing.T) { + c := NewCtx(t) + defer c.Close() + + build := testBuild(1) + c.client.UploadBuild(build) + + machineInfo := []byte("info1") + + // Create a crash with machine information and check the returned machine + // information field is equal. + crash := &dashapi.Crash{ + BuildID: "build1", + Title: "title1", + Maintainers: []string{`"Foo Bar" <foo@bar.com>`, `bar@foo.com`}, + Log: []byte("log1"), + Report: []byte("report1"), + MachineInfo: machineInfo, + } + c.client.ReportCrash(crash) + rep := c.client.pollBug() + c.expectEQ(machineInfo, rep.MachineInfo) + + // Check that a link to machine information page is created on the dashboard, + // and the content is correct. + indexPage, err := c.AuthGET(AccessAdmin, "/test1") + c.expectOK(err) + bugLinkRegex := regexp.MustCompile(`<a href="(/bug\?id=[^"]+)">title1</a>`) + bugLinkSubmatch := bugLinkRegex.FindSubmatch(indexPage) + c.expectEQ(len(bugLinkSubmatch), 2) + bugURL := string(bugLinkSubmatch[1]) + + bugPage, err := c.AuthGET(AccessAdmin, bugURL) + c.expectOK(err) + infoLinkRegex := regexp.MustCompile(`<a href="(/text\?tag=MachineInfo[^"]+)">machine info</a>`) + infoLinkSubmatch := infoLinkRegex.FindSubmatch(bugPage) + c.expectEQ(len(infoLinkSubmatch), 2) + infoURL := string(infoLinkSubmatch[1]) + + receivedInfo, err := c.AuthGET(AccessAdmin, infoURL) + c.expectOK(err) + c.expectEQ(receivedInfo, machineInfo) +} diff --git a/dashboard/app/templates.html b/dashboard/app/templates.html index 5743368a1..c07ef4cfb 100644 --- a/dashboard/app/templates.html +++ b/dashboard/app/templates.html @@ -342,6 +342,7 @@ Use of this source code is governed by Apache 2 LICENSE that can be found in the <td class="repro">{{if $b.ReportLink}}<a href="{{$b.ReportLink}}">report</a>{{end}}</td> <td class="repro">{{if $b.ReproSyzLink}}<a href="{{$b.ReproSyzLink}}">syz</a>{{end}}</td> <td class="repro">{{if $b.ReproCLink}}<a href="{{$b.ReproCLink}}">C</a>{{end}}</td> + <td class="repro">{{if $b.MachineInfoLink}}<a href="{{$b.MachineInfoLink}}">machine info</a>{{end}}</td> {{if $.HasMaintainers}} <td class="maintainers" title="{{$b.Maintainers}}">{{$b.Maintainers}}</td> {{end}} diff --git a/dashboard/dashapi/dashapi.go b/dashboard/dashapi/dashapi.go index 2c2a993ea..4748905b4 100644 --- a/dashboard/dashapi/dashapi.go +++ b/dashboard/dashapi/dashapi.go @@ -241,6 +241,7 @@ type Crash struct { Recipients Recipients Log []byte Report []byte + MachineInfo []byte // The following is optional and is filled only after repro. ReproOpts []byte ReproSyz []byte @@ -333,6 +334,8 @@ type BugReport struct { ReproCLink string ReproSyz []byte ReproSyzLink string + MachineInfo []byte + MachineInfoLink string CrashID int64 // returned back in BugUpdate NumCrashes int64 HappenedOn []string // list of kernel repo aliases diff --git a/syz-manager/manager.go b/syz-manager/manager.go index 4abd27a30..05af6d30b 100644 --- a/syz-manager/manager.go +++ b/syz-manager/manager.go @@ -695,12 +695,13 @@ func (mgr *Manager) saveCrash(crash *Crash) bool { return true } dc := &dashapi.Crash{ - BuildID: mgr.cfg.Tag, - Title: crash.Title, - Corrupted: crash.Corrupted, - Recipients: crash.Recipients.ToDash(), - Log: crash.Output, - Report: crash.Report.Report, + BuildID: mgr.cfg.Tag, + Title: crash.Title, + Corrupted: crash.Corrupted, + Recipients: crash.Recipients.ToDash(), + Log: crash.Output, + Report: crash.Report.Report, + MachineInfo: crash.machineInfo, } resp, err := mgr.dash.ReportCrash(dc) if err != nil { |
