1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-11-29 23:07:45 +02:00
Files
opentelemetry-go/sdk/trace/simple_span_processor_test.go
Flc゛ 80cb909774 refactor: replace context.Background() with t.Context()/b.Context() in tests (#7352)
Based on the Go version we currently use, the dependency already
supports 1.24+, which allows using `t.Context()` and `b.Context()` in
unit tests and benchmarks respectively.

- Enable `context-background` and `context-todo` in
[`usetesting`](https://golangci-lint.run/docs/linters/configuration/#usetesting)
- Adjust the code to support linter detection

---------

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
Co-authored-by: Tyler Yahn <codingalias@gmail.com>
Co-authored-by: Damien Mathieu <42@dmathieu.com>
2025-09-23 09:52:45 +02:00

171 lines
4.2 KiB
Go

// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package trace
import (
"context"
"errors"
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
type simpleTestExporter struct {
spans []ReadOnlySpan
shutdown bool
}
func (t *simpleTestExporter) ExportSpans(_ context.Context, spans []ReadOnlySpan) error {
t.spans = append(t.spans, spans...)
return nil
}
func (t *simpleTestExporter) Shutdown(ctx context.Context) error {
t.shutdown = true
select {
case <-ctx.Done():
// Ensure context deadline tests receive the expected error.
return ctx.Err()
default:
return nil
}
}
var _ SpanExporter = (*simpleTestExporter)(nil)
func TestNewSimpleSpanProcessor(t *testing.T) {
if ssp := NewSimpleSpanProcessor(&simpleTestExporter{}); ssp == nil {
t.Error("failed to create new SimpleSpanProcessor")
}
}
func TestNewSimpleSpanProcessorWithNilExporter(t *testing.T) {
if ssp := NewSimpleSpanProcessor(nil); ssp == nil {
t.Error("failed to create new SimpleSpanProcessor with nil exporter")
}
}
func TestSimpleSpanProcessorOnEnd(t *testing.T) {
tp := basicTracerProvider(t)
te := simpleTestExporter{}
ssp := NewSimpleSpanProcessor(&te)
tp.RegisterSpanProcessor(ssp)
startSpan(tp, "TestSimpleSpanProcessorOnEnd").End()
wantTraceID := tid
gotTraceID := te.spans[0].SpanContext().TraceID()
if wantTraceID != gotTraceID {
t.Errorf("SimplerSpanProcessor OnEnd() check: got %+v, want %+v\n", gotTraceID, wantTraceID)
}
}
func TestSimpleSpanProcessorShutdown(t *testing.T) {
exporter := &simpleTestExporter{}
ssp := NewSimpleSpanProcessor(exporter)
// Ensure we can export a span before we test we cannot after shutdown.
tp := basicTracerProvider(t)
tp.RegisterSpanProcessor(ssp)
startSpan(tp, "TestSimpleSpanProcessorShutdown").End()
nExported := len(exporter.spans)
if nExported != 1 {
t.Error("failed to verify span export")
}
if err := ssp.Shutdown(t.Context()); err != nil {
t.Errorf("shutting the SimpleSpanProcessor down: %v", err)
}
if !exporter.shutdown {
t.Error("SimpleSpanProcessor.Shutdown did not shut down exporter")
}
startSpan(tp, "TestSimpleSpanProcessorShutdown").End()
if len(exporter.spans) > nExported {
t.Error("exported span to shutdown exporter")
}
}
func TestSimpleSpanProcessorShutdownOnEndConcurrentSafe(t *testing.T) {
exporter := &simpleTestExporter{}
ssp := NewSimpleSpanProcessor(exporter)
tp := basicTracerProvider(t)
tp.RegisterSpanProcessor(ssp)
stop := make(chan struct{})
done := make(chan struct{})
go func() {
defer func() {
done <- struct{}{}
}()
for {
select {
case <-stop:
return
default:
startSpan(tp, "TestSimpleSpanProcessorShutdownOnEndConcurrentSafe").End()
}
}
}()
if err := ssp.Shutdown(t.Context()); err != nil {
t.Errorf("shutting the SimpleSpanProcessor down: %v", err)
}
if !exporter.shutdown {
t.Error("SimpleSpanProcessor.Shutdown did not shut down exporter")
}
stop <- struct{}{}
<-done
}
func TestSimpleSpanProcessorShutdownOnEndConcurrentSafe2(t *testing.T) {
exporter := &simpleTestExporter{}
ssp := NewSimpleSpanProcessor(exporter)
tp := basicTracerProvider(t)
tp.RegisterSpanProcessor(ssp)
var wg sync.WaitGroup
wg.Add(2)
span := func(spanName string) {
assert.NotPanics(t, func() {
defer wg.Done()
_, span := tp.Tracer("test").Start(t.Context(), spanName)
span.End()
})
}
go span("test-span-1")
go span("test-span-2")
wg.Wait()
assert.NoError(t, ssp.Shutdown(t.Context()))
assert.True(t, exporter.shutdown, "exporter shutdown")
}
func TestSimpleSpanProcessorShutdownHonorsContextDeadline(t *testing.T) {
ctx, cancel := context.WithTimeout(t.Context(), time.Nanosecond)
defer cancel()
<-ctx.Done()
ssp := NewSimpleSpanProcessor(&simpleTestExporter{})
if got, want := ssp.Shutdown(ctx), context.DeadlineExceeded; !errors.Is(got, want) {
t.Errorf("SimpleSpanProcessor.Shutdown did not return %v, got %v", want, got)
}
}
func TestSimpleSpanProcessorShutdownHonorsContextCancel(t *testing.T) {
ctx, cancel := context.WithCancel(t.Context())
cancel()
ssp := NewSimpleSpanProcessor(&simpleTestExporter{})
if got, want := ssp.Shutdown(ctx), context.Canceled; !errors.Is(got, want) {
t.Errorf("SimpleSpanProcessor.Shutdown did not return %v, got %v", want, got)
}
}