gvisor/tools/parsers/parser_main.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)
}