From 3660f5ce842271ba20efe8db900a9efaeec7569a Mon Sep 17 00:00:00 2001 From: Paulo Janotti Date: Mon, 22 Mar 2021 14:11:10 -0700 Subject: [PATCH] Add lifecycle tests to all default components (#2741) * Add lifecycle tests to all defaultcomponents * Remove commented code in test * Change lifecycle tests per #2757 * Use errors.Is * Remove extra lines * Remove unneeded cast function --- .../default_exporters_test.go | 211 ++++++++++++++++++ ...lts_test.go => default_extensions_test.go} | 116 +++------- .../default_processors_test.go | 173 ++++++++++++++ .../default_receivers_test.go | 166 ++++++++++++++ 4 files changed, 584 insertions(+), 82 deletions(-) create mode 100644 service/defaultcomponents/default_exporters_test.go rename service/defaultcomponents/{defaults_test.go => default_extensions_test.go} (55%) create mode 100644 service/defaultcomponents/default_processors_test.go create mode 100644 service/defaultcomponents/default_receivers_test.go diff --git a/service/defaultcomponents/default_exporters_test.go b/service/defaultcomponents/default_exporters_test.go new file mode 100644 index 00000000000..e95e0add79a --- /dev/null +++ b/service/defaultcomponents/default_exporters_test.go @@ -0,0 +1,211 @@ +// 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 defaultcomponents + +import ( + "context" + "errors" + "io/ioutil" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configerror" + "go.opentelemetry.io/collector/config/configgrpc" + "go.opentelemetry.io/collector/config/configmodels" + "go.opentelemetry.io/collector/exporter/fileexporter" + "go.opentelemetry.io/collector/exporter/jaegerexporter" + "go.opentelemetry.io/collector/exporter/kafkaexporter" + "go.opentelemetry.io/collector/exporter/opencensusexporter" + "go.opentelemetry.io/collector/exporter/otlpexporter" + "go.opentelemetry.io/collector/exporter/otlphttpexporter" + "go.opentelemetry.io/collector/exporter/prometheusexporter" + "go.opentelemetry.io/collector/exporter/zipkinexporter" + "go.opentelemetry.io/collector/testutil" +) + +func TestDefaultExporters(t *testing.T) { + factories, err := Components() + assert.NoError(t, err) + + expFactories := factories.Exporters + endpoint := testutil.GetAvailableLocalAddress(t) + + tests := []struct { + exporter configmodels.Type + getConfigFn getExporterConfigFn + }{ + { + exporter: "file", + getConfigFn: func() configmodels.Exporter { + cfg := expFactories["file"].CreateDefaultConfig().(*fileexporter.Config) + f, err := ioutil.TempFile("", "otelcol_defaults_file_exporter_test*.tmp") + require.NoError(t, err) + assert.NoError(t, f.Close()) + cfg.Path = f.Name() + return cfg + }, + }, + { + exporter: "jaeger", + getConfigFn: func() configmodels.Exporter { + cfg := expFactories["jaeger"].CreateDefaultConfig().(*jaegerexporter.Config) + cfg.Endpoint = endpoint + return cfg + }, + }, + { + exporter: "kafka", + getConfigFn: func() configmodels.Exporter { + cfg := expFactories["kafka"].CreateDefaultConfig().(*kafkaexporter.Config) + cfg.Brokers = []string{"invalid:9092"} + // this disables contacting the broker so we can successfully create the exporter + cfg.Metadata.Full = false + return cfg + }, + }, + { + exporter: "logging", + }, + { + exporter: "opencensus", + getConfigFn: func() configmodels.Exporter { + cfg := expFactories["opencensus"].CreateDefaultConfig().(*opencensusexporter.Config) + cfg.GRPCClientSettings = configgrpc.GRPCClientSettings{ + Endpoint: endpoint, + } + return cfg + }, + }, + { + exporter: "otlp", + getConfigFn: func() configmodels.Exporter { + cfg := expFactories["otlp"].CreateDefaultConfig().(*otlpexporter.Config) + cfg.GRPCClientSettings = configgrpc.GRPCClientSettings{ + Endpoint: endpoint, + } + return cfg + }, + }, + { + exporter: "otlphttp", + getConfigFn: func() configmodels.Exporter { + cfg := expFactories["otlphttp"].CreateDefaultConfig().(*otlphttpexporter.Config) + cfg.Endpoint = "http://" + endpoint + return cfg + }, + }, + { + exporter: "prometheus", + getConfigFn: func() configmodels.Exporter { + cfg := expFactories["prometheus"].CreateDefaultConfig().(*prometheusexporter.Config) + cfg.Endpoint = endpoint + return cfg + }, + }, + { + exporter: "prometheusremotewrite", + }, + { + exporter: "zipkin", + getConfigFn: func() configmodels.Exporter { + cfg := expFactories["zipkin"].CreateDefaultConfig().(*zipkinexporter.Config) + cfg.Endpoint = endpoint + return cfg + }, + }, + } + + assert.Equal(t, len(tests), len(expFactories)) + for _, tt := range tests { + t.Run(string(tt.exporter), func(t *testing.T) { + factory, ok := expFactories[tt.exporter] + require.True(t, ok) + assert.Equal(t, tt.exporter, factory.Type()) + assert.Equal(t, tt.exporter, factory.CreateDefaultConfig().Type()) + + verifyExporterLifecycle(t, factory, tt.getConfigFn) + }) + } +} + +// GetExporterConfigFn is used customize the configuration passed to the verification. +// This is used to change ports or provide values required but not provided by the +// default configuration. +type getExporterConfigFn func() configmodels.Exporter + +// verifyExporterLifecycle is used to test if an exporter type can handle the typical +// lifecycle of a component. The getConfigFn parameter only need to be specified if +// the test can't be done with the default configuration for the component. +func verifyExporterLifecycle(t *testing.T, factory component.ExporterFactory, getConfigFn getExporterConfigFn) { + ctx := context.Background() + host := newAssertNoErrorHost(t) + expCreateParams := component.ExporterCreateParams{ + Logger: zap.NewNop(), + ApplicationStartInfo: component.DefaultApplicationStartInfo(), + } + + if getConfigFn == nil { + getConfigFn = factory.CreateDefaultConfig + } + + createFns := []createExporterFn{ + wrapCreateLogsExp(factory), + wrapCreateTracesExp(factory), + wrapCreateMetricsExp(factory), + } + + for _, createFn := range createFns { + firstExp, err := createFn(ctx, expCreateParams, getConfigFn()) + if errors.Is(err, configerror.ErrDataTypeIsNotSupported) { + continue + } + require.NoError(t, err) + require.NoError(t, firstExp.Start(ctx, host)) + require.NoError(t, firstExp.Shutdown(ctx)) + + secondExp, err := createFn(ctx, expCreateParams, getConfigFn()) + require.NoError(t, err) + require.NoError(t, secondExp.Start(ctx, host)) + require.NoError(t, secondExp.Shutdown(ctx)) + } +} + +type createExporterFn func( + ctx context.Context, + params component.ExporterCreateParams, + cfg configmodels.Exporter, +) (component.Exporter, error) + +func wrapCreateLogsExp(factory component.ExporterFactory) createExporterFn { + return func(ctx context.Context, params component.ExporterCreateParams, cfg configmodels.Exporter) (component.Exporter, error) { + return factory.CreateLogsExporter(ctx, params, cfg) + } +} + +func wrapCreateTracesExp(factory component.ExporterFactory) createExporterFn { + return func(ctx context.Context, params component.ExporterCreateParams, cfg configmodels.Exporter) (component.Exporter, error) { + return factory.CreateTracesExporter(ctx, params, cfg) + } +} + +func wrapCreateMetricsExp(factory component.ExporterFactory) createExporterFn { + return func(ctx context.Context, params component.ExporterCreateParams, cfg configmodels.Exporter) (component.Exporter, error) { + return factory.CreateMetricsExporter(ctx, params, cfg) + } +} diff --git a/service/defaultcomponents/defaults_test.go b/service/defaultcomponents/default_extensions_test.go similarity index 55% rename from service/defaultcomponents/defaults_test.go rename to service/defaultcomponents/default_extensions_test.go index a8deb6c0782..aa2088130b1 100644 --- a/service/defaultcomponents/defaults_test.go +++ b/service/defaultcomponents/default_extensions_test.go @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Program otelcol is the OpenTelemetry Collector that collects stats -// and traces and exports to a configured backend. package defaultcomponents import ( @@ -29,85 +27,40 @@ import ( "go.opentelemetry.io/collector/config/configmodels" ) -func TestDefaultComponents(t *testing.T) { - expectedExtensions := []configmodels.Type{ - "health_check", - "pprof", - "zpages", - "fluentbit", - } - expectedReceivers := []configmodels.Type{ - "jaeger", - "zipkin", - "prometheus", - "opencensus", - "otlp", - "hostmetrics", - "fluentforward", - "kafka", - } - expectedProcessors := []configmodels.Type{ - "attributes", - "resource", - "batch", - "memory_limiter", - "probabilistic_sampler", - "span", - "filter", - } - expectedExporters := []configmodels.Type{ - "opencensus", - "prometheus", - "prometheusremotewrite", - "logging", - "zipkin", - "jaeger", - "file", - "otlp", - "otlphttp", - "kafka", - } - - factories, err := Components() - assert.NoError(t, err) - - exts := factories.Extensions - assert.Equal(t, len(expectedExtensions), len(exts)) - for _, k := range expectedExtensions { - v, ok := exts[k] - assert.True(t, ok) - assert.Equal(t, k, v.Type()) - cfg := v.CreateDefaultConfig() - assert.Equal(t, k, cfg.Type()) - - verifyExtensionLifecycle(t, v, nil) - } +func TestDefaultExtensions(t *testing.T) { + allFactories, err := Components() + require.NoError(t, err) - recvs := factories.Receivers - assert.Equal(t, len(expectedReceivers), len(recvs)) - for _, k := range expectedReceivers { - v, ok := recvs[k] - require.True(t, ok) - assert.Equal(t, k, v.Type()) - assert.Equal(t, k, v.CreateDefaultConfig().Type()) + extFactories := allFactories.Extensions + + tests := []struct { + extension configmodels.Type + getConfigFn getExtensionConfigFn + }{ + { + extension: "health_check", + }, + { + extension: "pprof", + }, + { + extension: "zpages", + }, + { + extension: "fluentbit", + }, } - procs := factories.Processors - assert.Equal(t, len(expectedProcessors), len(procs)) - for _, k := range expectedProcessors { - v, ok := procs[k] - require.True(t, ok) - assert.Equal(t, k, v.Type()) - assert.Equal(t, k, v.CreateDefaultConfig().Type()) - } + assert.Equal(t, len(tests), len(extFactories)) + for _, tt := range tests { + t.Run(string(tt.extension), func(t *testing.T) { + factory, ok := extFactories[tt.extension] + require.True(t, ok) + assert.Equal(t, tt.extension, factory.Type()) + assert.Equal(t, tt.extension, factory.CreateDefaultConfig().Type()) - exps := factories.Exporters - assert.Equal(t, len(expectedExporters), len(exps)) - for _, k := range expectedExporters { - v, ok := exps[k] - require.True(t, ok) - assert.Equal(t, k, v.Type()) - assert.Equal(t, k, v.CreateDefaultConfig().Type()) + verifyExtensionLifecycle(t, factory, nil) + }) } } @@ -134,13 +87,12 @@ func verifyExtensionLifecycle(t *testing.T, factory component.ExtensionFactory, firstExt, err := factory.CreateExtension(ctx, extCreateParams, getConfigFn()) require.NoError(t, err) require.NoError(t, firstExt.Start(ctx, host)) + require.NoError(t, firstExt.Shutdown(ctx)) secondExt, err := factory.CreateExtension(ctx, extCreateParams, getConfigFn()) - assert.NoError(t, err) - - assert.NoError(t, firstExt.Shutdown(ctx)) - assert.NoError(t, secondExt.Start(ctx, host)) - assert.NoError(t, secondExt.Shutdown(ctx)) + require.NoError(t, err) + require.NoError(t, secondExt.Start(ctx, host)) + require.NoError(t, secondExt.Shutdown(ctx)) } // assertNoErrorHost implements a component.Host that asserts that there were no errors. diff --git a/service/defaultcomponents/default_processors_test.go b/service/defaultcomponents/default_processors_test.go new file mode 100644 index 00000000000..612a15d1732 --- /dev/null +++ b/service/defaultcomponents/default_processors_test.go @@ -0,0 +1,173 @@ +// 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 defaultcomponents + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configerror" + "go.opentelemetry.io/collector/config/configmodels" + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/processor/attributesprocessor" + "go.opentelemetry.io/collector/processor/memorylimiter" + "go.opentelemetry.io/collector/processor/processorhelper" + "go.opentelemetry.io/collector/processor/resourceprocessor" + "go.opentelemetry.io/collector/processor/spanprocessor" +) + +func TestDefaultProcessors(t *testing.T) { + allFactories, err := Components() + require.NoError(t, err) + + procFactories := allFactories.Processors + + tests := []struct { + processor configmodels.Type + getConfigFn getProcessorConfigFn + }{ + { + processor: "attributes", + getConfigFn: func() configmodels.Processor { + cfg := procFactories["attributes"].CreateDefaultConfig().(*attributesprocessor.Config) + cfg.Actions = []processorhelper.ActionKeyValue{ + {Key: "attribute1", Action: processorhelper.INSERT, Value: 123}, + } + return cfg + }, + }, + { + processor: "batch", + }, + { + processor: "filter", + }, + { + processor: "memory_limiter", + getConfigFn: func() configmodels.Processor { + cfg := procFactories["memory_limiter"].CreateDefaultConfig().(*memorylimiter.Config) + cfg.CheckInterval = 100 * time.Millisecond + cfg.MemoryLimitMiB = 1024 * 1024 + return cfg + }, + }, + { + processor: "probabilistic_sampler", + }, + { + processor: "resource", + getConfigFn: func() configmodels.Processor { + cfg := procFactories["resource"].CreateDefaultConfig().(*resourceprocessor.Config) + cfg.AttributesActions = []processorhelper.ActionKeyValue{ + {Key: "attribute1", Action: processorhelper.INSERT, Value: 123}, + } + return cfg + }, + }, + { + processor: "span", + getConfigFn: func() configmodels.Processor { + cfg := procFactories["span"].CreateDefaultConfig().(*spanprocessor.Config) + cfg.Rename.FromAttributes = []string{"test-key"} + return cfg + }, + }, + } + + assert.Equal(t, len(tests), len(procFactories)) + for _, tt := range tests { + t.Run(string(tt.processor), func(t *testing.T) { + factory, ok := procFactories[tt.processor] + require.True(t, ok) + assert.Equal(t, tt.processor, factory.Type()) + assert.Equal(t, tt.processor, factory.CreateDefaultConfig().Type()) + + verifyProcessorLifecycle(t, factory, tt.getConfigFn) + }) + } +} + +// getProcessorConfigFn is used customize the configuration passed to the verification. +// This is used to change ports or provide values required but not provided by the +// default configuration. +type getProcessorConfigFn func() configmodels.Processor + +// verifyProcessorLifecycle is used to test if an processor type can handle the typical +// lifecycle of a component. The getConfigFn parameter only need to be specified if +// the test can't be done with the default configuration for the component. +func verifyProcessorLifecycle(t *testing.T, factory component.ProcessorFactory, getConfigFn getProcessorConfigFn) { + ctx := context.Background() + host := newAssertNoErrorHost(t) + processorCreateParams := component.ProcessorCreateParams{ + Logger: zap.NewNop(), + ApplicationStartInfo: component.DefaultApplicationStartInfo(), + } + + if getConfigFn == nil { + getConfigFn = factory.CreateDefaultConfig + } + + createFns := []createProcessorFn{ + wrapCreateLogsProc(factory), + wrapCreateTracesProc(factory), + wrapCreateMetricsProc(factory), + } + + for _, createFn := range createFns { + firstExp, err := createFn(ctx, processorCreateParams, getConfigFn()) + if errors.Is(err, configerror.ErrDataTypeIsNotSupported) { + continue + } + require.NoError(t, err) + require.NoError(t, firstExp.Start(ctx, host)) + require.NoError(t, firstExp.Shutdown(ctx)) + + secondExp, err := createFn(ctx, processorCreateParams, getConfigFn()) + require.NoError(t, err) + require.NoError(t, secondExp.Start(ctx, host)) + require.NoError(t, secondExp.Shutdown(ctx)) + } +} + +type createProcessorFn func( + ctx context.Context, + params component.ProcessorCreateParams, + cfg configmodels.Processor, +) (component.Processor, error) + +func wrapCreateLogsProc(factory component.ProcessorFactory) createProcessorFn { + return func(ctx context.Context, params component.ProcessorCreateParams, cfg configmodels.Processor) (component.Processor, error) { + return factory.CreateLogsProcessor(ctx, params, cfg, consumertest.NewLogsNop()) + } +} + +func wrapCreateMetricsProc(factory component.ProcessorFactory) createProcessorFn { + return func(ctx context.Context, params component.ProcessorCreateParams, cfg configmodels.Processor) (component.Processor, error) { + return factory.CreateMetricsProcessor(ctx, params, cfg, consumertest.NewMetricsNop()) + } +} + +func wrapCreateTracesProc(factory component.ProcessorFactory) createProcessorFn { + return func(ctx context.Context, params component.ProcessorCreateParams, cfg configmodels.Processor) (component.Processor, error) { + return factory.CreateTracesProcessor(ctx, params, cfg, consumertest.NewTracesNop()) + } +} diff --git a/service/defaultcomponents/default_receivers_test.go b/service/defaultcomponents/default_receivers_test.go new file mode 100644 index 00000000000..deb9de7e5da --- /dev/null +++ b/service/defaultcomponents/default_receivers_test.go @@ -0,0 +1,166 @@ +// 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 defaultcomponents + +import ( + "context" + "errors" + "testing" + + promconfig "github.com/prometheus/prometheus/config" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configerror" + "go.opentelemetry.io/collector/config/configmodels" + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/receiver/prometheusreceiver" +) + +func TestDefaultReceivers(t *testing.T) { + allFactories, err := Components() + assert.NoError(t, err) + + rcvrFactories := allFactories.Receivers + + tests := []struct { + receiver configmodels.Type + skipLifecyle bool + getConfigFn getReceiverConfigFn + }{ + { + receiver: "fluentforward", + }, + { + receiver: "hostmetrics", + }, + { + receiver: "jaeger", + }, + { + receiver: "kafka", + skipLifecyle: true, // TODO: It needs access to internals to successful start. + }, + { + receiver: "opencensus", + skipLifecyle: true, // TODO: Usage of CMux doesn't allow proper shutdown. + }, + { + receiver: "otlp", + skipLifecyle: true, // TODO: Upcoming PR to fix zipkin lifecycle. + }, + { + receiver: "prometheus", + getConfigFn: func() configmodels.Receiver { + cfg := rcvrFactories["prometheus"].CreateDefaultConfig().(*prometheusreceiver.Config) + cfg.PrometheusConfig = &promconfig.Config{ + ScrapeConfigs: []*promconfig.ScrapeConfig{ + {JobName: "test"}, + }, + } + return cfg + }, + }, + { + receiver: "zipkin", + skipLifecyle: true, // TODO: Upcoming PR to fix zipkin lifecycle. + }, + } + + assert.Equal(t, len(tests), len(rcvrFactories)) + for _, tt := range tests { + t.Run(string(tt.receiver), func(t *testing.T) { + factory, ok := rcvrFactories[tt.receiver] + require.True(t, ok) + assert.Equal(t, tt.receiver, factory.Type()) + assert.Equal(t, tt.receiver, factory.CreateDefaultConfig().Type()) + + if tt.skipLifecyle { + t.Log("Skipping lifecycle test", tt.receiver) + } else { + verifyReceiverLifecycle(t, factory, tt.getConfigFn) + } + }) + } +} + +// getReceiverConfigFn is used customize the configuration passed to the verification. +// This is used to change ports or provide values required but not provided by the +// default configuration. +type getReceiverConfigFn func() configmodels.Receiver + +// verifyReceiverLifecycle is used to test if a receiver type can handle the typical +// lifecycle of a component. The getConfigFn parameter only need to be specified if +// the test can't be done with the default configuration for the component. +func verifyReceiverLifecycle(t *testing.T, factory component.ReceiverFactory, getConfigFn getReceiverConfigFn) { + ctx := context.Background() + host := newAssertNoErrorHost(t) + receiverCreateParams := component.ReceiverCreateParams{ + Logger: zap.NewNop(), + ApplicationStartInfo: component.DefaultApplicationStartInfo(), + } + + if getConfigFn == nil { + getConfigFn = factory.CreateDefaultConfig + } + + createFns := []createReceiverFn{ + wrapCreateLogsRcvr(factory), + wrapCreateTracesRcvr(factory), + wrapCreateMetricsRcvr(factory), + } + + for _, createFn := range createFns { + firstRcvr, err := createFn(ctx, receiverCreateParams, getConfigFn()) + if errors.Is(err, configerror.ErrDataTypeIsNotSupported) { + continue + } + require.NoError(t, err) + require.NoError(t, firstRcvr.Start(ctx, host)) + require.NoError(t, firstRcvr.Shutdown(ctx)) + + secondRcvr, err := createFn(ctx, receiverCreateParams, getConfigFn()) + require.NoError(t, err) + require.NoError(t, secondRcvr.Start(ctx, host)) + require.NoError(t, secondRcvr.Shutdown(ctx)) + } +} + +// assertNoErrorHost implements a component.Host that asserts that there were no errors. +type createReceiverFn func( + ctx context.Context, + params component.ReceiverCreateParams, + cfg configmodels.Receiver, +) (component.Receiver, error) + +func wrapCreateLogsRcvr(factory component.ReceiverFactory) createReceiverFn { + return func(ctx context.Context, params component.ReceiverCreateParams, cfg configmodels.Receiver) (component.Receiver, error) { + return factory.CreateLogsReceiver(ctx, params, cfg, consumertest.NewLogsNop()) + } +} + +func wrapCreateMetricsRcvr(factory component.ReceiverFactory) createReceiverFn { + return func(ctx context.Context, params component.ReceiverCreateParams, cfg configmodels.Receiver) (component.Receiver, error) { + return factory.CreateMetricsReceiver(ctx, params, cfg, consumertest.NewMetricsNop()) + } +} + +func wrapCreateTracesRcvr(factory component.ReceiverFactory) createReceiverFn { + return func(ctx context.Context, params component.ReceiverCreateParams, cfg configmodels.Receiver) (component.Receiver, error) { + return factory.CreateTracesReceiver(ctx, params, cfg, consumertest.NewTracesNop()) + } +}