You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-11-23 22:34:47 +02:00
Add OC bridge internal unit tests (#2164)
This commit is contained in:
56
bridge/opencensus/internal/oc2otel/attributes_test.go
Normal file
56
bridge/opencensus/internal/oc2otel/attributes_test.go
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright The 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 oc2otel
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
octrace "go.opencensus.io/trace"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
func TestAttributes(t *testing.T) {
|
||||
in := []octrace.Attribute{
|
||||
octrace.BoolAttribute("bool", true),
|
||||
octrace.Int64Attribute("int64", 49),
|
||||
octrace.Float64Attribute("float64", 1.618),
|
||||
octrace.StringAttribute("key", "val"),
|
||||
}
|
||||
|
||||
want := []attribute.KeyValue{
|
||||
attribute.Bool("bool", true),
|
||||
attribute.Int64("int64", 49),
|
||||
attribute.Float64("float64", 1.618),
|
||||
attribute.String("key", "val"),
|
||||
}
|
||||
got := Attributes(in)
|
||||
|
||||
if len(got) != len(want) {
|
||||
t.Errorf("Attributes conversion failed: want %#v, got %#v", want, got)
|
||||
}
|
||||
for i := range got {
|
||||
if g, w := got[i], want[i]; g != w {
|
||||
t.Errorf("Attributes conversion: want %#v, got %#v", w, g)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttributeValueUnknown(t *testing.T) {
|
||||
got := AttributeValue([]byte{})
|
||||
if got != attribute.StringValue("unknown") {
|
||||
t.Errorf("AttributeValue of unknown wrong: %#v", got)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright The 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 oc2otel
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
octrace "go.opencensus.io/trace"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
func TestStartOptionsSpanKind(t *testing.T) {
|
||||
conv := map[int]trace.SpanKind{
|
||||
octrace.SpanKindClient: trace.SpanKindClient,
|
||||
octrace.SpanKindServer: trace.SpanKindServer,
|
||||
octrace.SpanKindUnspecified: trace.SpanKindUnspecified,
|
||||
}
|
||||
|
||||
for oc, otel := range conv {
|
||||
ocOpts := []octrace.StartOption{octrace.WithSpanKind(oc)}
|
||||
otelOpts, err := StartOptions(ocOpts)
|
||||
if err != nil {
|
||||
t.Errorf("StartOptions errored: %v", err)
|
||||
continue
|
||||
}
|
||||
c := trace.NewSpanStartConfig(otelOpts...)
|
||||
if c.SpanKind() != otel {
|
||||
t.Errorf("conversion of SpanKind start option: got %v, want %v", c.SpanKind(), otel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStartOptionsSamplerErrors(t *testing.T) {
|
||||
ocOpts := []octrace.StartOption{octrace.WithSampler(octrace.AlwaysSample())}
|
||||
_, err := StartOptions(ocOpts)
|
||||
if err == nil {
|
||||
t.Error("StartOptions should error Sampler option")
|
||||
}
|
||||
}
|
||||
264
bridge/opencensus/internal/span_test.go
Normal file
264
bridge/opencensus/internal/span_test.go
Normal file
@@ -0,0 +1,264 @@
|
||||
// Copyright The 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 internal_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
octrace "go.opencensus.io/trace"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/bridge/opencensus/internal"
|
||||
"go.opentelemetry.io/otel/bridge/opencensus/internal/oc2otel"
|
||||
"go.opentelemetry.io/otel/bridge/opencensus/internal/otel2oc"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
type span struct {
|
||||
trace.Span
|
||||
|
||||
recording bool
|
||||
ended bool
|
||||
sc trace.SpanContext
|
||||
name string
|
||||
sCode codes.Code
|
||||
sMsg string
|
||||
attrs []attribute.KeyValue
|
||||
eName string
|
||||
eOpts []trace.EventOption
|
||||
}
|
||||
|
||||
func (s *span) IsRecording() bool { return s.recording }
|
||||
func (s *span) End(...trace.SpanEndOption) { s.ended = true }
|
||||
func (s *span) SpanContext() trace.SpanContext { return s.sc }
|
||||
func (s *span) SetName(n string) { s.name = n }
|
||||
func (s *span) SetStatus(c codes.Code, d string) { s.sCode, s.sMsg = c, d }
|
||||
func (s *span) SetAttributes(a ...attribute.KeyValue) { s.attrs = a }
|
||||
func (s *span) AddEvent(n string, o ...trace.EventOption) { s.eName, s.eOpts = n, o }
|
||||
|
||||
func TestSpanIsRecordingEvents(t *testing.T) {
|
||||
s := &span{recording: true}
|
||||
ocS := internal.NewSpan(s)
|
||||
if !ocS.IsRecordingEvents() {
|
||||
t.Errorf("span.IsRecordingEvents() = false, want true")
|
||||
}
|
||||
s.recording = false
|
||||
if ocS.IsRecordingEvents() {
|
||||
t.Errorf("span.IsRecordingEvents() = true, want false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpanEnd(t *testing.T) {
|
||||
s := new(span)
|
||||
ocS := internal.NewSpan(s)
|
||||
if s.ended {
|
||||
t.Fatal("new span already ended")
|
||||
}
|
||||
|
||||
ocS.End()
|
||||
if !s.ended {
|
||||
t.Error("span.End() did not end OpenTelemetry span")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpanSpanContext(t *testing.T) {
|
||||
sc := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: [16]byte{1},
|
||||
SpanID: [8]byte{1},
|
||||
})
|
||||
// Do not test the conversion, only that the method is called.
|
||||
converted := otel2oc.SpanContext(sc)
|
||||
|
||||
s := &span{sc: sc}
|
||||
ocS := internal.NewSpan(s)
|
||||
if ocS.SpanContext() != converted {
|
||||
t.Error("span.SpanContext did not use OpenTelemetry SpanContext")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpanSetName(t *testing.T) {
|
||||
// OpenCensus does not set a name if not recording.
|
||||
s := &span{recording: true}
|
||||
ocS := internal.NewSpan(s)
|
||||
name := "test name"
|
||||
ocS.SetName(name)
|
||||
if s.name != name {
|
||||
t.Error("span.SetName did not set OpenTelemetry span name")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpanSetStatus(t *testing.T) {
|
||||
// OpenCensus does not set a status if not recording.
|
||||
s := &span{recording: true}
|
||||
ocS := internal.NewSpan(s)
|
||||
|
||||
c, d := codes.Error, "error"
|
||||
status := octrace.Status{Code: int32(c), Message: d}
|
||||
ocS.SetStatus(status)
|
||||
|
||||
if s.sCode != c {
|
||||
t.Error("span.SetStatus failed to set OpenTelemetry status code")
|
||||
}
|
||||
if s.sMsg != d {
|
||||
t.Error("span.SetStatus failed to set OpenTelemetry status description")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpanAddAttributes(t *testing.T) {
|
||||
attrs := []octrace.Attribute{
|
||||
octrace.BoolAttribute("a", true),
|
||||
}
|
||||
// Do not test the conversion, only that the method is called.
|
||||
converted := oc2otel.Attributes(attrs)
|
||||
|
||||
// OpenCensus does not set attributes if not recording.
|
||||
s := &span{recording: true}
|
||||
ocS := internal.NewSpan(s)
|
||||
ocS.AddAttributes(attrs...)
|
||||
|
||||
if len(s.attrs) != len(converted) || s.attrs[0] != converted[0] {
|
||||
t.Error("span.AddAttributes failed to set OpenTelemetry attributes")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpanAnnotate(t *testing.T) {
|
||||
name := "annotation"
|
||||
attrs := []octrace.Attribute{
|
||||
octrace.BoolAttribute("a", true),
|
||||
}
|
||||
// Do not test the conversion, only that the method is called.
|
||||
want := oc2otel.Attributes(attrs)
|
||||
|
||||
// OpenCensus does not set events if not recording.
|
||||
s := &span{recording: true}
|
||||
ocS := internal.NewSpan(s)
|
||||
ocS.Annotate(attrs, name)
|
||||
|
||||
if s.eName != name {
|
||||
t.Error("span.Annotate did not set event name")
|
||||
}
|
||||
|
||||
got := trace.NewEventConfig(s.eOpts...).Attributes()
|
||||
if len(want) != len(got) || want[0] != got[0] {
|
||||
t.Error("span.Annotate did not set event options")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpanAnnotatef(t *testing.T) {
|
||||
format := "annotation %s"
|
||||
attrs := []octrace.Attribute{
|
||||
octrace.BoolAttribute("a", true),
|
||||
}
|
||||
// Do not test the conversion, only that the method is called.
|
||||
want := oc2otel.Attributes(attrs)
|
||||
|
||||
// OpenCensus does not set events if not recording.
|
||||
s := &span{recording: true}
|
||||
ocS := internal.NewSpan(s)
|
||||
ocS.Annotatef(attrs, format, "a")
|
||||
|
||||
if s.eName != "annotation a" {
|
||||
t.Error("span.Annotatef did not set event name")
|
||||
}
|
||||
|
||||
got := trace.NewEventConfig(s.eOpts...).Attributes()
|
||||
if len(want) != len(got) || want[0] != got[0] {
|
||||
t.Error("span.Annotatef did not set event options")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpanAddMessageSendEvent(t *testing.T) {
|
||||
var u, c int64 = 1, 2
|
||||
|
||||
// OpenCensus does not set events if not recording.
|
||||
s := &span{recording: true}
|
||||
ocS := internal.NewSpan(s)
|
||||
ocS.AddMessageSendEvent(0, u, c)
|
||||
|
||||
if s.eName != internal.MessageSendEvent {
|
||||
t.Error("span.AddMessageSendEvent did not set event name")
|
||||
}
|
||||
|
||||
got := trace.NewEventConfig(s.eOpts...).Attributes()
|
||||
if len(got) != 2 {
|
||||
t.Fatalf("span.AddMessageSendEvent set %d attributes, want 2", len(got))
|
||||
}
|
||||
|
||||
want := attribute.KeyValue{Key: internal.UncompressedKey, Value: attribute.Int64Value(u)}
|
||||
if got[0] != want {
|
||||
t.Errorf("span.AddMessageSendEvent wrong uncompressed attribute: %v", got[0])
|
||||
}
|
||||
|
||||
want = attribute.KeyValue{Key: internal.CompressedKey, Value: attribute.Int64Value(c)}
|
||||
if got[1] != want {
|
||||
t.Errorf("span.AddMessageSendEvent wrong compressed attribute: %v", got[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpanAddMessageReceiveEvent(t *testing.T) {
|
||||
var u, c int64 = 3, 4
|
||||
|
||||
// OpenCensus does not set events if not recording.
|
||||
s := &span{recording: true}
|
||||
ocS := internal.NewSpan(s)
|
||||
ocS.AddMessageReceiveEvent(0, u, c)
|
||||
|
||||
if s.eName != internal.MessageReceiveEvent {
|
||||
t.Error("span.AddMessageReceiveEvent did not set event name")
|
||||
}
|
||||
|
||||
got := trace.NewEventConfig(s.eOpts...).Attributes()
|
||||
if len(got) != 2 {
|
||||
t.Fatalf("span.AddMessageReceiveEvent set %d attributes, want 2", len(got))
|
||||
}
|
||||
|
||||
want := attribute.KeyValue{Key: internal.UncompressedKey, Value: attribute.Int64Value(u)}
|
||||
if got[0] != want {
|
||||
t.Errorf("span.AddMessageReceiveEvent wrong uncompressed attribute: %v", got[0])
|
||||
}
|
||||
|
||||
want = attribute.KeyValue{Key: internal.CompressedKey, Value: attribute.Int64Value(c)}
|
||||
if got[1] != want {
|
||||
t.Errorf("span.AddMessageReceiveEvent wrong compressed attribute: %v", got[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpanAddLinkFails(t *testing.T) {
|
||||
h, restore := withHandler()
|
||||
defer restore()
|
||||
|
||||
// OpenCensus does not try to set links if not recording.
|
||||
s := &span{recording: true}
|
||||
ocS := internal.NewSpan(s)
|
||||
ocS.AddLink(octrace.Link{})
|
||||
|
||||
if h.err == nil {
|
||||
t.Error("span.AddLink failed to raise an error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpanString(t *testing.T) {
|
||||
sc := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: [16]byte{1},
|
||||
SpanID: [8]byte{1},
|
||||
})
|
||||
|
||||
s := &span{sc: sc}
|
||||
ocS := internal.NewSpan(s)
|
||||
if expected := "span 0100000000000000"; ocS.String() != expected {
|
||||
t.Errorf("span.String = %q, not %q", ocS.String(), expected)
|
||||
}
|
||||
}
|
||||
161
bridge/opencensus/internal/tracer_test.go
Normal file
161
bridge/opencensus/internal/tracer_test.go
Normal file
@@ -0,0 +1,161 @@
|
||||
// Copyright The 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 internal_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
octrace "go.opencensus.io/trace"
|
||||
|
||||
"go.opentelemetry.io/otel/bridge/opencensus/internal"
|
||||
"go.opentelemetry.io/otel/bridge/opencensus/internal/oc2otel"
|
||||
"go.opentelemetry.io/otel/bridge/opencensus/internal/otel2oc"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
type handler struct{ err error }
|
||||
|
||||
func (h *handler) Handle(e error) { h.err = e }
|
||||
|
||||
func withHandler() (*handler, func()) {
|
||||
h := new(handler)
|
||||
original := internal.Handle
|
||||
internal.Handle = h.Handle
|
||||
return h, func() { internal.Handle = original }
|
||||
}
|
||||
|
||||
type tracer struct {
|
||||
ctx context.Context
|
||||
name string
|
||||
opts []trace.SpanStartOption
|
||||
}
|
||||
|
||||
func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
|
||||
t.ctx, t.name, t.opts = ctx, name, opts
|
||||
noop := trace.NewNoopTracerProvider().Tracer("testing")
|
||||
return noop.Start(ctx, name, opts...)
|
||||
}
|
||||
|
||||
type ctxKey string
|
||||
|
||||
func TestTracerStartSpan(t *testing.T) {
|
||||
h, restore := withHandler()
|
||||
defer restore()
|
||||
|
||||
otelTracer := &tracer{}
|
||||
ocTracer := internal.NewTracer(otelTracer)
|
||||
|
||||
ctx := context.WithValue(context.Background(), ctxKey("key"), "value")
|
||||
name := "testing span"
|
||||
ocTracer.StartSpan(ctx, name, octrace.WithSpanKind(octrace.SpanKindClient))
|
||||
if h.err != nil {
|
||||
t.Fatalf("OC tracer.StartSpan errored: %v", h.err)
|
||||
}
|
||||
|
||||
if otelTracer.ctx != ctx {
|
||||
t.Error("OTel tracer.Start called with wrong context")
|
||||
}
|
||||
if otelTracer.name != name {
|
||||
t.Error("OTel tracer.Start called with wrong name")
|
||||
}
|
||||
sk := trace.SpanKindClient
|
||||
c := trace.NewSpanStartConfig(otelTracer.opts...)
|
||||
if c.SpanKind() != sk {
|
||||
t.Errorf("OTel tracer.Start called with wrong options: %#v", c)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTracerStartSpanReportsErrors(t *testing.T) {
|
||||
h, restore := withHandler()
|
||||
defer restore()
|
||||
|
||||
ocTracer := internal.NewTracer(&tracer{})
|
||||
ocTracer.StartSpan(context.Background(), "", octrace.WithSampler(octrace.AlwaysSample()))
|
||||
if h.err == nil {
|
||||
t.Error("OC tracer.StartSpan no error when converting Sampler")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTracerStartSpanWithRemoteParent(t *testing.T) {
|
||||
otelTracer := new(tracer)
|
||||
ocTracer := internal.NewTracer(otelTracer)
|
||||
sc := octrace.SpanContext{TraceID: [16]byte{1}, SpanID: [8]byte{1}}
|
||||
converted := oc2otel.SpanContext(sc).WithRemote(true)
|
||||
|
||||
ocTracer.StartSpanWithRemoteParent(context.Background(), "", sc)
|
||||
|
||||
got := trace.SpanContextFromContext(otelTracer.ctx)
|
||||
if !got.Equal(converted) {
|
||||
t.Error("tracer.StartSpanWithRemoteParent failed to set remote parent")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTracerFromContext(t *testing.T) {
|
||||
sc := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: [16]byte{1},
|
||||
SpanID: [8]byte{1},
|
||||
})
|
||||
ctx := trace.ContextWithSpanContext(context.Background(), sc)
|
||||
|
||||
noop := trace.NewNoopTracerProvider().Tracer("TestTracerFromContext")
|
||||
// Test using the fact that the No-Op span will propagate a span context .
|
||||
ctx, _ = noop.Start(ctx, "test")
|
||||
|
||||
got := internal.NewTracer(noop).FromContext(ctx).SpanContext()
|
||||
// Do not test the convedsion, only that the propagtion.
|
||||
want := otel2oc.SpanContext(sc)
|
||||
if got != want {
|
||||
t.Errorf("tracer.FromContext returned wrong context: %#v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTracerNewContext(t *testing.T) {
|
||||
sc := trace.NewSpanContext(trace.SpanContextConfig{
|
||||
TraceID: [16]byte{1},
|
||||
SpanID: [8]byte{1},
|
||||
})
|
||||
ctx := trace.ContextWithSpanContext(context.Background(), sc)
|
||||
|
||||
noop := trace.NewNoopTracerProvider().Tracer("TestTracerNewContext")
|
||||
// Test using the fact that the No-Op span will propagate a span context .
|
||||
_, s := noop.Start(ctx, "test")
|
||||
|
||||
ocTracer := internal.NewTracer(noop)
|
||||
ctx = ocTracer.NewContext(context.Background(), internal.NewSpan(s))
|
||||
got := trace.SpanContextFromContext(ctx)
|
||||
|
||||
if !got.Equal(sc) {
|
||||
t.Error("tracer.NewContext did not attach Span to context")
|
||||
}
|
||||
}
|
||||
|
||||
type differentSpan struct {
|
||||
octrace.SpanInterface
|
||||
}
|
||||
|
||||
func (s *differentSpan) String() string { return "testing span" }
|
||||
|
||||
func TestTracerNewContextErrors(t *testing.T) {
|
||||
h, restore := withHandler()
|
||||
defer restore()
|
||||
|
||||
ocTracer := internal.NewTracer(&tracer{})
|
||||
ocSpan := octrace.NewSpan(&differentSpan{})
|
||||
ocTracer.NewContext(context.Background(), ocSpan)
|
||||
if h.err == nil {
|
||||
t.Error("tracer.NewContext did not error for unrecognized span")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user