Skip to content

Commit

Permalink
Ensure all exporters are added to lifecycle test (#6933)
Browse files Browse the repository at this point in the history
* Ensure all exporters are added to lifecycle test

In order to help test coverage up and ensuring that all components are
tested, I have added what I could to the lifecycle tests for exporters
while adding two additional helps within test util.

* Adding message to check to highlight what needs to be done

* Fixing typo
  • Loading branch information
MovieStoreGuy authored Dec 27, 2021
1 parent 7aad2e7 commit 15d5e25
Show file tree
Hide file tree
Showing 4 changed files with 288 additions and 11 deletions.
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")
}

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)
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")
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)
}

0 comments on commit 15d5e25

Please sign in to comment.