1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2024-11-24 08:22:25 +02:00

Remove the deprecated oteltest package (#2234)

Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>
This commit is contained in:
Tyler Yahn 2021-09-09 15:49:39 -07:00 committed by GitHub
parent 486afd347f
commit 9e7812d1fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 1 additions and 2146 deletions

View File

@ -256,16 +256,6 @@ updates:
schedule: schedule:
day: sunday day: sunday
interval: weekly interval: weekly
-
package-ecosystem: gomod
directory: /oteltest
labels:
- dependencies
- go
- "Skip Changelog"
schedule:
day: sunday
interval: weekly
- -
package-ecosystem: gomod package-ecosystem: gomod
directory: /internal/tools/semconv-gen directory: /internal/tools/semconv-gen

View File

@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Removed ### Removed
- Removed the deprecated package `go.opentelemetry.io/otel/oteltest`. (#2234)
- Removed the deprecated package `go.opentelemetry.io/otel/bridge/opencensus/utils`. (#2233) - Removed the deprecated package `go.opentelemetry.io/otel/bridge/opencensus/utils`. (#2233)
## [1.0.0-RC3] - 2021-09-02 ## [1.0.0-RC3] - 2021-09-02

View File

@ -43,8 +43,6 @@ replace go.opentelemetry.io/otel/sdk => ../../sdk
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

View File

@ -60,8 +60,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../../metric replace go.opentelemetry.io/otel/metric => ../../../metric
replace go.opentelemetry.io/otel/oteltest => ../../../oteltest
replace go.opentelemetry.io/otel/sdk => ../../../sdk replace go.opentelemetry.io/otel/sdk => ../../../sdk
replace go.opentelemetry.io/otel/sdk/export/metric => ../../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../../sdk/export/metric

View File

@ -40,8 +40,6 @@ replace go.opentelemetry.io/otel/sdk => ../../sdk
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

View File

@ -59,8 +59,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk => ../../sdk replace go.opentelemetry.io/otel/sdk => ../../sdk
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric

View File

@ -40,8 +40,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

View File

@ -42,8 +42,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

View File

@ -44,8 +44,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

View File

@ -43,8 +43,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

View File

@ -45,8 +45,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

View File

@ -42,8 +42,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

View File

@ -41,8 +41,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

View File

@ -38,8 +38,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

View File

@ -25,8 +25,6 @@ replace go.opentelemetry.io/otel/exporters/otlp => ../
replace go.opentelemetry.io/otel/metric => ../../../metric replace go.opentelemetry.io/otel/metric => ../../../metric
replace go.opentelemetry.io/otel/oteltest => ../../../oteltest
replace go.opentelemetry.io/otel/trace => ../../../trace replace go.opentelemetry.io/otel/trace => ../../../trace
replace go.opentelemetry.io/otel/sdk/export/metric => ../../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../../sdk/export/metric

View File

@ -27,8 +27,6 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../
replace go.opentelemetry.io/otel/metric => ../../../../metric replace go.opentelemetry.io/otel/metric => ../../../../metric
replace go.opentelemetry.io/otel/oteltest => ../../../../oteltest
replace go.opentelemetry.io/otel/trace => ../../../../trace replace go.opentelemetry.io/otel/trace => ../../../../trace
replace go.opentelemetry.io/otel/bridge/opencensus => ../../../../bridge/opencensus replace go.opentelemetry.io/otel/bridge/opencensus => ../../../../bridge/opencensus

View File

@ -23,8 +23,6 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../
replace go.opentelemetry.io/otel/metric => ../../../../metric replace go.opentelemetry.io/otel/metric => ../../../../metric
replace go.opentelemetry.io/otel/oteltest => ../../../../oteltest
replace go.opentelemetry.io/otel/trace => ../../../../trace replace go.opentelemetry.io/otel/trace => ../../../../trace
replace go.opentelemetry.io/otel/bridge/opencensus => ../../../../bridge/opencensus replace go.opentelemetry.io/otel/bridge/opencensus => ../../../../bridge/opencensus

View File

@ -21,8 +21,6 @@ replace go.opentelemetry.io/otel/sdk => ../../../sdk
replace go.opentelemetry.io/otel/metric => ../../../metric replace go.opentelemetry.io/otel/metric => ../../../metric
replace go.opentelemetry.io/otel/oteltest => ../../../oteltest
replace go.opentelemetry.io/otel/trace => ../../../trace replace go.opentelemetry.io/otel/trace => ../../../trace
replace go.opentelemetry.io/otel/bridge/opencensus => ../../../bridge/opencensus replace go.opentelemetry.io/otel/bridge/opencensus => ../../../bridge/opencensus

View File

@ -19,8 +19,6 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace => ../
replace go.opentelemetry.io/otel/metric => ../../../../metric replace go.opentelemetry.io/otel/metric => ../../../../metric
replace go.opentelemetry.io/otel/oteltest => ../../../../oteltest
replace go.opentelemetry.io/otel/trace => ../../../../trace replace go.opentelemetry.io/otel/trace => ../../../../trace
replace go.opentelemetry.io/otel/bridge/opencensus => ../../../../bridge/opencensus replace go.opentelemetry.io/otel/bridge/opencensus => ../../../../bridge/opencensus

View File

@ -50,8 +50,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../../../metric replace go.opentelemetry.io/otel/metric => ../../../../metric
replace go.opentelemetry.io/otel/oteltest => ../../../../oteltest
replace go.opentelemetry.io/otel/sdk => ../../../../sdk replace go.opentelemetry.io/otel/sdk => ../../../../sdk
replace go.opentelemetry.io/otel/sdk/export/metric => ../../../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../../../sdk/export/metric

View File

@ -54,8 +54,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk => ../../sdk replace go.opentelemetry.io/otel/sdk => ../../sdk
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric

View File

@ -46,8 +46,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../../metric replace go.opentelemetry.io/otel/metric => ../../../metric
replace go.opentelemetry.io/otel/oteltest => ../../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../../sdk/metric

View File

@ -44,8 +44,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../../metric replace go.opentelemetry.io/otel/metric => ../../../metric
replace go.opentelemetry.io/otel/oteltest => ../../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../../sdk/metric

View File

@ -41,8 +41,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

2
go.mod
View File

@ -42,8 +42,6 @@ replace go.opentelemetry.io/otel/internal/metric => ./internal/metric
replace go.opentelemetry.io/otel/metric => ./metric replace go.opentelemetry.io/otel/metric => ./metric
replace go.opentelemetry.io/otel/oteltest => ./oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ./sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ./sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ./sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ./sdk/metric

View File

@ -48,8 +48,6 @@ replace go.opentelemetry.io/otel/exporters/zipkin => ../../exporters/zipkin
replace go.opentelemetry.io/otel/internal/tools => ../tools replace go.opentelemetry.io/otel/internal/tools => ../tools
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk => ../../sdk replace go.opentelemetry.io/otel/sdk => ../../sdk
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric

View File

@ -44,8 +44,6 @@ replace go.opentelemetry.io/otel/sdk => ../../sdk
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ../../sdk/metric

View File

@ -32,8 +32,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../internal/tools
replace go.opentelemetry.io/otel/metric => ./ replace go.opentelemetry.io/otel/metric => ./
replace go.opentelemetry.io/otel/oteltest => ../oteltest
replace go.opentelemetry.io/otel/sdk => ../sdk replace go.opentelemetry.io/otel/sdk => ../sdk
replace go.opentelemetry.io/otel/sdk/export/metric => ../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../sdk/export/metric

View File

@ -1,141 +0,0 @@
// 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 oteltest // import "go.opentelemetry.io/otel/oteltest"
import (
"context"
"encoding/binary"
"sync"
"sync/atomic"
"go.opentelemetry.io/otel/trace"
)
// defaultSpanContextFunc returns the default SpanContextFunc.
func defaultSpanContextFunc() func(context.Context) trace.SpanContext {
var traceID, spanID uint64 = 1, 1
return func(ctx context.Context) trace.SpanContext {
var sc trace.SpanContext
if current := trace.SpanContextFromContext(ctx); current.IsValid() {
sc = current
} else {
var tid trace.TraceID
binary.BigEndian.PutUint64(tid[:], atomic.AddUint64(&traceID, 1))
sc = sc.WithTraceID(tid)
}
var sid trace.SpanID
binary.BigEndian.PutUint64(sid[:], atomic.AddUint64(&spanID, 1))
return sc.WithSpanID(sid)
}
}
type config struct {
// SpanContextFunc returns a SpanContext from an parent Context for a
// new span.
SpanContextFunc func(context.Context) trace.SpanContext
// SpanRecorder keeps track of spans.
SpanRecorder *SpanRecorder
}
func newConfig(opts ...Option) config {
conf := config{}
for _, opt := range opts {
opt.apply(&conf)
}
if conf.SpanContextFunc == nil {
conf.SpanContextFunc = defaultSpanContextFunc()
}
return conf
}
// Option applies an option to a config.
type Option interface {
apply(*config)
}
type spanContextFuncOption struct {
SpanContextFunc func(context.Context) trace.SpanContext
}
func (o spanContextFuncOption) apply(c *config) {
c.SpanContextFunc = o.SpanContextFunc
}
// WithSpanContextFunc sets the SpanContextFunc used to generate a new Spans
// context from a parent SpanContext.
func WithSpanContextFunc(f func(context.Context) trace.SpanContext) Option {
return spanContextFuncOption{SpanContextFunc: f}
}
type spanRecorderOption struct {
SpanRecorder *SpanRecorder
}
func (o spanRecorderOption) apply(c *config) {
c.SpanRecorder = o.SpanRecorder
}
// WithSpanRecorder sets the SpanRecorder to use with the TracerProvider for
// testing.
func WithSpanRecorder(sr *SpanRecorder) Option {
return spanRecorderOption{SpanRecorder: sr}
}
// SpanRecorder performs operations to record a span as it starts and ends.
// It is designed to be concurrent safe and can by used by multiple goroutines.
type SpanRecorder struct {
startedMu sync.RWMutex
started []*Span
doneMu sync.RWMutex
done []*Span
}
// OnStart records span as started.
func (ssr *SpanRecorder) OnStart(span *Span) {
ssr.startedMu.Lock()
defer ssr.startedMu.Unlock()
ssr.started = append(ssr.started, span)
}
// OnEnd records span as completed.
func (ssr *SpanRecorder) OnEnd(span *Span) {
ssr.doneMu.Lock()
defer ssr.doneMu.Unlock()
ssr.done = append(ssr.done, span)
}
// Started returns a copy of all started Spans in the order they were started.
func (ssr *SpanRecorder) Started() []*Span {
ssr.startedMu.RLock()
defer ssr.startedMu.RUnlock()
started := make([]*Span, len(ssr.started))
for i := range ssr.started {
started[i] = ssr.started[i]
}
return started
}
// Completed returns a copy of all ended Spans in the order they were ended.
func (ssr *SpanRecorder) Completed() []*Span {
ssr.doneMu.RLock()
defer ssr.doneMu.RUnlock()
done := make([]*Span, len(ssr.done))
for i := range ssr.done {
done[i] = ssr.done[i]
}
return done
}

View File

@ -1,63 +0,0 @@
// 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 oteltest provides testing utilities for the otel package.
This package is currently in a Release Candidate phase. Backwards incompatible changes
may be introduced prior to v1.0.0, but we believe the current API is ready to stabilize.
API Validation
The Harness can be used to validate an implementation of the OpenTelemetry API
defined by the `otel` package.
func TestCustomSDKTracingImplementation(t *testing.T) {
yourTraceProvider := NewTracerProvider()
subjectFactory := func() otel.Tracer {
return yourTraceProvider.Tracer("testing")
}
oteltest.NewHarness(t).TestTracer(subjectFactory)
}
Currently the Harness only provides testing of the trace portion of the
OpenTelemetry API.
Trace Testing
To test tracing functionality a full testing implementation of the
OpenTelemetry tracing API are provided. The provided TracerProvider, Tracer,
and Span all implement their related interface and are designed to allow
introspection of their state and history. Additionally, a SpanRecorder can be
provided to the TracerProvider to record all Spans started and ended by the
testing structures.
sr := new(oteltest.SpanRecorder)
tp := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr))
Deprecated: This package contains an alternate implementation of the
OpenTelemetry SDK. This means it will diverge from the one commonly used in
real world operations and therefore will not provide adequate testing
guarantees for users. Because of this, this package should not be used to test
performance or behavior of code running OpenTelemetry. Instead, the
SpanRecorder from the go.opentelemetry.io/otel/sdk/trace/tracetest package can
be registered with the default SDK (go.opentelemetry.io/otel/sdk/trace) as a
SpanProcessor and used to test. This will ensure code will work with the
default SDK. If users do not want to include a dependency on the default SDK
it is recommended to run integration tests in their own module to isolate the
dependency (see go.opentelemetry.io/otel/bridge/opencensus/test as an
example).
*/
package oteltest // import "go.opentelemetry.io/otel/oteltest"

View File

@ -1,28 +0,0 @@
// 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 oteltest // import "go.opentelemetry.io/otel/oteltest"
import (
"time"
"go.opentelemetry.io/otel/attribute"
)
// Event encapsulates the properties of calls to AddEvent.
type Event struct {
Timestamp time.Time
Name string
Attributes map[attribute.Key]attribute.Value
}

View File

@ -1,73 +0,0 @@
module go.opentelemetry.io/otel/oteltest
go 1.15
replace go.opentelemetry.io/otel => ../
replace go.opentelemetry.io/otel/bridge/opencensus => ../bridge/opencensus
replace go.opentelemetry.io/otel/bridge/opentracing => ../bridge/opentracing
replace go.opentelemetry.io/otel/example/jaeger => ../example/jaeger
replace go.opentelemetry.io/otel/example/namedtracer => ../example/namedtracer
replace go.opentelemetry.io/otel/example/opencensus => ../example/opencensus
replace go.opentelemetry.io/otel/example/otel-collector => ../example/otel-collector
replace go.opentelemetry.io/otel/example/prom-collector => ../example/prom-collector
replace go.opentelemetry.io/otel/example/prometheus => ../example/prometheus
replace go.opentelemetry.io/otel/example/zipkin => ../example/zipkin
replace go.opentelemetry.io/otel/exporters/prometheus => ../exporters/prometheus
replace go.opentelemetry.io/otel/exporters/jaeger => ../exporters/jaeger
replace go.opentelemetry.io/otel/exporters/zipkin => ../exporters/zipkin
replace go.opentelemetry.io/otel/internal/tools => ../internal/tools
replace go.opentelemetry.io/otel/metric => ../metric
replace go.opentelemetry.io/otel/internal/metric => ../internal/metric
replace go.opentelemetry.io/otel/oteltest => ./
replace go.opentelemetry.io/otel/sdk => ../sdk
replace go.opentelemetry.io/otel/sdk/export/metric => ../sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ../sdk/metric
replace go.opentelemetry.io/otel/trace => ../trace
require (
github.com/stretchr/testify v1.7.0
go.opentelemetry.io/otel v1.0.0-RC3
go.opentelemetry.io/otel/trace v1.0.0-RC3
)
replace go.opentelemetry.io/otel/example/passthrough => ../example/passthrough
replace go.opentelemetry.io/otel/exporters/otlp/otlptrace => ../exporters/otlp/otlptrace
replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc => ../exporters/otlp/otlptrace/otlptracegrpc
replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => ../exporters/otlp/otlptrace/otlptracehttp
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../exporters/otlp/otlpmetric
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../exporters/otlp/otlpmetric/otlpmetricgrpc
replace go.opentelemetry.io/otel/exporters/stdout/stdoutmetric => ../exporters/stdout/stdoutmetric
replace go.opentelemetry.io/otel/exporters/stdout/stdouttrace => ../exporters/stdout/stdouttrace
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp => ../exporters/otlp/otlpmetric/otlpmetrichttp
replace go.opentelemetry.io/otel/bridge/opencensus/test => ../bridge/opencensus/test
replace go.opentelemetry.io/otel/example/fib => ../example/fib

View File

@ -1,15 +0,0 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -1,34 +0,0 @@
// 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 oteltest // import "go.opentelemetry.io/otel/oteltest"
import (
"testing"
"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 = 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 internaltest.NewHarness(t)
}

View File

@ -1,73 +0,0 @@
// 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 oteltest // import "go.opentelemetry.io/otel/oteltest"
import (
"sync"
"go.opentelemetry.io/otel/trace"
)
// TracerProvider is a testing TracerProvider. It is an functioning
// implementation of an OpenTelemetry TracerProvider and can be configured
// with a SpanRecorder that it configure all Tracers it creates to record
// their Spans with.
type TracerProvider struct {
config config
tracersMu sync.Mutex
tracers map[instrumentation]*Tracer
}
var _ trace.TracerProvider = (*TracerProvider)(nil)
// NewTracerProvider returns a *TracerProvider configured with options.
func NewTracerProvider(options ...Option) *TracerProvider {
return &TracerProvider{
config: newConfig(options...),
tracers: make(map[instrumentation]*Tracer),
}
}
type instrumentation struct {
Name, Version string
}
// Tracer returns an OpenTelemetry Tracer used for testing.
func (p *TracerProvider) Tracer(instName string, opts ...trace.TracerOption) trace.Tracer {
conf := trace.NewTracerConfig(opts...)
inst := instrumentation{
Name: instName,
Version: conf.InstrumentationVersion(),
}
p.tracersMu.Lock()
defer p.tracersMu.Unlock()
t, ok := p.tracers[inst]
if !ok {
t = &Tracer{
Name: instName,
Version: conf.InstrumentationVersion(),
provider: p,
}
p.tracers[inst] = t
}
return t
}
// DefaultTracer returns a default tracer for testing purposes.
func DefaultTracer() trace.Tracer {
return NewTracerProvider().Tracer("")
}

View File

@ -1,229 +0,0 @@
// 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 oteltest // import "go.opentelemetry.io/otel/oteltest"
import (
"fmt"
"reflect"
"sync"
"time"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
"go.opentelemetry.io/otel/trace"
)
var _ trace.Span = (*Span)(nil)
// Span is an OpenTelemetry Span used for testing.
type Span struct {
lock sync.RWMutex
tracer *Tracer
spanContext trace.SpanContext
parentSpanID trace.SpanID
ended bool
name string
startTime time.Time
endTime time.Time
statusCode codes.Code
statusMessage string
attributes map[attribute.Key]attribute.Value
events []Event
links []trace.Link
spanKind trace.SpanKind
}
// End ends s. If the Tracer that created s was configured with a
// SpanRecorder, that recorder's OnEnd method is called as the final part of
// this method.
func (s *Span) End(opts ...trace.SpanEndOption) {
s.lock.Lock()
defer s.lock.Unlock()
if s.ended {
return
}
c := trace.NewSpanEndConfig(opts...)
s.endTime = time.Now()
if endTime := c.Timestamp(); !endTime.IsZero() {
s.endTime = endTime
}
s.ended = true
if s.tracer.provider.config.SpanRecorder != nil {
s.tracer.provider.config.SpanRecorder.OnEnd(s)
}
}
// RecordError records an error as an exception Span event.
func (s *Span) RecordError(err error, opts ...trace.EventOption) {
if err == nil || s.ended {
return
}
errType := reflect.TypeOf(err)
errTypeString := fmt.Sprintf("%s.%s", errType.PkgPath(), errType.Name())
if errTypeString == "." {
errTypeString = errType.String()
}
opts = append(opts, trace.WithAttributes(
semconv.ExceptionTypeKey.String(errTypeString),
semconv.ExceptionMessageKey.String(err.Error()),
))
s.AddEvent(semconv.ExceptionEventName, opts...)
}
// AddEvent adds an event to s.
func (s *Span) AddEvent(name string, o ...trace.EventOption) {
s.lock.Lock()
defer s.lock.Unlock()
if s.ended {
return
}
c := trace.NewEventConfig(o...)
var attributes map[attribute.Key]attribute.Value
if l := len(c.Attributes()); l > 0 {
attributes = make(map[attribute.Key]attribute.Value, l)
for _, attr := range c.Attributes() {
attributes[attr.Key] = attr.Value
}
}
s.events = append(s.events, Event{
Timestamp: c.Timestamp(),
Name: name,
Attributes: attributes,
})
}
// IsRecording returns the recording state of s.
func (s *Span) IsRecording() bool {
return true
}
// SpanContext returns the SpanContext of s.
func (s *Span) SpanContext() trace.SpanContext {
return s.spanContext
}
// SetStatus sets the status of s in the form of a code and a message.
func (s *Span) SetStatus(code codes.Code, msg string) {
s.lock.Lock()
defer s.lock.Unlock()
if s.ended {
return
}
s.statusCode = code
s.statusMessage = msg
}
// SetName sets the name of s.
func (s *Span) SetName(name string) {
s.lock.Lock()
defer s.lock.Unlock()
if s.ended {
return
}
s.name = name
}
// SetAttributes sets attrs as attributes of s.
func (s *Span) SetAttributes(attrs ...attribute.KeyValue) {
s.lock.Lock()
defer s.lock.Unlock()
if s.ended {
return
}
for _, attr := range attrs {
s.attributes[attr.Key] = attr.Value
}
}
// Name returns the name most recently set on s, either at or after creation
// time. It cannot be change after End has been called on s.
func (s *Span) Name() string { return s.name }
// ParentSpanID returns the SpanID of the parent Span. If s is a root Span,
// and therefore does not have a parent, the returned SpanID will be invalid
// (i.e., it will contain all zeroes).
func (s *Span) ParentSpanID() trace.SpanID { return s.parentSpanID }
// Attributes returns the attributes set on s, either at or after creation
// time. If the same attribute key was set multiple times, the last call will
// be used. Attributes cannot be changed after End has been called on s.
func (s *Span) Attributes() map[attribute.Key]attribute.Value {
s.lock.RLock()
defer s.lock.RUnlock()
attributes := make(map[attribute.Key]attribute.Value)
for k, v := range s.attributes {
attributes[k] = v
}
return attributes
}
// Events returns the events set on s. Events cannot be changed after End has
// been called on s.
func (s *Span) Events() []Event { return s.events }
// Links returns the links set on s at creation time. If multiple links for
// the same SpanContext were set, the last link will be used.
func (s *Span) Links() []trace.Link { return s.links }
// StartTime returns the time at which s was started. This will be the
// wall-clock time unless a specific start time was provided.
func (s *Span) StartTime() time.Time { return s.startTime }
// EndTime returns the time at which s was ended if at has been ended, or
// false otherwise. If the span has been ended, the returned time will be the
// wall-clock time unless a specific end time was provided.
func (s *Span) EndTime() (time.Time, bool) { return s.endTime, s.ended }
// Ended returns whether s has been ended, i.e. whether End has been called at
// least once on s.
func (s *Span) Ended() bool { return s.ended }
// StatusCode returns the code of the status most recently set on s, or
// codes.OK if no status has been explicitly set. It cannot be changed after
// End has been called on s.
func (s *Span) StatusCode() codes.Code { return s.statusCode }
// StatusMessage returns the status message most recently set on s or the
// empty string if no status message was set.
func (s *Span) StatusMessage() string { return s.statusMessage }
// SpanKind returns the span kind of s.
func (s *Span) SpanKind() trace.SpanKind { return s.spanKind }
// TracerProvider returns a trace.TracerProvider that can be used to generate
// additional Spans on the same telemetry pipeline as the current Span.
func (s *Span) TracerProvider() trace.TracerProvider {
return s.tracer.provider
}

View File

@ -1,594 +0,0 @@
// 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 oteltest_test
import (
"context"
"errors"
"fmt"
"sync"
"testing"
"time"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
ottest "go.opentelemetry.io/otel/internal/internaltest"
"go.opentelemetry.io/otel/internal/matchers"
//nolint:staticcheck
"go.opentelemetry.io/otel/oteltest"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
"go.opentelemetry.io/otel/trace"
)
func TestSpan(t *testing.T) {
t.Run("#End", func(t *testing.T) {
tp := oteltest.NewTracerProvider()
t.Run("ends the span", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
e.Expect(subject.Ended()).ToBeFalse()
_, ok = subject.EndTime()
e.Expect(ok).ToBeFalse()
start := time.Now()
subject.End()
end := time.Now()
e.Expect(subject.Ended()).ToBeTrue()
endTime, ok := subject.EndTime()
e.Expect(ok).ToBeTrue()
e.Expect(endTime).ToBeTemporally(matchers.AfterOrSameTime, start)
e.Expect(endTime).ToBeTemporally(matchers.BeforeOrSameTime, end)
})
t.Run("only takes effect the first time it is called", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
subject.End()
expectedEndTime, ok := subject.EndTime()
e.Expect(ok).ToBeTrue()
subject.End()
endTime, ok := subject.EndTime()
e.Expect(ok).ToBeTrue()
e.Expect(endTime).ToEqual(expectedEndTime)
})
t.Run("uses the time from WithTimestamp", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
expectedEndTime := time.Now().AddDate(5, 0, 0)
subject.End(trace.WithTimestamp(expectedEndTime))
e.Expect(subject.Ended()).ToBeTrue()
endTime, ok := subject.EndTime()
e.Expect(ok).ToBeTrue()
e.Expect(endTime).ToEqual(expectedEndTime)
})
})
t.Run("#RecordError", func(t *testing.T) {
tp := oteltest.NewTracerProvider()
t.Run("records an error", func(t *testing.T) {
t.Parallel()
scenarios := []struct {
err error
typ string
msg string
}{
{
err: ottest.NewTestError("test error"),
typ: "go.opentelemetry.io/otel/internal/internaltest.TestError",
msg: "test error",
},
{
err: errors.New("test error 2"),
typ: "*errors.errorString",
msg: "test error 2",
},
}
for _, s := range scenarios {
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
testTime := time.Now()
subject.RecordError(s.err, trace.WithTimestamp(testTime))
expectedEvents := []oteltest.Event{{
Timestamp: testTime,
Name: semconv.ExceptionEventName,
Attributes: map[attribute.Key]attribute.Value{
semconv.ExceptionTypeKey: attribute.StringValue(s.typ),
semconv.ExceptionMessageKey: attribute.StringValue(s.msg),
},
}}
e.Expect(subject.Events()).ToEqual(expectedEvents)
e.Expect(subject.StatusCode()).ToEqual(codes.Unset)
e.Expect(subject.StatusMessage()).ToEqual("")
}
})
t.Run("cannot be set after the span has ended", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
subject.End()
subject.RecordError(errors.New("ignored error"))
e.Expect(len(subject.Events())).ToEqual(0)
})
t.Run("has no effect with nil error", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
subject.RecordError(nil)
e.Expect(len(subject.Events())).ToEqual(0)
})
})
t.Run("#IsRecording", func(t *testing.T) {
tp := oteltest.NewTracerProvider()
t.Run("returns true", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, subject := tracer.Start(context.Background(), "test")
e.Expect(subject.IsRecording()).ToBeTrue()
})
})
t.Run("#SpanContext", func(t *testing.T) {
tp := oteltest.NewTracerProvider()
t.Run("returns a valid SpanContext", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, subject := tracer.Start(context.Background(), "test")
e.Expect(subject.SpanContext().IsValid()).ToBeTrue()
})
t.Run("returns a consistent value", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, subject := tracer.Start(context.Background(), "test")
e.Expect(subject.SpanContext()).ToEqual(subject.SpanContext())
})
})
t.Run("#Name", func(t *testing.T) {
tp := oteltest.NewTracerProvider()
t.Run("returns the most recently set name on the span", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
originalName := "test"
_, span := tracer.Start(context.Background(), originalName)
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
e.Expect(subject.Name()).ToEqual(originalName)
subject.SetName("in-between")
newName := "new name"
subject.SetName(newName)
e.Expect(subject.Name()).ToEqual(newName)
})
t.Run("cannot be changed after the span has been ended", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
originalName := "test"
_, span := tracer.Start(context.Background(), originalName)
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
subject.End()
subject.SetName("new name")
e.Expect(subject.Name()).ToEqual(originalName)
})
})
t.Run("#Attributes", func(t *testing.T) {
tp := oteltest.NewTracerProvider()
t.Run("returns an empty map by default", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
e.Expect(subject.Attributes()).ToEqual(map[attribute.Key]attribute.Value{})
})
t.Run("returns the most recently set attributes", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
attr1 := attribute.String("key1", "value1")
attr2 := attribute.String("key2", "value2")
attr3 := attribute.String("key3", "value3")
unexpectedAttr := attr2.Key.String("unexpected")
subject.SetAttributes(attr1, unexpectedAttr, attr3)
subject.SetAttributes(attr2)
attributes := subject.Attributes()
e.Expect(attributes[attr1.Key]).ToEqual(attr1.Value)
e.Expect(attributes[attr2.Key]).ToEqual(attr2.Value)
e.Expect(attributes[attr3.Key]).ToEqual(attr3.Value)
})
t.Run("cannot be changed after the span has been ended", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
expectedAttr := attribute.String("key", "value")
subject.SetAttributes(expectedAttr)
subject.End()
unexpectedAttr := expectedAttr.Key.String("unexpected")
subject.SetAttributes(unexpectedAttr)
subject.End()
attributes := subject.Attributes()
e.Expect(attributes[expectedAttr.Key]).ToEqual(expectedAttr.Value)
})
t.Run("can be used concurrently with setter", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
subject.SetAttributes(attribute.String("key", "value"))
}()
go func() {
defer wg.Done()
subject.Attributes()
}()
wg.Wait()
})
})
t.Run("#Links", func(t *testing.T) {
tp := oteltest.NewTracerProvider()
t.Run("returns an empty map by default", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
e.Expect(len(subject.Links())).ToEqual(0)
})
})
t.Run("#Events", func(t *testing.T) {
tp := oteltest.NewTracerProvider()
t.Run("returns an empty slice by default", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
e.Expect(len(subject.Events())).ToEqual(0)
})
t.Run("returns all of the added events", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
event1Name := "event1"
event1Attributes := []attribute.KeyValue{
attribute.String("event1Attr1", "foo"),
attribute.String("event1Attr2", "bar"),
}
event1Start := time.Now()
subject.AddEvent(event1Name, trace.WithAttributes(event1Attributes...))
event1End := time.Now()
event2Timestamp := time.Now().AddDate(5, 0, 0)
event2Name := "event1"
event2Attributes := []attribute.KeyValue{
attribute.String("event2Attr", "abc"),
}
subject.AddEvent(event2Name, trace.WithTimestamp(event2Timestamp), trace.WithAttributes(event2Attributes...))
events := subject.Events()
e.Expect(len(events)).ToEqual(2)
event1 := events[0]
e.Expect(event1.Timestamp).ToBeTemporally(matchers.AfterOrSameTime, event1Start)
e.Expect(event1.Timestamp).ToBeTemporally(matchers.BeforeOrSameTime, event1End)
e.Expect(event1.Name).ToEqual(event1Name)
for _, attr := range event1Attributes {
e.Expect(event1.Attributes[attr.Key]).ToEqual(attr.Value)
}
event2 := events[1]
e.Expect(event2.Timestamp).ToEqual(event2Timestamp)
e.Expect(event2.Name).ToEqual(event2Name)
for _, attr := range event2Attributes {
e.Expect(event2.Attributes[attr.Key]).ToEqual(attr.Value)
}
})
t.Run("cannot be changed after the span has been ended", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
subject.AddEvent("test")
e.Expect(len(subject.Events())).ToEqual(1)
expectedEvent := subject.Events()[0]
subject.End()
subject.AddEvent("should not occur")
e.Expect(len(subject.Events())).ToEqual(1)
e.Expect(subject.Events()[0]).ToEqual(expectedEvent)
})
})
t.Run("#Status", func(t *testing.T) {
tp := oteltest.NewTracerProvider()
t.Run("defaults to OK", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
e.Expect(subject.StatusCode()).ToEqual(codes.Unset)
subject.End()
e.Expect(subject.StatusCode()).ToEqual(codes.Unset)
})
statuses := []codes.Code{
codes.Unset,
codes.Error,
codes.Ok,
}
for _, status := range statuses {
t.Run("returns the most recently set status on the span", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
subject.SetStatus(codes.Ok, "Ok")
subject.SetStatus(status, "Yo!")
e.Expect(subject.StatusCode()).ToEqual(status)
e.Expect(subject.StatusMessage()).ToEqual("Yo!")
})
t.Run("cannot be changed after the span has been ended", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test")
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
originalStatus := codes.Ok
subject.SetStatus(originalStatus, "OK")
subject.End()
subject.SetStatus(status, fmt.Sprint(status))
e.Expect(subject.StatusCode()).ToEqual(originalStatus)
e.Expect(subject.StatusMessage()).ToEqual("OK")
})
}
})
t.Run("#SpanKind", func(t *testing.T) {
tp := oteltest.NewTracerProvider()
t.Run("returns the value given at start", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
tracer := tp.Tracer(t.Name())
_, span := tracer.Start(context.Background(), "test",
trace.WithSpanKind(trace.SpanKindConsumer))
subject, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
subject.End()
e.Expect(subject.SpanKind()).ToEqual(trace.SpanKindConsumer)
})
})
t.Run("can provide a valid TracerProvider", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
sr := new(oteltest.SpanRecorder)
tracerA := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr)).Tracer(t.Name())
ctx, spanA := tracerA.Start(context.Background(), "span1")
e.Expect(len(sr.Started())).ToEqual(1)
_, spanB := spanA.TracerProvider().Tracer("extracted").Start(ctx, "span2")
spans := sr.Started()
e.Expect(len(spans)).ToEqual(2)
e.Expect(spans[0]).ToEqual(spanA)
e.Expect(spans[1]).ToEqual(spanB)
})
}

