diff --git a/sdk/metric/manual_reader_test.go b/sdk/metric/manual_reader_test.go index 33c053f424e..dbaa4b6465f 100644 --- a/sdk/metric/manual_reader_test.go +++ b/sdk/metric/manual_reader_test.go @@ -15,60 +15,9 @@ package metric // import "go.opentelemetry.io/otel/sdk/metric/reader" import ( - "context" "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "go.opentelemetry.io/otel/sdk/metric/export" ) -func TestManualReaderNotRegistered(t *testing.T) { - rdr := &manualReader{} - - _, err := rdr.Collect(context.Background()) - require.ErrorIs(t, err, ErrReaderNotRegistered) -} - -type testProducer struct{} - -var testMetrics = export.Metrics{ - // TODO: test with actual data. -} - -func (p testProducer) produce(context.Context) (export.Metrics, error) { - return testMetrics, nil -} - -func TestManualReaderProducer(t *testing.T) { - rdr := &manualReader{} - rdr.register(testProducer{}) - - m, err := rdr.Collect(context.Background()) - assert.NoError(t, err) - assert.Equal(t, testMetrics, m) -} - -func TestManualReaderCollectAfterShutdown(t *testing.T) { - rdr := &manualReader{} - rdr.register(testProducer{}) - err := rdr.Shutdown(context.Background()) - require.NoError(t, err) - - m, err := rdr.Collect(context.Background()) - assert.ErrorIs(t, err, ErrReaderShutdown) - assert.Equal(t, export.Metrics{}, m) -} - -func TestManualReaderShutdown(t *testing.T) { - rdr := &manualReader{} - rdr.register(testProducer{}) - - err := rdr.Shutdown(context.Background()) - require.NoError(t, err) - - err = rdr.Shutdown(context.Background()) - assert.ErrorIs(t, err, ErrReaderShutdown) - +func TestManualReader(t *testing.T) { + testReaderHarness(t, func() Reader { return NewManualReader() }) } diff --git a/sdk/metric/reader_test.go b/sdk/metric/reader_test.go new file mode 100644 index 00000000000..03d2459c4b4 --- /dev/null +++ b/sdk/metric/reader_test.go @@ -0,0 +1,92 @@ +// 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 metric // import "go.opentelemetry.io/otel/sdk/metric/reader" + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/otel/sdk/metric/export" +) + +type readerFactory func() Reader + +func testReaderHarness(t *testing.T, f readerFactory) { + t.Run("ErrorForNotRegistered", func(t *testing.T) { + r := f() + ctx := context.Background() + + _, err := r.Collect(ctx) + require.ErrorIs(t, err, ErrReaderNotRegistered) + + // Ensure Reader is allowed clean up attempt. + _ = r.Shutdown(ctx) + }) + + t.Run("Producer", func(t *testing.T) { + r := f() + r.register(testProducer{}) + ctx := context.Background() + + m, err := r.Collect(ctx) + assert.NoError(t, err) + assert.Equal(t, testMetrics, m) + + // Ensure Reader is allowed clean up attempt. + _ = r.Shutdown(ctx) + }) + + t.Run("CollectAfterShutdown", func(t *testing.T) { + r := f() + r.register(testProducer{}) + require.NoError(t, r.Shutdown(context.Background())) + + m, err := r.Collect(context.Background()) + assert.ErrorIs(t, err, ErrReaderShutdown) + assert.Equal(t, export.Metrics{}, m) + }) + + t.Run("ShutdownTwice", func(t *testing.T) { + r := f() + r.register(testProducer{}) + require.NoError(t, r.Shutdown(context.Background())) + + assert.ErrorIs(t, r.Shutdown(context.Background()), ErrReaderShutdown) + }) + + t.Run("MultipleForceFlush", func(t *testing.T) { + r := f() + r.register(testProducer{}) + ctx := context.Background() + require.NoError(t, r.ForceFlush(ctx)) + assert.NoError(t, r.ForceFlush(ctx)) + + // Ensure Reader is allowed clean up attempt. + _ = r.Shutdown(ctx) + }) +} + +var testMetrics = export.Metrics{ + // TODO: test with actual data. +} + +type testProducer struct{} + +func (p testProducer) produce(context.Context) (export.Metrics, error) { + return testMetrics, nil +}