aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-04-16 11:45:48 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-04-16 11:46:10 +0200
commit802ac9125dff4a0cfc5d124994c04c0944538489 (patch)
tree65155b8ea41a0fce2e0a241a5ac849c2ca815958
parent7a67784ca8bdc3b26cce2f0ec9a40d2dd9ec9396 (diff)
dashboard/app: fix error link in emails
Fixes #559
-rw-r--r--dashboard/app/jobs.go3
-rw-r--r--dashboard/app/jobs_test.go50
-rw-r--r--dashboard/app/main.go3
-rw-r--r--dashboard/app/reporting.go1
-rw-r--r--dashboard/app/reporting_email.go1
5 files changed, 53 insertions, 5 deletions
diff --git a/dashboard/app/jobs.go b/dashboard/app/jobs.go
index 17648afdf..e1a5f4d60 100644
--- a/dashboard/app/jobs.go
+++ b/dashboard/app/jobs.go
@@ -341,9 +341,6 @@ func createBugReportForJob(c context.Context, job *Job, jobKey *datastore.Key, c
if err != nil {
return nil, err
}
- if len(jobError) > maxMailLogLen {
- jobError = jobError[:maxMailLogLen]
- }
patch, _, err := getText(c, textPatch, job.Patch)
if err != nil {
return nil, err
diff --git a/dashboard/app/jobs_test.go b/dashboard/app/jobs_test.go
index 00d58d6eb..218ab63f3 100644
--- a/dashboard/app/jobs_test.go
+++ b/dashboard/app/jobs_test.go
@@ -6,6 +6,7 @@
package dash
import (
+ "bytes"
"fmt"
"strings"
"testing"
@@ -166,6 +167,8 @@ Raw console output: %[3]v
c.checkURLContents(kernelConfigLink, build.KernelConfig)
c.checkURLContents(logLink, jobDoneReq.CrashLog)
}
+
+ // Testing fails with an error.
c.incomingEmail(sender, "#syz test: git://git.git/git.git kernel-branch\n"+patch, EmailOptMessageID(2))
c.expectOK(c.API(client2, key2, "job_poll", &dashapi.JobPollReq{[]string{build.Manager}}, pollResp))
jobDoneReq = &dashapi.JobDoneReq{
@@ -206,11 +209,58 @@ Kernel config: %[2]v
c.checkURLContents(kernelConfigLink, build.KernelConfig)
}
+ // Testing fails with a huge error that can't be inlined in email.
c.incomingEmail(sender, "#syz test: git://git.git/git.git kernel-branch\n"+patch, EmailOptMessageID(3))
c.expectOK(c.API(client2, key2, "job_poll", &dashapi.JobPollReq{[]string{build.Manager}}, pollResp))
jobDoneReq = &dashapi.JobDoneReq{
ID: pollResp.ID,
Build: *build,
+ Error: bytes.Repeat([]byte{'a', 'b', 'c'}, (maxInlineError+100)/3),
+ }
+ c.expectOK(c.API(client2, key2, "job_done", jobDoneReq, nil))
+ c.expectOK(c.GET("/email_poll"))
+ c.expectEQ(len(c.emailSink), 1)
+ {
+ dbJob, dbBuild := c.loadJob(pollResp.ID)
+ patchLink := externalLink(c.ctx, textPatch, dbJob.Patch)
+ errorLink := externalLink(c.ctx, textError, dbJob.Error)
+ kernelConfigLink := externalLink(c.ctx, textKernelConfig, dbBuild.KernelConfig)
+ msg := <-c.emailSink
+ c.expectEQ(len(msg.Attachments), 0)
+ truncatedError := string(jobDoneReq.Error[len(jobDoneReq.Error)-maxInlineError:])
+ body := fmt.Sprintf(`Hello,
+
+syzbot tried to test the proposed patch but build/boot failed:
+
+%[1]v
+
+Error text is too large and was truncated, full error text is at:
+%[2]v
+
+
+Tested on repo1/branch1 commit
+kernel_commit1 (Sat Feb 3 04:05:06 0001 +0000)
+kernel_commit_title1
+
+compiler: compiler1
+Patch: %[3]v
+Kernel config: %[4]v
+
+
+`, truncatedError, errorLink, patchLink, kernelConfigLink)
+ if msg.Body != body {
+ t.Fatalf("got email body:\n%s\n\nwant:\n%s", msg.Body, body)
+ }
+ c.checkURLContents(patchLink, []byte(patch))
+ c.checkURLContents(errorLink, jobDoneReq.Error)
+ c.checkURLContents(kernelConfigLink, build.KernelConfig)
+ }
+
+ c.incomingEmail(sender, "#syz test: git://git.git/git.git kernel-branch\n"+patch, EmailOptMessageID(4))
+ c.expectOK(c.API(client2, key2, "job_poll", &dashapi.JobPollReq{[]string{build.Manager}}, pollResp))
+ jobDoneReq = &dashapi.JobDoneReq{
+ ID: pollResp.ID,
+ Build: *build,
}
c.expectOK(c.API(client2, key2, "job_done", jobDoneReq, nil))
c.expectOK(c.GET("/email_poll"))
diff --git a/dashboard/app/main.go b/dashboard/app/main.go
index 0f679ecf5..65d60aebd 100644
--- a/dashboard/app/main.go
+++ b/dashboard/app/main.go
@@ -30,6 +30,7 @@ func init() {
http.Handle("/x/repro.syz", handlerWrapper(handleTextX(textReproSyz)))
http.Handle("/x/repro.c", handlerWrapper(handleTextX(textReproC)))
http.Handle("/x/patch.diff", handlerWrapper(handleTextX(textPatch)))
+ http.Handle("/x/error.txt", handlerWrapper(handleTextX(textError)))
}
type uiMain struct {
@@ -313,7 +314,7 @@ func textFilename(tag string) string {
case textPatch:
return "patch.diff"
case textError:
- return "log.txt"
+ return "error.txt"
default:
return "text.txt"
}
diff --git a/dashboard/app/reporting.go b/dashboard/app/reporting.go
index 4a6fb1665..423bab3e4 100644
--- a/dashboard/app/reporting.go
+++ b/dashboard/app/reporting.go
@@ -27,6 +27,7 @@ import (
const (
maxMailLogLen = 1 << 20
maxMailReportLen = 64 << 10
+ maxInlineError = 16 << 10
internalError = "internal error"
// This is embedded as first line of syzkaller reproducer files.
syzReproPrefix = "# See https://goo.gl/kgGztJ for information about syzkaller reproducers.\n"
diff --git a/dashboard/app/reporting_email.go b/dashboard/app/reporting_email.go
index c0277dadb..1608c836d 100644
--- a/dashboard/app/reporting_email.go
+++ b/dashboard/app/reporting_email.go
@@ -157,7 +157,6 @@ func emailReport(c context.Context, rep *dashapi.BugReport, templ string) error
}
to := email.MergeEmailLists([]string{cfg.Email}, rep.CC)
// Build error output and failing VM boot log can be way too long to inline.
- const maxInlineError = 16 << 10
if len(rep.Error) > maxInlineError {
rep.Error = rep.Error[len(rep.Error)-maxInlineError:]
} else {