1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2026-06-03 18:35:08 +02:00
Files
opentelemetry-go/bridge/opencensus/trace_test.go
T
Matthieu MOREL 1bae8f7347 chore: enable extra-rules from gofumpt (#7114)
#### Description

Enable extra rules from
[gofumpt](https://golangci-lint.run/usage/formatters/#gofumpt) that also
fixes paramTypeCombine from go-critic

Also defines `go.opentelemetry.io/otel` as in
https://github.com/open-telemetry/opentelemetry-go-contrib/pull/7637

Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
2025-08-03 08:24:33 -07:00

237 lines
6.8 KiB
Go

// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package opencensus // import "go.opentelemetry.io/otel/bridge/opencensus"
import (
"context"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
octrace "go.opencensus.io/trace"
"go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/trace/tracetest"
oteltrace "go.opentelemetry.io/otel/trace"
)
func TestNewTraceBridge(t *testing.T) {
exporter := tracetest.NewInMemoryExporter()
tp := trace.NewTracerProvider(trace.WithSyncer(exporter))
bridge := newTraceBridge([]TraceOption{WithTracerProvider(tp)})
_, span := bridge.StartSpan(context.Background(), "foo")
span.End()
gotSpans := exporter.GetSpans()
require.Len(t, gotSpans, 1)
gotSpan := gotSpans[0]
assert.Equal(t, scopeName, gotSpan.InstrumentationScope.Name)
assert.Equal(t, gotSpan.InstrumentationScope.Version, Version())
}
func TestOCSpanContextToOTel(t *testing.T) {
input := octrace.SpanContext{
TraceID: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
SpanID: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
TraceOptions: octrace.TraceOptions(1),
}
want := oteltrace.NewSpanContext(oteltrace.SpanContextConfig{
TraceID: oteltrace.TraceID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
SpanID: oteltrace.SpanID{1, 2, 3, 4, 5, 6, 7, 8},
TraceFlags: oteltrace.TraceFlags(1),
})
got := OCSpanContextToOTel(input)
assert.Equal(t, want, got)
}
func TestOTelSpanContextToOC(t *testing.T) {
tests := []struct {
name string
input oteltrace.SpanContext
expected octrace.SpanContext
}{
{
name: "empty span context",
input: oteltrace.SpanContext{},
expected: octrace.SpanContext{
TraceID: [16]byte{},
SpanID: [8]byte{},
TraceOptions: octrace.TraceOptions(0),
},
},
{
name: "sampled span context",
input: oteltrace.NewSpanContext(oteltrace.SpanContextConfig{
TraceID: oteltrace.TraceID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
SpanID: oteltrace.SpanID{1, 2, 3, 4, 5, 6, 7, 8},
TraceFlags: oteltrace.FlagsSampled,
}),
expected: octrace.SpanContext{
TraceID: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
SpanID: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
TraceOptions: octrace.TraceOptions(1),
},
},
{
name: "not sampled span context",
input: oteltrace.NewSpanContext(oteltrace.SpanContextConfig{
TraceID: oteltrace.TraceID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
SpanID: oteltrace.SpanID{1, 2, 3, 4, 5, 6, 7, 8},
}),
expected: octrace.SpanContext{
TraceID: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
SpanID: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
TraceOptions: octrace.TraceOptions(0),
},
},
{
name: "span context with tracestate",
input: func() oteltrace.SpanContext {
ts := oteltrace.TraceState{}
ts, _ = ts.Insert("key1", "value1")
ts, _ = ts.Insert("key2", "value2")
return oteltrace.NewSpanContext(oteltrace.SpanContextConfig{
TraceID: oteltrace.TraceID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
SpanID: oteltrace.SpanID{1, 2, 3, 4, 5, 6, 7, 8},
TraceState: ts,
})
}(),
expected: octrace.SpanContext{
TraceID: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
SpanID: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
TraceOptions: octrace.TraceOptions(0),
// Tracestate will be set by the conversion function
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := OTelSpanContextToOC(tt.input)
assert.Equal(t, tt.expected.TraceID, got.TraceID, "TraceID should be correctly converted")
assert.Equal(t, tt.expected.SpanID, got.SpanID, "SpanID should be correctly converted")
assert.Equal(t, tt.expected.TraceOptions, got.TraceOptions, "TraceOptions should be correctly converted")
// Verify Tracestate is populated when input has tracestate
if tt.input.TraceState().Len() > 0 {
assert.NotNil(t, got.Tracestate, "Tracestate should be populated when input has tracestate")
// Verify the tracestate entries are preserved
expectedTraceState := tt.input.TraceState().String()
gotEntries := got.Tracestate.Entries()
// Convert entries back to a string representation for comparison
var gotTraceStateEntries []string
for _, entry := range gotEntries {
gotTraceStateEntries = append(gotTraceStateEntries, entry.Key+"="+entry.Value)
}
gotTraceState := ""
if len(gotTraceStateEntries) > 0 {
gotTraceState = strings.Join(gotTraceStateEntries, ",")
}
assert.Equal(t, expectedTraceState, gotTraceState, "Tracestate should preserve entries")
} else if got.Tracestate != nil {
// For empty tracestate cases, ensure the field is properly handled
entries := got.Tracestate.Entries()
assert.Empty(t, entries, "Empty tracestate should result in empty entries")
}
})
}
}
func TestInstallTraceBridge(t *testing.T) {
originalTracer := octrace.DefaultTracer
defer func() {
octrace.DefaultTracer = originalTracer
}()
tests := []struct {
name string
opts []TraceOption
expectValidSpans bool
}{
{
name: "install with default options",
opts: nil,
expectValidSpans: false,
},
{
name: "install with custom tracer provider",
opts: []TraceOption{
WithTracerProvider(trace.NewTracerProvider()),
},
expectValidSpans: true,
},
{
name: "install with tracer provider with exporter",
opts: []TraceOption{
WithTracerProvider(
trace.NewTracerProvider(
trace.WithSyncer(tracetest.NewInMemoryExporter()),
),
),
},
expectValidSpans: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
beforeTracer := octrace.DefaultTracer
InstallTraceBridge(tt.opts...)
assert.NotEqual(
t,
beforeTracer,
octrace.DefaultTracer,
"DefaultTracer should be updated",
)
assert.NotNil(
t,
octrace.DefaultTracer,
"DefaultTracer should not be nil",
)
ctx, span := octrace.DefaultTracer.StartSpan(
context.Background(),
"test-span",
)
assert.NotNil(
t,
span,
"Should be able to create spans",
)
assert.NotNil(t, ctx, "Should return a valid context")
spanContext := span.SpanContext()
if tt.expectValidSpans {
assert.NotEqual(
t,
octrace.TraceID{},
spanContext.TraceID,
"Span should have a non-zero TraceID",
)
assert.NotEqual(
t,
octrace.SpanID{},
spanContext.SpanID,
"Span should have a non-zero SpanID",
)
}
span.End()
spanFromContext := octrace.DefaultTracer.FromContext(ctx)
assert.NotNil(
t,
spanFromContext,
"Should be able to get span from context",
)
})
}
}