From a7208c2ee5c35d2bd0b7b7be3ba3e1e54d4dff02 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Wed, 19 Jun 2024 03:18:02 +0000 Subject: [PATCH] add unit test for runtime metrics --- instrumentation/runtime/runtime_test.go | 12 -- instrumentation/runtime/test/go.mod | 24 ++++ instrumentation/runtime/test/go.sum | 29 ++++ instrumentation/runtime/test/runtime_test.go | 134 +++++++++++++++++++ 4 files changed, 187 insertions(+), 12 deletions(-) delete mode 100644 instrumentation/runtime/runtime_test.go create mode 100644 instrumentation/runtime/test/go.mod create mode 100644 instrumentation/runtime/test/go.sum create mode 100644 instrumentation/runtime/test/runtime_test.go diff --git a/instrumentation/runtime/runtime_test.go b/instrumentation/runtime/runtime_test.go deleted file mode 100644 index 78d89a3c391..00000000000 --- a/instrumentation/runtime/runtime_test.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package runtime_test - -// TODO(#2757): Add integration tests for the runtime instrumentation. These -// tests depend on -// https://github.com/open-telemetry/opentelemetry-go/issues/3031 being -// resolved. -// -// The added tests will depend on the metric SDK. Therefore, they should be -// added to a sub-directory called "test" instead of this file. diff --git a/instrumentation/runtime/test/go.mod b/instrumentation/runtime/test/go.mod new file mode 100644 index 00000000000..5e51e6cfe19 --- /dev/null +++ b/instrumentation/runtime/test/go.mod @@ -0,0 +1,24 @@ +module go.opentelemetry.io/contrib/instrumentation/runtime/test + +go 1.21 + +require ( + github.com/stretchr/testify v1.9.0 + go.opentelemetry.io/contrib/instrumentation/runtime v0.52.0 + go.opentelemetry.io/otel v1.27.0 + go.opentelemetry.io/otel/sdk v1.27.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/trace v1.27.0 // indirect + golang.org/x/sys v0.20.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace go.opentelemetry.io/contrib/instrumentation/runtime => ../ diff --git a/instrumentation/runtime/test/go.sum b/instrumentation/runtime/test/go.sum new file mode 100644 index 00000000000..fc620f7e822 --- /dev/null +++ b/instrumentation/runtime/test/go.sum @@ -0,0 +1,29 @@ +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.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/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.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= +go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= +go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= +go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= +go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= +go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= +go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= +go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/instrumentation/runtime/test/runtime_test.go b/instrumentation/runtime/test/runtime_test.go new file mode 100644 index 00000000000..03d5475ff26 --- /dev/null +++ b/instrumentation/runtime/test/runtime_test.go @@ -0,0 +1,134 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package runtime // import "go.opentelemetry.io/contrib/instrumentation/runtime/test" + +import ( + "context" + "math" + "runtime/debug" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk/instrumentation" + "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" + "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" + + "go.opentelemetry.io/contrib/instrumentation/runtime" +) + +func TestRuntimeWithLimit(t *testing.T) { + t.Setenv("OTEL_GO_X_DEPRECATED_RUNTIME_METRICS", "false") + debug.SetMemoryLimit(1234567890) + // reset to default + defer debug.SetMemoryLimit(math.MaxInt64) + + reader := metric.NewManualReader() + mp := metric.NewMeterProvider(metric.WithReader(reader)) + runtime.Start(runtime.WithMeterProvider(mp)) + rm := metricdata.ResourceMetrics{} + err := reader.Collect(context.Background(), &rm) + assert.NoError(t, err) + require.Len(t, rm.ScopeMetrics, 1) + require.Len(t, rm.ScopeMetrics[0].Metrics, 8) + + expectedScopeMetric := metricdata.ScopeMetrics{ + Scope: instrumentation.Scope{ + Name: "go.opentelemetry.io/contrib/instrumentation/runtime", + Version: runtime.Version(), + }, + Metrics: []metricdata.Metrics{ + { + Name: "go.memory.used", + Description: "Memory used by the Go runtime.", + Unit: "By", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: false, + DataPoints: []metricdata.DataPoint[int64]{ + { + Attributes: attribute.NewSet(attribute.String("go.memory.type", "stack")), + }, + { + Attributes: attribute.NewSet(attribute.String("go.memory.type", "other")), + }, + }, + }, + }, + { + Name: "go.memory.limit", + Description: "Go runtime memory limit configured by the user, if a limit exists.", + Unit: "By", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: false, + DataPoints: []metricdata.DataPoint[int64]{{}}, + }, + }, + { + Name: "go.memory.allocated", + Description: "Memory allocated to the heap by the application.", + Unit: "By", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: true, + DataPoints: []metricdata.DataPoint[int64]{{}}, + }, + }, + { + Name: "go.memory.allocations", + Description: "Count of allocations to the heap by the application.", + Unit: "{allocation}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: true, + DataPoints: []metricdata.DataPoint[int64]{{}}, + }, + }, + { + Name: "go.memory.gc.goal", + Description: "Heap size target for the end of the GC cycle.", + Unit: "By", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: false, + DataPoints: []metricdata.DataPoint[int64]{{}}, + }, + }, + { + Name: "go.goroutine.count", + Description: "Count of live goroutines.", + Unit: "{goroutine}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: false, + DataPoints: []metricdata.DataPoint[int64]{{}}, + }, + }, + { + Name: "go.processor.limit", + Description: "The number of OS threads that can execute user-level Go code simultaneously.", + Unit: "{thread}", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: false, + DataPoints: []metricdata.DataPoint[int64]{{}}, + }, + }, + { + Name: "go.config.gogc", + Description: "Heap size target percentage configured by the user, otherwise 100.", + Unit: "%", + Data: metricdata.Sum[int64]{ + Temporality: metricdata.CumulativeTemporality, + IsMonotonic: false, + DataPoints: []metricdata.DataPoint[int64]{{}}, + }, + }, + }, + } + metricdatatest.AssertEqual(t, expectedScopeMetric, rm.ScopeMetrics[0], metricdatatest.IgnoreTimestamp(), metricdatatest.IgnoreValue()) +}