github.com/thiagoyeds/go-cloud@v0.26.0/internal/testing/octest/exporter.go (about) 1 // Copyright 2019 The Go Cloud Development Kit Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package octest supports testing of OpenCensus integrations. 16 package octest 17 18 // This code was copied from cloud.google.com/go/internal/testutil/trace.go 19 20 import ( 21 "log" 22 "sync" 23 "time" 24 25 "go.opencensus.io/stats/view" 26 "go.opencensus.io/trace" 27 ) 28 29 // TestExporter is an exporter of OpenCensus traces and metrics, for testing. 30 // It should be created with NewTestExporter. 31 type TestExporter struct { 32 mu sync.Mutex 33 spans []*trace.SpanData 34 Stats chan *view.Data 35 } 36 37 // NewTestExporter creates a TestExporter and registers it with OpenCensus. 38 func NewTestExporter(views []*view.View) *TestExporter { 39 te := &TestExporter{Stats: make(chan *view.Data)} 40 41 // Register for metrics. 42 view.RegisterExporter(te) 43 // The reporting period will affect how long it takes to get stats (view.Data). 44 // We want it short so tests don't take too long, but long enough so that all 45 // the actions in a test complete. 46 // If the period is too short, then some actions may not be finished when the first 47 // call to ExportView happens. diffCounts checks for matching counts, so it will 48 // fail in that case. 49 // Tests that use the exporter (search for TestOpenCensus) are designed to avoid 50 // network traffic or computation, so they finish quickly. But we must account for 51 // the race detector, which slows everything down. 52 view.SetReportingPeriod(100 * time.Millisecond) 53 if err := view.Register(views...); err != nil { 54 log.Fatal(err) 55 } 56 57 // Register for traces. 58 trace.RegisterExporter(te) 59 trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) 60 61 return te 62 } 63 64 // ExportSpan "exports" a span by remembering it. 65 func (te *TestExporter) ExportSpan(s *trace.SpanData) { 66 te.mu.Lock() 67 defer te.mu.Unlock() 68 te.spans = append(te.spans, s) 69 } 70 71 // ExportView exports a view by writing it to the Stats channel. 72 func (te *TestExporter) ExportView(vd *view.Data) { 73 if len(vd.Rows) > 0 { 74 select { 75 case te.Stats <- vd: 76 default: 77 } 78 } 79 } 80 81 func (te *TestExporter) Spans() []*trace.SpanData { 82 te.mu.Lock() 83 defer te.mu.Unlock() 84 return te.spans 85 } 86 87 // Counts returns the first exported data that includes aggregated counts. 88 func (te *TestExporter) Counts() []*view.Row { 89 // Wait for counts. Expect all counts to arrive in the same view.Data. 90 for { 91 data := <-te.Stats 92 if _, ok := data.Rows[0].Data.(*view.CountData); !ok { 93 continue 94 } 95 return data.Rows 96 } 97 } 98 99 // Unregister unregisters the exporter from OpenCensus. 100 func (te *TestExporter) Unregister() { 101 view.UnregisterExporter(te) 102 trace.UnregisterExporter(te) 103 view.SetReportingPeriod(0) // reset to default value 104 }