1// Copyright The OpenTelemetry 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// http://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 15package internal_test 16 17import ( 18 "context" 19 "testing" 20 21 octrace "go.opencensus.io/trace" 22 23 "go.opentelemetry.io/otel/bridge/opencensus/internal" 24 "go.opentelemetry.io/otel/bridge/opencensus/internal/oc2otel" 25 "go.opentelemetry.io/otel/bridge/opencensus/internal/otel2oc" 26 "go.opentelemetry.io/otel/trace" 27) 28 29type handler struct{ err error } 30 31func (h *handler) Handle(e error) { h.err = e } 32 33func withHandler() (*handler, func()) { 34 h := new(handler) 35 original := internal.Handle 36 internal.Handle = h.Handle 37 return h, func() { internal.Handle = original } 38} 39 40type tracer struct { 41 ctx context.Context 42 name string 43 opts []trace.SpanStartOption 44} 45 46func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) { 47 t.ctx, t.name, t.opts = ctx, name, opts 48 noop := trace.NewNoopTracerProvider().Tracer("testing") 49 return noop.Start(ctx, name, opts...) 50} 51 52type ctxKey string 53 54func TestTracerStartSpan(t *testing.T) { 55 h, restore := withHandler() 56 defer restore() 57 58 otelTracer := &tracer{} 59 ocTracer := internal.NewTracer(otelTracer) 60 61 ctx := context.WithValue(context.Background(), ctxKey("key"), "value") 62 name := "testing span" 63 ocTracer.StartSpan(ctx, name, octrace.WithSpanKind(octrace.SpanKindClient)) 64 if h.err != nil { 65 t.Fatalf("OC tracer.StartSpan errored: %v", h.err) 66 } 67 68 if otelTracer.ctx != ctx { 69 t.Error("OTel tracer.Start called with wrong context") 70 } 71 if otelTracer.name != name { 72 t.Error("OTel tracer.Start called with wrong name") 73 } 74 sk := trace.SpanKindClient 75 c := trace.NewSpanStartConfig(otelTracer.opts...) 76 if c.SpanKind() != sk { 77 t.Errorf("OTel tracer.Start called with wrong options: %#v", c) 78 } 79} 80 81func TestTracerStartSpanReportsErrors(t *testing.T) { 82 h, restore := withHandler() 83 defer restore() 84 85 ocTracer := internal.NewTracer(&tracer{}) 86 ocTracer.StartSpan(context.Background(), "", octrace.WithSampler(octrace.AlwaysSample())) 87 if h.err == nil { 88 t.Error("OC tracer.StartSpan no error when converting Sampler") 89 } 90} 91 92func TestTracerStartSpanWithRemoteParent(t *testing.T) { 93 otelTracer := new(tracer) 94 ocTracer := internal.NewTracer(otelTracer) 95 sc := octrace.SpanContext{TraceID: [16]byte{1}, SpanID: [8]byte{1}} 96 converted := oc2otel.SpanContext(sc).WithRemote(true) 97 98 ocTracer.StartSpanWithRemoteParent(context.Background(), "", sc) 99 100 got := trace.SpanContextFromContext(otelTracer.ctx) 101 if !got.Equal(converted) { 102 t.Error("tracer.StartSpanWithRemoteParent failed to set remote parent") 103 } 104} 105 106func TestTracerFromContext(t *testing.T) { 107 sc := trace.NewSpanContext(trace.SpanContextConfig{ 108 TraceID: [16]byte{1}, 109 SpanID: [8]byte{1}, 110 }) 111 ctx := trace.ContextWithSpanContext(context.Background(), sc) 112 113 noop := trace.NewNoopTracerProvider().Tracer("TestTracerFromContext") 114 // Test using the fact that the No-Op span will propagate a span context . 115 ctx, _ = noop.Start(ctx, "test") 116 117 got := internal.NewTracer(noop).FromContext(ctx).SpanContext() 118 // Do not test the convedsion, only that the propagtion. 119 want := otel2oc.SpanContext(sc) 120 if got != want { 121 t.Errorf("tracer.FromContext returned wrong context: %#v", got) 122 } 123} 124 125func TestTracerNewContext(t *testing.T) { 126 sc := trace.NewSpanContext(trace.SpanContextConfig{ 127 TraceID: [16]byte{1}, 128 SpanID: [8]byte{1}, 129 }) 130 ctx := trace.ContextWithSpanContext(context.Background(), sc) 131 132 noop := trace.NewNoopTracerProvider().Tracer("TestTracerNewContext") 133 // Test using the fact that the No-Op span will propagate a span context . 134 _, s := noop.Start(ctx, "test") 135 136 ocTracer := internal.NewTracer(noop) 137 ctx = ocTracer.NewContext(context.Background(), internal.NewSpan(s)) 138 got := trace.SpanContextFromContext(ctx) 139 140 if !got.Equal(sc) { 141 t.Error("tracer.NewContext did not attach Span to context") 142 } 143} 144 145type differentSpan struct { 146 octrace.SpanInterface 147} 148 149func (s *differentSpan) String() string { return "testing span" } 150 151func TestTracerNewContextErrors(t *testing.T) { 152 h, restore := withHandler() 153 defer restore() 154 155 ocTracer := internal.NewTracer(&tracer{}) 156 ocSpan := octrace.NewSpan(&differentSpan{}) 157 ocTracer.NewContext(context.Background(), ocSpan) 158 if h.err == nil { 159 t.Error("tracer.NewContext did not error for unrecognized span") 160 } 161} 162