View File

@ -1,230 +0,0 @@
// 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 oteltest // import "go.opentelemetry.io/otel/oteltest"
import (
"context"
"fmt"
"strconv"
"strings"
"sync"
"testing"
"go.opentelemetry.io/otel/propagation"
)
type ctxKeyType string
// TextMapCarrier provides a testing storage medium to for a
// TextMapPropagator. It records all the operations it performs.
//
// Deprecated: this will be removed in the next major release.
type TextMapCarrier struct {
mtx sync.Mutex
gets []string
sets [][2]string
data map[string]string
}
// NewTextMapCarrier returns a new *TextMapCarrier populated with data.
//
// Deprecated: this will be removed in the next major release.
func NewTextMapCarrier(data map[string]string) *TextMapCarrier {
copied := make(map[string]string, len(data))
for k, v := range data {
copied[k] = v
}
return &TextMapCarrier{data: copied}
}
// Keys returns the keys for which this carrier has a value.
func (c *TextMapCarrier) Keys() []string {
c.mtx.Lock()
defer c.mtx.Unlock()
result := make([]string, 0, len(c.data))
for k := range c.data {
result = append(result, k)
}
return result
}
// Get returns the value associated with the passed key.
func (c *TextMapCarrier) Get(key string) string {
c.mtx.Lock()
defer c.mtx.Unlock()
c.gets = append(c.gets, key)
return c.data[key]
}
// GotKey tests if c.Get has been called for key.
func (c *TextMapCarrier) GotKey(t *testing.T, key string) bool {
c.mtx.Lock()
defer c.mtx.Unlock()
for _, k := range c.gets {
if k == key {
return true
}
}
t.Errorf("TextMapCarrier.Get(%q) has not been called", key)
return false
}
// GotN tests if n calls to c.Get have been made.
func (c *TextMapCarrier) GotN(t *testing.T, n int) bool {
c.mtx.Lock()
defer c.mtx.Unlock()
if len(c.gets) != n {
t.Errorf("TextMapCarrier.Get was called %d times, not %d", len(c.gets), n)
return false
}
return true
}
// Set stores the key-value pair.
func (c *TextMapCarrier) Set(key, value string) {
c.mtx.Lock()
defer c.mtx.Unlock()
c.sets = append(c.sets, [2]string{key, value})
c.data[key] = value
}
// SetKeyValue tests if c.Set has been called for the key-value pair.
func (c *TextMapCarrier) SetKeyValue(t *testing.T, key, value string) bool {
c.mtx.Lock()
defer c.mtx.Unlock()
var vals []string
for _, pair := range c.sets {
if key == pair[0] {
if value == pair[1] {
return true
}
vals = append(vals, pair[1])
}
}
if len(vals) > 0 {
t.Errorf("TextMapCarrier.Set called with %q and %v values, but not %s", key, vals, value)
}
t.Errorf("TextMapCarrier.Set(%q,%q) has not been called", key, value)
return false
}
// SetN tests if n calls to c.Set have been made.
func (c *TextMapCarrier) SetN(t *testing.T, n int) bool {
c.mtx.Lock()
defer c.mtx.Unlock()
if len(c.sets) != n {
t.Errorf("TextMapCarrier.Set was called %d times, not %d", len(c.sets), n)
return false
}
return true
}
// Reset zeros out the internal state recording of c.
func (c *TextMapCarrier) Reset() {
c.mtx.Lock()
defer c.mtx.Unlock()
c.gets = nil
c.sets = nil
c.data = make(map[string]string)
}
type state struct {
Injections uint64
Extractions uint64
}
func newState(encoded string) state {
if encoded == "" {
return state{}
}
split := strings.SplitN(encoded, ",", 2)
injects, _ := strconv.ParseUint(split[0], 10, 64)
extracts, _ := strconv.ParseUint(split[1], 10, 64)
return state{
Injections: injects,
Extractions: extracts,
}
}
func (s state) String() string {
return fmt.Sprintf("%d,%d", s.Injections, s.Extractions)
}
// TextMapPropagator is a propagation.TextMapPropagator used for testing.
//
// Deprecated: this will be removed in the next major release.
type TextMapPropagator struct {
Name string
ctxKey ctxKeyType
}
// NewTextMapPropagator returns a new TextMapPropagator for testing.
//
// Deprecated: this will be removed in the next major release.
func NewTextMapPropagator(name string) *TextMapPropagator {
return &TextMapPropagator{Name: name, ctxKey: ctxKeyType(name)}
}
func (p *TextMapPropagator) stateFromContext(ctx context.Context) state {
if v := ctx.Value(p.ctxKey); v != nil {
if s, ok := v.(state); ok {
return s
}
}
return state{}
}
func (p *TextMapPropagator) stateFromCarrier(carrier propagation.TextMapCarrier) state {
return newState(carrier.Get(p.Name))
}
// Inject set cross-cutting concerns for p from the Context into the carrier.
func (p *TextMapPropagator) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {
s := p.stateFromContext(ctx)
s.Injections++
carrier.Set(p.Name, s.String())
}
// InjectedN tests if p has made n injections to carrier.
func (p *TextMapPropagator) InjectedN(t *testing.T, carrier *TextMapCarrier, n int) bool {
if actual := p.stateFromCarrier(carrier).Injections; actual != uint64(n) {
t.Errorf("TextMapPropagator{%q} injected %d times, not %d", p.Name, actual, n)
return false
}
return true
}
// Extract reads cross-cutting concerns for p from the carrier into a Context.
func (p *TextMapPropagator) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {
s := p.stateFromCarrier(carrier)
s.Extractions++
return context.WithValue(ctx, p.ctxKey, s)
}
// ExtractedN tests if p has made n extractions from the lineage of ctx.
// nolint (context is not first arg)
func (p *TextMapPropagator) ExtractedN(t *testing.T, ctx context.Context, n int) bool {
if actual := p.stateFromContext(ctx).Extractions; actual != uint64(n) {
t.Errorf("TextMapPropagator{%q} extracted %d time, not %d", p.Name, actual, n)
return false
}
return true
}
// Fields returns p.Name as the key who's value is set with Inject.
func (p *TextMapPropagator) Fields() []string { return []string{p.Name} }

