From 1aa58af2ef851dfcf1838584ff2d4defb27ac709 Mon Sep 17 00:00:00 2001 From: Joshua Timmons Date: Thu, 28 Dec 2023 14:33:12 -0500 Subject: [PATCH] Add test specific to EnableAll --- go.work | 1 + spanlint_test.go | 11 +- testdata/enablechecks/enablechecks.go | 195 ++++++++++++++++++++++++++ testdata/enablechecks/go.mod | 12 ++ testdata/enablechecks/go.sum | 21 +++ 5 files changed, 236 insertions(+), 4 deletions(-) create mode 100644 testdata/enablechecks/enablechecks.go create mode 100644 testdata/enablechecks/go.mod create mode 100644 testdata/enablechecks/go.sum diff --git a/go.work b/go.work index 6d1b8cd..55652cf 100644 --- a/go.work +++ b/go.work @@ -5,4 +5,5 @@ use ( ./testdata/base ./testdata/disableerrorchecks ./testdata/enableall + ./testdata/enablechecks ) diff --git a/spanlint_test.go b/spanlint_test.go index 8ea4faa..061357b 100644 --- a/spanlint_test.go +++ b/spanlint_test.go @@ -14,16 +14,19 @@ func Test(t *testing.T) { for dir, config := range map[string]*spanlint.Config{ "base": spanlint.NewDefaultConfig(), - "enableall": { - EnableSetStatusCheck: true, - EnableRecordErrorCheck: true, - }, "disableerrorchecks": { EnableSetStatusCheck: true, IgnoreSetStatusCheckSignatures: regexp.MustCompile("telemetry.Record"), EnableRecordErrorCheck: true, IgnoreRecordErrorCheckSignatures: regexp.MustCompile("telemetry.Record"), }, + "enableall": { + EnableAll: true, + }, + "enablechecks": { + EnableSetStatusCheck: true, + EnableRecordErrorCheck: true, + }, } { dir := dir t.Run(dir, func(t *testing.T) { diff --git a/testdata/enablechecks/enablechecks.go b/testdata/enablechecks/enablechecks.go new file mode 100644 index 0000000..4aa200b --- /dev/null +++ b/testdata/enablechecks/enablechecks.go @@ -0,0 +1,195 @@ +package enableall + +import ( + "context" + "errors" + "fmt" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/codes" +) + +type testError struct{} + +func (e *testError) Error() string { + return "foo" +} + +// incorrect + +func _() { + otel.Tracer("foo").Start(context.Background(), "bar") // want "span is unassigned, probable memory leak" + ctx, _ := otel.Tracer("foo").Start(context.Background(), "bar") // want "span is unassigned, probable memory leak" + fmt.Print(ctx) +} + +func _() { + ctx, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.End is not called on all paths, possible memory leak" + print(ctx.Done(), span.IsRecording()) +} // want "return can be reached without calling span.End" + +func _() { + var ctx, span = otel.Tracer("foo").Start(context.Background(), "bar") // want "span.End is not called on all paths, possible memory leak" + print(ctx.Done(), span.IsRecording()) +} // want "return can be reached without calling span.End" + +func _() { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.End is not called on all paths, possible memory leak" + _, span = otel.Tracer("foo").Start(context.Background(), "bar") + fmt.Print(span) + defer span.End() +} // want "return can be reached without calling span.End" + +func _() error { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths" + defer span.End() + + if true { + err := errors.New("foo") + span.RecordError(err) + return err // want "return can be reached without calling span.SetStatus" + } + + return nil +} + +func _() error { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths" + defer span.End() + + if true { + span.RecordError(errors.New("foo")) + return errors.New("foo") // want "return can be reached without calling span.SetStatus" + } + + return nil +} + +func _() error { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths" + defer span.End() + + if true { + span.RecordError(errors.New("foo")) + return &testError{} // want "return can be reached without calling span.SetStatus" + } + + return nil +} + +func _() error { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.RecordError is not called on all paths" + defer span.End() + + if true { + span.SetStatus(codes.Error, "foo") + return &testError{} // want "return can be reached without calling span.RecordError" + } + + return nil +} + +func _() (string, error) { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths" + defer span.End() + + if true { + span.RecordError(errors.New("foo")) + return "", &testError{} // want "return can be reached without calling span.SetStatus" + } + + return "", nil +} + +func _() (string, error) { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths" + defer span.End() + + if true { + span.RecordError(errors.New("foo")) + return "", errors.New("foo") // want "return can be reached without calling span.SetStatus" + } + + return "", nil +} + +func _() { + f := func() error { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths" + defer span.End() + + if true { + span.RecordError(errors.New("foo")) + return errors.New("foo") // want "return can be reached without calling span.SetStatus" + } + + return nil + } + fmt.Println(f) +} + +func _() error { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.SetStatus is not called on all paths" + defer span.End() + + { + if true { + span.RecordError(errors.New("foo")) + return errors.New("foo") // want "return can be reached without calling span.SetStatus" + } + } + + return nil +} + +// correct + +func _() error { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") + defer span.End() + + return nil +} + +func _() error { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") + defer span.End() + + if true { + return nil + } + + return nil +} + +func _() error { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") + defer span.End() + + if false { + err := errors.New("foo") + span.SetStatus(codes.Error, err.Error()) + span.RecordError(err) + return err + } + + if true { + span.SetStatus(codes.Error, "foo") + span.RecordError(errors.New("foo")) + return errors.New("bar") + } + + return nil +} + +func _() { + _, span := otel.Tracer("foo").Start(context.Background(), "bar") + defer span.End() + + _, span = otel.Tracer("foo").Start(context.Background(), "bar") + defer span.End() +} + +func _() { + // TODO: https://andydote.co.uk/2023/09/19/tracing-is-better/ +} diff --git a/testdata/enablechecks/go.mod b/testdata/enablechecks/go.mod new file mode 100644 index 0000000..34b7fcb --- /dev/null +++ b/testdata/enablechecks/go.mod @@ -0,0 +1,12 @@ +module github.com/jjti/go-spanlint/testdata/enablechecks + +go 1.21.3 + +require go.opentelemetry.io/otel v1.21.0 + +require ( + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect +) diff --git a/testdata/enablechecks/go.sum b/testdata/enablechecks/go.sum new file mode 100644 index 0000000..65c608c --- /dev/null +++ b/testdata/enablechecks/go.sum @@ -0,0 +1,21 @@ +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= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=