diff --git a/sdk/go.mod b/sdk/go.mod index 7e4dd27c9..44ce135c6 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -5,16 +5,20 @@ go 1.22.0 toolchain go1.22.6 require ( + github.com/stretchr/testify v1.9.0 go.opentelemetry.io/collector/pdata v1.15.0 go.opentelemetry.io/otel v1.30.0 go.opentelemetry.io/otel/trace v1.30.0 ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kr/text v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/sys v0.21.0 // indirect @@ -22,4 +26,5 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect google.golang.org/grpc v1.66.0 // indirect google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/sdk/go.sum b/sdk/go.sum index bea79268b..dcd043b08 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -1,3 +1,4 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -10,6 +11,10 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -17,6 +22,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 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/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= @@ -70,5 +77,8 @@ google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sdk/trace.go b/sdk/trace.go index 67e3fd2b0..b011fae2a 100644 --- a/sdk/trace.go +++ b/sdk/trace.go @@ -94,15 +94,38 @@ type span struct { span ptrace.Span } -func (s *span) SpanContext() trace.SpanContext { return s.spanContext } +func (s *span) SpanContext() trace.SpanContext { + if s == nil { + return trace.SpanContext{} + } + return s.spanContext +} -func (s *span) IsRecording() bool { return s.sampled } +func (s *span) IsRecording() bool { + if s == nil { + return false + } + return s.sampled +} -func (s *span) SetStatus(c codes.Code, msg string) { /* TODO: implement */ } +func (s *span) SetStatus(c codes.Code, msg string) { + if s == nil || !s.sampled { + return + } + /* TODO: implement */ +} -func (s *span) SetAttributes(attrs ...attribute.KeyValue) { /* TODO: implement */ } +func (s *span) SetAttributes(attrs ...attribute.KeyValue) { + if s == nil || !s.sampled { + return + } + /* TODO: implement */ +} func (s *span) End(opts ...trace.SpanEndOption) { + if s == nil || !s.sampled { + return + } // TODO: implement. s.ended(nil) } @@ -112,12 +135,34 @@ func (s *span) End(opts ...trace.SpanEndOption) { //go:noinline func (*span) ended(buf []byte) {} -func (s *span) RecordError(err error, opts ...trace.EventOption) { /* TODO: implement */ } +func (s *span) RecordError(err error, opts ...trace.EventOption) { + if s == nil || err == nil || !s.sampled { + return + } + /* TODO: implement */ +} -func (s *span) AddEvent(name string, opts ...trace.EventOption) { /* TODO: implement */ } +func (s *span) AddEvent(name string, opts ...trace.EventOption) { + if s == nil || !s.sampled { + return + } + /* TODO: implement */ +} -func (s *span) AddLink(link trace.Link) { /* TODO: implement */ } +func (s *span) AddLink(link trace.Link) { + if s == nil || !s.sampled { + return + } + /* TODO: implement */ +} -func (s *span) SetName(name string) { /* TODO: implement */ } +func (s *span) SetName(name string) { + if s == nil || !s.sampled { + return + } + /* TODO: implement */ +} -func (*span) TracerProvider() trace.TracerProvider { return GetTracerProvider() } +func (*span) TracerProvider() trace.TracerProvider { + return GetTracerProvider() +} diff --git a/sdk/trace_test.go b/sdk/trace_test.go new file mode 100644 index 000000000..91a9636e5 --- /dev/null +++ b/sdk/trace_test.go @@ -0,0 +1,49 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package sdk + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace" +) + +var attrs = []attribute.KeyValue{ + attribute.Bool("bool", true), + attribute.Int("int", -1), + attribute.Int64("int64", 43), + attribute.Float64("float64", 0.3), + attribute.String("string", "value"), + attribute.BoolSlice("bool slice", []bool{true, false, true}), + attribute.IntSlice("int slice", []int{-1, -30, 328}), + attribute.Int64Slice("int64 slice", []int64{1030, 0, 0}), + attribute.Float64Slice("float64 slice", []float64{1e9}), + attribute.StringSlice("string slice", []string{"one", "two"}), +} + +func TestSpanNilUnsampledGuards(t *testing.T) { + run := func(fn func(s *span)) func(*testing.T) { + return func(t *testing.T) { + t.Helper() + + f := func(s *span) func() { return func() { fn(s) } } + assert.NotPanics(t, f(nil), "nil span") + assert.NotPanics(t, f(new(span)), "unsampled span") + } + } + + t.Run("End", run(func(s *span) { s.End() })) + t.Run("AddEvent", run(func(s *span) { s.AddEvent("event name") })) + t.Run("AddLink", run(func(s *span) { s.AddLink(trace.Link{}) })) + t.Run("IsRecording", run(func(s *span) { _ = s.IsRecording() })) + t.Run("RecordError", run(func(s *span) { s.RecordError(nil) })) + t.Run("SpanContext", run(func(s *span) { _ = s.SpanContext() })) + t.Run("SetStatus", run(func(s *span) { s.SetStatus(codes.Error, "test") })) + t.Run("SetName", run(func(s *span) { s.SetName("span name") })) + t.Run("SetAttributes", run(func(s *span) { s.SetAttributes(attrs...) })) + t.Run("TracerProvider", run(func(s *span) { _ = s.TracerProvider() })) +}