From 19bd435f7d6275cbfbb01c354c45ab0df0df395c Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Fri, 3 Dec 2021 17:07:11 +0000 Subject: tools/syz-testbed: add switching between tables to the web interface Formalise HTML table management - introduce the map, which lists the available stat tables and their generators. Render only one page at a time and let the user switch them. Implement the generation of the bug table. --- tools/syz-testbed/html.go | 143 +++++++++++++++++++++++++++++++--------------- 1 file changed, 96 insertions(+), 47 deletions(-) (limited to 'tools') diff --git a/tools/syz-testbed/html.go b/tools/syz-testbed/html.go index d4e23fc4e..fd77b4acb 100644 --- a/tools/syz-testbed/html.go +++ b/tools/syz-testbed/html.go @@ -134,9 +134,17 @@ type uiTable struct { AlignedBy string } +type uiTableType struct { + Title string + Generator func(urlPrefix string, view *StatView, r *http.Request) (*uiTable, error) + URL string +} + type uiStatView struct { - Name string - Table uiTable + Name string + TableTypes map[string]uiTableType + ActiveTableType string + ActiveTable *uiTable } type uiMainPage struct { @@ -146,63 +154,94 @@ type uiMainPage struct { ActiveView uiStatView } +func (ctx *TestbedContext) httpMainStatsTable(urlPrefix string, view *StatView, r *http.Request) (*uiTable, error) { + alignBy := r.FormValue("align") + if alignBy == "" { + alignBy = "fuzzing" + } + table, err := view.AlignedStatsTable(alignBy) + if err != nil { + return nil, fmt.Errorf("stat table generation failed: %s", err) + } + baseColumn := r.FormValue("base_column") + if baseColumn != "" { + err := table.SetRelativeValues(baseColumn) + if err != nil { + log.Printf("failed to execute SetRelativeValues: %s", err) + } + } + + return &uiTable{ + Table: table, + Extra: baseColumn != "", + ColumnURL: func(column string) string { + if column == baseColumn { + return "" + } + v := url.Values{} + v.Set("base_column", column) + v.Set("align", alignBy) + return urlPrefix + v.Encode() + }, + RowURL: func(row string) string { + if row == alignBy { + return "" + } + v := url.Values{} + v.Set("base_column", baseColumn) + v.Set("align", row) + return urlPrefix + v.Encode() + }, + AlignedBy: alignBy, + }, nil +} + +func (ctx *TestbedContext) httpMainBugTable(urlPrefix string, view *StatView, r *http.Request) (*uiTable, error) { + table, err := view.GenerateBugTable() + if err != nil { + return nil, fmt.Errorf("stat table generation failed: %s", err) + } + return &uiTable{ + Table: table, + }, nil +} + func (ctx *TestbedContext) httpMain(w http.ResponseWriter, r *http.Request) { activeView, err := ctx.getCurrentStatView(r) if err != nil { http.Error(w, fmt.Sprintf("%s", err), http.StatusInternalServerError) return } - views, err := ctx.GetStatViews() if err != nil { http.Error(w, fmt.Sprintf("%s", err), http.StatusInternalServerError) return } + genTableURL := func(tableType string) string { + v := url.Values{} + v.Set("view", activeView.Name) + v.Set("table", tableType) + return "/?" + v.Encode() + } uiView := uiStatView{Name: activeView.Name} - - alignBy := r.FormValue("align") - if alignBy == "" { - alignBy = "fuzzing" + uiView.TableTypes = map[string]uiTableType{ + "stats": uiTableType{"Statistics", ctx.httpMainStatsTable, genTableURL("stats")}, + "bugs": uiTableType{"Bugs", ctx.httpMainBugTable, genTableURL("bugs")}, } - table, err := activeView.AlignedStatsTable(alignBy) + uiView.ActiveTableType = r.FormValue("table") + if uiView.ActiveTableType == "" { + uiView.ActiveTableType = "stats" + } + tableType, found := uiView.TableTypes[uiView.ActiveTableType] + if !found { + http.Error(w, fmt.Sprintf("%s", err), http.StatusInternalServerError) + return + } + uiView.ActiveTable, err = tableType.Generator(tableType.URL+"&", activeView, r) if err != nil { - log.Printf("stat table generation failed: %s", err) - } else { - baseColumn := r.FormValue("base_column") - if baseColumn != "" { - err := table.SetRelativeValues(baseColumn) - if err != nil { - log.Printf("failed to execute SetRelativeValues: %s", err) - } - } - - uiView.Table = uiTable{ - Table: table, - Extra: baseColumn != "", - ColumnURL: func(column string) string { - if column == baseColumn { - return "" - } - v := url.Values{} - v.Set("view", activeView.Name) - v.Set("base_column", column) - v.Set("align", alignBy) - return "/?" + v.Encode() - }, - RowURL: func(row string) string { - if row == alignBy { - return "" - } - v := url.Values{} - v.Set("view", activeView.Name) - v.Set("base_column", baseColumn) - v.Set("align", row) - return "/?" + v.Encode() - }, - AlignedBy: alignBy, - } + http.Error(w, fmt.Sprintf("%s", err), http.StatusInternalServerError) + return } - data := &uiMainPage{ Name: ctx.Config.Name, Summary: uiTable{Table: ctx.TestbedStatsTable()}, @@ -342,11 +381,21 @@ href="?view={{$view.Name}}">█ {{$view.Name}} {{end}} {{template "PrintTable" .Summary}} - -Stat view "{{$.ActiveView.Name}}"
+{{$activeView := $.ActiveView}} +

Stat view "{{$activeView.Name}}"

+Tables: +{{range $typeKey, $type := $activeView.TableTypes}} + {{if eq $typeKey $activeView.ActiveTableType}} + {{$type.Title}} + {{else}} + {{$type.Title}} + {{end}} +   +{{end}} +
Graph over time / Graph over executions
-{{template "PrintTable" $.ActiveView.Table}} +{{template "PrintTable" $.ActiveView.ActiveTable}} -- cgit mrf-deployment