1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-04-07 07:00:13 +02:00
2024-04-25 17:11:45 +02:00

181 lines
4.5 KiB
Go

// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package stdoutmetric_test // import "go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
import (
"bytes"
"context"
"encoding/json"
"io"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
"go.opentelemetry.io/otel/sdk/metric"
"go.opentelemetry.io/otel/sdk/metric/metricdata"
)
func testEncoderOption() stdoutmetric.Option {
// Discard export output for testing.
enc := json.NewEncoder(io.Discard)
return stdoutmetric.WithEncoder(enc)
}
func testCtxErrHonored(factory func(*testing.T) func(context.Context) error) func(t *testing.T) {
return func(t *testing.T) {
t.Helper()
ctx := context.Background()
t.Run("DeadlineExceeded", func(t *testing.T) {
innerCtx, innerCancel := context.WithTimeout(ctx, time.Nanosecond)
t.Cleanup(innerCancel)
<-innerCtx.Done()
f := factory(t)
assert.ErrorIs(t, f(innerCtx), context.DeadlineExceeded)
})
t.Run("Canceled", func(t *testing.T) {
innerCtx, innerCancel := context.WithCancel(ctx)
innerCancel()
f := factory(t)
assert.ErrorIs(t, f(innerCtx), context.Canceled)
})
t.Run("NoError", func(t *testing.T) {
f := factory(t)
assert.NoError(t, f(ctx))
})
}
}
func testCtxErrIgnored(factory func(*testing.T) func(context.Context) error) func(t *testing.T) {
return func(t *testing.T) {
t.Helper()
ctx := context.Background()
t.Run("Canceled Ignored", func(t *testing.T) {
innerCtx, innerCancel := context.WithCancel(ctx)
innerCancel()
f := factory(t)
assert.NoError(t, f(innerCtx))
})
t.Run("NoError", func(t *testing.T) {
f := factory(t)
assert.NoError(t, f(ctx))
})
}
}
func TestExporterExportHonorsContextErrors(t *testing.T) {
t.Run("Export", testCtxErrHonored(func(t *testing.T) func(context.Context) error {
exp, err := stdoutmetric.New(testEncoderOption())
require.NoError(t, err)
return func(ctx context.Context) error {
data := new(metricdata.ResourceMetrics)
return exp.Export(ctx, data)
}
}))
}
func TestExporterForceFlushIgnoresContextErrors(t *testing.T) {
t.Run("ForceFlush", testCtxErrIgnored(func(t *testing.T) func(context.Context) error {
exp, err := stdoutmetric.New(testEncoderOption())
require.NoError(t, err)
return exp.ForceFlush
}))
}
func TestExporterShutdownIgnoresContextErrors(t *testing.T) {
t.Run("Shutdown", testCtxErrIgnored(func(t *testing.T) func(context.Context) error {
exp, err := stdoutmetric.New(testEncoderOption())
require.NoError(t, err)
return exp.Shutdown
}))
}
func TestShutdownExporterReturnsShutdownErrorOnExport(t *testing.T) {
var (
data = new(metricdata.ResourceMetrics)
ctx = context.Background()
exp, err = stdoutmetric.New(testEncoderOption())
)
require.NoError(t, err)
require.NoError(t, exp.Shutdown(ctx))
assert.EqualError(t, exp.Export(ctx, data), "exporter shutdown")
}
func deltaSelector(metric.InstrumentKind) metricdata.Temporality {
return metricdata.DeltaTemporality
}
func TestExportWithOptions(t *testing.T) {
var (
data = new(metricdata.ResourceMetrics)
ctx = context.Background()
)
for _, tt := range []struct {
name string
opts []stdoutmetric.Option
expectedData string
}{
{
name: "with no options",
expectedData: "{\"Resource\":null,\"ScopeMetrics\":null}\n",
},
{
name: "with pretty print",
opts: []stdoutmetric.Option{
stdoutmetric.WithPrettyPrint(),
},
expectedData: "{\n\t\"Resource\": null,\n\t\"ScopeMetrics\": null\n}\n",
},
} {
t.Run(tt.name, func(t *testing.T) {
var b bytes.Buffer
opts := append(tt.opts, stdoutmetric.WithWriter(&b))
exp, err := stdoutmetric.New(opts...)
require.NoError(t, err)
require.NoError(t, exp.Export(ctx, data))
assert.Equal(t, tt.expectedData, b.String())
})
}
}
func TestTemporalitySelector(t *testing.T) {
exp, err := stdoutmetric.New(
testEncoderOption(),
stdoutmetric.WithTemporalitySelector(deltaSelector),
)
require.NoError(t, err)
var unknownKind metric.InstrumentKind
assert.Equal(t, metricdata.DeltaTemporality, exp.Temporality(unknownKind))
}
func dropSelector(metric.InstrumentKind) metric.Aggregation {
return metric.AggregationDrop{}
}
func TestAggregationSelector(t *testing.T) {
exp, err := stdoutmetric.New(
testEncoderOption(),
stdoutmetric.WithAggregationSelector(dropSelector),
)
require.NoError(t, err)
var unknownKind metric.InstrumentKind
assert.Equal(t, metric.AggregationDrop{}, exp.Aggregation(unknownKind))
}