View File

@ -1,133 +0,0 @@
// 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 oteltest
import (
"context"
"reflect"
"testing"
)
var (
key, value = "test", "true"
)
func TestTextMapCarrierKeys(t *testing.T) {
tmc := NewTextMapCarrier(map[string]string{key: value})
expected, actual := []string{key}, tmc.Keys()
if !reflect.DeepEqual(actual, expected) {
t.Errorf("expected tmc.Keys() to be %v but it was %v", expected, actual)
}
}
func TestTextMapCarrierGet(t *testing.T) {
tmc := NewTextMapCarrier(map[string]string{key: value})
tmc.GotN(t, 0)
if got := tmc.Get("empty"); got != "" {
t.Errorf("TextMapCarrier.Get returned %q for an empty key", got)
}
tmc.GotKey(t, "empty")
tmc.GotN(t, 1)
if got := tmc.Get(key); got != value {
t.Errorf("TextMapCarrier.Get(%q) returned %q, want %q", key, got, value)
}
tmc.GotKey(t, key)
tmc.GotN(t, 2)
}
func TestTextMapCarrierSet(t *testing.T) {
tmc := NewTextMapCarrier(nil)
tmc.SetN(t, 0)
tmc.Set(key, value)
if got, ok := tmc.data[key]; !ok {
t.Errorf("TextMapCarrier.Set(%q,%q) failed to store pair", key, value)
} else if got != value {
t.Errorf("TextMapCarrier.Set(%q,%q) stored (%q,%q), not (%q,%q)", key, value, key, got, key, value)
}
tmc.SetKeyValue(t, key, value)
tmc.SetN(t, 1)
}
func TestTextMapCarrierReset(t *testing.T) {
tmc := NewTextMapCarrier(map[string]string{key: value})
tmc.GotN(t, 0)
tmc.SetN(t, 0)
tmc.Reset()
tmc.GotN(t, 0)
tmc.SetN(t, 0)
if got := tmc.Get(key); got != "" {
t.Error("TextMapCarrier.Reset() failed to clear initial data")
}
tmc.GotN(t, 1)
tmc.GotKey(t, key)
tmc.Set(key, value)
tmc.SetKeyValue(t, key, value)
tmc.SetN(t, 1)
tmc.Reset()
tmc.GotN(t, 0)
tmc.SetN(t, 0)
if got := tmc.Get(key); got != "" {
t.Error("TextMapCarrier.Reset() failed to clear data")
}
}
func TestTextMapPropagatorInjectExtract(t *testing.T) {
name := "testing"
ctx := context.Background()
carrier := NewTextMapCarrier(map[string]string{name: value})
propagator := NewTextMapPropagator(name)
propagator.Inject(ctx, carrier)
// Carrier value overridden with state.
if carrier.SetKeyValue(t, name, "1,0") {
// Ensure nothing has been extracted yet.
propagator.ExtractedN(t, ctx, 0)
// Test the injection was counted.
propagator.InjectedN(t, carrier, 1)
}
ctx = propagator.Extract(ctx, carrier)
v := ctx.Value(ctxKeyType(name))
if v == nil {
t.Error("TextMapPropagator.Extract failed to extract state")
}
if s, ok := v.(state); !ok {
t.Error("TextMapPropagator.Extract did not extract proper state")
} else if s.Extractions != 1 {
t.Error("TextMapPropagator.Extract did not increment state.Extractions")
}
if carrier.GotKey(t, name) {
// Test the extraction was counted.
propagator.ExtractedN(t, ctx, 1)
// Ensure no additional injection was recorded.
propagator.InjectedN(t, carrier, 1)
}
}
func TestTextMapPropagatorFields(t *testing.T) {
name := "testing"
propagator := NewTextMapPropagator(name)
if got := propagator.Fields(); len(got) != 1 {
t.Errorf("TextMapPropagator.Fields returned %d fields, want 1", len(got))
} else if got[0] != name {
t.Errorf("TextMapPropagator.Fields returned %q, want %q", got[0], name)
}
}
func TestNewStateEmpty(t *testing.T) {
if want, got := (state{}), newState(""); got != want {
t.Errorf("newState(\"\") returned %v, want %v", got, want)
}
}

