130 lines
4.5 KiB
Go
130 lines
4.5 KiB
Go
|
// Copyright 2020 The gVisor Authors.
|
||
|
//
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
// you may not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
// See the License for the specific language governing permissions and
|
||
|
// limitations under the License.
|
||
|
|
||
|
// Binary parser parses Benchmark data from golang benchmarks,
|
||
|
// puts it into a Schema for BigQuery, and sends it to BigQuery.
|
||
|
// parser will also initialize a table with the Benchmarks BigQuery schema.
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"io/ioutil"
|
||
|
"os"
|
||
|
|
||
|
"gvisor.dev/gvisor/runsc/flag"
|
||
|
bq "gvisor.dev/gvisor/tools/bigquery"
|
||
|
"gvisor.dev/gvisor/tools/parsers"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
initString = "init"
|
||
|
initDescription = "initializes a new table with benchmarks schema"
|
||
|
parseString = "parse"
|
||
|
parseDescription = "parses given benchmarks file and sends it to BigQuery table."
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
// The init command will create a new dataset/table in the given project and initialize
|
||
|
// the table with the schema in //tools/bigquery/bigquery.go. If the table/dataset exists
|
||
|
// or has been initialized, init has no effect and successfully returns.
|
||
|
initCmd = flag.NewFlagSet(initString, flag.ContinueOnError)
|
||
|
initProject = initCmd.String("project", "", "GCP project to send benchmarks.")
|
||
|
initDataset = initCmd.String("dataset", "", "dataset to send benchmarks data.")
|
||
|
initTable = initCmd.String("table", "", "table to send benchmarks data.")
|
||
|
|
||
|
// The parse command parses benchmark data in `file` and sends it to the
|
||
|
// requested table.
|
||
|
parseCmd = flag.NewFlagSet(parseString, flag.ContinueOnError)
|
||
|
file = parseCmd.String("file", "", "file to parse for benchmarks")
|
||
|
name = parseCmd.String("suite_name", "", "name of the benchmark suite")
|
||
|
clNumber = parseCmd.String("cl", "", "changelist number of this run")
|
||
|
gitCommit = parseCmd.String("git_commit", "", "git commit sha for this run")
|
||
|
parseProject = parseCmd.String("project", "", "GCP project to send benchmarks.")
|
||
|
parseDataset = parseCmd.String("dataset", "", "dataset to send benchmarks data.")
|
||
|
parseTable = parseCmd.String("table", "", "table to send benchmarks data.")
|
||
|
official = parseCmd.Bool("official", false, "mark input data as official.")
|
||
|
)
|
||
|
|
||
|
// initBenchmarks initializes a dataset/table in a BigQuery project.
|
||
|
func initBenchmarks(ctx context.Context) error {
|
||
|
return bq.InitBigQuery(ctx, *initProject, *initDataset, *initTable, nil)
|
||
|
}
|
||
|
|
||
|
// parseBenchmarks parses the given file into the BigQuery schema,
|
||
|
// adds some custom data for the commit, and sends the data to BigQuery.
|
||
|
func parseBenchmarks(ctx context.Context) error {
|
||
|
data, err := ioutil.ReadFile(*file)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("failed to read file: %v", err)
|
||
|
}
|
||
|
suite, err := parsers.ParseOutput(string(data), *name, *official)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("failed parse data: %v", err)
|
||
|
}
|
||
|
extraConditions := []*bq.Condition{
|
||
|
{
|
||
|
Name: "change_list",
|
||
|
Value: *clNumber,
|
||
|
},
|
||
|
{
|
||
|
Name: "commit",
|
||
|
Value: *gitCommit,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
suite.Conditions = append(suite.Conditions, extraConditions...)
|
||
|
return bq.SendBenchmarks(ctx, suite, *parseProject, *parseDataset, *parseTable, nil)
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
ctx := context.Background()
|
||
|
switch {
|
||
|
// the "init" command
|
||
|
case len(os.Args) >= 2 && os.Args[1] == initString:
|
||
|
if err := initCmd.Parse(os.Args[2:]); err != nil {
|
||
|
fmt.Fprintf(os.Stderr, "failed parse flags: %v", err)
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
if err := initBenchmarks(ctx); err != nil {
|
||
|
failure := "failed to initialize project: %s dataset: %s table: %s: %v"
|
||
|
fmt.Fprintf(os.Stderr, failure, *parseProject, *parseDataset, *parseTable, err)
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
// the "parse" command.
|
||
|
case len(os.Args) >= 2 && os.Args[1] == parseString:
|
||
|
if err := parseCmd.Parse(os.Args[2:]); err != nil {
|
||
|
fmt.Fprintf(os.Stderr, "failed parse flags: %v", err)
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
if err := parseBenchmarks(ctx); err != nil {
|
||
|
fmt.Fprintf(os.Stderr, "failed parse benchmarks: %v", err)
|
||
|
os.Exit(1)
|
||
|
}
|
||
|
default:
|
||
|
printUsage()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// printUsage prints the top level usage string.
|
||
|
func printUsage() {
|
||
|
usage := `Usage: parser <command> <flags> ...
|
||
|
|
||
|
Available commands:
|
||
|
%s %s
|
||
|
%s %s
|
||
|
`
|
||
|
fmt.Fprintf(os.Stderr, usage, initCmd.Name(), initDescription, parseCmd.Name(), parseDescription)
|
||
|
}
|