mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-03-05 15:05:51 +02:00
* Add golint to linters and resolve issues. I decided to remove constructors for some of the propagation types because the constructors can be reduced to either using the zero value or a single, non optional member. * Enable gofmt and commit fixes
175 lines
4.7 KiB
Go
175 lines
4.7 KiB
Go
// Copyright 2019, OpenTelemetry 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 sdk
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
|
|
"go.opentelemetry.io/api/core"
|
|
"go.opentelemetry.io/api/key"
|
|
"go.opentelemetry.io/api/metric"
|
|
"go.opentelemetry.io/api/trace"
|
|
|
|
"go.opentelemetry.io/experimental/streaming/exporter"
|
|
"go.opentelemetry.io/experimental/streaming/sdk/internal"
|
|
)
|
|
|
|
func TestEvents(t *testing.T) {
|
|
obs := internal.NewTestObserver()
|
|
_ = New(obs).WithSpan(context.Background(), "test", func(ctx context.Context) error {
|
|
type test1Type struct{}
|
|
type test2Type struct{}
|
|
sp := trace.CurrentSpan(ctx)
|
|
k1v1 := key.New("k1").String("v1")
|
|
k2v2 := key.New("k2").String("v2")
|
|
k3v3 := key.New("k3").String("v3")
|
|
ctx1 := context.WithValue(ctx, test1Type{}, 42)
|
|
sp.AddEvent(ctx1, "one two three", k1v1)
|
|
ctx2 := context.WithValue(ctx1, test2Type{}, "foo")
|
|
sp.AddEvent(ctx2, "testing", k2v2, k3v3)
|
|
|
|
got := obs.Events(exporter.ADD_EVENT)
|
|
for idx := range got {
|
|
if got[idx].Time.IsZero() {
|
|
t.Errorf("Event %d has zero timestamp", idx)
|
|
}
|
|
got[idx].Time = time.Time{}
|
|
}
|
|
if len(got) != 2 {
|
|
t.Errorf("Expected two events, got %d", len(got))
|
|
}
|
|
sdkSpan := sp.(*span)
|
|
want := []exporter.Event{
|
|
{
|
|
Type: exporter.ADD_EVENT,
|
|
String: "one two three",
|
|
Attributes: []core.KeyValue{k1v1},
|
|
Scope: sdkSpan.ScopeID(),
|
|
},
|
|
{
|
|
Type: exporter.ADD_EVENT,
|
|
String: "testing",
|
|
Attributes: []core.KeyValue{k2v2, k3v3},
|
|
Scope: sdkSpan.ScopeID(),
|
|
},
|
|
}
|
|
if diffEvents(t, got, want) {
|
|
checkContext(t, got[0].Context, test1Type{}, 42)
|
|
checkContextMissing(t, got[0].Context, test2Type{})
|
|
checkContext(t, got[1].Context, test1Type{}, 42)
|
|
checkContext(t, got[1].Context, test2Type{}, "foo")
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func TestCustomStartEndTime(t *testing.T) {
|
|
startTime := time.Date(2019, time.August, 27, 14, 42, 0, 0, time.UTC)
|
|
endTime := startTime.Add(time.Second * 20)
|
|
obs := internal.NewTestObserver()
|
|
tracer := New(obs)
|
|
_, span := tracer.Start(
|
|
context.Background(),
|
|
"testspan",
|
|
trace.WithStartTime(startTime),
|
|
)
|
|
span.End(trace.WithEndTime(endTime))
|
|
want := []exporter.Event{
|
|
{
|
|
Type: exporter.START_SPAN,
|
|
Time: startTime,
|
|
String: "testspan",
|
|
},
|
|
{
|
|
Type: exporter.END_SPAN,
|
|
Time: endTime,
|
|
},
|
|
}
|
|
got := append(obs.Events(exporter.START_SPAN), obs.Events(exporter.END_SPAN)...)
|
|
diffEvents(t, got, want, "Scope")
|
|
}
|
|
|
|
func checkContextMissing(t *testing.T, ctx context.Context, key interface{}) bool {
|
|
gotValue := ctx.Value(key)
|
|
if gotValue != nil {
|
|
keyType := reflect.TypeOf(key)
|
|
t.Errorf("Expected %s to be missing in context", keyType)
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func checkContext(t *testing.T, ctx context.Context, key, wantValue interface{}) bool {
|
|
gotValue := ctx.Value(key)
|
|
if gotValue == nil {
|
|
keyType := reflect.TypeOf(key)
|
|
t.Errorf("Expected %s to exist in context", keyType)
|
|
return false
|
|
}
|
|
if diff := cmp.Diff(gotValue, wantValue); diff != "" {
|
|
keyType := reflect.TypeOf(key)
|
|
t.Errorf("Context value for key %s: -got +want %s", keyType, diff)
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func measurementCompare(m1, m2 metric.Measurement) bool {
|
|
// Nil descriptor normally shouldn't happen, unless there is
|
|
// some struct with the Measurement field that didn't get
|
|
// initialized.
|
|
m1Nil := m1.Descriptor == nil
|
|
m2Nil := m2.Descriptor == nil
|
|
if m1Nil != m2Nil {
|
|
return false
|
|
}
|
|
if m1Nil {
|
|
return m1.Value.AsRaw() == m2.Value.AsRaw()
|
|
}
|
|
if m1.Descriptor.ID() != m2.Descriptor.ID() {
|
|
return false
|
|
}
|
|
m2Raw := m2.Value.AsRaw()
|
|
kind := m1.Descriptor.ValueKind()
|
|
return m1.Value.RawCompare(m2Raw, kind) == 0
|
|
}
|
|
|
|
func diffEvents(t *testing.T, got, want []exporter.Event, extraIgnoredFields ...string) bool {
|
|
ignoredPaths := map[string]struct{}{
|
|
"Sequence": {},
|
|
"Context": {},
|
|
}
|
|
for _, field := range extraIgnoredFields {
|
|
ignoredPaths[field] = struct{}{}
|
|
}
|
|
opts := []cmp.Option{
|
|
cmp.FilterPath(func(path cmp.Path) bool {
|
|
_, found := ignoredPaths[path.String()]
|
|
return found
|
|
}, cmp.Ignore()),
|
|
cmp.Comparer(measurementCompare),
|
|
}
|
|
if diff := cmp.Diff(got, want, opts...); diff != "" {
|
|
t.Errorf("Events: -got +want %s", diff)
|
|
return false
|
|
}
|
|
return true
|
|
}
|