View File

@ -1,84 +0,0 @@
// 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 oteltest // import "go.opentelemetry.io/otel/oteltest"
import (
"context"
"time"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
var _ trace.Tracer = (*Tracer)(nil)
// Tracer is an OpenTelemetry Tracer implementation used for testing.
type Tracer struct {
// Name is the instrumentation name.
Name string
// Version is the instrumentation version.
Version string
provider *TracerProvider
}
// Start creates a span. If t is configured with a SpanRecorder its OnStart
// method will be called after the created Span has been initialized.
func (t *Tracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
c := trace.NewSpanStartConfig(opts...)
startTime := time.Now()
if st := c.Timestamp(); !st.IsZero() {
startTime = st
}
span := &Span{
tracer: t,
startTime: startTime,
attributes: make(map[attribute.Key]attribute.Value),
links: []trace.Link{},
spanKind: c.SpanKind(),
}
if c.NewRoot() {
span.spanContext = t.provider.config.SpanContextFunc(context.Background())
} else {
span.spanContext = t.provider.config.SpanContextFunc(ctx)
if current := trace.SpanContextFromContext(ctx); current.IsValid() {
span.spanContext = span.spanContext.WithTraceID(current.TraceID())
span.parentSpanID = current.SpanID()
}
}
for _, link := range c.Links() {
for i, sl := range span.links {
if sl.SpanContext.SpanID() == link.SpanContext.SpanID() &&
sl.SpanContext.TraceID() == link.SpanContext.TraceID() &&
sl.SpanContext.TraceFlags() == link.SpanContext.TraceFlags() &&
sl.SpanContext.TraceState().String() == link.SpanContext.TraceState().String() {
span.links[i].Attributes = link.Attributes
break
}
}
span.links = append(span.links, link)
}
span.SetName(name)
span.SetAttributes(c.Attributes()...)
if t.provider.config.SpanRecorder != nil {
t.provider.config.SpanRecorder.OnStart(span)
}
return trace.ContextWithSpan(ctx, span), span
}

View File

@ -1,295 +0,0 @@
// 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 oteltest_test
import (
"context"
"fmt"
"sync"
"sync/atomic"
"testing"
"time"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/internal/internaltest"
"go.opentelemetry.io/otel/internal/matchers"
//nolint:staticcheck
"go.opentelemetry.io/otel/oteltest"
"go.opentelemetry.io/otel/trace"
)
func TestTracer(t *testing.T) {
tp := oteltest.NewTracerProvider()
internaltest.NewHarness(t).TestTracer(func() func() trace.Tracer {
tp := oteltest.NewTracerProvider()
var i uint64
return func() trace.Tracer {
return tp.Tracer(fmt.Sprintf("tracer %d", atomic.AddUint64(&i, 1)))
}
}())
t.Run("#Start", func(t *testing.T) {
testTracedSpan(t, func(tracer trace.Tracer, name string) (trace.Span, error) {
_, span := tracer.Start(context.Background(), name)
return span, nil
})
t.Run("uses the start time from WithTimestamp", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
expectedStartTime := time.Now().AddDate(5, 0, 0)
subject := tp.Tracer(t.Name())
_, span := subject.Start(context.Background(), "test", trace.WithTimestamp(expectedStartTime))
testSpan, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
e.Expect(testSpan.StartTime()).ToEqual(expectedStartTime)
})
t.Run("uses the attributes from WithAttributes", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
attr1 := attribute.String("a", "1")
attr2 := attribute.String("b", "2")
subject := tp.Tracer(t.Name())
_, span := subject.Start(context.Background(), "test", trace.WithAttributes(attr1, attr2))
testSpan, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
attributes := testSpan.Attributes()
e.Expect(attributes[attr1.Key]).ToEqual(attr1.Value)
e.Expect(attributes[attr2.Key]).ToEqual(attr2.Value)
})
t.Run("uses the current span from context as parent", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
subject := tp.Tracer(t.Name())
parent, parentSpan := subject.Start(context.Background(), "parent")
parentSpanContext := parentSpan.SpanContext()
_, span := subject.Start(parent, "child")
testSpan, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
childSpanContext := testSpan.SpanContext()
e.Expect(childSpanContext.TraceID()).ToEqual(parentSpanContext.TraceID())
e.Expect(childSpanContext.SpanID()).NotToEqual(parentSpanContext.SpanID())
e.Expect(testSpan.ParentSpanID()).ToEqual(parentSpanContext.SpanID())
})
t.Run("uses the current span from context as parent, even if it is remote", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
subject := tp.Tracer(t.Name())
ctx, _ := subject.Start(context.Background(), "local grandparent")
_, s := subject.Start(ctx, "remote parent")
ctx = trace.ContextWithRemoteSpanContext(ctx, s.SpanContext())
parentSpanContext := trace.SpanContextFromContext(ctx)
_, span := subject.Start(ctx, "child")
testSpan, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
childSpanContext := testSpan.SpanContext()
e.Expect(childSpanContext.TraceID()).ToEqual(parentSpanContext.TraceID())
e.Expect(childSpanContext.SpanID()).NotToEqual(parentSpanContext.SpanID())
e.Expect(testSpan.ParentSpanID()).ToEqual(parentSpanContext.SpanID())
})
t.Run("creates new root when context does not have a current span", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
subject := tp.Tracer(t.Name())
_, napSpan := subject.Start(context.Background(), "not-a-parent")
napSpanContext := napSpan.SpanContext()
_, span := subject.Start(context.Background(), "child")
testSpan, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
childSpanContext := testSpan.SpanContext()
e.Expect(childSpanContext.TraceID()).NotToEqual(napSpanContext.TraceID())
e.Expect(childSpanContext.SpanID()).NotToEqual(napSpanContext.SpanID())
e.Expect(testSpan.ParentSpanID().IsValid()).ToBeFalse()
})
t.Run("creates new root when requested, even if context has current span", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
subject := tp.Tracer(t.Name())
ctx, napSpan := subject.Start(context.Background(), "not-a-parent")
napSpanContext := napSpan.SpanContext()
_, span := subject.Start(ctx, "child", trace.WithNewRoot())
testSpan, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
childSpanContext := testSpan.SpanContext()
e.Expect(childSpanContext.IsValid()).ToBeTrue()
e.Expect(childSpanContext.TraceID()).NotToEqual(napSpanContext.TraceID())
e.Expect(childSpanContext.SpanID()).NotToEqual(napSpanContext.SpanID())
e.Expect(testSpan.ParentSpanID().IsValid()).ToBeFalse()
})
t.Run("uses the links provided through WithLinks", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
subject := tp.Tracer(t.Name())
_, span := subject.Start(context.Background(), "link1")
link1 := trace.Link{
SpanContext: span.SpanContext(),
Attributes: []attribute.KeyValue{
attribute.String("a", "1"),
},
}
_, span = subject.Start(context.Background(), "link2")
link2 := trace.Link{
SpanContext: span.SpanContext(),
Attributes: []attribute.KeyValue{
attribute.String("b", "2"),
},
}
_, span = subject.Start(context.Background(), "test", trace.WithLinks(link1, link2))
testSpan, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
links := testSpan.Links()
e.Expect(links[0].Attributes).ToEqual(link1.Attributes)
e.Expect(links[1].Attributes).ToEqual(link2.Attributes)
})
})
}
func testTracedSpan(t *testing.T, fn func(tracer trace.Tracer, name string) (trace.Span, error)) {
tp := oteltest.NewTracerProvider()
t.Run("starts a span with the expected name", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
subject := tp.Tracer(t.Name())
expectedName := "test name"
span, err := fn(subject, expectedName)
e.Expect(err).ToBeNil()
testSpan, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
e.Expect(testSpan.Name()).ToEqual(expectedName)
})
t.Run("uses the current time as the start time", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
subject := tp.Tracer(t.Name())
start := time.Now()
span, err := fn(subject, "test")
end := time.Now()
e.Expect(err).ToBeNil()
testSpan, ok := span.(*oteltest.Span)
e.Expect(ok).ToBeTrue()
e.Expect(testSpan.StartTime()).ToBeTemporally(matchers.AfterOrSameTime, start)
e.Expect(testSpan.StartTime()).ToBeTemporally(matchers.BeforeOrSameTime, end)
})
t.Run("calls SpanRecorder.OnStart", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
sr := new(oteltest.SpanRecorder)
subject := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr)).Tracer(t.Name())
subject.Start(context.Background(), "span1")
e.Expect(len(sr.Started())).ToEqual(1)
span, err := fn(subject, "span2")
e.Expect(err).ToBeNil()
spans := sr.Started()
e.Expect(len(spans)).ToEqual(2)
e.Expect(spans[1]).ToEqual(span)
})
t.Run("can be run concurrently with another call", func(t *testing.T) {
t.Parallel()
e := matchers.NewExpecter(t)
sr := new(oteltest.SpanRecorder)
subject := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr)).Tracer(t.Name())
numSpans := 2
var wg sync.WaitGroup
wg.Add(numSpans)
for i := 0; i < numSpans; i++ {
go func() {
_, err := fn(subject, "test")
e.Expect(err).ToBeNil()
wg.Done()
}()
}
wg.Wait()
e.Expect(len(sr.Started())).ToEqual(numSpans)
})
}

