syzkaller/pkg/html/html.go
Zubin Mithra bad3cce26c dashboard/app: allow reporting of BisectFix results
* Modify mail_bisect_result.txt to allow for sending fix bisection
results.
* Modify BisectResult to have a Fix field; introduce selectBisect for
use within the template for choosing between BisectCause/BisectFix
fields.
* Modify bisectFromJob() to return BisectResult with Fix field set if
relevant.
* Modify the tests inside bisect_test.go to account for bisect fix
related reporting emails.
* Modify incomingMail() to ignore any emails from syzbot itself.
2019-08-30 19:50:12 -07:00

185 lines
4.5 KiB
Go

// Copyright 2018 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.
//go:generate bash -c "echo '// AUTOGENERATED FILE' > generated.go"
//go:generate bash -c "echo 'package html' > generated.go"
//go:generate bash -c "echo 'const style = `' >> generated.go"
//go:generate bash -c "cat ../../dashboard/app/static/style.css >> generated.go"
//go:generate bash -c "echo '`' >> generated.go"
//go:generate bash -c "echo 'const js = `' >> generated.go"
//go:generate bash -c "cat ../../dashboard/app/static/common.js >> generated.go"
//go:generate bash -c "echo '`' >> generated.go"
package html
import (
"fmt"
"html/template"
"strings"
texttemplate "text/template"
"time"
"github.com/google/syzkaller/dashboard/dashapi"
)
func CreatePage(page string) *template.Template {
const headTempl = `<style type="text/css" media="screen">%v</style><script>%v</script>`
page = strings.Replace(page, "{{HEAD}}", fmt.Sprintf(headTempl, style, js), 1)
return template.Must(template.New("").Funcs(Funcs).Parse(page))
}
func CreateGlob(glob string) *template.Template {
return template.Must(template.New("").Funcs(Funcs).ParseGlob(glob))
}
func CreateTextGlob(glob string) *texttemplate.Template {
return texttemplate.Must(texttemplate.New("").Funcs(texttemplate.FuncMap(Funcs)).ParseGlob(glob))
}
var Funcs = template.FuncMap{
"link": link,
"optlink": optlink,
"formatTime": FormatTime,
"formatDate": FormatDate,
"formatKernelTime": formatKernelTime,
"formatClock": formatClock,
"formatDuration": formatDuration,
"formatLateness": formatLateness,
"formatReproLevel": formatReproLevel,
"formatStat": formatStat,
"formatShortHash": formatShortHash,
"formatTagHash": formatTagHash,
"formatCommitTableTitle": formatCommitTableTitle,
"formatList": formatStringList,
"selectBisect": selectBisect,
}
func selectBisect(rep *dashapi.BugReport) *dashapi.BisectResult {
if rep.BisectFix != nil {
return rep.BisectFix
}
return rep.BisectCause
}
func link(url, text string) template.HTML {
text = template.HTMLEscapeString(text)
if url != "" {
text = fmt.Sprintf(`<a href="%v">%v</a>`, url, text)
}
return template.HTML(text)
}
func optlink(url, text string) template.HTML {
if url == "" {
return template.HTML("")
}
return link(url, text)
}
func FormatTime(t time.Time) string {
if t.IsZero() {
return ""
}
return t.Format("2006/01/02 15:04")
}
func FormatDate(t time.Time) string {
if t.IsZero() {
return ""
}
return t.Format("2006/01/02")
}
func formatKernelTime(t time.Time) string {
if t.IsZero() {
return ""
}
// This is how dates appear in git log.
return t.Format("Mon Jan 2 15:04:05 2006 -0700")
}
func formatClock(t time.Time) string {
if t.IsZero() {
return ""
}
return t.Format("15:04")
}
func formatDuration(d time.Duration) string {
if d == 0 {
return ""
}
days := int(d / (24 * time.Hour))
hours := int(d / time.Hour % 24)
mins := int(d / time.Minute % 60)
if days >= 10 {
return fmt.Sprintf("%vd", days)
} else if days != 0 {
return fmt.Sprintf("%vd%02vh", days, hours)
} else if hours != 0 {
return fmt.Sprintf("%vh%02vm", hours, mins)
}
return fmt.Sprintf("%vm", mins)
}
func formatLateness(now, t time.Time) string {
if t.IsZero() {
return "never"
}
d := now.Sub(t)
if d < 5*time.Minute {
return "now"
}
return formatDuration(d)
}
func formatReproLevel(l dashapi.ReproLevel) string {
switch l {
case dashapi.ReproLevelSyz:
return "syz"
case dashapi.ReproLevelC:
return "C"
default:
return ""
}
}
func formatStat(v int64) string {
if v == 0 {
return ""
}
return fmt.Sprint(v)
}
func formatShortHash(v string) string {
const hashLen = 8
if len(v) <= hashLen {
return v
}
return v[:hashLen]
}
func formatTagHash(v string) string {
// Note: Fixes/References commit tags should include 12-char hash
// (see Documentation/process/submitting-patches.rst). Don't change this const.
const hashLen = 12
if len(v) <= hashLen {
return v
}
return v[:hashLen]
}
func formatCommitTableTitle(v string) string {
// This function is very specific to how we format tables in text emails.
// Truncate commit title so that whole line fits into 78 chars.
const commitTitleLen = 51
if len(v) <= commitTitleLen {
return v
}
return v[:commitTitleLen-2] + ".."
}
func formatStringList(list []string) string {
return strings.Join(list, ", ")
}