You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-11-23 22:34:47 +02:00
Based on the Go version we currently use, the dependency already supports 1.24+, which allows using `t.Context()` and `b.Context()` in unit tests and benchmarks respectively. - Enable `context-background` and `context-todo` in [`usetesting`](https://golangci-lint.run/docs/linters/configuration/#usetesting) - Adjust the code to support linter detection --------- Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> Co-authored-by: Tyler Yahn <codingalias@gmail.com> Co-authored-by: Damien Mathieu <42@dmathieu.com>
181 lines
4.5 KiB
Go
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 := t.Context()
|
|
|
|
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 := t.Context()
|
|
|
|
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 = t.Context()
|
|
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 = t.Context()
|
|
)
|
|
|
|
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))
|
|
}
|