mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-27 05:10:43 +00:00
dashboard/app: allow main UI to show bisect results
* Modify uiBug type. Rename BisectCause to BisectCauseDone. Introduce BisectFixDone. * Modify createUIBug() and MergeUIBug() to set the above fields appropriately. * Modify bug_list to display the bisection status; remove yesSort() as it is not used anymore. Adjust ".list_table .stat" to appropriate width. * Add TestBugBisectionStatus() to check bisection status on main page. * Add file from running "make generate": pkg/html/generated.go
This commit is contained in:
parent
657092bddf
commit
a02b5bcae2
@ -819,3 +819,102 @@ func TestBugBisectionResults(t *testing.T) {
|
||||
c.expectTrue(bytes.Contains(content, []byte("Bisection: fixed by")))
|
||||
c.expectTrue(bytes.Contains(content, []byte("kernel: add a fix")))
|
||||
}
|
||||
|
||||
// Test that bisection status shows up on main page
|
||||
func TestBugBisectionStatus(t *testing.T) {
|
||||
c := NewCtx(t)
|
||||
defer c.Close()
|
||||
|
||||
// Upload a crash report
|
||||
build := testBuild(1)
|
||||
c.client2.UploadBuild(build)
|
||||
crash := testCrashWithRepro(build, 1)
|
||||
c.client2.ReportCrash(crash)
|
||||
c.client2.pollEmailBug()
|
||||
|
||||
// Receive the JobBisectCause and send cause information
|
||||
resp := c.client2.pollJobs(build.Manager)
|
||||
c.client2.expectNE(resp.ID, "")
|
||||
c.client2.expectEQ(resp.Type, dashapi.JobBisectCause)
|
||||
jobID := resp.ID
|
||||
done := &dashapi.JobDoneReq{
|
||||
ID: jobID,
|
||||
Build: *build,
|
||||
Log: []byte("bisectfix log 4"),
|
||||
CrashTitle: "bisectfix crash title 4",
|
||||
CrashLog: []byte("bisectfix crash log 4"),
|
||||
CrashReport: []byte("bisectfix crash report 4"),
|
||||
Commits: []dashapi.Commit{
|
||||
{
|
||||
Hash: "36e65cb4a0448942ec316b24d60446bbd5cc7827",
|
||||
Title: "kernel: add a bug",
|
||||
Author: "author@kernel.org",
|
||||
AuthorName: "Author Kernelov",
|
||||
CC: []string{
|
||||
"reviewer1@kernel.org", "\"Reviewer2\" <reviewer2@kernel.org>",
|
||||
// These must be filtered out:
|
||||
"syzbot@testapp.appspotmail.com",
|
||||
"syzbot+1234@testapp.appspotmail.com",
|
||||
"\"syzbot\" <syzbot+1234@testapp.appspotmail.com>",
|
||||
},
|
||||
Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),
|
||||
},
|
||||
},
|
||||
}
|
||||
c.expectOK(c.client2.JobDone(done))
|
||||
|
||||
// Fetch bug, namespace details
|
||||
var bugs []*Bug
|
||||
_, err := db.NewQuery("Bug").GetAll(c.ctx, &bugs)
|
||||
c.expectEQ(err, nil)
|
||||
c.expectEQ(len(bugs), 1)
|
||||
url := fmt.Sprintf("/%v", bugs[0].Namespace)
|
||||
content, err := c.httpRequest("GET", url, "", AccessAdmin)
|
||||
c.expectEQ(err, nil)
|
||||
c.expectTrue(bytes.Contains(content, []byte("cause")))
|
||||
|
||||
// Advance time by 30 days and read out any notification emails
|
||||
{
|
||||
c.advanceTime(30 * 24 * time.Hour)
|
||||
msg := c.client2.pollEmailBug()
|
||||
c.expectTrue(strings.Contains(msg.Body, "syzbot has bisected this bug to:"))
|
||||
msg = c.client2.pollEmailBug()
|
||||
c.expectTrue(strings.Contains(msg.Body, "Sending this report upstream."))
|
||||
msg = c.client2.pollEmailBug()
|
||||
c.expectTrue(strings.Contains(msg.Body, "syzbot found the following crash"))
|
||||
}
|
||||
|
||||
// Receive a JobBisectfix and send fix information.
|
||||
resp = c.client2.pollJobs(build.Manager)
|
||||
c.client2.expectNE(resp.ID, "")
|
||||
c.client2.expectEQ(resp.Type, dashapi.JobBisectFix)
|
||||
jobID = resp.ID
|
||||
done = &dashapi.JobDoneReq{
|
||||
ID: jobID,
|
||||
Build: *build,
|
||||
Log: []byte("bisectfix log 4"),
|
||||
CrashTitle: "bisectfix crash title 4",
|
||||
CrashLog: []byte("bisectfix crash log 4"),
|
||||
CrashReport: []byte("bisectfix crash report 4"),
|
||||
Commits: []dashapi.Commit{
|
||||
{
|
||||
Hash: "46e65cb4a0448942ec316b24d60446bbd5cc7827",
|
||||
Title: "kernel: add a fix",
|
||||
Author: "author@kernel.org",
|
||||
AuthorName: "Author Kernelov",
|
||||
CC: []string{
|
||||
"reviewer1@kernel.org", "\"Reviewer2\" <reviewer2@kernel.org>",
|
||||
// These must be filtered out:
|
||||
"syzbot@testapp.appspotmail.com",
|
||||
"syzbot+1234@testapp.appspotmail.com",
|
||||
"\"syzbot\" <syzbot+1234@testapp.appspotmail.com>",
|
||||
},
|
||||
Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),
|
||||
},
|
||||
},
|
||||
}
|
||||
c.expectOK(c.client2.JobDone(done))
|
||||
content, err = c.httpRequest("GET", url, "", AccessAdmin)
|
||||
c.expectEQ(err, nil)
|
||||
c.expectTrue(bytes.Contains(content, []byte("cause+fix")))
|
||||
}
|
||||
|
@ -134,25 +134,26 @@ type uiBugGroup struct {
|
||||
}
|
||||
|
||||
type uiBug struct {
|
||||
Namespace string
|
||||
Title string
|
||||
NumCrashes int64
|
||||
NumCrashesBad bool
|
||||
BisectCause bool
|
||||
FirstTime time.Time
|
||||
LastTime time.Time
|
||||
ReportedTime time.Time
|
||||
ClosedTime time.Time
|
||||
ReproLevel dashapi.ReproLevel
|
||||
ReportingIndex int
|
||||
Status string
|
||||
Link string
|
||||
ExternalLink string
|
||||
CreditEmail string
|
||||
Commits []*uiCommit
|
||||
PatchedOn []string
|
||||
MissingOn []string
|
||||
NumManagers int
|
||||
Namespace string
|
||||
Title string
|
||||
NumCrashes int64
|
||||
NumCrashesBad bool
|
||||
BisectCauseDone bool
|
||||
BisectFixDone bool
|
||||
FirstTime time.Time
|
||||
LastTime time.Time
|
||||
ReportedTime time.Time
|
||||
ClosedTime time.Time
|
||||
ReproLevel dashapi.ReproLevel
|
||||
ReportingIndex int
|
||||
Status string
|
||||
Link string
|
||||
ExternalLink string
|
||||
CreditEmail string
|
||||
Commits []*uiCommit
|
||||
PatchedOn []string
|
||||
MissingOn []string
|
||||
NumManagers int
|
||||
}
|
||||
|
||||
type uiCrash struct {
|
||||
@ -734,21 +735,22 @@ func createUIBug(c context.Context, bug *Bug, state *ReportingState, managers []
|
||||
}
|
||||
id := bug.keyHash()
|
||||
uiBug := &uiBug{
|
||||
Namespace: bug.Namespace,
|
||||
Title: bug.displayTitle(),
|
||||
BisectCause: bug.BisectCause > BisectPending,
|
||||
NumCrashes: bug.NumCrashes,
|
||||
FirstTime: bug.FirstTime,
|
||||
LastTime: bug.LastTime,
|
||||
ReportedTime: reported,
|
||||
ClosedTime: bug.Closed,
|
||||
ReproLevel: bug.ReproLevel,
|
||||
ReportingIndex: reportingIdx,
|
||||
Status: status,
|
||||
Link: bugLink(id),
|
||||
ExternalLink: link,
|
||||
CreditEmail: creditEmail,
|
||||
NumManagers: len(managers),
|
||||
Namespace: bug.Namespace,
|
||||
Title: bug.displayTitle(),
|
||||
BisectCauseDone: bug.BisectCause > BisectPending,
|
||||
BisectFixDone: bug.BisectFix > BisectPending,
|
||||
NumCrashes: bug.NumCrashes,
|
||||
FirstTime: bug.FirstTime,
|
||||
LastTime: bug.LastTime,
|
||||
ReportedTime: reported,
|
||||
ClosedTime: bug.Closed,
|
||||
ReproLevel: bug.ReproLevel,
|
||||
ReportingIndex: reportingIdx,
|
||||
Status: status,
|
||||
Link: bugLink(id),
|
||||
ExternalLink: link,
|
||||
CreditEmail: creditEmail,
|
||||
NumManagers: len(managers),
|
||||
}
|
||||
updateBugBadness(c, uiBug)
|
||||
if len(bug.Commits) != 0 {
|
||||
@ -783,7 +785,8 @@ func createUIBug(c context.Context, bug *Bug, state *ReportingState, managers []
|
||||
|
||||
func mergeUIBug(c context.Context, bug *uiBug, dup *Bug) {
|
||||
bug.NumCrashes += dup.NumCrashes
|
||||
bug.BisectCause = bug.BisectCause || dup.BisectCause > BisectPending
|
||||
bug.BisectCauseDone = bug.BisectCauseDone || dup.BisectCause > BisectPending
|
||||
bug.BisectFixDone = bug.BisectFixDone || dup.BisectFix > BisectPending
|
||||
if bug.LastTime.Before(dup.LastTime) {
|
||||
bug.LastTime = dup.LastTime
|
||||
}
|
||||
|
@ -41,7 +41,6 @@ function isSorted(values) {
|
||||
function textSort(v) { return v.toLowerCase(); }
|
||||
function numSort(v) { return -parseInt(v); }
|
||||
function floatSort(v) { return -parseFloat(v); }
|
||||
function yesSort(v) { return v == "yes" ? 0 : 1; }
|
||||
function reproSort(v) { return v == "C" ? 0 : v == "syz" ? 1 : 2; }
|
||||
function patchedSort(v) { return v == "" ? -1 : parseInt(v); }
|
||||
|
||||
|
@ -127,8 +127,8 @@ table td, table th {
|
||||
}
|
||||
|
||||
.list_table .stat {
|
||||
width: 50pt;
|
||||
max-width: 50pt;
|
||||
width: 55pt;
|
||||
max-width: 55pt;
|
||||
font-family: monospace;
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ Use of this source code is governed by Apache 2 LICENSE that can be found in the
|
||||
{{end}}
|
||||
<th><a onclick="return sortTable(this, 'Title', textSort)" href="#">Title</a></th>
|
||||
<th><a onclick="return sortTable(this, 'Repro', reproSort)" href="#">Repro</a></th>
|
||||
<th><a onclick="return sortTable(this, 'Bisected', yesSort)" href="#">Bisected</a></th>
|
||||
<th><a onclick="return sortTable(this, 'Bisected', textSort)" href="#">Bisected</a></th>
|
||||
<th><a onclick="return sortTable(this, 'Count', numSort)" href="#">Count</a></th>
|
||||
<th><a onclick="return sortTable(this, 'Last', timeSort)" href="#">Last</a></th>
|
||||
<th><a onclick="return sortTable(this, 'Reported', timeSort)" href="#">Reported</a></th>
|
||||
@ -101,7 +101,15 @@ Use of this source code is governed by Apache 2 LICENSE that can be found in the
|
||||
{{if $.ShowNamespace}}<td>{{$b.Namespace}}</td>{{end}}
|
||||
<td class="title"><a href="{{$b.Link}}">{{$b.Title}}</a></td>
|
||||
<td class="stat">{{formatReproLevel $b.ReproLevel}}</td>
|
||||
<td class="stat">{{if $b.BisectCause}}yes{{end}}</td>
|
||||
<td class="stat">
|
||||
{{if and $b.BisectCauseDone $b.BisectFixDone}}
|
||||
cause+fix
|
||||
{{else if $b.BisectCauseDone}}
|
||||
cause
|
||||
{{else if $b.BisectFixDone}}
|
||||
fix
|
||||
{{end}}
|
||||
</td>
|
||||
<td class="stat {{if $b.NumCrashesBad}}bad{{end}}">{{$b.NumCrashes}}</td>
|
||||
<td class="stat">{{formatLateness $.Now $b.LastTime}}</td>
|
||||
<td class="stat">
|
||||
|
@ -130,8 +130,8 @@ table td, table th {
|
||||
}
|
||||
|
||||
.list_table .stat {
|
||||
width: 50pt;
|
||||
max-width: 50pt;
|
||||
width: 55pt;
|
||||
max-width: 55pt;
|
||||
font-family: monospace;
|
||||
text-align: right;
|
||||
}
|
||||
@ -221,7 +221,6 @@ function isSorted(values) {
|
||||
function textSort(v) { return v.toLowerCase(); }
|
||||
function numSort(v) { return -parseInt(v); }
|
||||
function floatSort(v) { return -parseFloat(v); }
|
||||
function yesSort(v) { return v == "yes" ? 0 : 1; }
|
||||
function reproSort(v) { return v == "C" ? 0 : v == "syz" ? 1 : 2; }
|
||||
function patchedSort(v) { return v == "" ? -1 : parseInt(v); }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user