Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(389)

Unified Diff: fuzzer/go/frontend/main.go

Issue 1419793011: Add front page of Fuzzer (Closed) Base URL: https://skia.googlesource.com/buildbot@file
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « fuzzer/elements.html ('k') | fuzzer/go/fuzz/stacktrace.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: fuzzer/go/frontend/main.go
diff --git a/fuzzer/go/frontend/main.go b/fuzzer/go/frontend/main.go
index f3873a78e1d2944c0860a8c80b256c78c643e385..fe688d8a7c4e27d297e74bac9854345a9213df75 100644
--- a/fuzzer/go/frontend/main.go
+++ b/fuzzer/go/frontend/main.go
@@ -4,213 +4,208 @@ import (
"encoding/json"
"flag"
"fmt"
- htemplate "html/template"
- "math/rand"
+ "html/template"
"net/http"
- "os"
"path/filepath"
- "runtime"
- "time"
+)
+import (
"github.com/gorilla/mux"
- metrics "github.com/rcrowley/go-metrics"
"github.com/skia-dev/glog"
- "go.skia.org/infra/fuzzer/go/config"
- "go.skia.org/infra/go/auth"
+)
+
+import (
+ "go.skia.org/infra/fuzzer/go/fuzz"
"go.skia.org/infra/go/common"
"go.skia.org/infra/go/login"
"go.skia.org/infra/go/metadata"
+ "go.skia.org/infra/go/skiaversion"
"go.skia.org/infra/go/util"
- "google.golang.org/api/storage/v1"
+)
+
+const (
+ // OAUTH2_CALLBACK_PATH is callback endpoint used for the Oauth2 flow.
+ OAUTH2_CALLBACK_PATH = "/oauth2callback/"
)
var (
// indexTemplate is the main index.html page we serve.
- indexTemplate *htemplate.Template = nil
-
- requestsCounter = metrics.NewRegisteredCounter("requests", metrics.DefaultRegistry)
- router *mux.Router = mux.NewRouter()
- client *http.Client = nil
- store *storage.Service = nil
+ indexTemplate *template.Template = nil
+ detailsTemplate *template.Template = nil
)
// Command line flags.
var (
- configFilename = flag.String("config", "fuzzer.toml", "Configuration filename")
-)
-
-const (
- // OAUTH2_CALLBACK_PATH is callback endpoint used for the Oauth2 flow.
- OAUTH2_CALLBACK_PATH = "/oauth2callback/"
+ graphiteServer = flag.String("graphite_server", "localhost:2003", "Where is Graphite metrics ingestion server running.")
+ host = flag.String("host", "localhost", "HTTP service host")
+ port = flag.String("port", ":80", "HTTP service port (e.g., ':8002')")
+ local = flag.Bool("local", false, "Running locally if true. As opposed to in production.")
+ resourcesDir = flag.String("resources_dir", "", "The directory to find templates, JS, and CSS files. If blank the current directory will be used.")
+
+ authWhiteList = flag.String("auth_whitelist", login.DEFAULT_DOMAIN_WHITELIST, "White space separated list of domains and email addresses that are allowed to login.")
+ redirectURL = flag.String("redirect_url", "https://fuzzer.skia.org/oauth2callback/", "OAuth2 redirect url. Only used when local=false.")
)
func Init() {
- defer common.LogPanic()
+ reloadTemplates()
+}
- rand.Seed(time.Now().UnixNano())
+func reloadTemplates() {
+ indexTemplate = template.Must(template.ParseFiles(
+ filepath.Join(*resourcesDir, "templates/index.html"),
+ filepath.Join(*resourcesDir, "templates/header.html"),
+ ))
+}
- common.InitWithMetricsCB("fuzzer", func() string {
- common.DecodeTomlFile(*configFilename, &config.Config)
- return config.Config.FrontEnd.GraphiteServer
- })
+func main() {
+ defer common.LogPanic()
+ // Calls flag.Parse()
+ common.InitWithMetrics("fuzzer", graphiteServer)
- if config.Config.Common.ResourcePath == "" {
- _, filename, _, _ := runtime.Caller(0)
- config.Config.Common.ResourcePath = filepath.Join(filepath.Dir(filename), "../..")
- }
+ Init()
- path, err := filepath.Abs(config.Config.Common.ResourcePath)
- if err != nil {
- glog.Fatalf("Couldn't get absolute path to fuzzer resources: %s", err)
- }
- if err := os.Chdir(path); err != nil {
- glog.Fatal(err)
- }
+ setupOAuth()
- indexTemplate = htemplate.Must(htemplate.ParseFiles(
- filepath.Join(path, "templates/index.html"),
- filepath.Join(path, "templates/header.html"),
- filepath.Join(path, "templates/titlebar.html"),
- filepath.Join(path, "templates/footer.html"),
- ))
+ runServer()
+}
- if client, err = auth.NewClient(config.Config.Common.DoOAuth, config.Config.Common.OAuthCacheFile, storage.DevstorageFullControlScope); err != nil {
- glog.Fatalf("Failed to create authenticated HTTP client: %s", err)
+func setupOAuth() {
+ var cookieSalt = "notverysecret"
+ // This clientID and clientSecret are only used for setting up a local server.
+ // Production id and secrets are in metadata and will be loaded from there.
+ var clientID = "31977622648-ubjke2f3staq6ouas64r31h8f8tcbiqp.apps.googleusercontent.com"
+ var clientSecret = "rK-kRY71CXmcg0v9I9KIgWci"
+ var useRedirectURL = fmt.Sprintf("http://localhost%s/oauth2callback/", *port)
+ if !*local {
+ cookieSalt = metadata.Must(metadata.ProjectGet(metadata.COOKIESALT))
+ clientID = metadata.Must(metadata.ProjectGet(metadata.CLIENT_ID))
+ clientSecret = metadata.Must(metadata.ProjectGet(metadata.CLIENT_SECRET))
+ useRedirectURL = *redirectURL
}
+ login.Init(clientID, clientSecret, useRedirectURL, cookieSalt, login.DEFAULT_SCOPE, *authWhiteList, *local)
+}
- if store, err = storage.New(client); err != nil {
- glog.Fatalf("Failed to create storage service client: %s", err)
+func runServer() {
+ serverURL := "https://" + *host
+ if *local {
+ serverURL = "http://" + *host + *port
}
-}
-type IndexContext struct {
- LoadFuzzListURL string
-}
+ r := mux.NewRouter()
+ r.PathPrefix("/res/").HandlerFunc(util.MakeResourceHandler(*resourcesDir))
-func getURL(router *mux.Router, name string, pairs ...string) string {
- route := router.Get(name)
- if route == nil {
- glog.Fatalf("Couldn't find any route named %s", name)
- }
+ r.HandleFunc(OAUTH2_CALLBACK_PATH, login.OAuth2CallbackHandler)
+ r.HandleFunc("/", indexHandler)
+ r.HandleFunc("/details", detailHandler)
+ r.HandleFunc("/loginstatus/", login.StatusHandler)
+ r.HandleFunc("/logout/", login.LogoutHandler)
+ r.HandleFunc("/json/version", skiaversion.JsonHandler)
+ r.HandleFunc("/json/fuzz-list", fuzzListHandler)
- routeURL, err := route.URL(pairs...)
- if err != nil {
- glog.Fatalf("Couldn't resolve route %s into a URL", routeURL)
- }
+ rootHandler := login.ForceAuth(util.LoggingGzipRequestResponse(r), OAUTH2_CALLBACK_PATH)
- return routeURL.String()
+ http.Handle("/", rootHandler)
+ glog.Infof("Ready to serve on %s", serverURL)
+ glog.Fatal(http.ListenAndServe(*port, nil))
}
-func mainHandler(w http.ResponseWriter, r *http.Request) {
- glog.Infof("Main Handler: %q\n", r.URL.Path)
- requestsCounter.Inc(1)
- if r.Method == "GET" {
- // Expand the template.
- w.Header().Set("Content-Type", "text/html")
- fuzzListURL := getURL(router, "fuzzListHandler")
- context := IndexContext{
- fuzzListURL,
- }
- if err := indexTemplate.Execute(w, context); err != nil {
- glog.Errorf("Failed to expand template: %q\n", err)
- }
+func indexHandler(w http.ResponseWriter, r *http.Request) {
+ if *local {
+ reloadTemplates()
}
-}
-// makeResourceHandler creates a static file handler that sets a caching policy.
-func makeResourceHandler() func(http.ResponseWriter, *http.Request) {
- fileServer := http.FileServer(http.Dir(config.Config.Common.ResourcePath))
- return func(w http.ResponseWriter, r *http.Request) {
- w.Header().Add("Cache-Control", string(300))
- fileServer.ServeHTTP(w, r)
- }
-}
+ w.Header().Set("Content-Type", "text/html")
-func getFuzzes(baseDir string) []string {
- results := []string{}
- glog.Infof("Opening bucket/directory: %s/%s", config.Config.Common.FuzzOutputGSBucket, baseDir)
-
- req := store.Objects.List(config.Config.Common.FuzzOutputGSBucket).Prefix(baseDir + "/").Delimiter("/")
- for req != nil {
- resp, err := req.Do()
- if err != nil {
- return results
- }
- for _, result := range resp.Prefixes {
- results = append(results, result[len(baseDir)+1:len(result)-1])
- }
- if len(resp.NextPageToken) > 0 {
- req.PageToken(resp.NextPageToken)
- } else {
- req = nil
- }
+ if err := indexTemplate.Execute(w, nil); err != nil {
+ glog.Errorf("Failed to write or encode output: %s", err)
}
- return results
}
-func fuzzListHandler(w http.ResponseWriter, r *http.Request) {
- if err := r.ParseForm(); err != nil {
- util.ReportError(w, r, err, "Failed to parse form data.")
- return
+func detailHandler(w http.ResponseWriter, r *http.Request) {
+ if *local {
+ reloadTemplates()
}
- w.Header().Set("Content-Type", "application/json")
- enc := json.NewEncoder(w)
-
- fuzzes := []string{}
+ w.Header().Set("Content-Type", "text/html")
- failed := r.FormValue("failed")
- passed := r.FormValue("passed")
-
- if failed == "true" {
- fuzzes = append(fuzzes, getFuzzes("failed")...)
- }
- if passed == "true" {
- fuzzes = append(fuzzes, getFuzzes("working")...)
- }
-
- if err := enc.Encode(fuzzes); err != nil {
+ if err := detailsTemplate.Execute(w, nil); err != nil {
glog.Errorf("Failed to write or encode output: %s", err)
}
}
-func main() {
- flag.Parse()
- Init()
+type fuzzReport []fuzzReportFile
- // Set up login
- var cookieSalt = "notverysecret"
- var clientID = "31977622648-ubjke2f3staq6ouas64r31h8f8tcbiqp.apps.googleusercontent.com"
- var clientSecret = "rK-kRY71CXmcg0v9I9KIgWci"
- var useRedirectURL = fmt.Sprintf("http://localhost%s/oauth2callback/", config.Config.FrontEnd.Port)
- if !config.Config.Common.Local {
- cookieSalt = metadata.Must(metadata.ProjectGet(metadata.COOKIESALT))
- clientID = metadata.Must(metadata.ProjectGet(metadata.CLIENT_ID))
- clientSecret = metadata.Must(metadata.ProjectGet(metadata.CLIENT_SECRET))
- useRedirectURL = config.Config.FrontEnd.RedirectURL
- }
+type fuzzReportFile struct {
+ FileName string `json:"fileName"`
+ BinaryCount int `json:"binaryCount"`
+ ApiCount int `json:"apiCount"`
+ Functions []fuzzReportFunction `json:"byFunction"`
+}
- login.Init(clientID, clientSecret, useRedirectURL, cookieSalt, login.DEFAULT_SCOPE, login.DEFAULT_DOMAIN_WHITELIST, config.Config.Common.Local)
+type fuzzReportFunction struct {
+ FunctionName string `json:"functionName"`
+ BinaryCount int `json:"binaryCount"`
+ ApiCount int `json:"apiCount"`
+ LineNumbers []fuzzReportLineNumber `json:"byLineNumber"`
+}
- // Set up the login related resources.
- router.HandleFunc(OAUTH2_CALLBACK_PATH, login.OAuth2CallbackHandler)
- router.HandleFunc("/loginstatus/", login.StatusHandler)
- router.HandleFunc("/logout/", login.LogoutHandler)
+type fuzzReportLineNumber struct {
+ LineNumber int `json:"lineNumber"`
+ BinaryCount int `json:"binaryCount"`
+ ApiCount int `json:"apiCount"`
+ BinaryDetails []fuzzReportBinary `json:"binaryReports"`
+}
- router.HandleFunc("/", mainHandler)
- router.HandleFunc("/failed", mainHandler)
- router.HandleFunc("/passed", mainHandler)
- router.PathPrefix("/res/").HandlerFunc(makeResourceHandler())
+// We make this intermediate struct so we can control the json names and disentagle the backend structure from what is displayed/visualized
+type fuzzReportBinary struct {
+ DebugStackTrace fuzz.StackTrace `json:"debugStackTrace"`
+ ReleaseStackTrace fuzz.StackTrace `json:"releaseStackTrace"`
+ HumanReadableFlags []string `json:"flags"`
+ BadBinaryName string `json:"binaryName"`
+ BinaryType string `json:"binaryType"`
+}
- jsonRouter := router.PathPrefix("/_").Subrouter()
- jsonRouter.HandleFunc("/list", fuzzListHandler).Name("fuzzListHandler")
+func fuzzListHandler(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/json")
- rootHandler := util.LoggingGzipRequestResponse(router)
- if config.Config.FrontEnd.ForceLogin {
- rootHandler = login.ForceAuth(rootHandler, OAUTH2_CALLBACK_PATH)
+ mockFuzzes := fuzzReport{
+ {
+ "foo.h", 30, 0, []fuzzReportFunction{
+ {
+ "frizzle()", 18, 0, []fuzzReportLineNumber{
+ {
+ 64, 17, 0, []fuzzReportBinary{},
+ },
+ {
+ 69, 1, 0, []fuzzReportBinary{},
+ },
+ },
+ }, {
+ "zizzle()", 12, 0, []fuzzReportLineNumber{
+ {
+ 123, 12, 0, []fuzzReportBinary{},
+ },
+ },
+ },
+ },
+ }, {
+ "bar.h", 15, 3, []fuzzReportFunction{
+ {
+ "frizzle()", 15, 3, []fuzzReportLineNumber{
+ {
+ 566, 15, 2, []fuzzReportBinary{},
+ },
+ {
+ 568, 0, 1, []fuzzReportBinary{},
+ },
+ },
+ },
+ },
+ },
+ }
+
+ if err := json.NewEncoder(w).Encode(mockFuzzes); err != nil {
+ glog.Errorf("Failed to write or encode output: %s", err)
+ return
}
-
- http.Handle("/", rootHandler)
-
- glog.Fatal(http.ListenAndServe(config.Config.FrontEnd.Port, nil))
}
« no previous file with comments | « fuzzer/elements.html ('k') | fuzzer/go/fuzz/stacktrace.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698