diff options
Diffstat (limited to 'tools/bigquery/bigquery.go')
-rw-r--r-- | tools/bigquery/bigquery.go | 260 |
1 files changed, 0 insertions, 260 deletions
diff --git a/tools/bigquery/bigquery.go b/tools/bigquery/bigquery.go deleted file mode 100644 index 5aa1fe5dc..000000000 --- a/tools/bigquery/bigquery.go +++ /dev/null @@ -1,260 +0,0 @@ -// 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. - -// Package bigquery defines a BigQuery schema for benchmarks. -// -// This package contains a schema for BigQuery and methods for publishing -// benchmark data into tables. -package bigquery - -import ( - "context" - "fmt" - "strconv" - "strings" - "time" - - bq "cloud.google.com/go/bigquery" - "google.golang.org/api/option" -) - -// Suite is the top level structure for a benchmark run. BigQuery -// will infer the schema from this. -type Suite struct { - Name string `bq:"name"` - Conditions []*Condition `bq:"conditions"` - Benchmarks []*Benchmark `bq:"benchmarks"` - Official bool `bq:"official"` - Timestamp time.Time `bq:"timestamp"` -} - -func (s *Suite) String() string { - var sb strings.Builder - s.debugString(&sb, "") - return sb.String() -} - -// writeLine writes a line of text to the given string builder with a prefix. -func writeLine(sb *strings.Builder, prefix string, format string, values ...interface{}) { - if prefix != "" { - sb.WriteString(prefix) - } - sb.WriteString(fmt.Sprintf(format, values...)) - sb.WriteString("\n") -} - -// debugString writes debug information to the given string builder with the -// given prefix. -func (s *Suite) debugString(sb *strings.Builder, prefix string) { - writeLine(sb, prefix, "Benchmark suite %s:", s.Name) - writeLine(sb, prefix, "Timestamp: %v", s.Timestamp) - if !s.Official { - writeLine(sb, prefix, " **** NOTE: Data is not official. **** ") - } - if numConditions := len(s.Conditions); numConditions == 0 { - writeLine(sb, prefix, "Conditions: None.") - } else { - writeLine(sb, prefix, "Conditions (%d):", numConditions) - for _, condition := range s.Conditions { - condition.debugString(sb, prefix+" ") - } - } - if numBenchmarks := len(s.Benchmarks); numBenchmarks == 0 { - writeLine(sb, prefix, "Benchmarks: None.") - } else { - writeLine(sb, prefix, "Benchmarks (%d):", numBenchmarks) - for _, benchmark := range s.Benchmarks { - benchmark.debugString(sb, prefix+" ") - } - } - sb.WriteString(fmt.Sprintf("End of data for benchmark suite %s.", s.Name)) -} - -// Benchmark represents an individual benchmark in a suite. -type Benchmark struct { - Name string `bq:"name"` - Condition []*Condition `bq:"cond"` - Metric []*Metric `bq:"metric"` -} - -// String implements the String method for Benchmark -func (bm *Benchmark) String() string { - var sb strings.Builder - bm.debugString(&sb, "") - return sb.String() -} - -// debugString writes debug information to the given string builder with the -// given prefix. -func (bm *Benchmark) debugString(sb *strings.Builder, prefix string) { - writeLine(sb, prefix, "Benchmark: %s", bm.Name) - if numConditions := len(bm.Condition); numConditions == 0 { - writeLine(sb, prefix, " Conditions: None.") - } else { - writeLine(sb, prefix, " Conditions (%d):", numConditions) - for _, condition := range bm.Condition { - condition.debugString(sb, prefix+" ") - } - } - if numMetrics := len(bm.Metric); numMetrics == 0 { - writeLine(sb, prefix, " Metrics: None.") - } else { - writeLine(sb, prefix, " Metrics (%d):", numMetrics) - for _, metric := range bm.Metric { - metric.debugString(sb, prefix+" ") - } - } -} - -// AddMetric adds a metric to an existing Benchmark. -func (bm *Benchmark) AddMetric(metricName, unit string, sample float64) { - m := &Metric{ - Name: metricName, - Unit: unit, - Sample: sample, - } - bm.Metric = append(bm.Metric, m) -} - -// AddCondition adds a condition to an existing Benchmark. -func (bm *Benchmark) AddCondition(name, value string) { - bm.Condition = append(bm.Condition, NewCondition(name, value)) -} - -// NewBenchmark initializes a new benchmark. -func NewBenchmark(name string, iters int) *Benchmark { - return &Benchmark{ - Name: name, - Metric: make([]*Metric, 0), - Condition: []*Condition{ - { - Name: "iterations", - Value: strconv.Itoa(iters), - }, - }, - } -} - -// Condition represents qualifiers for the benchmark or suite. For example: -// Get_Pid/1/real_time would have Benchmark Name "Get_Pid" with "1" -// and "real_time" parameters as conditions. Suite conditions include -// information such as the CL number and platform name. -type Condition struct { - Name string `bq:"name"` - Value string `bq:"value"` -} - -// NewCondition returns a new Condition with the given name and value. -func NewCondition(name, value string) *Condition { - return &Condition{ - Name: name, - Value: value, - } -} - -func (c *Condition) String() string { - var sb strings.Builder - c.debugString(&sb, "") - return sb.String() -} - -// debugString writes debug information to the given string builder with the -// given prefix. -func (c *Condition) debugString(sb *strings.Builder, prefix string) { - writeLine(sb, prefix, "Condition: %s = %s", c.Name, c.Value) -} - -// Metric holds the actual metric data and unit information for this benchmark. -type Metric struct { - Name string `bq:"name"` - Unit string `bq:"unit"` - Sample float64 `bq:"sample"` -} - -func (m *Metric) String() string { - var sb strings.Builder - m.debugString(&sb, "") - return sb.String() -} - -// debugString writes debug information to the given string builder with the -// given prefix. -func (m *Metric) debugString(sb *strings.Builder, prefix string) { - writeLine(sb, prefix, "Metric %s: %f %s", m.Name, m.Sample, m.Unit) -} - -// InitBigQuery initializes a BigQuery dataset/table in the project. If the dataset/table already exists, it is not duplicated. -func InitBigQuery(ctx context.Context, projectID, datasetID, tableID string, opts []option.ClientOption) error { - client, err := bq.NewClient(ctx, projectID, opts...) - if err != nil { - return fmt.Errorf("failed to initialize client on project %s: %v", projectID, err) - } - defer client.Close() - - dataset := client.Dataset(datasetID) - if err := dataset.Create(ctx, nil); err != nil && !checkDuplicateError(err) { - return fmt.Errorf("failed to create dataset: %s: %v", datasetID, err) - } - - table := dataset.Table(tableID) - schema, err := bq.InferSchema(Suite{}) - if err != nil { - return fmt.Errorf("failed to infer schema: %v", err) - } - - if err := table.Create(ctx, &bq.TableMetadata{Schema: schema}); err != nil && !checkDuplicateError(err) { - return fmt.Errorf("failed to create table: %s: %v", tableID, err) - } - return nil -} - -// NewBenchmarkWithMetric creates a new sending to BigQuery, initialized with a -// single iteration and single metric. -func NewBenchmarkWithMetric(name, metric, unit string, value float64) *Benchmark { - b := NewBenchmark(name, 1) - b.AddMetric(metric, unit, value) - return b -} - -// NewSuite initializes a new Suite. -func NewSuite(name string, official bool) *Suite { - return &Suite{ - Name: name, - Timestamp: time.Now().UTC(), - Benchmarks: make([]*Benchmark, 0), - Conditions: make([]*Condition, 0), - Official: official, - } -} - -// SendBenchmarks sends the slice of benchmarks to the BigQuery dataset/table. -func SendBenchmarks(ctx context.Context, suite *Suite, projectID, datasetID, tableID string, opts []option.ClientOption) error { - client, err := bq.NewClient(ctx, projectID, opts...) - if err != nil { - return fmt.Errorf("failed to initialize client on project: %s: %v", projectID, err) - } - defer client.Close() - - uploader := client.Dataset(datasetID).Table(tableID).Uploader() - if err = uploader.Put(ctx, suite); err != nil { - return fmt.Errorf("failed to upload benchmarks %s to project %s, table %s.%s: %v", suite.Name, projectID, datasetID, tableID, err) - } - - return nil -} - -// BigQuery will error "409" for duplicate tables and datasets. -func checkDuplicateError(err error) bool { - return strings.Contains(err.Error(), "googleapi: Error 409: Already Exists") -} |