mirror of
https://github.com/reactos/syzkaller.git
synced 2025-02-24 21:50:40 +00:00

1. Use dashboard style. 2. Allow sorting of tables. 3. Show old crashes in grey. 4. Use tables instead of text output for more pages. 5. Show corpus inputs on a separate page to allow copy-pasting. 6. Use standard JS sorting instead of custom bubble sort (much faster). 7. Fix off-by one in table sorting. Fixes #694
111 lines
2.6 KiB
Go
111 lines
2.6 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"
|
|
"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))
|
|
}
|
|
|
|
var funcs = template.FuncMap{
|
|
"formatTime": FormatTime,
|
|
"formatClock": formatClock,
|
|
"formatDuration": formatDuration,
|
|
"formatLateness": formatLateness,
|
|
"formatReproLevel": formatReproLevel,
|
|
"formatStat": formatStat,
|
|
"formatShortHash": formatShortHash,
|
|
}
|
|
|
|
func FormatTime(t time.Time) string {
|
|
if t.IsZero() {
|
|
return ""
|
|
}
|
|
return t.Format("2006/01/02 15:04")
|
|
}
|
|
|
|
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]
|
|
}
|