View File

@ -1,43 +0,0 @@
// 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 oteltest
import (
"fmt"
"strings"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
// TraceStateFromKeyValues is a convenience function to create a
// trace.TraceState from provided key/value pairs. There is no inverse to this
// function, returning attributes from a TraceState, because the TraceState,
// by definition from the W3C tracecontext specification, stores values as
// opaque strings. Therefore, it is not possible to decode the original value
// type from TraceState. Be sure to not use this outside of testing purposes.
//
// Deprecated: use trace.ParseTraceState instead.
func TraceStateFromKeyValues(kvs ...attribute.KeyValue) (trace.TraceState, error) {
if len(kvs) == 0 {
return trace.TraceState{}, nil
}
members := make([]string, len(kvs))
for i, kv := range kvs {
members[i] = fmt.Sprintf("%s=%s", string(kv.Key), kv.Value.Emit())
}
return trace.ParseTraceState(strings.Join(members, ","))
}

View File

@ -1,40 +0,0 @@
// 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 oteltest
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/attribute"
)
func TestTraceStateFromKeyValues(t *testing.T) {
ts, err := TraceStateFromKeyValues()
require.NoError(t, err)
assert.Equal(t, 0, ts.Len(), "empty attributes creats zero value TraceState")
ts, err = TraceStateFromKeyValues(
attribute.String("key0", "string"),
attribute.Bool("key1", true),
attribute.Int64("key2", 1),
attribute.Float64("key3", 1.1),
)
require.NoError(t, err)
expected := "key0=string,key1=true,key2=1,key3=1.1"
assert.Equal(t, expected, ts.String())
}

