// Copyright 2022 Google LLC // // 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 import ( "context" "strings" "testing" "time" "go.opencensus.io/trace" ) // testExporter is a testing exporter for validating captured spans. type testExporter struct { spans []*trace.SpanData } func (te *testExporter) ExportSpan(s *trace.SpanData) { te.spans = append(te.spans, s) } // hasSpans checks that the exporter has all the span names // specified in the slice. It returns the unmatched names. func (te *testExporter) hasSpans(names []string) []string { matches := make(map[string]struct{}) for _, n := range names { matches[n] = struct{}{} } for _, s := range te.spans { delete(matches, s.Name) } var unmatched []string for k := range matches { unmatched = append(unmatched, k) } return unmatched } func TestIntegration_Tracing(t *testing.T) { if client == nil { t.Skip("Integration tests skipped") } ctx := context.Background() for _, tc := range []struct { description string callF func(ctx context.Context) wantSpans []string }{ { description: "fast path query", callF: func(ctx context.Context) { client.Query("SELECT SESSION_USER()").Read(ctx) }, wantSpans: []string{"bigquery.jobs.query", "cloud.google.com/go/bigquery.Query.Run"}, }, { description: "slow path query", callF: func(ctx context.Context) { q := client.Query("SELECT SESSION_USER()") q.JobTimeout = time.Hour q.Read(ctx) }, wantSpans: []string{"bigquery.jobs.insert", "bigquery.jobs.getQueryResults", "cloud.google.com/go/bigquery.Job.Read", "cloud.google.com/go/bigquery.Query.Run"}, }, { description: "table metadata", callF: func(ctx context.Context) { client.DatasetInProject("bigquery-public-data", "samples").Table("shakespeare").Metadata(ctx) }, wantSpans: []string{"bigquery.tables.get", "cloud.google.com/go/bigquery.Table.Metadata"}, }, } { exporter := &testExporter{} trace.RegisterExporter(exporter) traceCtx, span := trace.StartSpan(ctx, "testspan", trace.WithSampler(trace.AlwaysSample())) tc.callF(traceCtx) span.End() trace.UnregisterExporter(exporter) if unmatched := exporter.hasSpans(tc.wantSpans); len(unmatched) > 0 { t.Errorf("case (%s): unmatched spans: %s", tc.description, strings.Join(unmatched, ",")) } } }