From 9f28e5fa0d14cb4f213ada64ae062cb8ed44fd24 Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Thu, 22 Jul 2021 11:42:36 -0700 Subject: [PATCH 1/4] Deprecate oteltest.Harness for removal --- internal/internaltest/harness.go | 341 +++++++++++++++++++++++++++++++ oteltest/harness.go | 4 + oteltest/tracer_test.go | 3 +- sdk/trace/trace_test.go | 2 +- 4 files changed, 348 insertions(+), 2 deletions(-) create mode 100644 internal/internaltest/harness.go diff --git a/internal/internaltest/harness.go b/internal/internaltest/harness.go new file mode 100644 index 00000000000..88306803244 --- /dev/null +++ b/internal/internaltest/harness.go @@ -0,0 +1,341 @@ +// 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 internaltest // import "go.opentelemetry.io/otel/internal/internaltest" + +import ( + "context" + "fmt" + "sync" + "testing" + "time" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/internal/matchers" + "go.opentelemetry.io/otel/trace" +) + +// Harness is a testing harness used to test implementations of the +// OpenTelemetry API. +type Harness struct { + t *testing.T +} + +// NewHarness returns an instantiated *Harness using t. +func NewHarness(t *testing.T) *Harness { + return &Harness{ + t: t, + } +} + +// TestTracerProvider runs validation tests for an implementation of the OpenTelemetry +// TracerProvider API. +func (h *Harness) TestTracerProvider(subjectFactory func() trace.TracerProvider) { + h.t.Run("#Start", func(t *testing.T) { + t.Run("allow creating an arbitrary number of TracerProvider instances", func(t *testing.T) { + t.Parallel() + + e := matchers.NewExpecter(t) + + tp1 := subjectFactory() + tp2 := subjectFactory() + + e.Expect(tp1).NotToEqual(tp2) + }) + t.Run("all methods are safe to be called concurrently", func(t *testing.T) { + t.Parallel() + + runner := func(tp trace.TracerProvider) <-chan struct{} { + done := make(chan struct{}) + go func(tp trace.TracerProvider) { + var wg sync.WaitGroup + for i := 0; i < 20; i++ { + wg.Add(1) + go func(name, version string) { + _ = tp.Tracer(name, trace.WithInstrumentationVersion(version)) + wg.Done() + }(fmt.Sprintf("tracer %d", i%5), fmt.Sprintf("%d", i)) + } + wg.Wait() + done <- struct{}{} + }(tp) + return done + } + + matchers.NewExpecter(t).Expect(func() { + // Run with multiple TracerProvider to ensure they encapsulate + // their own Tracers. + tp1 := subjectFactory() + tp2 := subjectFactory() + + done1 := runner(tp1) + done2 := runner(tp2) + + <-done1 + <-done2 + }).NotToPanic() + }) + }) +} + +// TestTracer runs validation tests for an implementation of the OpenTelemetry +// Tracer API. +func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) { + h.t.Run("#Start", func(t *testing.T) { + t.Run("propagates the original context", func(t *testing.T) { + t.Parallel() + + e := matchers.NewExpecter(t) + subject := subjectFactory() + + ctxKey := testCtxKey{} + ctxValue := "ctx value" + ctx := context.WithValue(context.Background(), ctxKey, ctxValue) + + ctx, _ = subject.Start(ctx, "test") + + e.Expect(ctx.Value(ctxKey)).ToEqual(ctxValue) + }) + + t.Run("returns a span containing the expected properties", func(t *testing.T) { + t.Parallel() + + e := matchers.NewExpecter(t) + subject := subjectFactory() + + _, span := subject.Start(context.Background(), "test") + + e.Expect(span).NotToBeNil() + + e.Expect(span.SpanContext().IsValid()).ToBeTrue() + }) + + t.Run("stores the span on the provided context", func(t *testing.T) { + t.Parallel() + + e := matchers.NewExpecter(t) + subject := subjectFactory() + + ctx, span := subject.Start(context.Background(), "test") + + e.Expect(span).NotToBeNil() + e.Expect(span.SpanContext()).NotToEqual(trace.SpanContext{}) + e.Expect(trace.SpanFromContext(ctx)).ToEqual(span) + }) + + t.Run("starts spans with unique trace and span IDs", func(t *testing.T) { + t.Parallel() + + e := matchers.NewExpecter(t) + subject := subjectFactory() + + _, span1 := subject.Start(context.Background(), "span1") + _, span2 := subject.Start(context.Background(), "span2") + + sc1 := span1.SpanContext() + sc2 := span2.SpanContext() + + e.Expect(sc1.TraceID()).NotToEqual(sc2.TraceID()) + e.Expect(sc1.SpanID()).NotToEqual(sc2.SpanID()) + }) + + t.Run("propagates a parent's trace ID through the context", func(t *testing.T) { + t.Parallel() + + e := matchers.NewExpecter(t) + subject := subjectFactory() + + ctx, parent := subject.Start(context.Background(), "parent") + _, child := subject.Start(ctx, "child") + + psc := parent.SpanContext() + csc := child.SpanContext() + + e.Expect(csc.TraceID()).ToEqual(psc.TraceID()) + e.Expect(csc.SpanID()).NotToEqual(psc.SpanID()) + }) + + t.Run("ignores parent's trace ID when new root is requested", func(t *testing.T) { + t.Parallel() + + e := matchers.NewExpecter(t) + subject := subjectFactory() + + ctx, parent := subject.Start(context.Background(), "parent") + _, child := subject.Start(ctx, "child", trace.WithNewRoot()) + + psc := parent.SpanContext() + csc := child.SpanContext() + + e.Expect(csc.TraceID()).NotToEqual(psc.TraceID()) + e.Expect(csc.SpanID()).NotToEqual(psc.SpanID()) + }) + + t.Run("propagates remote parent's trace ID through the context", func(t *testing.T) { + t.Parallel() + + e := matchers.NewExpecter(t) + subject := subjectFactory() + + _, remoteParent := subject.Start(context.Background(), "remote parent") + parentCtx := trace.ContextWithRemoteSpanContext(context.Background(), remoteParent.SpanContext()) + _, child := subject.Start(parentCtx, "child") + + psc := remoteParent.SpanContext() + csc := child.SpanContext() + + e.Expect(csc.TraceID()).ToEqual(psc.TraceID()) + e.Expect(csc.SpanID()).NotToEqual(psc.SpanID()) + }) + + t.Run("ignores remote parent's trace ID when new root is requested", func(t *testing.T) { + t.Parallel() + + e := matchers.NewExpecter(t) + subject := subjectFactory() + + _, remoteParent := subject.Start(context.Background(), "remote parent") + parentCtx := trace.ContextWithRemoteSpanContext(context.Background(), remoteParent.SpanContext()) + _, child := subject.Start(parentCtx, "child", trace.WithNewRoot()) + + psc := remoteParent.SpanContext() + csc := child.SpanContext() + + e.Expect(csc.TraceID()).NotToEqual(psc.TraceID()) + e.Expect(csc.SpanID()).NotToEqual(psc.SpanID()) + }) + + t.Run("all methods are safe to be called concurrently", func(t *testing.T) { + t.Parallel() + + e := matchers.NewExpecter(t) + tracer := subjectFactory() + + ctx, parent := tracer.Start(context.Background(), "span") + + runner := func(tp trace.Tracer) <-chan struct{} { + done := make(chan struct{}) + go func(tp trace.Tracer) { + var wg sync.WaitGroup + for i := 0; i < 20; i++ { + wg.Add(1) + go func(name string) { + defer wg.Done() + _, child := tp.Start(ctx, name) + + psc := parent.SpanContext() + csc := child.SpanContext() + + e.Expect(csc.TraceID()).ToEqual(psc.TraceID()) + e.Expect(csc.SpanID()).NotToEqual(psc.SpanID()) + }(fmt.Sprintf("span %d", i)) + } + wg.Wait() + done <- struct{}{} + }(tp) + return done + } + + e.Expect(func() { + done := runner(tracer) + + <-done + }).NotToPanic() + }) + }) + + h.testSpan(subjectFactory) +} + +func (h *Harness) testSpan(tracerFactory func() trace.Tracer) { + var methods = map[string]func(span trace.Span){ + "#End": func(span trace.Span) { + span.End() + }, + "#AddEvent": func(span trace.Span) { + span.AddEvent("test event") + }, + "#AddEventWithTimestamp": func(span trace.Span) { + span.AddEvent("test event", trace.WithTimestamp(time.Now().Add(1*time.Second))) + }, + "#SetStatus": func(span trace.Span) { + span.SetStatus(codes.Error, "internal") + }, + "#SetName": func(span trace.Span) { + span.SetName("new name") + }, + "#SetAttributes": func(span trace.Span) { + span.SetAttributes(attribute.String("key1", "value"), attribute.Int("key2", 123)) + }, + } + var mechanisms = map[string]func() trace.Span{ + "Span created via Tracer#Start": func() trace.Span { + tracer := tracerFactory() + _, subject := tracer.Start(context.Background(), "test") + + return subject + }, + "Span created via span.TracerProvider()": func() trace.Span { + ctx, spanA := tracerFactory().Start(context.Background(), "span1") + + _, spanB := spanA.TracerProvider().Tracer("second").Start(ctx, "span2") + return spanB + }, + } + + for mechanismName, mechanism := range mechanisms { + h.t.Run(mechanismName, func(t *testing.T) { + for methodName, method := range methods { + t.Run(methodName, func(t *testing.T) { + t.Run("is thread-safe", func(t *testing.T) { + t.Parallel() + + span := mechanism() + + wg := &sync.WaitGroup{} + wg.Add(2) + + go func() { + defer wg.Done() + + method(span) + }() + + go func() { + defer wg.Done() + + method(span) + }() + + wg.Wait() + }) + }) + } + + t.Run("#End", func(t *testing.T) { + t.Run("can be called multiple times", func(t *testing.T) { + t.Parallel() + + span := mechanism() + + span.End() + span.End() + }) + }) + }) + } +} + +type testCtxKey struct{} diff --git a/oteltest/harness.go b/oteltest/harness.go index 140d93bb7cb..130f0b2887d 100644 --- a/oteltest/harness.go +++ b/oteltest/harness.go @@ -29,11 +29,15 @@ import ( // Harness is a testing harness used to test implementations of the // OpenTelemetry API. +// +// Deprecated: this will be removed in the next major release. type Harness struct { t *testing.T } // NewHarness returns an instantiated *Harness using t. +// +// Deprecated: this will be removed in the next major release. func NewHarness(t *testing.T) *Harness { return &Harness{ t: t, diff --git a/oteltest/tracer_test.go b/oteltest/tracer_test.go index 69de7472363..9da214538fa 100644 --- a/oteltest/tracer_test.go +++ b/oteltest/tracer_test.go @@ -23,6 +23,7 @@ import ( "time" "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/internal/internaltest" "go.opentelemetry.io/otel/internal/matchers" "go.opentelemetry.io/otel/oteltest" "go.opentelemetry.io/otel/trace" @@ -31,7 +32,7 @@ import ( func TestTracer(t *testing.T) { tp := oteltest.NewTracerProvider() - oteltest.NewHarness(t).TestTracer(func() func() trace.Tracer { + internaltest.NewHarness(t).TestTracer(func() func() trace.Tracer { tp := oteltest.NewTracerProvider() var i uint64 return func() trace.Tracer { diff --git a/sdk/trace/trace_test.go b/sdk/trace/trace_test.go index 4bf1116108b..8f91be33e5c 100644 --- a/sdk/trace/trace_test.go +++ b/sdk/trace/trace_test.go @@ -88,7 +88,7 @@ func init() { } func TestTracerFollowsExpectedAPIBehaviour(t *testing.T) { - harness := oteltest.NewHarness(t) + harness := ottest.NewHarness(t) harness.TestTracerProvider(func() trace.TracerProvider { return NewTracerProvider(WithSampler(TraceIDRatioBased(0))) From 28aa594d1d95a60ba6a7e89a06f12ff8109d1cc2 Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Thu, 22 Jul 2021 11:50:28 -0700 Subject: [PATCH 2/4] Add changes to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00cc68b561f..7f098e05b92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Deprecated - The `TextMapCarrier` and `TextMapPropagator` from the `go.opentelemetry.io/otel/oteltest` package and their associated creation functions (`TextMapCarrier`, `NewTextMapPropagator`) are deprecated. (#2114) +- The `Harness` type from the `go.opentelemetry.io/otel/oteltest` package and its associated creation function, `NewHarness` are deprecated and will be removed in the next release. (#2123) ### Removed From 9508040a719bc1f0cc20815efd35ac1d5a1d2f87 Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Thu, 22 Jul 2021 15:05:49 -0700 Subject: [PATCH 3/4] Alias oteltest.Harness to internaltest --- oteltest/harness.go | 317 +------------------------------------------- 1 file changed, 3 insertions(+), 314 deletions(-) diff --git a/oteltest/harness.go b/oteltest/harness.go index 130f0b2887d..aed51395ed9 100644 --- a/oteltest/harness.go +++ b/oteltest/harness.go @@ -15,331 +15,20 @@ package oteltest // import "go.opentelemetry.io/otel/oteltest" import ( - "context" - "fmt" - "sync" "testing" - "time" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/internal/matchers" - "go.opentelemetry.io/otel/trace" + "go.opentelemetry.io/otel/internal/internaltest" ) // Harness is a testing harness used to test implementations of the // OpenTelemetry API. // // Deprecated: this will be removed in the next major release. -type Harness struct { - t *testing.T -} +type Harness = internaltest.Harness // NewHarness returns an instantiated *Harness using t. // // Deprecated: this will be removed in the next major release. func NewHarness(t *testing.T) *Harness { - return &Harness{ - t: t, - } -} - -// TestTracerProvider runs validation tests for an implementation of the OpenTelemetry -// TracerProvider API. -func (h *Harness) TestTracerProvider(subjectFactory func() trace.TracerProvider) { - h.t.Run("#Start", func(t *testing.T) { - t.Run("allow creating an arbitrary number of TracerProvider instances", func(t *testing.T) { - t.Parallel() - - e := matchers.NewExpecter(t) - - tp1 := subjectFactory() - tp2 := subjectFactory() - - e.Expect(tp1).NotToEqual(tp2) - }) - t.Run("all methods are safe to be called concurrently", func(t *testing.T) { - t.Parallel() - - runner := func(tp trace.TracerProvider) <-chan struct{} { - done := make(chan struct{}) - go func(tp trace.TracerProvider) { - var wg sync.WaitGroup - for i := 0; i < 20; i++ { - wg.Add(1) - go func(name, version string) { - _ = tp.Tracer(name, trace.WithInstrumentationVersion(version)) - wg.Done() - }(fmt.Sprintf("tracer %d", i%5), fmt.Sprintf("%d", i)) - } - wg.Wait() - done <- struct{}{} - }(tp) - return done - } - - matchers.NewExpecter(t).Expect(func() { - // Run with multiple TracerProvider to ensure they encapsulate - // their own Tracers. - tp1 := subjectFactory() - tp2 := subjectFactory() - - done1 := runner(tp1) - done2 := runner(tp2) - - <-done1 - <-done2 - }).NotToPanic() - }) - }) + return internaltest.NewHarness(t) } - -// TestTracer runs validation tests for an implementation of the OpenTelemetry -// Tracer API. -func (h *Harness) TestTracer(subjectFactory func() trace.Tracer) { - h.t.Run("#Start", func(t *testing.T) { - t.Run("propagates the original context", func(t *testing.T) { - t.Parallel() - - e := matchers.NewExpecter(t) - subject := subjectFactory() - - ctxKey := testCtxKey{} - ctxValue := "ctx value" - ctx := context.WithValue(context.Background(), ctxKey, ctxValue) - - ctx, _ = subject.Start(ctx, "test") - - e.Expect(ctx.Value(ctxKey)).ToEqual(ctxValue) - }) - - t.Run("returns a span containing the expected properties", func(t *testing.T) { - t.Parallel() - - e := matchers.NewExpecter(t) - subject := subjectFactory() - - _, span := subject.Start(context.Background(), "test") - - e.Expect(span).NotToBeNil() - - e.Expect(span.SpanContext().IsValid()).ToBeTrue() - }) - - t.Run("stores the span on the provided context", func(t *testing.T) { - t.Parallel() - - e := matchers.NewExpecter(t) - subject := subjectFactory() - - ctx, span := subject.Start(context.Background(), "test") - - e.Expect(span).NotToBeNil() - e.Expect(span.SpanContext()).NotToEqual(trace.SpanContext{}) - e.Expect(trace.SpanFromContext(ctx)).ToEqual(span) - }) - - t.Run("starts spans with unique trace and span IDs", func(t *testing.T) { - t.Parallel() - - e := matchers.NewExpecter(t) - subject := subjectFactory() - - _, span1 := subject.Start(context.Background(), "span1") - _, span2 := subject.Start(context.Background(), "span2") - - sc1 := span1.SpanContext() - sc2 := span2.SpanContext() - - e.Expect(sc1.TraceID()).NotToEqual(sc2.TraceID()) - e.Expect(sc1.SpanID()).NotToEqual(sc2.SpanID()) - }) - - t.Run("propagates a parent's trace ID through the context", func(t *testing.T) { - t.Parallel() - - e := matchers.NewExpecter(t) - subject := subjectFactory() - - ctx, parent := subject.Start(context.Background(), "parent") - _, child := subject.Start(ctx, "child") - - psc := parent.SpanContext() - csc := child.SpanContext() - - e.Expect(csc.TraceID()).ToEqual(psc.TraceID()) - e.Expect(csc.SpanID()).NotToEqual(psc.SpanID()) - }) - - t.Run("ignores parent's trace ID when new root is requested", func(t *testing.T) { - t.Parallel() - - e := matchers.NewExpecter(t) - subject := subjectFactory() - - ctx, parent := subject.Start(context.Background(), "parent") - _, child := subject.Start(ctx, "child", trace.WithNewRoot()) - - psc := parent.SpanContext() - csc := child.SpanContext() - - e.Expect(csc.TraceID()).NotToEqual(psc.TraceID()) - e.Expect(csc.SpanID()).NotToEqual(psc.SpanID()) - }) - - t.Run("propagates remote parent's trace ID through the context", func(t *testing.T) { - t.Parallel() - - e := matchers.NewExpecter(t) - subject := subjectFactory() - - _, remoteParent := subject.Start(context.Background(), "remote parent") - parentCtx := trace.ContextWithRemoteSpanContext(context.Background(), remoteParent.SpanContext()) - _, child := subject.Start(parentCtx, "child") - - psc := remoteParent.SpanContext() - csc := child.SpanContext() - - e.Expect(csc.TraceID()).ToEqual(psc.TraceID()) - e.Expect(csc.SpanID()).NotToEqual(psc.SpanID()) - }) - - t.Run("ignores remote parent's trace ID when new root is requested", func(t *testing.T) { - t.Parallel() - - e := matchers.NewExpecter(t) - subject := subjectFactory() - - _, remoteParent := subject.Start(context.Background(), "remote parent") - parentCtx := trace.ContextWithRemoteSpanContext(context.Background(), remoteParent.SpanContext()) - _, child := subject.Start(parentCtx, "child", trace.WithNewRoot()) - - psc := remoteParent.SpanContext() - csc := child.SpanContext() - - e.Expect(csc.TraceID()).NotToEqual(psc.TraceID()) - e.Expect(csc.SpanID()).NotToEqual(psc.SpanID()) - }) - - t.Run("all methods are safe to be called concurrently", func(t *testing.T) { - t.Parallel() - - e := matchers.NewExpecter(t) - tracer := subjectFactory() - - ctx, parent := tracer.Start(context.Background(), "span") - - runner := func(tp trace.Tracer) <-chan struct{} { - done := make(chan struct{}) - go func(tp trace.Tracer) { - var wg sync.WaitGroup - for i := 0; i < 20; i++ { - wg.Add(1) - go func(name string) { - defer wg.Done() - _, child := tp.Start(ctx, name) - - psc := parent.SpanContext() - csc := child.SpanContext() - - e.Expect(csc.TraceID()).ToEqual(psc.TraceID()) - e.Expect(csc.SpanID()).NotToEqual(psc.SpanID()) - }(fmt.Sprintf("span %d", i)) - } - wg.Wait() - done <- struct{}{} - }(tp) - return done - } - - e.Expect(func() { - done := runner(tracer) - - <-done - }).NotToPanic() - }) - }) - - h.testSpan(subjectFactory) -} - -func (h *Harness) testSpan(tracerFactory func() trace.Tracer) { - var methods = map[string]func(span trace.Span){ - "#End": func(span trace.Span) { - span.End() - }, - "#AddEvent": func(span trace.Span) { - span.AddEvent("test event") - }, - "#AddEventWithTimestamp": func(span trace.Span) { - span.AddEvent("test event", trace.WithTimestamp(time.Now().Add(1*time.Second))) - }, - "#SetStatus": func(span trace.Span) { - span.SetStatus(codes.Error, "internal") - }, - "#SetName": func(span trace.Span) { - span.SetName("new name") - }, - "#SetAttributes": func(span trace.Span) { - span.SetAttributes(attribute.String("key1", "value"), attribute.Int("key2", 123)) - }, - } - var mechanisms = map[string]func() trace.Span{ - "Span created via Tracer#Start": func() trace.Span { - tracer := tracerFactory() - _, subject := tracer.Start(context.Background(), "test") - - return subject - }, - "Span created via span.TracerProvider()": func() trace.Span { - ctx, spanA := tracerFactory().Start(context.Background(), "span1") - - _, spanB := spanA.TracerProvider().Tracer("second").Start(ctx, "span2") - return spanB - }, - } - - for mechanismName, mechanism := range mechanisms { - h.t.Run(mechanismName, func(t *testing.T) { - for methodName, method := range methods { - t.Run(methodName, func(t *testing.T) { - t.Run("is thread-safe", func(t *testing.T) { - t.Parallel() - - span := mechanism() - - wg := &sync.WaitGroup{} - wg.Add(2) - - go func() { - defer wg.Done() - - method(span) - }() - - go func() { - defer wg.Done() - - method(span) - }() - - wg.Wait() - }) - }) - } - - t.Run("#End", func(t *testing.T) { - t.Run("can be called multiple times", func(t *testing.T) { - t.Parallel() - - span := mechanism() - - span.End() - span.End() - }) - }) - }) - } -} - -type testCtxKey struct{} From 4007fe60b1578ac0c85304a66a71d6766d0bf0e2 Mon Sep 17 00:00:00 2001 From: Anthony Mirabella Date: Mon, 26 Jul 2021 11:20:48 -0400 Subject: [PATCH 4/4] Update oteltest/tracer_test.go remove `oteltest` import. --- sdk/go.mod | 1 - sdk/trace/trace_test.go | 1 - 2 files changed, 2 deletions(-) diff --git a/sdk/go.mod b/sdk/go.mod index 6925b631f6b..f4fce1474b0 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -8,7 +8,6 @@ require ( github.com/google/go-cmp v0.5.6 github.com/stretchr/testify v1.7.0 go.opentelemetry.io/otel v1.0.0-RC1 - go.opentelemetry.io/otel/oteltest v1.0.0-RC1 go.opentelemetry.io/otel/trace v1.0.0-RC1 golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 ) diff --git a/sdk/trace/trace_test.go b/sdk/trace/trace_test.go index e932c675d73..01007f2ce05 100644 --- a/sdk/trace/trace_test.go +++ b/sdk/trace/trace_test.go @@ -29,7 +29,6 @@ import ( "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/oteltest" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "go.opentelemetry.io/otel/trace"