Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure all exporters are added to lifecycle test #6933

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions exporter/sentryexporter/sentry_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"encoding/hex"
"errors"
"fmt"
"log"
"net/http"
"strconv"
"strings"
Expand Down Expand Up @@ -444,7 +443,7 @@ func CreateSentryExporter(config *Config, set component.ExporterCreateSettings)
allEventsFlushed := transport.Flush(ctx)

if !allEventsFlushed {
log.Print("Could not flush all events, reached timeout")
set.Logger.Warn("Could not flush all events, reached timeout")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated this due to the amount of spam it produced throughout testing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

return nil
Expand Down
239 changes: 230 additions & 9 deletions internal/components/exporters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ package components
import (
"context"
"errors"
"io/ioutil"
"os"
"runtime"
"testing"

Expand All @@ -32,16 +30,39 @@ import (
"go.opentelemetry.io/collector/exporter/otlpexporter"
"go.opentelemetry.io/collector/exporter/otlphttpexporter"

"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/alibabacloudlogserviceexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/awsemfexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/awskinesisexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/awsprometheusremotewriteexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/awsxrayexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/azuremonitorexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/carbonexporter"
ddconf "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/config"
dtconf "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/dynatraceexporter/config"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/elasticexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/f5cloudexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/honeycombexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/humioexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/influxdbexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/jaegerexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/jaegerthrifthttpexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/kafkaexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/loadbalancingexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/logzioexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/lokiexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/newrelicexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/opencensusexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/parquetexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sapmexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sentryexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/signalfxexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/skywalkingexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/splunkhecexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sumologicexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/tanzuobservabilityexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/tencentcloudlogserviceexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/zipkinexporter"
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/testutil"
)
Expand All @@ -52,9 +73,6 @@ func TestDefaultExporters(t *testing.T) {

expFactories := factories.Exporters
endpoint := testutil.GetAvailableLocalAddress(t)
parquetTempDir, err := ioutil.TempDir("", "*")
assert.NoError(t, err)
defer os.RemoveAll(parquetTempDir)

tests := []struct {
exporter config.Type
Expand All @@ -65,8 +83,7 @@ func TestDefaultExporters(t *testing.T) {
exporter: "file",
getConfigFn: func() config.Exporter {
cfg := expFactories["file"].CreateDefaultConfig().(*fileexporter.Config)
f, err := ioutil.TempFile("", "otelcol_defaults_file_exporter_test*.tmp")
require.NoError(t, err)
f := testutil.NewTemporaryFile(t)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to test helper so my /tmp would clear up after each test run

assert.NoError(t, f.Close())
cfg.Path = f.Name()
return cfg
Expand Down Expand Up @@ -134,7 +151,7 @@ func TestDefaultExporters(t *testing.T) {
exporter: "parquet",
getConfigFn: func() config.Exporter {
cfg := expFactories["parquet"].CreateDefaultConfig().(*parquetexporter.Config)
cfg.Path = parquetTempDir
cfg.Path = testutil.NewTemporaryDirectory(t)
return cfg
},
},
Expand Down Expand Up @@ -184,11 +201,215 @@ func TestDefaultExporters(t *testing.T) {
return cfg
},
},
{
exporter: "awskinesis",
getConfigFn: func() config.Exporter {
cfg := expFactories["awskinesis"].CreateDefaultConfig().(*awskinesisexporter.Config)
cfg.AWS.KinesisEndpoint = endpoint
return cfg
},
},
{
exporter: "awsprometheusremotewrite",
getConfigFn: func() config.Exporter {
cfg := expFactories["awsprometheusremotewrite"].CreateDefaultConfig().(*awsprometheusremotewriteexporter.Config)
cfg.HTTPClientSettings.Endpoint = "http://" + endpoint
return cfg
},
},
{
exporter: "alibabacloud_logservice",
getConfigFn: func() config.Exporter {
cfg := expFactories["alibabacloud_logservice"].CreateDefaultConfig().(*alibabacloudlogserviceexporter.Config)
cfg.Endpoint = "http://" + endpoint
cfg.Project = "otel-testing"
cfg.Logstore = "otel-data"
return cfg
},
},
{
exporter: "awsemf",
getConfigFn: func() config.Exporter {
cfg := expFactories["awsemf"].CreateDefaultConfig().(*awsemfexporter.Config)
cfg.Endpoint = "http://" + endpoint
cfg.Region = "local"
return cfg
},
},
{
exporter: "awsxray",
getConfigFn: func() config.Exporter {
cfg := expFactories["awsxray"].CreateDefaultConfig().(*awsxrayexporter.Config)
cfg.Endpoint = "http://" + endpoint
cfg.Region = "local"
return cfg
},
},
{
exporter: "azuremonitor",
getConfigFn: func() config.Exporter {
cfg := expFactories["azuremonitor"].CreateDefaultConfig().(*azuremonitorexporter.Config)
cfg.Endpoint = "http://" + endpoint

return cfg
},
},
{
exporter: "carbon",
getConfigFn: func() config.Exporter {
cfg := expFactories["carbon"].CreateDefaultConfig().(*carbonexporter.Config)
cfg.Endpoint = "http://" + endpoint
return cfg
},
},
{
exporter: "datadog",
getConfigFn: func() config.Exporter {
cfg := expFactories["datadog"].CreateDefaultConfig().(*ddconf.Config)
cfg.API.Key = "cutedogsgotoheaven"
return cfg
},
},
{
exporter: "dynatrace",
getConfigFn: func() config.Exporter {
cfg := expFactories["dynatrace"].CreateDefaultConfig().(*dtconf.Config)
cfg.Endpoint = "http://" + endpoint
cfg.APIToken = "dynamictracing"
return cfg
},
},
{
exporter: "elastic",
getConfigFn: func() config.Exporter {
cfg := expFactories["elastic"].CreateDefaultConfig().(*elasticexporter.Config)
cfg.APMServerURL = "http://" + endpoint
return cfg
},
},
{
exporter: "f5cloud",
getConfigFn: func() config.Exporter {
f := testutil.NewTemporaryFile(t)

cfg := expFactories["f5cloud"].CreateDefaultConfig().(*f5cloudexporter.Config)
cfg.Endpoint = "http://" + endpoint
cfg.Source = "magic-source"
cfg.AuthConfig.CredentialFile = f.Name()

return cfg
},
},
{
exporter: "googlecloud",
skipLifecycle: true, // Requires credentials to be able to successfully load the exporter
},
{
exporter: "honeycomb",
getConfigFn: func() config.Exporter {
cfg := expFactories["honeycomb"].CreateDefaultConfig().(*honeycombexporter.Config)
cfg.APIURL = "http://" + endpoint
cfg.APIKey = "busybeesworking"
return cfg
},
},
{
exporter: "humio",
getConfigFn: func() config.Exporter {
cfg := expFactories["humio"].CreateDefaultConfig().(*humioexporter.Config)
cfg.Endpoint = "http://" + endpoint
return cfg
},
},
{
exporter: "influxdb",
getConfigFn: func() config.Exporter {
cfg := expFactories["influxdb"].CreateDefaultConfig().(*influxdbexporter.Config)
cfg.Endpoint = "http://" + endpoint
return cfg
},
},
{
exporter: "loadbalancing",
getConfigFn: func() config.Exporter {
cfg := expFactories["loadbalancing"].CreateDefaultConfig().(*loadbalancingexporter.Config)
return cfg
},
},
{
exporter: "logzio",
getConfigFn: func() config.Exporter {
cfg := expFactories["logzio"].CreateDefaultConfig().(*logzioexporter.Config)
cfg.CustomEndpoint = "http://" + endpoint
return cfg
},
},
{
exporter: "loki",
getConfigFn: func() config.Exporter {
cfg := expFactories["loki"].CreateDefaultConfig().(*lokiexporter.Config)
cfg.Endpoint = "http://" + endpoint
return cfg
},
},
{
exporter: "newrelic",
getConfigFn: func() config.Exporter {
cfg := expFactories["newrelic"].CreateDefaultConfig().(*newrelicexporter.Config)
cfg.CommonConfig.HostOverride = "http://" + endpoint
return cfg
},
},
{
exporter: "sentry",
getConfigFn: func() config.Exporter {
cfg := expFactories["sentry"].CreateDefaultConfig().(*sentryexporter.Config)
return cfg
},
},
{
exporter: "skywalking",
getConfigFn: func() config.Exporter {
cfg := expFactories["skywalking"].CreateDefaultConfig().(*skywalkingexporter.Config)
return cfg
},
},
{
exporter: "stackdriver",
skipLifecycle: true, // Is a deprecated exporter that has moved to google cloud exporter
},
{
exporter: "sumologic",
getConfigFn: func() config.Exporter {
cfg := expFactories["sumologic"].CreateDefaultConfig().(*sumologicexporter.Config)
cfg.Endpoint = "http://" + endpoint

return cfg
},
},
{
exporter: "tanzuobservability",
getConfigFn: func() config.Exporter {
cfg := expFactories["tanzuobservability"].CreateDefaultConfig().(*tanzuobservabilityexporter.Config)
cfg.Traces.Endpoint = "http://" + endpoint
return cfg
},
},
{
exporter: "tencentcloud_logservice",
getConfigFn: func() config.Exporter {
cfg := expFactories["tencentcloud_logservice"].CreateDefaultConfig().(*tencentcloudlogserviceexporter.Config)

return cfg
},
},
}

assert.Equal(t, len(tests)+25 /* not tested */, len(expFactories))
assert.Equal(t, len(tests), len(expFactories), "All user configurable components must be added to the lifecycle test")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use assert.Len here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add them in a follow up PR

for _, tt := range tests {
t.Run(string(tt.exporter), func(t *testing.T) {
t.Parallel()

factory, ok := expFactories[tt.exporter]
require.True(t, ok)
assert.Equal(t, tt.exporter, factory.Type())
Expand Down
25 changes: 25 additions & 0 deletions internal/coreinternal/testutil/testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ package testutil // import "github.com/open-telemetry/opentelemetry-collector-co

import (
"net"
"os"
"os/exec"
"runtime"
"strconv"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -109,3 +111,26 @@ func createExclusionsList(exclusionsText string, t *testing.T) []portpair {
}
return exclusions
}

// NewTemporaryFile creates a file that can be used within the scope of the test
// and will be closed then removed from the file system during the test cleanup
func NewTemporaryFile(tb testing.TB) *os.File {
file, err := os.CreateTemp("", "otelcol_defaults_file_exporter_test*.tmp")
require.NoError(tb, err, "Must not error when creating a temporary file")
tb.Cleanup(func() {
assert.NoError(tb, file.Close(), "Must not error when closing the file")
assert.NoError(tb, os.Remove(file.Name()), "Must not fail removing temporary file used for testing")
})
return file
}

// NewTemporaryDirectory creates a new temporary directory that can be used within the scope of
// test or benchmark and the directory will be cleaned up with all files contained within directory.
func NewTemporaryDirectory(tb testing.TB) (absolutePath string) {
name, err := os.MkdirTemp("", "open-telemetry-test-dir-*")
require.NoError(tb, err, "Must not error when creating a test dir")
tb.Cleanup(func() {
assert.NoError(tb, os.RemoveAll(name), "Must not error when removing temporary directory")
})
return name
}
32 changes: 32 additions & 0 deletions internal/coreinternal/testutil/testutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ package testutil

import (
"net"
"os"
"strconv"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -73,3 +75,33 @@ Start Port End Port
emptyExclusions := createExclusionsList(emptyExclusionsText, t)
require.Equal(t, len(emptyExclusions), 0)
}

func TestTemporaryFile(t *testing.T) {
var filename string

t.Run("scoped lifetime", func(t *testing.T) {
f := NewTemporaryFile(t)
filename = f.Name()

_, err := os.Stat(filename)
assert.ErrorIs(t, err, nil)
})

_, err := os.Stat(filename)
assert.ErrorIs(t, err, os.ErrNotExist)
}

func TestTemporaryDirectory(t *testing.T) {
var tmp string

t.Run("scoped lifetime", func(t *testing.T) {
tmp = NewTemporaryDirectory(t)

stat, err := os.Stat(tmp)
assert.NoError(t, err)
assert.True(t, stat.IsDir(), "Must have the directory permissions set")
})

_, err := os.Stat(tmp)
assert.ErrorIs(t, err, os.ErrNotExist)
}