View File

@ -32,8 +32,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../../metric replace go.opentelemetry.io/otel/metric => ../../../metric
replace go.opentelemetry.io/otel/oteltest => ../../../oteltest
replace go.opentelemetry.io/otel/sdk => ../.. replace go.opentelemetry.io/otel/sdk => ../..
replace go.opentelemetry.io/otel/sdk/export/metric => ./ replace go.opentelemetry.io/otel/sdk/export/metric => ./

View File

@ -42,8 +42,6 @@ replace go.opentelemetry.io/otel/sdk => ./
replace go.opentelemetry.io/otel/metric => ../metric replace go.opentelemetry.io/otel/metric => ../metric
replace go.opentelemetry.io/otel/oteltest => ../oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ./export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ./export/metric
replace go.opentelemetry.io/otel/sdk/metric => ./metric replace go.opentelemetry.io/otel/sdk/metric => ./metric

View File

@ -32,8 +32,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../../internal/tools
replace go.opentelemetry.io/otel/metric => ../../metric replace go.opentelemetry.io/otel/metric => ../../metric
replace go.opentelemetry.io/otel/oteltest => ../../oteltest
replace go.opentelemetry.io/otel/sdk => ../ replace go.opentelemetry.io/otel/sdk => ../
replace go.opentelemetry.io/otel/sdk/export/metric => ../export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../export/metric

View File

@ -32,8 +32,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../internal/tools
replace go.opentelemetry.io/otel/metric => ../metric replace go.opentelemetry.io/otel/metric => ../metric
replace go.opentelemetry.io/otel/oteltest => ../oteltest
replace go.opentelemetry.io/otel/sdk => ../sdk replace go.opentelemetry.io/otel/sdk => ../sdk
replace go.opentelemetry.io/otel/sdk/export/metric => ../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../sdk/export/metric

View File

@ -30,7 +30,6 @@ module-sets:
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp
- go.opentelemetry.io/otel/exporters/stdout/stdouttrace - go.opentelemetry.io/otel/exporters/stdout/stdouttrace
- go.opentelemetry.io/otel/oteltest
- go.opentelemetry.io/otel/trace - go.opentelemetry.io/otel/trace
- go.opentelemetry.io/otel/sdk - go.opentelemetry.io/otel/sdk
experimental-metrics: experimental-metrics: