2019-09-03 20:03:51 +02:00
|
|
|
// 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/trace"
|
|
|
|
|
|
2019-09-23 14:39:10 -07:00
|
|
|
"go.opentelemetry.io/experimental/streaming/exporter"
|
2019-09-03 20:03:51 +02:00
|
|
|
"go.opentelemetry.io/experimental/streaming/sdk/internal"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestEvents(t *testing.T) {
|
2019-09-23 14:39:10 -07:00
|
|
|
obs := internal.NewTestObserver()
|
|
|
|
|
_ = New(obs).WithSpan(context.Background(), "test", func(ctx context.Context) error {
|
2019-09-03 20:03:51 +02:00
|
|
|
type test1Type struct{}
|
|
|
|
|
type test2Type struct{}
|
2019-09-25 19:30:02 +02:00
|
|
|
sp := trace.CurrentSpan(ctx)
|
2019-09-03 20:03:51 +02:00
|
|
|
k1v1 := key.New("k1").String("v1")
|
|
|
|
|
k2v2 := key.New("k2").String("v2")
|
|
|
|
|
k3v3 := key.New("k3").String("v3")
|
|
|
|
|
ctx1 := context.WithValue(ctx, test1Type{}, 42)
|
2019-09-25 19:30:02 +02:00
|
|
|
sp.AddEvent(ctx1, "one two three", k1v1)
|
2019-09-03 20:03:51 +02:00
|
|
|
ctx2 := context.WithValue(ctx1, test2Type{}, "foo")
|
2019-09-25 19:30:02 +02:00
|
|
|
sp.AddEvent(ctx2, "testing", k2v2, k3v3)
|
2019-09-03 20:03:51 +02:00
|
|
|
|
2019-09-23 14:39:10 -07:00
|
|
|
got := obs.Events(exporter.ADD_EVENT)
|
2019-09-03 20:03:51 +02:00
|
|
|
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))
|
|
|
|
|
}
|
2019-09-25 19:30:02 +02:00
|
|
|
sdkSpan := sp.(*span)
|
2019-09-23 14:39:10 -07:00
|
|
|
want := []exporter.Event{
|
2019-09-03 20:03:51 +02:00
|
|
|
{
|
2019-09-23 14:39:10 -07:00
|
|
|
Type: exporter.ADD_EVENT,
|
2019-09-03 20:03:51 +02:00
|
|
|
String: "one two three",
|
|
|
|
|
Attributes: []core.KeyValue{k1v1},
|
2019-09-25 19:30:02 +02:00
|
|
|
Scope: sdkSpan.ScopeID(),
|
2019-09-03 20:03:51 +02:00
|
|
|
},
|
|
|
|
|
{
|
2019-09-23 14:39:10 -07:00
|
|
|
Type: exporter.ADD_EVENT,
|
2019-09-03 20:03:51 +02:00
|
|
|
String: "testing",
|
|
|
|
|
Attributes: []core.KeyValue{k2v2, k3v3},
|
2019-09-25 19:30:02 +02:00
|
|
|
Scope: sdkSpan.ScopeID(),
|
2019-09-03 20:03:51 +02:00
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
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)
|
2019-09-23 14:39:10 -07:00
|
|
|
obs := internal.NewTestObserver()
|
|
|
|
|
tracer := New(obs)
|
2019-09-03 20:03:51 +02:00
|
|
|
_, span := tracer.Start(
|
|
|
|
|
context.Background(),
|
|
|
|
|
"testspan",
|
|
|
|
|
trace.WithStartTime(startTime),
|
|
|
|
|
)
|
2019-09-27 10:48:10 -07:00
|
|
|
span.End(trace.WithEndTime(endTime))
|
2019-09-23 14:39:10 -07:00
|
|
|
want := []exporter.Event{
|
2019-09-03 20:03:51 +02:00
|
|
|
{
|
2019-09-23 14:39:10 -07:00
|
|
|
Type: exporter.START_SPAN,
|
2019-09-03 20:03:51 +02:00
|
|
|
Time: startTime,
|
|
|
|
|
String: "testspan",
|
|
|
|
|
},
|
|
|
|
|
{
|
2019-09-27 10:48:10 -07:00
|
|
|
Type: exporter.END_SPAN,
|
2019-09-03 20:03:51 +02:00
|
|
|
Time: endTime,
|
|
|
|
|
},
|
|
|
|
|
}
|
2019-09-27 10:48:10 -07:00
|
|
|
got := append(obs.Events(exporter.START_SPAN), obs.Events(exporter.END_SPAN)...)
|
2019-09-03 20:03:51 +02:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-23 14:39:10 -07:00
|
|
|
func diffEvents(t *testing.T, got, want []exporter.Event, extraIgnoredFields ...string) bool {
|
2019-09-03 20:03:51 +02:00
|
|
|
ignoredPaths := map[string]struct{}{
|
|
|
|
|
"Sequence": struct{}{},
|
|
|
|
|
"Context": struct{}{},
|
|
|
|
|
}
|
|
|
|
|
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()),
|
|
|
|
|
}
|
|
|
|
|
if diff := cmp.Diff(got, want, opts...); diff != "" {
|
|
|
|
|
t.Errorf("Events: -got +want %s", diff)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|