diff --git a/instrumentation/github.com/astaxie/beego/otelbeego/test/beego_test.go b/instrumentation/github.com/astaxie/beego/otelbeego/test/beego_test.go index 92616953d78..f0cb8242760 100644 --- a/instrumentation/github.com/astaxie/beego/otelbeego/test/beego_test.go +++ b/instrumentation/github.com/astaxie/beego/otelbeego/test/beego_test.go @@ -29,8 +29,8 @@ import ( "go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego/internal" "go.opentelemetry.io/contrib/propagators/b3" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/nonrecording" "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/metric/metrictest" "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/sdk/trace/tracetest" semconv "go.opentelemetry.io/otel/semconv/v1.7.0" @@ -189,7 +189,7 @@ func TestStatic(t *testing.T) { defer replaceBeego() sr := tracetest.NewSpanRecorder() tracerProvider := trace.NewTracerProvider(trace.WithSpanProcessor(sr)) - meterProvider := nonrecording.NewNoopMeterProvider() + meterProvider, metricExporter := metrictest.NewTestMeterProvider() file, err := ioutil.TempFile("", "static-*.html") require.NoError(t, err) defer os.Remove(file.Name()) @@ -220,8 +220,7 @@ func TestStatic(t *testing.T) { spans := sr.Ended() require.Len(t, spans, 1) assertSpan(t, spans[0], tc) - // TODO: Replace with in memory exporter https://github.com/open-telemetry/opentelemetry-go/issues/2722 - // assertMetrics(t, meterProvider.MeasurementBatches, tc) + assertMetrics(t, metricExporter.GetRecords(), tc) } func TestRender(t *testing.T) { @@ -288,7 +287,7 @@ func TestRender(t *testing.T) { func runTest(t *testing.T, tc *testCase, url string) { sr := tracetest.NewSpanRecorder() tracerProvider := trace.NewTracerProvider(trace.WithSpanProcessor(sr)) - meterProvider := nonrecording.NewNoopMeterProvider() + meterProvider, metricExporter := metrictest.NewTestMeterProvider() addTestRoutes(t) defer replaceBeego() @@ -327,8 +326,7 @@ func runTest(t *testing.T, tc *testCase, url string) { } else { require.Len(t, spans, 0) } - // TODO: Replace with in memory exporter https://github.com/open-telemetry/opentelemetry-go/issues/2722 - // assertMetrics(t, meterProvider.MeasurementBatches, tc) + assertMetrics(t, metricExporter.GetRecords(), tc) } func defaultAttributes() []attribute.KeyValue { @@ -347,14 +345,13 @@ func assertSpan(t *testing.T, span trace.ReadOnlySpan, tc *testCase) { } } -// TODO: Replace with in memory exporter https://github.com/open-telemetry/opentelemetry-go/issues/2722 -// func assertMetrics(t *testing.T, batches []metrictest.Batch, tc *testCase) { -// for _, batch := range batches { -// for _, att := range tc.expectedAttributes { -// require.Contains(t, batch.Labels, att) -// } -// } -// } +func assertMetrics(t *testing.T, records []metrictest.ExportRecord, tc *testCase) { + for _, record := range records { + for _, att := range tc.expectedAttributes { + require.Contains(t, record.Attributes, att) + } + } +} // ------------------------------------------ Test Cases diff --git a/instrumentation/github.com/astaxie/beego/otelbeego/test/go.mod b/instrumentation/github.com/astaxie/beego/otelbeego/test/go.mod index e4dcbfb4471..55dcc0bd94b 100644 --- a/instrumentation/github.com/astaxie/beego/otelbeego/test/go.mod +++ b/instrumentation/github.com/astaxie/beego/otelbeego/test/go.mod @@ -8,8 +8,8 @@ require ( go.opentelemetry.io/contrib/instrumentation/github.com/astaxie/beego/otelbeego v0.31.0 go.opentelemetry.io/contrib/propagators/b3 v1.6.0 go.opentelemetry.io/otel v1.6.3 - go.opentelemetry.io/otel/metric v0.29.0 go.opentelemetry.io/otel/sdk v1.6.3 + go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 ) replace ( diff --git a/instrumentation/github.com/astaxie/beego/otelbeego/test/go.sum b/instrumentation/github.com/astaxie/beego/otelbeego/test/go.sum index e9c792b5b6b..849eee3d053 100644 --- a/instrumentation/github.com/astaxie/beego/otelbeego/test/go.sum +++ b/instrumentation/github.com/astaxie/beego/otelbeego/test/go.sum @@ -11,6 +11,8 @@ github.com/astaxie/beego v1.12.3 h1:SAQkdD2ePye+v8Gn1r4X6IKZM1wd28EyUOVQ3PDSOOQ= github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA= github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ= github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -153,6 +155,8 @@ go.opentelemetry.io/otel/metric v0.29.0 h1:7unM/I13Dbc1VHw8lTPQ7zfNIgkhcb8BZhujX go.opentelemetry.io/otel/metric v0.29.0/go.mod h1:HahKFp1OC1RNTsuO/HNMBHHJR+dmHZ7wLARRgGDwjLQ= go.opentelemetry.io/otel/sdk v1.6.3 h1:prSHYdwCQOX5DrsEzxowH3nLhoAzEBdZhvrR79scfLs= go.opentelemetry.io/otel/sdk v1.6.3/go.mod h1:A4iWF7HTXa+GWL/AaqESz28VuSBIcZ+0CV+IzJ5NMiQ= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 h1:w97SUMLzaACqAmuyNR6S+1N2o90Y3Kcvz6S8xp8uysM= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2/go.mod h1:IFkFNKI8Gq8zBdqOKdODCL9+LInBZLXaGpqSIKphNuU= go.opentelemetry.io/otel/trace v1.6.3 h1:IqN4L+5b0mPNjdXIiZ90Ni4Bl5BRkDQywePLWemd9bc= go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/instrumentation/github.com/gocql/gocql/otelgocql/test/go.mod b/instrumentation/github.com/gocql/gocql/otelgocql/test/go.mod index d1fd21544c6..f8bfb1e583c 100644 --- a/instrumentation/github.com/gocql/gocql/otelgocql/test/go.mod +++ b/instrumentation/github.com/gocql/gocql/otelgocql/test/go.mod @@ -9,6 +9,7 @@ require ( go.opentelemetry.io/contrib/instrumentation/github.com/gocql/gocql/otelgocql v0.31.0 go.opentelemetry.io/otel v1.6.3 go.opentelemetry.io/otel/sdk v1.6.3 + go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 go.opentelemetry.io/otel/trace v1.6.3 ) diff --git a/instrumentation/github.com/gocql/gocql/otelgocql/test/go.sum b/instrumentation/github.com/gocql/gocql/otelgocql/test/go.sum index be3e193108e..fd714128620 100644 --- a/instrumentation/github.com/gocql/gocql/otelgocql/test/go.sum +++ b/instrumentation/github.com/gocql/gocql/otelgocql/test/go.sum @@ -1,3 +1,5 @@ +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= @@ -37,6 +39,8 @@ go.opentelemetry.io/otel/metric v0.29.0 h1:7unM/I13Dbc1VHw8lTPQ7zfNIgkhcb8BZhujX go.opentelemetry.io/otel/metric v0.29.0/go.mod h1:HahKFp1OC1RNTsuO/HNMBHHJR+dmHZ7wLARRgGDwjLQ= go.opentelemetry.io/otel/sdk v1.6.3 h1:prSHYdwCQOX5DrsEzxowH3nLhoAzEBdZhvrR79scfLs= go.opentelemetry.io/otel/sdk v1.6.3/go.mod h1:A4iWF7HTXa+GWL/AaqESz28VuSBIcZ+0CV+IzJ5NMiQ= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 h1:w97SUMLzaACqAmuyNR6S+1N2o90Y3Kcvz6S8xp8uysM= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2/go.mod h1:IFkFNKI8Gq8zBdqOKdODCL9+LInBZLXaGpqSIKphNuU= go.opentelemetry.io/otel/trace v1.6.3 h1:IqN4L+5b0mPNjdXIiZ90Ni4Bl5BRkDQywePLWemd9bc= go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= diff --git a/instrumentation/github.com/gocql/gocql/otelgocql/test/gocql_test.go b/instrumentation/github.com/gocql/gocql/otelgocql/test/gocql_test.go index 30679af50ea..c3771f2d24f 100644 --- a/instrumentation/github.com/gocql/gocql/otelgocql/test/gocql_test.go +++ b/instrumentation/github.com/gocql/gocql/otelgocql/test/gocql_test.go @@ -30,6 +30,9 @@ import ( "go.opentelemetry.io/contrib/instrumentation/github.com/gocql/gocql/otelgocql/internal" "go.opentelemetry.io/contrib/internal/util" "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/metrictest" + "go.opentelemetry.io/otel/sdk/metric/number" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/sdk/trace/tracetest" semconv "go.opentelemetry.io/otel/semconv/v1.7.0" @@ -49,21 +52,20 @@ func (m *mockConnectObserver) ObserveConnect(observedConnect gocql.ObservedConne m.callCount++ } -// TODO: Replace with in memory exporter https://github.com/open-telemetry/opentelemetry-go/issues/2722 -// type testRecord struct { -// name string -// meterName string -// attributes []attribute.KeyValue -// number number.Number -// numberKind number.Kind -// } +type testRecord struct { + name string + meterName string + attributes []attribute.KeyValue + number number.Number + numberKind number.Kind +} func TestQuery(t *testing.T) { defer afterEach() cluster := getCluster() sr := tracetest.NewSpanRecorder() tracerProvider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr)) - // meterProvider := metrictest.NewMeterProvider() + meterProvider, metricExporter := metrictest.NewTestMeterProvider() ctx, parentSpan := tracerProvider.Tracer(internal.InstrumentationName).Start(context.Background(), "gocql-test") @@ -71,7 +73,7 @@ func TestQuery(t *testing.T) { ctx, cluster, otelgocql.WithTracerProvider(tracerProvider), - // otelgocql.WithMeterProvider(meterProvider), + otelgocql.WithMeterProvider(meterProvider), otelgocql.WithConnectInstrumentation(false), ) require.NoError(t, err) @@ -109,71 +111,71 @@ func TestQuery(t *testing.T) { assertConnectionLevelAttributes(t, span) } - // TODO: Replace with in memory exporter https://github.com/open-telemetry/opentelemetry-go/issues/2722 - // // Check metrics - // actual := obtainTestRecords(meterProvider.MeasurementBatches) - // require.Len(t, actual, 3) - // expected := []testRecord{ - // { - // name: "db.cassandra.queries", - // meterName: internal.InstrumentationName, - // attributes: []attribute.KeyValue{ - // internal.CassDBSystem(), - // internal.CassPeerIP("127.0.0.1"), - // internal.CassPeerPort(9042), - // internal.CassVersion("3"), - // internal.CassHostID("test-id"), - // internal.CassHostState("UP"), - // internal.CassKeyspace(keyspace), - // internal.CassStatement(insertStmt), - // }, - // number: 1, - // }, - // { - // name: "db.cassandra.rows", - // meterName: internal.InstrumentationName, - // attributes: []attribute.KeyValue{ - // internal.CassDBSystem(), - // internal.CassPeerIP("127.0.0.1"), - // internal.CassPeerPort(9042), - // internal.CassVersion("3"), - // internal.CassHostID("test-id"), - // internal.CassHostState("UP"), - // internal.CassKeyspace(keyspace), - // }, - // number: 0, - // }, - // { - // name: "db.cassandra.latency", - // meterName: internal.InstrumentationName, - // attributes: []attribute.KeyValue{ - // internal.CassDBSystem(), - // internal.CassPeerIP("127.0.0.1"), - // internal.CassPeerPort(9042), - // internal.CassVersion("3"), - // internal.CassHostID("test-id"), - // internal.CassHostState("UP"), - // internal.CassKeyspace(keyspace), - // }, - // }, - // } - - // for _, record := range actual { - // switch record.name { - // case "db.cassandra.queries": - // recordEqual(t, expected[0], record) - // assert.Equal(t, expected[0].number, record.number) - // case "db.cassandra.rows": - // recordEqual(t, expected[1], record) - // assert.Equal(t, expected[1].number, record.number) - // case "db.cassandra.latency": - // recordEqual(t, expected[2], record) - // // The latency will vary, so just check that it exists - // assert.True(t, !record.number.IsZero(record.numberKind)) - // default: - // t.Fatalf("wrong metric %s", record.name) - // } - // } + // Check metrics + require.NoError(t, metricExporter.Collect(context.Background())) + actual := obtainTestRecords(metricExporter.GetRecords()) + require.Len(t, actual, 3) + expected := []testRecord{ + { + name: "db.cassandra.queries", + meterName: internal.InstrumentationName, + attributes: []attribute.KeyValue{ + internal.CassDBSystem(), + internal.CassPeerIP("127.0.0.1"), + internal.CassPeerPort(9042), + internal.CassVersion("3"), + internal.CassHostID("test-id"), + internal.CassHostState("UP"), + internal.CassKeyspace(keyspace), + internal.CassStatement(insertStmt), + }, + number: 1, + }, + { + name: "db.cassandra.rows", + meterName: internal.InstrumentationName, + attributes: []attribute.KeyValue{ + internal.CassDBSystem(), + internal.CassPeerIP("127.0.0.1"), + internal.CassPeerPort(9042), + internal.CassVersion("3"), + internal.CassHostID("test-id"), + internal.CassHostState("UP"), + internal.CassKeyspace(keyspace), + }, + number: 0, + }, + { + name: "db.cassandra.latency", + meterName: internal.InstrumentationName, + attributes: []attribute.KeyValue{ + internal.CassDBSystem(), + internal.CassPeerIP("127.0.0.1"), + internal.CassPeerPort(9042), + internal.CassVersion("3"), + internal.CassHostID("test-id"), + internal.CassHostState("UP"), + internal.CassKeyspace(keyspace), + }, + }, + } + + for _, record := range actual { + switch record.name { + case "db.cassandra.queries": + recordEqual(t, expected[0], record) + assert.Equal(t, expected[0].number, record.number) + case "db.cassandra.rows": + recordEqual(t, expected[1], record) + assert.Equal(t, expected[1].number, record.number) + case "db.cassandra.latency": + recordEqual(t, expected[2], record) + // The latency will vary, so just check that it exists + assert.True(t, !record.number.IsZero(record.numberKind)) + default: + t.Fatalf("wrong metric %s", record.name) + } + } } @@ -182,7 +184,7 @@ func TestBatch(t *testing.T) { cluster := getCluster() sr := tracetest.NewSpanRecorder() tracerProvider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr)) - // meterProvider := metrictest.NewMeterProvider() + meterProvider, metricExporter := metrictest.NewTestMeterProvider() ctx, parentSpan := tracerProvider.Tracer(internal.InstrumentationName).Start(context.Background(), "gocql-test") @@ -190,7 +192,7 @@ func TestBatch(t *testing.T) { ctx, cluster, otelgocql.WithTracerProvider(tracerProvider), - // otelgocql.WithMeterProvider(meterProvider), + otelgocql.WithMeterProvider(meterProvider), otelgocql.WithConnectInstrumentation(false), ) require.NoError(t, err) @@ -221,51 +223,52 @@ func TestBatch(t *testing.T) { assertConnectionLevelAttributes(t, span) } - // // Check metrics - // actual := obtainTestRecords(meterProvider.MeasurementBatches) - // require.Len(t, actual, 2) - // expected := []testRecord{ - // { - // name: "db.cassandra.batch.queries", - // meterName: internal.InstrumentationName, - // attributes: []attribute.KeyValue{ - // internal.CassDBSystem(), - // internal.CassPeerIP("127.0.0.1"), - // internal.CassPeerPort(9042), - // internal.CassVersion("3"), - // internal.CassHostID("test-id"), - // internal.CassHostState("UP"), - // internal.CassKeyspace(keyspace), - // }, - // number: 1, - // }, - // { - // name: "db.cassandra.latency", - // meterName: internal.InstrumentationName, - // attributes: []attribute.KeyValue{ - // internal.CassDBSystem(), - // internal.CassPeerIP("127.0.0.1"), - // internal.CassPeerPort(9042), - // internal.CassVersion("3"), - // internal.CassHostID("test-id"), - // internal.CassHostState("UP"), - // internal.CassKeyspace(keyspace), - // }, - // }, - // } - - // for _, record := range actual { - // switch record.name { - // case "db.cassandra.batch.queries": - // recordEqual(t, expected[0], record) - // assert.Equal(t, expected[0].number, record.number) - // case "db.cassandra.latency": - // recordEqual(t, expected[1], record) - // assert.True(t, !record.number.IsZero(record.numberKind)) - // default: - // t.Fatalf("wrong metric %s", record.name) - // } - // } + // Check metrics + require.NoError(t, metricExporter.Collect(context.Background())) + actual := obtainTestRecords(metricExporter.GetRecords()) + require.Len(t, actual, 2) + expected := []testRecord{ + { + name: "db.cassandra.batch.queries", + meterName: internal.InstrumentationName, + attributes: []attribute.KeyValue{ + internal.CassDBSystem(), + internal.CassPeerIP("127.0.0.1"), + internal.CassPeerPort(9042), + internal.CassVersion("3"), + internal.CassHostID("test-id"), + internal.CassHostState("UP"), + internal.CassKeyspace(keyspace), + }, + number: 1, + }, + { + name: "db.cassandra.latency", + meterName: internal.InstrumentationName, + attributes: []attribute.KeyValue{ + internal.CassDBSystem(), + internal.CassPeerIP("127.0.0.1"), + internal.CassPeerPort(9042), + internal.CassVersion("3"), + internal.CassHostID("test-id"), + internal.CassHostState("UP"), + internal.CassKeyspace(keyspace), + }, + }, + } + + for _, record := range actual { + switch record.name { + case "db.cassandra.batch.queries": + recordEqual(t, expected[0], record) + assert.Equal(t, expected[0].number, record.number) + case "db.cassandra.latency": + recordEqual(t, expected[1], record) + assert.True(t, !record.number.IsZero(record.numberKind)) + default: + t.Fatalf("wrong metric %s", record.name) + } + } } @@ -274,7 +277,7 @@ func TestConnection(t *testing.T) { cluster := getCluster() sr := tracetest.NewSpanRecorder() tracerProvider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr)) - // meterProvider := metrictest.NewMeterProvider() + meterProvider, metricExporter := metrictest.NewTestMeterProvider() connectObserver := &mockConnectObserver{0} ctx := context.Background() @@ -282,7 +285,7 @@ func TestConnection(t *testing.T) { ctx, cluster, otelgocql.WithTracerProvider(tracerProvider), - // otelgocql.WithMeterProvider(meterProvider), + otelgocql.WithMeterProvider(meterProvider), otelgocql.WithConnectObserver(connectObserver), ) require.NoError(t, err) @@ -300,31 +303,31 @@ func TestConnection(t *testing.T) { assertConnectionLevelAttributes(t, span) } - // // Verify the metrics - // actual := obtainTestRecords(meterProvider.MeasurementBatches) - // expected := []testRecord{ - // { - // name: "db.cassandra.connections", - // meterName: internal.InstrumentationName, - // attributes: []attribute.KeyValue{ - // internal.CassDBSystem(), - // internal.CassPeerIP("127.0.0.1"), - // internal.CassPeerPort(9042), - // internal.CassVersion("3"), - // internal.CassHostID("test-id"), - // internal.CassHostState("UP"), - // }, - // }, - // } - - // for _, record := range actual { - // switch record.name { - // case "db.cassandra.connections": - // recordEqual(t, expected[0], record) - // default: - // t.Fatalf("wrong metric %s", record.name) - // } - // } + // Verify the metrics + actual := obtainTestRecords(metricExporter.GetRecords()) + expected := []testRecord{ + { + name: "db.cassandra.connections", + meterName: internal.InstrumentationName, + attributes: []attribute.KeyValue{ + internal.CassDBSystem(), + internal.CassPeerIP("127.0.0.1"), + internal.CassPeerPort(9042), + internal.CassVersion("3"), + internal.CassHostID("test-id"), + internal.CassHostState("UP"), + }, + }, + } + + for _, record := range actual { + switch record.name { + case "db.cassandra.connections": + recordEqual(t, expected[0], record) + default: + t.Fatalf("wrong metric %s", record.name) + } + } } func TestHostOrIP(t *testing.T) { @@ -369,46 +372,53 @@ func getCluster() *gocql.ClusterConfig { return cluster } -// // obtainTestRecords creates a slice of testRecord with values -// // obtained from measurements -// func obtainTestRecords(mbs []metrictest.Batch) []testRecord { -// var records []testRecord -// for _, mb := range mbs { -// for _, m := range mb.Measurements { -// records = append( -// records, -// testRecord{ -// name: m.Instrument.Descriptor().Name(), -// meterName: mb.Library.InstrumentationName, -// attributes: mb.Labels, -// number: m.Number, -// numberKind: m.Instrument.Descriptor().NumberKind(), -// }, -// ) -// } -// } - -// return records -// } - -// // recordEqual checks that the given metric name and instrumentation names are equal. -// func recordEqual(t *testing.T, expected testRecord, actual testRecord) { -// assert.Equal(t, expected.name, actual.name) -// assert.Equal(t, expected.meterName, actual.meterName) -// require.Len(t, actual.attributes, len(expected.attributes)) -// actualSet := attribute.NewSet(actual.attributes...) -// for _, attribute := range expected.attributes { -// actualValue, ok := actualSet.Value(attribute.Key) -// assert.True(t, ok) -// assert.NotNil(t, actualValue) -// // Can't test equality of host id -// if attribute.Key != internal.CassHostIDKey && attribute.Key != internal.CassVersionKey { -// assert.Equal(t, attribute.Value, actualValue) -// } else { -// assert.NotEmpty(t, actualValue) -// } -// } -// } +// obtainTestRecords creates a slice of testRecord with values +// obtained from measurements +func obtainTestRecords(mers []metrictest.ExportRecord) []testRecord { + var records []testRecord + for _, mer := range mers { + var n number.Number + switch mer.AggregationKind { + case aggregation.SumKind, aggregation.HistogramKind: + n = mer.Sum + case aggregation.LastValueKind: + n = mer.LastValue + default: + panic(fmt.Sprintf("unsupported aggregation type: %v", mer.AggregationKind)) + } + records = append( + records, + testRecord{ + name: mer.InstrumentName, + meterName: mer.InstrumentationLibrary.InstrumentationName, + attributes: mer.Attributes, + number: n, + numberKind: mer.NumberKind, + }, + ) + } + + return records +} + +// recordEqual checks that the given metric name and instrumentation names are equal. +func recordEqual(t *testing.T, expected testRecord, actual testRecord) { + assert.Equal(t, expected.name, actual.name) + assert.Equal(t, expected.meterName, actual.meterName) + require.Len(t, actual.attributes, len(expected.attributes)) + actualSet := attribute.NewSet(actual.attributes...) + for _, attribute := range expected.attributes { + actualValue, ok := actualSet.Value(attribute.Key) + assert.True(t, ok) + assert.NotNil(t, actualValue) + // Can't test equality of host id + if attribute.Key != internal.CassHostIDKey && attribute.Key != internal.CassVersionKey { + assert.Equal(t, attribute.Value, actualValue) + } else { + assert.NotEmpty(t, actualValue) + } + } +} // beforeAll creates the testing keyspace and table if they do not already exist. func beforeAll() { diff --git a/instrumentation/host/example/go.mod b/instrumentation/host/example/go.mod index b52fb418251..a599e69f17f 100644 --- a/instrumentation/host/example/go.mod +++ b/instrumentation/host/example/go.mod @@ -9,7 +9,7 @@ replace ( require ( go.opentelemetry.io/contrib/instrumentation/host v0.31.0 - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.29.0 + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.29.1-0.20220425151224-b8e4241a32f2 go.opentelemetry.io/otel/metric v0.29.0 - go.opentelemetry.io/otel/sdk/metric v0.29.0 + go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 ) diff --git a/instrumentation/host/example/go.sum b/instrumentation/host/example/go.sum index 0a16ee08ccd..386382058ea 100644 --- a/instrumentation/host/example/go.sum +++ b/instrumentation/host/example/go.sum @@ -31,14 +31,15 @@ github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPR github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/otel v1.6.3 h1:FLOfo8f9JzFVFVyU+MSRJc2HdEAXQgm7pIv2uFKRSZE= go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.29.0 h1:mUrA42RV1UmBg2xsPhTNupzsP7IjVpjv22gSS265LzM= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.29.0/go.mod h1:BqT1BiSe514wsEw0dTUsnbRBJ7llxk3Y01vS/azqsrw= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.29.1-0.20220425151224-b8e4241a32f2 h1:gplMOZpn/MvBQDDu/5Mr9kIS6IZGpAY/C12qIXUaOJ8= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.29.1-0.20220425151224-b8e4241a32f2/go.mod h1:BqT1BiSe514wsEw0dTUsnbRBJ7llxk3Y01vS/azqsrw= go.opentelemetry.io/otel/metric v0.29.0 h1:7unM/I13Dbc1VHw8lTPQ7zfNIgkhcb8BZhujXOS4jKc= go.opentelemetry.io/otel/metric v0.29.0/go.mod h1:HahKFp1OC1RNTsuO/HNMBHHJR+dmHZ7wLARRgGDwjLQ= go.opentelemetry.io/otel/sdk v1.6.3 h1:prSHYdwCQOX5DrsEzxowH3nLhoAzEBdZhvrR79scfLs= go.opentelemetry.io/otel/sdk v1.6.3/go.mod h1:A4iWF7HTXa+GWL/AaqESz28VuSBIcZ+0CV+IzJ5NMiQ= -go.opentelemetry.io/otel/sdk/metric v0.29.0 h1:OCEp2igPFXQrGxSR/nwd/bDjkPlPlOVjIULA/ob0dNw= go.opentelemetry.io/otel/sdk/metric v0.29.0/go.mod h1:IFkFNKI8Gq8zBdqOKdODCL9+LInBZLXaGpqSIKphNuU= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 h1:w97SUMLzaACqAmuyNR6S+1N2o90Y3Kcvz6S8xp8uysM= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2/go.mod h1:IFkFNKI8Gq8zBdqOKdODCL9+LInBZLXaGpqSIKphNuU= go.opentelemetry.io/otel/trace v1.6.3 h1:IqN4L+5b0mPNjdXIiZ90Ni4Bl5BRkDQywePLWemd9bc= go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/instrumentation/host/go.mod b/instrumentation/host/go.mod index e49ac152b88..4a4b2738710 100644 --- a/instrumentation/host/go.mod +++ b/instrumentation/host/go.mod @@ -4,7 +4,9 @@ go 1.16 require ( github.com/shirou/gopsutil/v3 v3.22.3 + github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel v1.6.3 go.opentelemetry.io/otel/metric v0.29.0 + go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 // indirect ) diff --git a/instrumentation/host/go.sum b/instrumentation/host/go.sum index 3ab2ecc26f1..01e89800d82 100644 --- a/instrumentation/host/go.sum +++ b/instrumentation/host/go.sum @@ -1,3 +1,5 @@ +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -31,15 +33,21 @@ go.opentelemetry.io/otel v1.6.3 h1:FLOfo8f9JzFVFVyU+MSRJc2HdEAXQgm7pIv2uFKRSZE= go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= go.opentelemetry.io/otel/metric v0.29.0 h1:7unM/I13Dbc1VHw8lTPQ7zfNIgkhcb8BZhujXOS4jKc= go.opentelemetry.io/otel/metric v0.29.0/go.mod h1:HahKFp1OC1RNTsuO/HNMBHHJR+dmHZ7wLARRgGDwjLQ= +go.opentelemetry.io/otel/sdk v1.6.3 h1:prSHYdwCQOX5DrsEzxowH3nLhoAzEBdZhvrR79scfLs= +go.opentelemetry.io/otel/sdk v1.6.3/go.mod h1:A4iWF7HTXa+GWL/AaqESz28VuSBIcZ+0CV+IzJ5NMiQ= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 h1:w97SUMLzaACqAmuyNR6S+1N2o90Y3Kcvz6S8xp8uysM= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2/go.mod h1:IFkFNKI8Gq8zBdqOKdODCL9+LInBZLXaGpqSIKphNuU= go.opentelemetry.io/otel/trace v1.6.3 h1:IqN4L+5b0mPNjdXIiZ90Ni4Bl5BRkDQywePLWemd9bc= go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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= diff --git a/instrumentation/host/host_test.go b/instrumentation/host/host_test.go index 1dbb6d8e81c..5a7dae0c939 100644 --- a/instrumentation/host/host_test.go +++ b/instrumentation/host/host_test.go @@ -14,206 +14,229 @@ package host_test -// TODO Replace with in memory exporter https://github.com/open-telemetry/opentelemetry-go/issues/2722 -// func getMetric(provider *metrictest.MeterProvider, name string, lbl attribute.KeyValue) float64 { -// for _, b := range provider.MeasurementBatches { -// foundAttribute := false -// for _, haveLabel := range b.Labels { -// if haveLabel != lbl { -// continue -// } -// foundAttribute = true -// break -// } -// if !foundAttribute { -// continue -// } - -// for _, m := range b.Measurements { -// if m.Instrument.Descriptor().Name() != name { -// continue -// } - -// return m.Number.CoerceToFloat64(m.Instrument.Descriptor().NumberKind()) -// } -// } -// panic("Could not locate a metric in test output") -// } - -// func TestHostCPU(t *testing.T) { -// provider := metrictest.NewMeterProvider() -// err := host.Start( -// host.WithMeterProvider(provider), -// ) -// assert.NoError(t, err) - -// proc, err := process.NewProcess(int32(os.Getpid())) -// require.NoError(t, err) - -// ctx := context.Background() -// processBefore, err := proc.TimesWithContext(ctx) -// require.NoError(t, err) - -// hostBefore, err := cpu.TimesWithContext(ctx, false) -// require.NoError(t, err) - -// start := time.Now() -// for time.Since(start) < time.Second { -// // This has a mix of user and system time, so serves -// // the purpose of advancing both process and host, -// // user and system CPU usage. -// _, err = proc.TimesWithContext(ctx) -// require.NoError(t, err) -// } - -// provider.RunAsyncInstruments() - -// processUser := getMetric(provider, "process.cpu.time", host.AttributeCPUTimeUser[0]) -// processSystem := getMetric(provider, "process.cpu.time", host.AttributeCPUTimeSystem[0]) - -// hostUser := getMetric(provider, "system.cpu.time", host.AttributeCPUTimeUser[0]) -// hostSystem := getMetric(provider, "system.cpu.time", host.AttributeCPUTimeSystem[0]) - -// processAfter, err := proc.TimesWithContext(ctx) -// require.NoError(t, err) - -// hostAfter, err := cpu.TimesWithContext(ctx, false) -// require.NoError(t, err) - -// // Validate process times: -// // User times are in range -// require.LessOrEqual(t, processBefore.User, processUser) -// require.GreaterOrEqual(t, processAfter.User, processUser) -// // System times are in range -// require.LessOrEqual(t, processBefore.System, processSystem) -// require.GreaterOrEqual(t, processAfter.System, processSystem) -// // Ranges are not empty -// require.NotEqual(t, processAfter.System, processBefore.System) -// require.NotEqual(t, processAfter.User, processBefore.User) - -// // Validate host times: -// // Correct assumptions: -// require.Equal(t, 1, len(hostBefore)) -// require.Equal(t, 1, len(hostAfter)) -// // User times are in range -// require.LessOrEqual(t, hostBefore[0].User, hostUser) -// require.GreaterOrEqual(t, hostAfter[0].User, hostUser) -// // System times are in range -// require.LessOrEqual(t, hostBefore[0].System, hostSystem) -// require.GreaterOrEqual(t, hostAfter[0].System, hostSystem) -// // Ranges are not empty -// require.NotEqual(t, hostAfter[0].System, hostBefore[0].System) -// require.NotEqual(t, hostAfter[0].User, hostBefore[0].User) - -// // TODO: We are not testing host "Other" nor "Idle" and -// // generally the specification hasn't been finalized, so -// // there's more to do. Moreover, "Other" is not portable and -// // "Idle" may not advance on a fully loaded machine => both -// // are difficult to test. -// } - -// func TestHostMemory(t *testing.T) { -// provider := metrictest.NewMeterProvider() -// err := host.Start( -// host.WithMeterProvider(provider), -// ) -// assert.NoError(t, err) - -// ctx := context.Background() -// vMem, err := mem.VirtualMemoryWithContext(ctx) -// require.NoError(t, err) - -// provider.RunAsyncInstruments() - -// hostUsed := getMetric(provider, "system.memory.usage", host.AttributeMemoryUsed[0]) -// assert.Greater(t, hostUsed, 0.0) -// assert.LessOrEqual(t, hostUsed, float64(vMem.Total)) - -// hostAvailable := getMetric(provider, "system.memory.usage", host.AttributeMemoryAvailable[0]) -// assert.GreaterOrEqual(t, hostAvailable, 0.0) -// assert.Less(t, hostAvailable, float64(vMem.Total)) - -// hostUsedUtil := getMetric(provider, "system.memory.utilization", host.AttributeMemoryUsed[0]) -// assert.Greater(t, hostUsedUtil, 0.0) -// assert.LessOrEqual(t, hostUsedUtil, 1.0) - -// hostAvailableUtil := getMetric(provider, "system.memory.utilization", host.AttributeMemoryAvailable[0]) -// assert.GreaterOrEqual(t, hostAvailableUtil, 0.0) -// assert.Less(t, hostAvailableUtil, 1.0) - -// if hostUsed > hostAvailable { -// assert.Greater(t, hostUsedUtil, hostAvailableUtil) -// } else { -// assert.Less(t, hostUsedUtil, hostAvailableUtil) -// } -// } - -// func sendBytes(t *testing.T, count int) error { -// conn1, err := gonet.ListenPacket("udp", "127.0.0.1:0") -// if err != nil { -// return err -// } -// defer conn1.Close() - -// conn2, err := gonet.ListenPacket("udp", "127.0.0.1:0") -// if err != nil { -// return err -// } -// defer conn2.Close() - -// data1 := make([]byte, 1000) -// data2 := make([]byte, 1000) -// for i := range data1 { -// data1[i] = byte(i) -// } - -// for ; count > 0; count -= len(data1) { -// _, err = conn1.WriteTo(data1, conn2.LocalAddr()) -// if err != nil { -// return err -// } -// _, readAddr, err := conn2.ReadFrom(data2) -// if err != nil { -// return err -// } - -// require.Equal(t, "udp", readAddr.Network()) -// require.Equal(t, conn1.LocalAddr().String(), readAddr.String()) -// } - -// return nil -// } - -// TODO Replace with in memory exporter https://github.com/open-telemetry/opentelemetry-go/issues/2722 -// func TestHostNetwork(t *testing.T) { -// provider := metrictest.NewMeterProvider() -// err := host.Start( -// host.WithMeterProvider(provider), -// ) -// assert.NoError(t, err) - -// ctx := context.Background() -// hostBefore, err := net.IOCountersWithContext(ctx, false) -// require.NoError(t, err) - -// const howMuch = 10000 -// err = sendBytes(t, howMuch) -// require.NoError(t, err) - -// // As we are going to read the /proc file system for this info, sleep a while: -// require.Eventually(t, func() bool { -// hostAfter, err := net.IOCountersWithContext(ctx, false) -// require.NoError(t, err) - -// return uint64(howMuch) <= hostAfter[0].BytesSent-hostBefore[0].BytesSent && -// uint64(howMuch) <= hostAfter[0].BytesRecv-hostBefore[0].BytesRecv -// }, 30*time.Second, time.Second/2) - -// provider.RunAsyncInstruments() -// hostTransmit := getMetric(provider, "system.network.io", host.AttributeNetworkTransmit[0]) -// hostReceive := getMetric(provider, "system.network.io", host.AttributeNetworkReceive[0]) - -// // Check that the recorded measurements reflect the same change: -// require.LessOrEqual(t, uint64(howMuch), uint64(hostTransmit)-hostBefore[0].BytesSent) -// require.LessOrEqual(t, uint64(howMuch), uint64(hostReceive)-hostBefore[0].BytesRecv) -// } +import ( + "context" + "fmt" + gonet "net" + "os" + "testing" + "time" + + "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v3/mem" + "github.com/shirou/gopsutil/v3/net" + "github.com/shirou/gopsutil/v3/process" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/contrib/instrumentation/host" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/metrictest" +) + +func getMetric(exp *metrictest.Exporter, name string, lbl attribute.KeyValue) float64 { + for _, r := range exp.GetRecords() { + foundAttribute := false + for _, haveLabel := range r.Attributes { + if haveLabel != lbl { + continue + } + foundAttribute = true + break + } + if !foundAttribute { + continue + } + + if r.InstrumentName != name { + continue + } + switch r.AggregationKind { + case aggregation.SumKind, aggregation.HistogramKind: + return r.Sum.CoerceToFloat64(r.NumberKind) + case aggregation.LastValueKind: + return r.LastValue.CoerceToFloat64(r.NumberKind) + default: + panic(fmt.Sprintf("invalid aggregation type: %v", r.AggregationKind)) + } + } + panic("Could not locate a metric in test output") +} + +func TestHostCPU(t *testing.T) { + provider, exp := metrictest.NewTestMeterProvider() + err := host.Start( + host.WithMeterProvider(provider), + ) + assert.NoError(t, err) + + proc, err := process.NewProcess(int32(os.Getpid())) + require.NoError(t, err) + + ctx := context.Background() + processBefore, err := proc.TimesWithContext(ctx) + require.NoError(t, err) + + hostBefore, err := cpu.TimesWithContext(ctx, false) + require.NoError(t, err) + + start := time.Now() + for time.Since(start) < time.Second { + // This has a mix of user and system time, so serves + // the purpose of advancing both process and host, + // user and system CPU usage. + _, err = proc.TimesWithContext(ctx) + require.NoError(t, err) + } + + require.NoError(t, exp.Collect(ctx)) + + processUser := getMetric(exp, "process.cpu.time", host.AttributeCPUTimeUser[0]) + processSystem := getMetric(exp, "process.cpu.time", host.AttributeCPUTimeSystem[0]) + + hostUser := getMetric(exp, "system.cpu.time", host.AttributeCPUTimeUser[0]) + hostSystem := getMetric(exp, "system.cpu.time", host.AttributeCPUTimeSystem[0]) + + processAfter, err := proc.TimesWithContext(ctx) + require.NoError(t, err) + + hostAfter, err := cpu.TimesWithContext(ctx, false) + require.NoError(t, err) + + // Validate process times: + // User times are in range + require.LessOrEqual(t, processBefore.User, processUser) + require.GreaterOrEqual(t, processAfter.User, processUser) + // System times are in range + require.LessOrEqual(t, processBefore.System, processSystem) + require.GreaterOrEqual(t, processAfter.System, processSystem) + // Ranges are not empty + require.NotEqual(t, processAfter.System, processBefore.System) + require.NotEqual(t, processAfter.User, processBefore.User) + + // Validate host times: + // Correct assumptions: + require.Equal(t, 1, len(hostBefore)) + require.Equal(t, 1, len(hostAfter)) + // User times are in range + require.LessOrEqual(t, hostBefore[0].User, hostUser) + require.GreaterOrEqual(t, hostAfter[0].User, hostUser) + // System times are in range + require.LessOrEqual(t, hostBefore[0].System, hostSystem) + require.GreaterOrEqual(t, hostAfter[0].System, hostSystem) + // Ranges are not empty + require.NotEqual(t, hostAfter[0].System, hostBefore[0].System) + require.NotEqual(t, hostAfter[0].User, hostBefore[0].User) + + // TODO: We are not testing host "Other" nor "Idle" and + // generally the specification hasn't been finalized, so + // there's more to do. Moreover, "Other" is not portable and + // "Idle" may not advance on a fully loaded machine => both + // are difficult to test. +} + +func TestHostMemory(t *testing.T) { + provider, exp := metrictest.NewTestMeterProvider() + err := host.Start( + host.WithMeterProvider(provider), + ) + assert.NoError(t, err) + + ctx := context.Background() + vMem, err := mem.VirtualMemoryWithContext(ctx) + require.NoError(t, err) + + require.NoError(t, exp.Collect(ctx)) + + hostUsed := getMetric(exp, "system.memory.usage", host.AttributeMemoryUsed[0]) + assert.Greater(t, hostUsed, 0.0) + assert.LessOrEqual(t, hostUsed, float64(vMem.Total)) + + hostAvailable := getMetric(exp, "system.memory.usage", host.AttributeMemoryAvailable[0]) + assert.GreaterOrEqual(t, hostAvailable, 0.0) + assert.Less(t, hostAvailable, float64(vMem.Total)) + + hostUsedUtil := getMetric(exp, "system.memory.utilization", host.AttributeMemoryUsed[0]) + assert.Greater(t, hostUsedUtil, 0.0) + assert.LessOrEqual(t, hostUsedUtil, 1.0) + + hostAvailableUtil := getMetric(exp, "system.memory.utilization", host.AttributeMemoryAvailable[0]) + assert.GreaterOrEqual(t, hostAvailableUtil, 0.0) + assert.Less(t, hostAvailableUtil, 1.0) + + if hostUsed > hostAvailable { + assert.Greater(t, hostUsedUtil, hostAvailableUtil) + } else { + assert.Less(t, hostUsedUtil, hostAvailableUtil) + } +} + +func sendBytes(t *testing.T, count int) error { + conn1, err := gonet.ListenPacket("udp", "127.0.0.1:0") + if err != nil { + return err + } + defer conn1.Close() + + conn2, err := gonet.ListenPacket("udp", "127.0.0.1:0") + if err != nil { + return err + } + defer conn2.Close() + + data1 := make([]byte, 1000) + data2 := make([]byte, 1000) + for i := range data1 { + data1[i] = byte(i) + } + + for ; count > 0; count -= len(data1) { + _, err = conn1.WriteTo(data1, conn2.LocalAddr()) + if err != nil { + return err + } + _, readAddr, err := conn2.ReadFrom(data2) + if err != nil { + return err + } + + require.Equal(t, "udp", readAddr.Network()) + require.Equal(t, conn1.LocalAddr().String(), readAddr.String()) + } + + return nil +} + +func TestHostNetwork(t *testing.T) { + provider, exp := metrictest.NewTestMeterProvider() + err := host.Start( + host.WithMeterProvider(provider), + ) + assert.NoError(t, err) + + ctx := context.Background() + hostBefore, err := net.IOCountersWithContext(ctx, false) + require.NoError(t, err) + + const howMuch = 10000 + err = sendBytes(t, howMuch) + require.NoError(t, err) + + // As we are going to read the /proc file system for this info, sleep a while: + require.Eventually(t, func() bool { + hostAfter, err := net.IOCountersWithContext(ctx, false) + require.NoError(t, err) + + return uint64(howMuch) <= hostAfter[0].BytesSent-hostBefore[0].BytesSent && + uint64(howMuch) <= hostAfter[0].BytesRecv-hostBefore[0].BytesRecv + }, 30*time.Second, time.Second/2) + + require.NoError(t, exp.Collect(ctx)) + hostTransmit := getMetric(exp, "system.network.io", host.AttributeNetworkTransmit[0]) + hostReceive := getMetric(exp, "system.network.io", host.AttributeNetworkReceive[0]) + + // Check that the recorded measurements reflect the same change: + require.LessOrEqual(t, uint64(howMuch), uint64(hostTransmit)-hostBefore[0].BytesSent) + require.LessOrEqual(t, uint64(howMuch), uint64(hostReceive)-hostBefore[0].BytesRecv) +} diff --git a/instrumentation/net/http/otelhttp/test/go.mod b/instrumentation/net/http/otelhttp/test/go.mod index 9520e37eb97..158486414d0 100644 --- a/instrumentation/net/http/otelhttp/test/go.mod +++ b/instrumentation/net/http/otelhttp/test/go.mod @@ -5,9 +5,9 @@ go 1.16 require ( github.com/stretchr/testify v1.7.1 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.31.0 - go.opentelemetry.io/otel v1.6.3 - go.opentelemetry.io/otel/metric v0.29.0 + go.opentelemetry.io/otel v1.6.4-0.20220425151224-b8e4241a32f2 go.opentelemetry.io/otel/sdk v1.6.3 + go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 go.opentelemetry.io/otel/trace v1.6.3 ) diff --git a/instrumentation/net/http/otelhttp/test/go.sum b/instrumentation/net/http/otelhttp/test/go.sum index ca01b27d63e..ce4ef777c04 100644 --- a/instrumentation/net/http/otelhttp/test/go.sum +++ b/instrumentation/net/http/otelhttp/test/go.sum @@ -1,3 +1,5 @@ +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= @@ -14,12 +16,15 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -go.opentelemetry.io/otel v1.6.3 h1:FLOfo8f9JzFVFVyU+MSRJc2HdEAXQgm7pIv2uFKRSZE= go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= +go.opentelemetry.io/otel v1.6.4-0.20220425151224-b8e4241a32f2 h1:GSrUIEdhVxw2ILmFjuNBVCzm0YAaInEDjZMGUwa8TCw= +go.opentelemetry.io/otel v1.6.4-0.20220425151224-b8e4241a32f2/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= go.opentelemetry.io/otel/metric v0.29.0 h1:7unM/I13Dbc1VHw8lTPQ7zfNIgkhcb8BZhujXOS4jKc= go.opentelemetry.io/otel/metric v0.29.0/go.mod h1:HahKFp1OC1RNTsuO/HNMBHHJR+dmHZ7wLARRgGDwjLQ= go.opentelemetry.io/otel/sdk v1.6.3 h1:prSHYdwCQOX5DrsEzxowH3nLhoAzEBdZhvrR79scfLs= go.opentelemetry.io/otel/sdk v1.6.3/go.mod h1:A4iWF7HTXa+GWL/AaqESz28VuSBIcZ+0CV+IzJ5NMiQ= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 h1:w97SUMLzaACqAmuyNR6S+1N2o90Y3Kcvz6S8xp8uysM= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2/go.mod h1:IFkFNKI8Gq8zBdqOKdODCL9+LInBZLXaGpqSIKphNuU= go.opentelemetry.io/otel/trace v1.6.3 h1:IqN4L+5b0mPNjdXIiZ90Ni4Bl5BRkDQywePLWemd9bc= go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= diff --git a/instrumentation/net/http/otelhttp/test/handler_test.go b/instrumentation/net/http/otelhttp/test/handler_test.go index 59909cf7b53..268aa0b57c1 100644 --- a/instrumentation/net/http/otelhttp/test/handler_test.go +++ b/instrumentation/net/http/otelhttp/test/handler_test.go @@ -16,6 +16,7 @@ package test import ( "context" + "fmt" "io" "io/ioutil" "net/http" @@ -28,18 +29,18 @@ import ( "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/metric/nonrecording" "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/metric/metrictest" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/sdk/trace/tracetest" + semconv "go.opentelemetry.io/otel/semconv/v1.10.0" ) -// TODO: Replace with in memory exporter https://github.com/open-telemetry/opentelemetry-go/issues/2722 -// func assertMetricAttributes(t *testing.T, expectedAttributes []attribute.KeyValue, measurementBatches []metrictest.Batch) { -// for _, batch := range measurementBatches { -// assert.ElementsMatch(t, expectedAttributes, batch.Labels) -// } -// } +func assertMetricAttributes(t *testing.T, expectedAttributes []attribute.KeyValue, expRec []metrictest.ExportRecord) { + for _, r := range expRec { + assert.ElementsMatch(t, expectedAttributes, r.Attributes) + } +} func TestHandlerBasics(t *testing.T) { rr := httptest.NewRecorder() @@ -47,8 +48,7 @@ func TestHandlerBasics(t *testing.T) { spanRecorder := tracetest.NewSpanRecorder() provider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(spanRecorder)) - // TODO: Replace with in memory exporter https://github.com/open-telemetry/opentelemetry-go/issues/2722 - meterProvider := nonrecording.NewNoopMeterProvider() + meterProvider, metricExporter := metrictest.NewTestMeterProvider() operation := "test_handler" @@ -72,21 +72,20 @@ func TestHandlerBasics(t *testing.T) { } h.ServeHTTP(rr, r) - // TODO: Verify meter recorded >0 batches - // if len(meterProvider.MeasurementBatches) == 0 { - // t.Fatalf("got 0 recorded measurements, expected 1 or more") - // } - - // TODO: Verify that batches had appropriate attributes - // attributesToVerify := []attribute.KeyValue{ - // semconv.HTTPServerNameKey.String(operation), - // semconv.HTTPSchemeHTTP, - // semconv.HTTPHostKey.String(r.Host), - // semconv.HTTPFlavorKey.String(fmt.Sprintf("1.%d", r.ProtoMinor)), - // attribute.String("test", "attribute"), - // } - - // assertMetricAttributes(t, attributesToVerify, meterProvider.MeasurementBatches) + require.NoError(t, metricExporter.Collect(context.Background())) + if len(metricExporter.GetRecords()) == 0 { + t.Fatalf("got 0 recorded measurements, expected 1 or more") + } + + attributesToVerify := []attribute.KeyValue{ + semconv.HTTPServerNameKey.String(operation), + semconv.HTTPSchemeHTTP, + semconv.HTTPHostKey.String(r.Host), + semconv.HTTPFlavorKey.String(fmt.Sprintf("1.%d", r.ProtoMinor)), + attribute.String("test", "attribute"), + } + + assertMetricAttributes(t, attributesToVerify, metricExporter.GetRecords()) if got, expected := rr.Result().StatusCode, http.StatusOK; got != expected { t.Fatalf("got %d, expected %d", got, expected) diff --git a/instrumentation/runtime/example/go.mod b/instrumentation/runtime/example/go.mod index 3f40a31eff1..8d685d98326 100644 --- a/instrumentation/runtime/example/go.mod +++ b/instrumentation/runtime/example/go.mod @@ -9,8 +9,8 @@ replace ( require ( go.opentelemetry.io/contrib/instrumentation/runtime v0.31.0 - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.29.0 + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.29.1-0.20220425151224-b8e4241a32f2 go.opentelemetry.io/otel/metric v0.29.0 - go.opentelemetry.io/otel/sdk/metric v0.29.0 + go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 // indirect ) diff --git a/instrumentation/runtime/example/go.sum b/instrumentation/runtime/example/go.sum index 664ff93d62a..fe8b671b2c8 100644 --- a/instrumentation/runtime/example/go.sum +++ b/instrumentation/runtime/example/go.sum @@ -16,14 +16,15 @@ github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMT github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opentelemetry.io/otel v1.6.3 h1:FLOfo8f9JzFVFVyU+MSRJc2HdEAXQgm7pIv2uFKRSZE= go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.29.0 h1:mUrA42RV1UmBg2xsPhTNupzsP7IjVpjv22gSS265LzM= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.29.0/go.mod h1:BqT1BiSe514wsEw0dTUsnbRBJ7llxk3Y01vS/azqsrw= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.29.1-0.20220425151224-b8e4241a32f2 h1:gplMOZpn/MvBQDDu/5Mr9kIS6IZGpAY/C12qIXUaOJ8= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.29.1-0.20220425151224-b8e4241a32f2/go.mod h1:BqT1BiSe514wsEw0dTUsnbRBJ7llxk3Y01vS/azqsrw= go.opentelemetry.io/otel/metric v0.29.0 h1:7unM/I13Dbc1VHw8lTPQ7zfNIgkhcb8BZhujXOS4jKc= go.opentelemetry.io/otel/metric v0.29.0/go.mod h1:HahKFp1OC1RNTsuO/HNMBHHJR+dmHZ7wLARRgGDwjLQ= go.opentelemetry.io/otel/sdk v1.6.3 h1:prSHYdwCQOX5DrsEzxowH3nLhoAzEBdZhvrR79scfLs= go.opentelemetry.io/otel/sdk v1.6.3/go.mod h1:A4iWF7HTXa+GWL/AaqESz28VuSBIcZ+0CV+IzJ5NMiQ= -go.opentelemetry.io/otel/sdk/metric v0.29.0 h1:OCEp2igPFXQrGxSR/nwd/bDjkPlPlOVjIULA/ob0dNw= go.opentelemetry.io/otel/sdk/metric v0.29.0/go.mod h1:IFkFNKI8Gq8zBdqOKdODCL9+LInBZLXaGpqSIKphNuU= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 h1:w97SUMLzaACqAmuyNR6S+1N2o90Y3Kcvz6S8xp8uysM= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2/go.mod h1:IFkFNKI8Gq8zBdqOKdODCL9+LInBZLXaGpqSIKphNuU= go.opentelemetry.io/otel/trace v1.6.3 h1:IqN4L+5b0mPNjdXIiZ90Ni4Bl5BRkDQywePLWemd9bc= go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/instrumentation/runtime/go.mod b/instrumentation/runtime/go.mod index ab1badac4e6..be78b020005 100644 --- a/instrumentation/runtime/go.mod +++ b/instrumentation/runtime/go.mod @@ -7,4 +7,5 @@ replace go.opentelemetry.io/contrib => ../.. require ( github.com/stretchr/testify v1.7.1 go.opentelemetry.io/otel/metric v0.29.0 + go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 ) diff --git a/instrumentation/runtime/go.sum b/instrumentation/runtime/go.sum index 43a705f24f5..74d2de22009 100644 --- a/instrumentation/runtime/go.sum +++ b/instrumentation/runtime/go.sum @@ -1,3 +1,5 @@ +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -16,8 +18,14 @@ go.opentelemetry.io/otel v1.6.3 h1:FLOfo8f9JzFVFVyU+MSRJc2HdEAXQgm7pIv2uFKRSZE= go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= go.opentelemetry.io/otel/metric v0.29.0 h1:7unM/I13Dbc1VHw8lTPQ7zfNIgkhcb8BZhujXOS4jKc= go.opentelemetry.io/otel/metric v0.29.0/go.mod h1:HahKFp1OC1RNTsuO/HNMBHHJR+dmHZ7wLARRgGDwjLQ= +go.opentelemetry.io/otel/sdk v1.6.3 h1:prSHYdwCQOX5DrsEzxowH3nLhoAzEBdZhvrR79scfLs= +go.opentelemetry.io/otel/sdk v1.6.3/go.mod h1:A4iWF7HTXa+GWL/AaqESz28VuSBIcZ+0CV+IzJ5NMiQ= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2 h1:w97SUMLzaACqAmuyNR6S+1N2o90Y3Kcvz6S8xp8uysM= +go.opentelemetry.io/otel/sdk/metric v0.29.1-0.20220425151224-b8e4241a32f2/go.mod h1:IFkFNKI8Gq8zBdqOKdODCL9+LInBZLXaGpqSIKphNuU= go.opentelemetry.io/otel/trace v1.6.3 h1:IqN4L+5b0mPNjdXIiZ90Ni4Bl5BRkDQywePLWemd9bc= go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= diff --git a/instrumentation/runtime/runtime_test.go b/instrumentation/runtime/runtime_test.go index 0f3ede542b6..f9694d13e44 100644 --- a/instrumentation/runtime/runtime_test.go +++ b/instrumentation/runtime/runtime_test.go @@ -15,12 +15,18 @@ package runtime_test import ( + "context" + "fmt" + goruntime "runtime" "testing" "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/contrib/instrumentation/runtime" + "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + "go.opentelemetry.io/otel/sdk/metric/metrictest" ) func TestRuntime(t *testing.T) { @@ -31,65 +37,67 @@ func TestRuntime(t *testing.T) { time.Sleep(time.Second) } -// TODO: Replace with in memory exporter https://github.com/open-telemetry/opentelemetry-go/issues/2722 -// func getGCCount(provider *metrictest.MeterProvider) int { -// for _, b := range provider.MeasurementBatches { -// for _, m := range b.Measurements { -// if m.Instrument.Descriptor().Name() == "process.runtime.go.gc.count" { -// return int(m.Number.CoerceToInt64(m.Instrument.Descriptor().NumberKind())) -// } -// } -// } -// panic("Could not locate a process.runtime.go.gc.count metric in test output") -// } - -// func testMinimumInterval(t *testing.T, shouldHappen bool, opts ...runtime.Option) { -// goruntime.GC() +func getGCCount(exp *metrictest.Exporter) int { + for _, r := range exp.GetRecords() { + if r.InstrumentName == "process.runtime.go.gc.count" { + switch r.AggregationKind { + case aggregation.SumKind, aggregation.HistogramKind: + return int(r.Sum.CoerceToInt64(r.NumberKind)) + case aggregation.LastValueKind: + return int(r.LastValue.CoerceToInt64(r.NumberKind)) + default: + panic(fmt.Sprintf("invalid aggregation type: %v", r.AggregationKind)) + } + } + } + panic("Could not locate a process.runtime.go.gc.count metric in test output") +} -// var mstats0 goruntime.MemStats -// goruntime.ReadMemStats(&mstats0) -// baseline := int(mstats0.NumGC) +func testMinimumInterval(t *testing.T, shouldHappen bool, opts ...runtime.Option) { + goruntime.GC() -// provider := metrictest.NewMeterProvider() + var mstats0 goruntime.MemStats + goruntime.ReadMemStats(&mstats0) + baseline := int(mstats0.NumGC) -// err := runtime.Start( -// append( -// opts, -// runtime.WithMeterProvider(provider), -// )..., -// ) -// assert.NoError(t, err) + provider, exp := metrictest.NewTestMeterProvider() -// goruntime.GC() + err := runtime.Start( + append( + opts, + runtime.WithMeterProvider(provider), + )..., + ) + assert.NoError(t, err) -// provider.RunAsyncInstruments() + goruntime.GC() -// require.Equal(t, 1, getGCCount(provider)-baseline) + require.NoError(t, exp.Collect(context.Background())) -// provider.MeasurementBatches = nil + require.Equal(t, 1, getGCCount(exp)-baseline) -// extra := 0 -// if shouldHappen { -// extra = 3 -// } + extra := 0 + if shouldHappen { + extra = 3 + } -// goruntime.GC() -// goruntime.GC() -// goruntime.GC() + goruntime.GC() + goruntime.GC() + goruntime.GC() -// provider.RunAsyncInstruments() + require.NoError(t, exp.Collect(context.Background())) -// require.Equal(t, 1+extra, getGCCount(provider)-baseline) -// } + require.Equal(t, 1+extra, getGCCount(exp)-baseline) +} -// func TestDefaultMinimumInterval(t *testing.T) { -// testMinimumInterval(t, false) -// } +func TestDefaultMinimumInterval(t *testing.T) { + testMinimumInterval(t, false) +} -// func TestNoMinimumInterval(t *testing.T) { -// testMinimumInterval(t, true, runtime.WithMinimumReadMemStatsInterval(0)) -// } +func TestNoMinimumInterval(t *testing.T) { + testMinimumInterval(t, true, runtime.WithMinimumReadMemStatsInterval(0)) +} -// func TestExplicitMinimumInterval(t *testing.T) { -// testMinimumInterval(t, false, runtime.WithMinimumReadMemStatsInterval(time.Hour)) -// } +func TestExplicitMinimumInterval(t *testing.T) { + testMinimumInterval(t, false, runtime.WithMinimumReadMemStatsInterval(time.Hour)) +}