2019-08-02 22:52:55 +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 trace
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2019-08-26 20:53:12 +02:00
|
|
|
"strings"
|
2019-08-02 22:52:55 +02:00
|
|
|
"sync/atomic"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/google/go-cmp/cmp"
|
2019-08-26 18:41:15 +02:00
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
|
2019-08-02 22:52:55 +02:00
|
|
|
"go.opentelemetry.io/api/core"
|
|
|
|
"go.opentelemetry.io/api/key"
|
2019-10-17 20:13:57 +02:00
|
|
|
"go.opentelemetry.io/api/testharness"
|
|
|
|
"go.opentelemetry.io/api/trace"
|
2019-08-02 22:52:55 +02:00
|
|
|
apitrace "go.opentelemetry.io/api/trace"
|
2019-10-08 20:56:58 +02:00
|
|
|
"go.opentelemetry.io/sdk/export"
|
2019-08-02 22:52:55 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2019-10-23 08:01:33 +02:00
|
|
|
tid core.TraceID
|
2019-08-02 22:52:55 +02:00
|
|
|
sid = uint64(0x0102040810203040)
|
|
|
|
)
|
|
|
|
|
2019-10-23 08:01:33 +02:00
|
|
|
func init() {
|
|
|
|
tid, _ = core.TraceIDFromHex("01020304050607080102040810203040")
|
|
|
|
}
|
|
|
|
|
2019-10-17 20:13:57 +02:00
|
|
|
func TestTracerFollowsExpectedAPIBehaviour(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
tp, err := NewProvider(WithConfig(Config{DefaultSampler: ProbabilitySampler(0)}))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to create provider, err: %v\n", err)
|
|
|
|
}
|
2019-10-17 20:13:57 +02:00
|
|
|
harness := testharness.NewHarness(t)
|
|
|
|
subjectFactory := func() trace.Tracer {
|
2019-10-22 22:19:11 +02:00
|
|
|
return tp.GetTracer("")
|
2019-10-17 20:13:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
harness.TestTracer(subjectFactory)
|
|
|
|
}
|
|
|
|
|
2019-08-02 22:52:55 +02:00
|
|
|
type testExporter struct {
|
2019-10-08 20:56:58 +02:00
|
|
|
spans []*export.SpanData
|
2019-08-02 22:52:55 +02:00
|
|
|
}
|
|
|
|
|
2019-10-08 20:56:58 +02:00
|
|
|
func (t *testExporter) ExportSpan(ctx context.Context, d *export.SpanData) {
|
|
|
|
t.spans = append(t.spans, d)
|
2019-08-02 22:52:55 +02:00
|
|
|
}
|
|
|
|
|
2019-08-26 20:53:12 +02:00
|
|
|
func TestSetName(t *testing.T) {
|
|
|
|
samplerIsCalled := false
|
|
|
|
fooSampler := Sampler(func(p SamplingParameters) SamplingDecision {
|
|
|
|
samplerIsCalled = true
|
|
|
|
t.Logf("called sampler for name %q", p.Name)
|
2019-10-22 22:19:11 +02:00
|
|
|
return SamplingDecision{Sample: strings.HasPrefix(p.Name, "SetName/foo")}
|
2019-08-26 20:53:12 +02:00
|
|
|
})
|
2019-10-22 22:19:11 +02:00
|
|
|
tp, _ := NewProvider(WithConfig(Config{DefaultSampler: fooSampler}))
|
|
|
|
|
2019-08-26 20:53:12 +02:00
|
|
|
type testCase struct {
|
|
|
|
name string
|
|
|
|
newName string
|
|
|
|
sampledBefore bool
|
|
|
|
sampledAfter bool
|
|
|
|
}
|
|
|
|
for idx, tt := range []testCase{
|
|
|
|
{ // 0
|
|
|
|
name: "foobar",
|
|
|
|
newName: "foobaz",
|
|
|
|
sampledBefore: true,
|
|
|
|
sampledAfter: true,
|
|
|
|
},
|
|
|
|
{ // 1
|
|
|
|
name: "foobar",
|
|
|
|
newName: "barbaz",
|
|
|
|
sampledBefore: true,
|
|
|
|
sampledAfter: false,
|
|
|
|
},
|
|
|
|
{ // 2
|
|
|
|
name: "barbar",
|
|
|
|
newName: "barbaz",
|
|
|
|
sampledBefore: false,
|
|
|
|
sampledAfter: false,
|
|
|
|
},
|
|
|
|
{ // 3
|
|
|
|
name: "barbar",
|
|
|
|
newName: "foobar",
|
|
|
|
sampledBefore: false,
|
|
|
|
sampledAfter: true,
|
|
|
|
},
|
|
|
|
} {
|
2019-10-22 22:19:11 +02:00
|
|
|
span := startNamedSpan(tp, "SetName", tt.name)
|
2019-08-26 20:53:12 +02:00
|
|
|
if !samplerIsCalled {
|
|
|
|
t.Errorf("%d: the sampler was not even called during span creation", idx)
|
|
|
|
}
|
|
|
|
samplerIsCalled = false
|
|
|
|
if gotSampledBefore := span.SpanContext().IsSampled(); tt.sampledBefore != gotSampledBefore {
|
|
|
|
t.Errorf("%d: invalid sampling decision before rename, expected %v, got %v", idx, tt.sampledBefore, gotSampledBefore)
|
|
|
|
}
|
|
|
|
span.SetName(tt.newName)
|
|
|
|
if !samplerIsCalled {
|
|
|
|
t.Errorf("%d: the sampler was not even called during span rename", idx)
|
|
|
|
}
|
|
|
|
samplerIsCalled = false
|
|
|
|
if gotSampledAfter := span.SpanContext().IsSampled(); tt.sampledAfter != gotSampledAfter {
|
|
|
|
t.Errorf("%d: invalid sampling decision after rename, expected %v, got %v", idx, tt.sampledAfter, gotSampledAfter)
|
|
|
|
}
|
2019-09-27 19:48:10 +02:00
|
|
|
span.End()
|
2019-08-26 20:53:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-02 22:52:55 +02:00
|
|
|
func TestRecordingIsOff(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
tp, _ := NewProvider()
|
|
|
|
_, span := tp.GetTracer("Recording off").Start(context.Background(), "StartSpan")
|
2019-09-27 19:48:10 +02:00
|
|
|
defer span.End()
|
2019-10-11 03:07:35 +02:00
|
|
|
if span.IsRecording() == true {
|
2019-08-02 22:52:55 +02:00
|
|
|
t.Error("new span is recording events")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: [rghetia] enable sampling test when Sampling is working.
|
|
|
|
|
|
|
|
func TestStartSpanWithChildOf(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
tp, _ := NewProvider()
|
|
|
|
tr := tp.GetTracer("SpanWith ChildOf")
|
|
|
|
|
2019-08-02 22:52:55 +02:00
|
|
|
sc1 := core.SpanContext{
|
2019-09-25 23:37:36 +02:00
|
|
|
TraceID: tid,
|
|
|
|
SpanID: sid,
|
|
|
|
TraceFlags: 0x0,
|
2019-08-02 22:52:55 +02:00
|
|
|
}
|
2019-10-22 22:19:11 +02:00
|
|
|
_, s1 := tr.Start(context.Background(), "span1-unsampled-parent1", apitrace.ChildOf(sc1))
|
2019-08-02 22:52:55 +02:00
|
|
|
if err := checkChild(sc1, s1); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
_, s2 := tr.Start(context.Background(), "span2-unsampled-parent1", apitrace.ChildOf(sc1))
|
2019-08-02 22:52:55 +02:00
|
|
|
if err := checkChild(sc1, s2); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
sc2 := core.SpanContext{
|
2019-09-25 23:37:36 +02:00
|
|
|
TraceID: tid,
|
|
|
|
SpanID: sid,
|
|
|
|
TraceFlags: 0x1,
|
2019-08-02 22:52:55 +02:00
|
|
|
//Tracestate: testTracestate,
|
|
|
|
}
|
2019-10-22 22:19:11 +02:00
|
|
|
_, s3 := tr.Start(context.Background(), "span3-sampled-parent2", apitrace.ChildOf(sc2))
|
2019-08-02 22:52:55 +02:00
|
|
|
if err := checkChild(sc2, s3); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
ctx, s4 := tr.Start(context.Background(), "span4-sampled-parent2", apitrace.ChildOf(sc2))
|
2019-08-02 22:52:55 +02:00
|
|
|
if err := checkChild(sc2, s4); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
s4Sc := s4.SpanContext()
|
2019-10-22 22:19:11 +02:00
|
|
|
_, s5 := tr.Start(ctx, "span5-implicit-childof-span4")
|
2019-08-02 22:52:55 +02:00
|
|
|
if err := checkChild(s4Sc, s5); err != nil {
|
2019-10-14 22:20:03 +02:00
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStartSpanWithFollowsFrom(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
tp, _ := NewProvider()
|
|
|
|
tr := tp.GetTracer("SpanWith FollowsFrom")
|
|
|
|
|
2019-10-14 22:20:03 +02:00
|
|
|
sc1 := core.SpanContext{
|
|
|
|
TraceID: tid,
|
|
|
|
SpanID: sid,
|
|
|
|
TraceFlags: 0x0,
|
|
|
|
}
|
2019-10-22 22:19:11 +02:00
|
|
|
_, s1 := tr.Start(context.Background(), "span1-unsampled-parent1", apitrace.FollowsFrom(sc1))
|
2019-10-14 22:20:03 +02:00
|
|
|
if err := checkChild(sc1, s1); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
_, s2 := tr.Start(context.Background(), "span2-unsampled-parent1", apitrace.FollowsFrom(sc1))
|
2019-10-14 22:20:03 +02:00
|
|
|
if err := checkChild(sc1, s2); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
sc2 := core.SpanContext{
|
|
|
|
TraceID: tid,
|
|
|
|
SpanID: sid,
|
|
|
|
TraceFlags: 0x1,
|
|
|
|
//Tracestate: testTracestate,
|
|
|
|
}
|
2019-10-22 22:19:11 +02:00
|
|
|
_, s3 := tr.Start(context.Background(), "span3-sampled-parent2", apitrace.FollowsFrom(sc2))
|
2019-10-14 22:20:03 +02:00
|
|
|
if err := checkChild(sc2, s3); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
ctx, s4 := tr.Start(context.Background(), "span4-sampled-parent2", apitrace.FollowsFrom(sc2))
|
2019-10-14 22:20:03 +02:00
|
|
|
if err := checkChild(sc2, s4); err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
s4Sc := s4.SpanContext()
|
2019-10-22 22:19:11 +02:00
|
|
|
_, s5 := tr.Start(ctx, "span5-implicit-childof-span4")
|
2019-10-14 22:20:03 +02:00
|
|
|
if err := checkChild(s4Sc, s5); err != nil {
|
2019-08-02 22:52:55 +02:00
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: [rghetia] Equivalent of SpanKind Test.
|
|
|
|
|
|
|
|
func TestSetSpanAttributes(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
te := &testExporter{}
|
|
|
|
tp, _ := NewProvider(WithSyncer(te))
|
|
|
|
span := startSpan(tp, "SpanAttribute")
|
2019-08-02 22:52:55 +02:00
|
|
|
span.SetAttribute(key.New("key1").String("value1"))
|
2019-10-22 22:19:11 +02:00
|
|
|
got, err := endSpan(te, span)
|
2019-08-02 22:52:55 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-10-08 20:56:58 +02:00
|
|
|
want := &export.SpanData{
|
2019-08-02 22:52:55 +02:00
|
|
|
SpanContext: core.SpanContext{
|
2019-09-25 23:37:36 +02:00
|
|
|
TraceID: tid,
|
|
|
|
TraceFlags: 0x1,
|
2019-08-02 22:52:55 +02:00
|
|
|
},
|
2019-09-25 22:22:33 +02:00
|
|
|
ParentSpanID: sid,
|
2019-10-22 22:19:11 +02:00
|
|
|
Name: "SpanAttribute/span0",
|
2019-09-25 22:22:33 +02:00
|
|
|
Attributes: []core.KeyValue{{
|
2019-10-17 07:49:58 +02:00
|
|
|
Key: core.Key("key1"),
|
2019-09-25 22:22:33 +02:00
|
|
|
Value: core.Value{Type: core.STRING, String: "value1"},
|
|
|
|
}},
|
2019-10-24 01:25:14 +02:00
|
|
|
SpanKind: "internal",
|
2019-08-02 22:52:55 +02:00
|
|
|
HasRemoteParent: true,
|
|
|
|
}
|
|
|
|
if diff := cmp.Diff(got, want); diff != "" {
|
|
|
|
t.Errorf("SetSpanAttributes: -got +want %s", diff)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSetSpanAttributesOverLimit(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
te := &testExporter{}
|
2019-08-02 22:52:55 +02:00
|
|
|
cfg := Config{MaxAttributesPerSpan: 2}
|
2019-10-22 22:19:11 +02:00
|
|
|
tp, _ := NewProvider(WithConfig(cfg), WithSyncer(te))
|
2019-08-02 22:52:55 +02:00
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
span := startSpan(tp, "SpanAttributesOverLimit")
|
2019-08-02 22:52:55 +02:00
|
|
|
span.SetAttribute(key.New("key1").String("value1"))
|
|
|
|
span.SetAttribute(key.New("key2").String("value2"))
|
|
|
|
span.SetAttribute(key.New("key1").String("value3")) // Replace key1.
|
|
|
|
span.SetAttribute(key.New("key4").String("value4")) // Remove key2 and add key4
|
2019-10-22 22:19:11 +02:00
|
|
|
got, err := endSpan(te, span)
|
2019-08-02 22:52:55 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-10-08 20:56:58 +02:00
|
|
|
want := &export.SpanData{
|
2019-08-02 22:52:55 +02:00
|
|
|
SpanContext: core.SpanContext{
|
2019-09-25 23:37:36 +02:00
|
|
|
TraceID: tid,
|
|
|
|
TraceFlags: 0x1,
|
2019-08-02 22:52:55 +02:00
|
|
|
},
|
|
|
|
ParentSpanID: sid,
|
2019-10-22 22:19:11 +02:00
|
|
|
Name: "SpanAttributesOverLimit/span0",
|
2019-09-25 22:22:33 +02:00
|
|
|
Attributes: []core.KeyValue{
|
|
|
|
{
|
2019-10-17 07:49:58 +02:00
|
|
|
Key: core.Key("key1"),
|
2019-09-25 22:22:33 +02:00
|
|
|
Value: core.Value{Type: core.STRING, String: "value3"},
|
|
|
|
},
|
|
|
|
{
|
2019-10-17 07:49:58 +02:00
|
|
|
Key: core.Key("key4"),
|
2019-09-25 22:22:33 +02:00
|
|
|
Value: core.Value{Type: core.STRING, String: "value4"},
|
|
|
|
},
|
|
|
|
},
|
2019-10-24 01:25:14 +02:00
|
|
|
SpanKind: "internal",
|
2019-08-02 22:52:55 +02:00
|
|
|
HasRemoteParent: true,
|
|
|
|
DroppedAttributeCount: 1,
|
|
|
|
}
|
|
|
|
if diff := cmp.Diff(got, want); diff != "" {
|
|
|
|
t.Errorf("SetSpanAttributesOverLimit: -got +want %s", diff)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestEvents(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
te := &testExporter{}
|
|
|
|
tp, _ := NewProvider(WithSyncer(te))
|
|
|
|
|
|
|
|
span := startSpan(tp, "Events")
|
2019-08-02 22:52:55 +02:00
|
|
|
k1v1 := key.New("key1").String("value1")
|
|
|
|
k2v2 := key.New("key2").String("value2")
|
|
|
|
k3v3 := key.New("key3").String("value3")
|
|
|
|
|
2019-09-03 20:03:51 +02:00
|
|
|
span.AddEvent(context.Background(), "foo", key.New("key1").String("value1"))
|
|
|
|
span.AddEvent(context.Background(), "bar",
|
2019-08-02 22:52:55 +02:00
|
|
|
key.New("key2").String("value2"),
|
|
|
|
key.New("key3").String("value3"),
|
|
|
|
)
|
2019-10-22 22:19:11 +02:00
|
|
|
got, err := endSpan(te, span)
|
2019-08-02 22:52:55 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := range got.MessageEvents {
|
2019-09-09 23:59:39 +02:00
|
|
|
if !checkTime(&got.MessageEvents[i].Time) {
|
|
|
|
t.Error("exporting span: expected nonzero Event Time")
|
2019-08-02 22:52:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-08 20:56:58 +02:00
|
|
|
want := &export.SpanData{
|
2019-08-02 22:52:55 +02:00
|
|
|
SpanContext: core.SpanContext{
|
2019-09-25 23:37:36 +02:00
|
|
|
TraceID: tid,
|
|
|
|
TraceFlags: 0x1,
|
2019-08-02 22:52:55 +02:00
|
|
|
},
|
|
|
|
ParentSpanID: sid,
|
2019-10-22 22:19:11 +02:00
|
|
|
Name: "Events/span0",
|
2019-08-02 22:52:55 +02:00
|
|
|
HasRemoteParent: true,
|
2019-10-08 20:56:58 +02:00
|
|
|
MessageEvents: []export.Event{
|
2019-09-09 23:59:39 +02:00
|
|
|
{Message: "foo", Attributes: []core.KeyValue{k1v1}},
|
|
|
|
{Message: "bar", Attributes: []core.KeyValue{k2v2, k3v3}},
|
2019-08-02 22:52:55 +02:00
|
|
|
},
|
2019-10-24 01:25:14 +02:00
|
|
|
SpanKind: "internal",
|
2019-08-02 22:52:55 +02:00
|
|
|
}
|
2019-10-08 20:56:58 +02:00
|
|
|
if diff := cmp.Diff(got, want, cmp.AllowUnexported(export.Event{})); diff != "" {
|
2019-08-02 22:52:55 +02:00
|
|
|
t.Errorf("Message Events: -got +want %s", diff)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestEventsOverLimit(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
te := &testExporter{}
|
2019-08-02 22:52:55 +02:00
|
|
|
cfg := Config{MaxEventsPerSpan: 2}
|
2019-10-22 22:19:11 +02:00
|
|
|
tp, _ := NewProvider(WithConfig(cfg), WithSyncer(te))
|
|
|
|
|
|
|
|
span := startSpan(tp, "EventsOverLimit")
|
2019-08-02 22:52:55 +02:00
|
|
|
k1v1 := key.New("key1").String("value1")
|
|
|
|
k2v2 := key.New("key2").String("value2")
|
|
|
|
k3v3 := key.New("key3").String("value3")
|
|
|
|
|
2019-09-03 20:03:51 +02:00
|
|
|
span.AddEvent(context.Background(), "fooDrop", key.New("key1").String("value1"))
|
|
|
|
span.AddEvent(context.Background(), "barDrop",
|
2019-08-02 22:52:55 +02:00
|
|
|
key.New("key2").String("value2"),
|
|
|
|
key.New("key3").String("value3"),
|
|
|
|
)
|
2019-09-03 20:03:51 +02:00
|
|
|
span.AddEvent(context.Background(), "foo", key.New("key1").String("value1"))
|
|
|
|
span.AddEvent(context.Background(), "bar",
|
2019-08-02 22:52:55 +02:00
|
|
|
key.New("key2").String("value2"),
|
|
|
|
key.New("key3").String("value3"),
|
|
|
|
)
|
2019-10-22 22:19:11 +02:00
|
|
|
got, err := endSpan(te, span)
|
2019-08-02 22:52:55 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := range got.MessageEvents {
|
2019-09-09 23:59:39 +02:00
|
|
|
if !checkTime(&got.MessageEvents[i].Time) {
|
|
|
|
t.Error("exporting span: expected nonzero Event Time")
|
2019-08-02 22:52:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-08 20:56:58 +02:00
|
|
|
want := &export.SpanData{
|
2019-08-02 22:52:55 +02:00
|
|
|
SpanContext: core.SpanContext{
|
2019-09-25 23:37:36 +02:00
|
|
|
TraceID: tid,
|
|
|
|
TraceFlags: 0x1,
|
2019-08-02 22:52:55 +02:00
|
|
|
},
|
|
|
|
ParentSpanID: sid,
|
2019-10-22 22:19:11 +02:00
|
|
|
Name: "EventsOverLimit/span0",
|
2019-10-08 20:56:58 +02:00
|
|
|
MessageEvents: []export.Event{
|
2019-09-09 23:59:39 +02:00
|
|
|
{Message: "foo", Attributes: []core.KeyValue{k1v1}},
|
|
|
|
{Message: "bar", Attributes: []core.KeyValue{k2v2, k3v3}},
|
2019-08-02 22:52:55 +02:00
|
|
|
},
|
|
|
|
DroppedMessageEventCount: 2,
|
|
|
|
HasRemoteParent: true,
|
2019-10-24 01:25:14 +02:00
|
|
|
SpanKind: "internal",
|
2019-08-02 22:52:55 +02:00
|
|
|
}
|
2019-10-08 20:56:58 +02:00
|
|
|
if diff := cmp.Diff(got, want, cmp.AllowUnexported(export.Event{})); diff != "" {
|
2019-08-02 22:52:55 +02:00
|
|
|
t.Errorf("Message Event over limit: -got +want %s", diff)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-21 09:26:20 +02:00
|
|
|
func TestAddLinks(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
te := &testExporter{}
|
|
|
|
tp, _ := NewProvider(WithSyncer(te))
|
|
|
|
|
|
|
|
span := startSpan(tp, "AddLinks")
|
2019-09-21 09:26:20 +02:00
|
|
|
k1v1 := key.New("key1").String("value1")
|
|
|
|
k2v2 := key.New("key2").String("value2")
|
|
|
|
|
2019-10-23 08:01:33 +02:00
|
|
|
sc1 := core.SpanContext{TraceID: core.TraceID([16]byte{1, 1}), SpanID: 0x3}
|
|
|
|
sc2 := core.SpanContext{TraceID: core.TraceID([16]byte{1, 1}), SpanID: 0x3}
|
2019-09-21 09:26:20 +02:00
|
|
|
|
|
|
|
link1 := apitrace.Link{SpanContext: sc1, Attributes: []core.KeyValue{k1v1}}
|
|
|
|
link2 := apitrace.Link{SpanContext: sc2, Attributes: []core.KeyValue{k2v2}}
|
|
|
|
span.AddLink(link1)
|
|
|
|
span.AddLink(link2)
|
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
got, err := endSpan(te, span)
|
2019-09-21 09:26:20 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-10-08 20:56:58 +02:00
|
|
|
want := &export.SpanData{
|
2019-09-21 09:26:20 +02:00
|
|
|
SpanContext: core.SpanContext{
|
2019-09-25 23:37:36 +02:00
|
|
|
TraceID: tid,
|
|
|
|
TraceFlags: 0x1,
|
2019-09-21 09:26:20 +02:00
|
|
|
},
|
|
|
|
ParentSpanID: sid,
|
2019-10-22 22:19:11 +02:00
|
|
|
Name: "AddLinks/span0",
|
2019-09-21 09:26:20 +02:00
|
|
|
HasRemoteParent: true,
|
|
|
|
Links: []apitrace.Link{
|
|
|
|
{SpanContext: sc1, Attributes: []core.KeyValue{k1v1}},
|
|
|
|
{SpanContext: sc2, Attributes: []core.KeyValue{k2v2}},
|
|
|
|
},
|
2019-10-24 01:25:14 +02:00
|
|
|
SpanKind: "internal",
|
2019-09-21 09:26:20 +02:00
|
|
|
}
|
2019-10-08 20:56:58 +02:00
|
|
|
if diff := cmp.Diff(got, want, cmp.AllowUnexported(export.Event{})); diff != "" {
|
2019-09-21 09:26:20 +02:00
|
|
|
t.Errorf("AddLink: -got +want %s", diff)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLinks(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
te := &testExporter{}
|
|
|
|
tp, _ := NewProvider(WithSyncer(te))
|
|
|
|
|
|
|
|
span := startSpan(tp, "Links")
|
2019-09-21 09:26:20 +02:00
|
|
|
k1v1 := key.New("key1").String("value1")
|
|
|
|
k2v2 := key.New("key2").String("value2")
|
|
|
|
k3v3 := key.New("key3").String("value3")
|
|
|
|
|
2019-10-23 08:01:33 +02:00
|
|
|
sc1 := core.SpanContext{TraceID: core.TraceID([16]byte{1, 1}), SpanID: 0x3}
|
|
|
|
sc2 := core.SpanContext{TraceID: core.TraceID([16]byte{1, 1}), SpanID: 0x3}
|
2019-09-21 09:26:20 +02:00
|
|
|
|
|
|
|
span.Link(sc1, key.New("key1").String("value1"))
|
|
|
|
span.Link(sc2,
|
|
|
|
key.New("key2").String("value2"),
|
|
|
|
key.New("key3").String("value3"),
|
|
|
|
)
|
2019-10-22 22:19:11 +02:00
|
|
|
got, err := endSpan(te, span)
|
2019-09-21 09:26:20 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-10-08 20:56:58 +02:00
|
|
|
want := &export.SpanData{
|
2019-09-21 09:26:20 +02:00
|
|
|
SpanContext: core.SpanContext{
|
2019-09-25 23:37:36 +02:00
|
|
|
TraceID: tid,
|
|
|
|
TraceFlags: 0x1,
|
2019-09-21 09:26:20 +02:00
|
|
|
},
|
|
|
|
ParentSpanID: sid,
|
2019-10-22 22:19:11 +02:00
|
|
|
Name: "Links/span0",
|
2019-09-21 09:26:20 +02:00
|
|
|
HasRemoteParent: true,
|
|
|
|
Links: []apitrace.Link{
|
|
|
|
{SpanContext: sc1, Attributes: []core.KeyValue{k1v1}},
|
|
|
|
{SpanContext: sc2, Attributes: []core.KeyValue{k2v2, k3v3}},
|
|
|
|
},
|
2019-10-24 01:25:14 +02:00
|
|
|
SpanKind: "internal",
|
2019-09-21 09:26:20 +02:00
|
|
|
}
|
2019-10-08 20:56:58 +02:00
|
|
|
if diff := cmp.Diff(got, want, cmp.AllowUnexported(export.Event{})); diff != "" {
|
2019-09-21 09:26:20 +02:00
|
|
|
t.Errorf("Link: -got +want %s", diff)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLinksOverLimit(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
te := &testExporter{}
|
2019-09-21 09:26:20 +02:00
|
|
|
cfg := Config{MaxLinksPerSpan: 2}
|
2019-10-22 22:19:11 +02:00
|
|
|
|
2019-10-23 08:01:33 +02:00
|
|
|
sc1 := core.SpanContext{TraceID: core.TraceID([16]byte{1, 1}), SpanID: 0x3}
|
|
|
|
sc2 := core.SpanContext{TraceID: core.TraceID([16]byte{1, 1}), SpanID: 0x3}
|
|
|
|
sc3 := core.SpanContext{TraceID: core.TraceID([16]byte{1, 1}), SpanID: 0x3}
|
|
|
|
|
|
|
|
tp, _ := NewProvider(WithConfig(cfg), WithSyncer(te))
|
2019-10-22 22:19:11 +02:00
|
|
|
span := startSpan(tp, "LinksOverLimit")
|
2019-09-21 09:26:20 +02:00
|
|
|
|
|
|
|
k2v2 := key.New("key2").String("value2")
|
|
|
|
k3v3 := key.New("key3").String("value3")
|
|
|
|
|
|
|
|
span.Link(sc1, key.New("key1").String("value1"))
|
|
|
|
span.Link(sc2, key.New("key2").String("value2"))
|
|
|
|
span.Link(sc3, key.New("key3").String("value3"))
|
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
got, err := endSpan(te, span)
|
2019-09-21 09:26:20 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-10-08 20:56:58 +02:00
|
|
|
want := &export.SpanData{
|
2019-09-21 09:26:20 +02:00
|
|
|
SpanContext: core.SpanContext{
|
2019-09-25 23:37:36 +02:00
|
|
|
TraceID: tid,
|
|
|
|
TraceFlags: 0x1,
|
2019-09-21 09:26:20 +02:00
|
|
|
},
|
|
|
|
ParentSpanID: sid,
|
2019-10-22 22:19:11 +02:00
|
|
|
Name: "LinksOverLimit/span0",
|
2019-09-21 09:26:20 +02:00
|
|
|
Links: []apitrace.Link{
|
|
|
|
{SpanContext: sc2, Attributes: []core.KeyValue{k2v2}},
|
|
|
|
{SpanContext: sc3, Attributes: []core.KeyValue{k3v3}},
|
|
|
|
},
|
|
|
|
DroppedLinkCount: 1,
|
|
|
|
HasRemoteParent: true,
|
2019-10-24 01:25:14 +02:00
|
|
|
SpanKind: "internal",
|
2019-09-21 09:26:20 +02:00
|
|
|
}
|
2019-10-08 20:56:58 +02:00
|
|
|
if diff := cmp.Diff(got, want, cmp.AllowUnexported(export.Event{})); diff != "" {
|
2019-09-21 09:26:20 +02:00
|
|
|
t.Errorf("Link over limit: -got +want %s", diff)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-02 22:52:55 +02:00
|
|
|
func TestSetSpanName(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
te := &testExporter{}
|
|
|
|
tp, _ := NewProvider(WithSyncer(te))
|
|
|
|
|
|
|
|
want := "SetSpanName/SpanName-1"
|
|
|
|
_, span := tp.GetTracer("SetSpanName").Start(context.Background(), "SpanName-1",
|
2019-08-02 22:52:55 +02:00
|
|
|
apitrace.ChildOf(core.SpanContext{
|
2019-09-25 23:37:36 +02:00
|
|
|
TraceID: tid,
|
|
|
|
SpanID: sid,
|
|
|
|
TraceFlags: 1,
|
2019-08-02 22:52:55 +02:00
|
|
|
}),
|
|
|
|
)
|
2019-10-22 22:19:11 +02:00
|
|
|
got, err := endSpan(te, span)
|
2019-08-02 22:52:55 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if got.Name != want {
|
|
|
|
t.Errorf("span.Name: got %q; want %q", got.Name, want)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSetSpanStatus(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
te := &testExporter{}
|
|
|
|
tp, _ := NewProvider(WithSyncer(te))
|
|
|
|
|
|
|
|
span := startSpan(tp, "SpanStatus")
|
2019-08-02 22:52:55 +02:00
|
|
|
span.SetStatus(codes.Canceled)
|
2019-10-22 22:19:11 +02:00
|
|
|
got, err := endSpan(te, span)
|
2019-08-02 22:52:55 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2019-10-08 20:56:58 +02:00
|
|
|
want := &export.SpanData{
|
2019-08-02 22:52:55 +02:00
|
|
|
SpanContext: core.SpanContext{
|
2019-09-25 23:37:36 +02:00
|
|
|
TraceID: tid,
|
|
|
|
TraceFlags: 0x1,
|
2019-08-02 22:52:55 +02:00
|
|
|
},
|
|
|
|
ParentSpanID: sid,
|
2019-10-22 22:19:11 +02:00
|
|
|
Name: "SpanStatus/span0",
|
2019-10-24 01:25:14 +02:00
|
|
|
SpanKind: "internal",
|
2019-08-02 22:52:55 +02:00
|
|
|
Status: codes.Canceled,
|
|
|
|
HasRemoteParent: true,
|
|
|
|
}
|
|
|
|
if diff := cmp.Diff(got, want); diff != "" {
|
|
|
|
t.Errorf("SetSpanStatus: -got +want %s", diff)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func remoteSpanContext() core.SpanContext {
|
|
|
|
return core.SpanContext{
|
2019-09-25 23:37:36 +02:00
|
|
|
TraceID: tid,
|
|
|
|
SpanID: sid,
|
|
|
|
TraceFlags: 1,
|
2019-08-02 22:52:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// checkChild is test utility function that tests that c has fields set appropriately,
|
|
|
|
// given that it is a child span of p.
|
|
|
|
func checkChild(p core.SpanContext, apiSpan apitrace.Span) error {
|
|
|
|
s := apiSpan.(*span)
|
|
|
|
if s == nil {
|
|
|
|
return fmt.Errorf("got nil child span, want non-nil")
|
|
|
|
}
|
|
|
|
if got, want := s.spanContext.TraceIDString(), p.TraceIDString(); got != want {
|
|
|
|
return fmt.Errorf("got child trace ID %s, want %s", got, want)
|
|
|
|
}
|
|
|
|
if childID, parentID := s.spanContext.SpanIDString(), p.SpanIDString(); childID == parentID {
|
|
|
|
return fmt.Errorf("got child span ID %s, parent span ID %s; want unequal IDs", childID, parentID)
|
|
|
|
}
|
2019-09-25 23:37:36 +02:00
|
|
|
if got, want := s.spanContext.TraceFlags, p.TraceFlags; got != want {
|
2019-08-02 22:52:55 +02:00
|
|
|
return fmt.Errorf("got child trace options %d, want %d", got, want)
|
|
|
|
}
|
|
|
|
// TODO [rgheita] : Fix tracestate test
|
|
|
|
//if got, want := c.spanContext.Tracestate, p.Tracestate; got != want {
|
|
|
|
// return fmt.Errorf("got child tracestate %v, want %v", got, want)
|
|
|
|
//}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-08-26 20:53:12 +02:00
|
|
|
// startSpan starts a span with a name "span0". See startNamedSpan for
|
|
|
|
// details.
|
2019-10-22 22:19:11 +02:00
|
|
|
func startSpan(tp *Provider, trName string) apitrace.Span {
|
|
|
|
return startNamedSpan(tp, trName, "span0")
|
2019-08-26 20:53:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// startNamed Span is a test utility func that starts a span with a
|
|
|
|
// passed name and with ChildOf option. remote span context contains
|
2019-09-25 23:37:36 +02:00
|
|
|
// TraceFlags with sampled bit set. This allows the span to be
|
2019-08-26 20:53:12 +02:00
|
|
|
// automatically sampled.
|
2019-10-22 22:19:11 +02:00
|
|
|
func startNamedSpan(tp *Provider, trName, name string) apitrace.Span {
|
|
|
|
_, span := tp.GetTracer(trName).Start(
|
2019-08-02 22:52:55 +02:00
|
|
|
context.Background(),
|
2019-08-26 20:53:12 +02:00
|
|
|
name,
|
2019-08-02 22:52:55 +02:00
|
|
|
apitrace.ChildOf(remoteSpanContext()),
|
2019-10-11 03:07:35 +02:00
|
|
|
apitrace.WithRecord(),
|
2019-08-02 22:52:55 +02:00
|
|
|
)
|
|
|
|
return span
|
|
|
|
}
|
|
|
|
|
|
|
|
// endSpan is a test utility function that ends the span in the context and
|
2019-10-08 20:56:58 +02:00
|
|
|
// returns the exported export.SpanData.
|
2019-08-02 22:52:55 +02:00
|
|
|
// It requires that span be sampled using one of these methods
|
|
|
|
// 1. Passing parent span context using ChildOf option
|
|
|
|
// 2. Use WithSampler(AlwaysSample())
|
|
|
|
// 3. Configuring AlwaysSample() as default sampler
|
|
|
|
//
|
|
|
|
// It also does some basic tests on the span.
|
2019-10-08 20:56:58 +02:00
|
|
|
// It also clears spanID in the export.SpanData to make the comparison easier.
|
2019-10-22 22:19:11 +02:00
|
|
|
func endSpan(te *testExporter, span apitrace.Span) (*export.SpanData, error) {
|
2019-08-02 22:52:55 +02:00
|
|
|
|
2019-10-11 03:07:35 +02:00
|
|
|
if !span.IsRecording() {
|
|
|
|
return nil, fmt.Errorf("IsRecording: got false, want true")
|
2019-08-02 22:52:55 +02:00
|
|
|
}
|
|
|
|
if !span.SpanContext().IsSampled() {
|
|
|
|
return nil, fmt.Errorf("IsSampled: got false, want true")
|
|
|
|
}
|
2019-09-27 19:48:10 +02:00
|
|
|
span.End()
|
2019-08-02 22:52:55 +02:00
|
|
|
if len(te.spans) != 1 {
|
|
|
|
return nil, fmt.Errorf("got exported spans %#v, want one span", te.spans)
|
|
|
|
}
|
|
|
|
got := te.spans[0]
|
|
|
|
if got.SpanContext.SpanID == 0 {
|
|
|
|
return nil, fmt.Errorf("exporting span: expected nonzero SpanID")
|
|
|
|
}
|
|
|
|
got.SpanContext.SpanID = 0
|
|
|
|
if !checkTime(&got.StartTime) {
|
|
|
|
return nil, fmt.Errorf("exporting span: expected nonzero StartTime")
|
|
|
|
}
|
|
|
|
if !checkTime(&got.EndTime) {
|
|
|
|
return nil, fmt.Errorf("exporting span: expected nonzero EndTime")
|
|
|
|
}
|
|
|
|
return got, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// checkTime checks that a nonzero time was set in x, then clears it.
|
|
|
|
func checkTime(x *time.Time) bool {
|
|
|
|
if x.IsZero() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
*x = time.Time{}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2019-10-08 20:56:58 +02:00
|
|
|
type fakeExporter map[string]*export.SpanData
|
2019-08-02 22:52:55 +02:00
|
|
|
|
2019-10-08 20:56:58 +02:00
|
|
|
func (f fakeExporter) ExportSpan(ctx context.Context, s *export.SpanData) {
|
|
|
|
f[s.Name] = s
|
2019-08-02 22:52:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestEndSpanTwice(t *testing.T) {
|
2019-10-08 20:56:58 +02:00
|
|
|
spans := make(fakeExporter)
|
2019-10-22 22:19:11 +02:00
|
|
|
tp, _ := NewProvider(WithSyncer(spans))
|
2019-10-08 20:56:58 +02:00
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
span := startSpan(tp, "EndSpanTwice")
|
2019-09-27 19:48:10 +02:00
|
|
|
span.End()
|
|
|
|
span.End()
|
2019-08-02 22:52:55 +02:00
|
|
|
if len(spans) != 1 {
|
|
|
|
t.Fatalf("expected only a single span, got %#v", spans)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStartSpanAfterEnd(t *testing.T) {
|
2019-10-08 20:56:58 +02:00
|
|
|
spans := make(fakeExporter)
|
2019-10-22 22:19:11 +02:00
|
|
|
tp, _ := NewProvider(WithConfig(Config{DefaultSampler: AlwaysSample()}), WithSyncer(spans))
|
2019-10-08 20:56:58 +02:00
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
tr := tp.GetTracer("SpanAfterEnd")
|
|
|
|
ctx, span0 := tr.Start(context.Background(), "parent", apitrace.ChildOf(remoteSpanContext()))
|
|
|
|
ctx1, span1 := tr.Start(ctx, "span-1")
|
2019-09-27 19:48:10 +02:00
|
|
|
span1.End()
|
2019-08-02 22:52:55 +02:00
|
|
|
// Start a new span with the context containing span-1
|
|
|
|
// even though span-1 is ended, we still add this as a new child of span-1
|
2019-10-22 22:19:11 +02:00
|
|
|
_, span2 := tr.Start(ctx1, "span-2")
|
2019-09-27 19:48:10 +02:00
|
|
|
span2.End()
|
|
|
|
span0.End()
|
2019-08-02 22:52:55 +02:00
|
|
|
if got, want := len(spans), 3; got != want {
|
|
|
|
t.Fatalf("len(%#v) = %d; want %d", spans, got, want)
|
|
|
|
}
|
2019-10-22 22:19:11 +02:00
|
|
|
if got, want := spans["SpanAfterEnd/span-1"].SpanContext.TraceID, spans["SpanAfterEnd/parent"].SpanContext.TraceID; got != want {
|
2019-08-02 22:52:55 +02:00
|
|
|
t.Errorf("span-1.TraceID=%q; want %q", got, want)
|
|
|
|
}
|
2019-10-22 22:19:11 +02:00
|
|
|
if got, want := spans["SpanAfterEnd/span-2"].SpanContext.TraceID, spans["SpanAfterEnd/parent"].SpanContext.TraceID; got != want {
|
2019-08-02 22:52:55 +02:00
|
|
|
t.Errorf("span-2.TraceID=%q; want %q", got, want)
|
|
|
|
}
|
2019-10-22 22:19:11 +02:00
|
|
|
if got, want := spans["SpanAfterEnd/span-1"].ParentSpanID, spans["SpanAfterEnd/parent"].SpanContext.SpanID; got != want {
|
2019-08-02 22:52:55 +02:00
|
|
|
t.Errorf("span-1.ParentSpanID=%q; want %q (parent.SpanID)", got, want)
|
|
|
|
}
|
2019-10-22 22:19:11 +02:00
|
|
|
if got, want := spans["SpanAfterEnd/span-2"].ParentSpanID, spans["SpanAfterEnd/span-1"].SpanContext.SpanID; got != want {
|
2019-08-02 22:52:55 +02:00
|
|
|
t.Errorf("span-2.ParentSpanID=%q; want %q (span1.SpanID)", got, want)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestChildSpanCount(t *testing.T) {
|
2019-10-08 20:56:58 +02:00
|
|
|
spans := make(fakeExporter)
|
2019-10-22 22:19:11 +02:00
|
|
|
tp, _ := NewProvider(WithConfig(Config{DefaultSampler: AlwaysSample()}), WithSyncer(spans))
|
2019-10-08 20:56:58 +02:00
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
tr := tp.GetTracer("ChidSpanCount")
|
|
|
|
ctx, span0 := tr.Start(context.Background(), "parent")
|
|
|
|
ctx1, span1 := tr.Start(ctx, "span-1")
|
|
|
|
_, span2 := tr.Start(ctx1, "span-2")
|
2019-09-27 19:48:10 +02:00
|
|
|
span2.End()
|
|
|
|
span1.End()
|
2019-08-02 22:52:55 +02:00
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
_, span3 := tr.Start(ctx, "span-3")
|
2019-09-27 19:48:10 +02:00
|
|
|
span3.End()
|
|
|
|
span0.End()
|
2019-08-02 22:52:55 +02:00
|
|
|
if got, want := len(spans), 4; got != want {
|
|
|
|
t.Fatalf("len(%#v) = %d; want %d", spans, got, want)
|
|
|
|
}
|
2019-10-22 22:19:11 +02:00
|
|
|
if got, want := spans["ChidSpanCount/span-3"].ChildSpanCount, 0; got != want {
|
2019-08-02 22:52:55 +02:00
|
|
|
t.Errorf("span-3.ChildSpanCount=%q; want %q", got, want)
|
|
|
|
}
|
2019-10-22 22:19:11 +02:00
|
|
|
if got, want := spans["ChidSpanCount/span-2"].ChildSpanCount, 0; got != want {
|
2019-08-02 22:52:55 +02:00
|
|
|
t.Errorf("span-2.ChildSpanCount=%q; want %q", got, want)
|
|
|
|
}
|
2019-10-22 22:19:11 +02:00
|
|
|
if got, want := spans["ChidSpanCount/span-1"].ChildSpanCount, 1; got != want {
|
2019-08-02 22:52:55 +02:00
|
|
|
t.Errorf("span-1.ChildSpanCount=%q; want %q", got, want)
|
|
|
|
}
|
2019-10-22 22:19:11 +02:00
|
|
|
if got, want := spans["ChidSpanCount/parent"].ChildSpanCount, 2; got != want {
|
2019-08-02 22:52:55 +02:00
|
|
|
t.Errorf("parent.ChildSpanCount=%q; want %q", got, want)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-27 19:48:10 +02:00
|
|
|
func TestNilSpanEnd(t *testing.T) {
|
2019-08-02 22:52:55 +02:00
|
|
|
var span *span
|
2019-09-27 19:48:10 +02:00
|
|
|
span.End()
|
2019-08-02 22:52:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestExecutionTracerTaskEnd(t *testing.T) {
|
|
|
|
var n uint64
|
2019-10-22 22:19:11 +02:00
|
|
|
tp, _ := NewProvider(WithConfig(Config{DefaultSampler: NeverSample()}))
|
|
|
|
tr := tp.GetTracer("Execution Tracer Task End")
|
|
|
|
|
2019-08-02 22:52:55 +02:00
|
|
|
executionTracerTaskEnd := func() {
|
|
|
|
atomic.AddUint64(&n, 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
var spans []*span
|
2019-10-22 22:19:11 +02:00
|
|
|
_, apiSpan := tr.Start(context.Background(), "foo")
|
2019-08-02 22:52:55 +02:00
|
|
|
s := apiSpan.(*span)
|
|
|
|
|
|
|
|
s.executionTracerTaskEnd = executionTracerTaskEnd
|
|
|
|
spans = append(spans, s) // never sample
|
|
|
|
|
2019-10-23 08:01:33 +02:00
|
|
|
tID, _ := core.TraceIDFromHex("0102030405060708090a0b0c0d0e0f")
|
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
_, apiSpan = tr.Start(
|
2019-08-02 22:52:55 +02:00
|
|
|
context.Background(),
|
|
|
|
"foo",
|
|
|
|
apitrace.ChildOf(
|
|
|
|
core.SpanContext{
|
2019-10-23 08:01:33 +02:00
|
|
|
TraceID: tID,
|
2019-09-25 23:37:36 +02:00
|
|
|
SpanID: uint64(0x0001020304050607),
|
|
|
|
TraceFlags: 0,
|
2019-08-02 22:52:55 +02:00
|
|
|
},
|
|
|
|
),
|
|
|
|
)
|
|
|
|
s = apiSpan.(*span)
|
|
|
|
s.executionTracerTaskEnd = executionTracerTaskEnd
|
|
|
|
spans = append(spans, s) // parent not sampled
|
|
|
|
|
2019-10-22 22:19:11 +02:00
|
|
|
//tp.ApplyConfig(Config{DefaultSampler: AlwaysSample()})
|
|
|
|
_, apiSpan = tr.Start(context.Background(), "foo")
|
2019-08-02 22:52:55 +02:00
|
|
|
s = apiSpan.(*span)
|
|
|
|
s.executionTracerTaskEnd = executionTracerTaskEnd
|
|
|
|
spans = append(spans, s) // always sample
|
|
|
|
|
|
|
|
for _, span := range spans {
|
2019-09-27 19:48:10 +02:00
|
|
|
span.End()
|
2019-08-02 22:52:55 +02:00
|
|
|
}
|
|
|
|
if got, want := n, uint64(len(spans)); got != want {
|
|
|
|
t.Fatalf("Execution tracer task ended for %v spans; want %v", got, want)
|
|
|
|
}
|
|
|
|
}
|
2019-09-03 20:03:51 +02:00
|
|
|
|
|
|
|
func TestCustomStartEndTime(t *testing.T) {
|
2019-10-22 22:19:11 +02:00
|
|
|
var te testExporter
|
|
|
|
tp, _ := NewProvider(WithSyncer(&te), WithConfig(Config{DefaultSampler: AlwaysSample()}))
|
|
|
|
|
2019-09-03 20:03:51 +02:00
|
|
|
startTime := time.Date(2019, time.August, 27, 14, 42, 0, 0, time.UTC)
|
|
|
|
endTime := startTime.Add(time.Second * 20)
|
2019-10-22 22:19:11 +02:00
|
|
|
_, span := tp.GetTracer("Custom Start and End time").Start(
|
2019-09-03 20:03:51 +02:00
|
|
|
context.Background(),
|
|
|
|
"testspan",
|
|
|
|
apitrace.WithStartTime(startTime),
|
|
|
|
)
|
2019-09-27 19:48:10 +02:00
|
|
|
span.End(apitrace.WithEndTime(endTime))
|
2019-10-08 20:56:58 +02:00
|
|
|
|
2019-09-03 20:03:51 +02:00
|
|
|
if len(te.spans) != 1 {
|
|
|
|
t.Fatalf("got exported spans %#v, want one span", te.spans)
|
|
|
|
}
|
|
|
|
got := te.spans[0]
|
|
|
|
if got.StartTime != startTime {
|
|
|
|
t.Errorf("expected start time to be %s, got %s", startTime, got.StartTime)
|
|
|
|
}
|
|
|
|
if got.EndTime != endTime {
|
|
|
|
t.Errorf("expected end time to be %s, got %s", endTime, got.EndTime)
|
|
|
|
}
|
|
|
|
}
|
2019-10-24 01:25:14 +02:00
|
|
|
|
|
|
|
func TestWithSpanKind(t *testing.T) {
|
|
|
|
var te testExporter
|
|
|
|
tp, _ := NewProvider(WithSyncer(&te), WithConfig(Config{DefaultSampler: AlwaysSample()}))
|
|
|
|
tr := tp.GetTracer("withSpanKind")
|
|
|
|
|
|
|
|
_, span := tr.Start(context.Background(), "WithoutSpanKind")
|
|
|
|
spanData, err := endSpan(&te, span)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
if spanData.SpanKind != apitrace.SpanKindInternal {
|
|
|
|
t.Errorf("Default value of Spankind should be Internal: got %+v, want %+v\n", spanData.SpanKind, apitrace.SpanKindInternal)
|
|
|
|
}
|
|
|
|
|
|
|
|
sks := []apitrace.SpanKind{
|
|
|
|
apitrace.SpanKindInternal,
|
|
|
|
apitrace.SpanKindServer,
|
|
|
|
apitrace.SpanKindClient,
|
|
|
|
apitrace.SpanKindProducer,
|
|
|
|
apitrace.SpanKindConsumer,
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, sk := range sks {
|
|
|
|
te.spans = nil
|
|
|
|
|
|
|
|
_, span := tr.Start(context.Background(), fmt.Sprintf("SpanKind-%v", sk), apitrace.WithSpanKind(sk))
|
|
|
|
spanData, err := endSpan(&te, span)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
if spanData.SpanKind != sk {
|
|
|
|
t.Errorf("WithSpanKind check: got %+v, want %+v\n", spanData.SpanKind, sks)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|