Skip to content

Commit

Permalink
Cleanup internal/testcomponents (#5522)
Browse files Browse the repository at this point in the history
* Remove unnecessary types.
* Expose example processor to allow start/shutdown tests.

Signed-off-by: Bogdan Drutu <[email protected]>
  • Loading branch information
bogdandrutu authored Jun 14, 2022
1 parent e5ac6d2 commit a88d448
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 116 deletions.
48 changes: 23 additions & 25 deletions internal/testcomponents/example_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@ import (
"go.opentelemetry.io/collector/pdata/ptrace"
)

// ExampleExporter is for testing purposes. We are defining an example config and factory
// for "exampleexporter" exporter type.
type ExampleExporter struct {
const expType = "exampleexporter"

// ExampleExporterConfig config for ExampleExporter.
type ExampleExporterConfig struct {
config.ExporterSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct
}

const expType = "exampleexporter"

// ExampleExporterFactory is factory for ExampleExporter.
var ExampleExporterFactory = component.NewExporterFactory(
expType,
Expand All @@ -41,65 +40,64 @@ var ExampleExporterFactory = component.NewExporterFactory(
component.WithMetricsExporter(createMetricsExporter),
component.WithLogsExporter(createLogsExporter))

// CreateDefaultConfig creates the default configuration for the Exporter.
func createExporterDefaultConfig() config.Exporter {
return &ExampleExporter{
return &ExampleExporterConfig{
ExporterSettings: config.NewExporterSettings(config.NewComponentID(expType)),
}
}

func createTracesExporter(context.Context, component.ExporterCreateSettings, config.Exporter) (component.TracesExporter, error) {
return &ExampleExporterConsumer{}, nil
return &ExampleExporter{}, nil
}

func createMetricsExporter(context.Context, component.ExporterCreateSettings, config.Exporter) (component.MetricsExporter, error) {
return &ExampleExporterConsumer{}, nil
return &ExampleExporter{}, nil
}

func createLogsExporter(context.Context, component.ExporterCreateSettings, config.Exporter) (component.LogsExporter, error) {
return &ExampleExporterConsumer{}, nil
return &ExampleExporter{}, nil
}

// ExampleExporterConsumer stores consumed traces and metrics for testing purposes.
type ExampleExporterConsumer struct {
Traces []ptrace.Traces
Metrics []pmetric.Metrics
Logs []plog.Logs
ExporterStarted bool
ExporterShutdown bool
// ExampleExporter stores consumed traces and metrics for testing purposes.
type ExampleExporter struct {
Traces []ptrace.Traces
Metrics []pmetric.Metrics
Logs []plog.Logs
Started bool
Stopped bool
}

// Start tells the exporter to start. The exporter may prepare for exporting
// by connecting to the endpoint. Host parameter can be used for communicating
// with the host after Start() has already returned.
func (exp *ExampleExporterConsumer) Start(_ context.Context, _ component.Host) error {
exp.ExporterStarted = true
func (exp *ExampleExporter) Start(_ context.Context, _ component.Host) error {
exp.Started = true
return nil
}

// ConsumeTraces receives ptrace.Traces for processing by the consumer.Traces.
func (exp *ExampleExporterConsumer) ConsumeTraces(_ context.Context, td ptrace.Traces) error {
func (exp *ExampleExporter) ConsumeTraces(_ context.Context, td ptrace.Traces) error {
exp.Traces = append(exp.Traces, td)
return nil
}

func (exp *ExampleExporterConsumer) Capabilities() consumer.Capabilities {
func (exp *ExampleExporter) Capabilities() consumer.Capabilities {
return consumer.Capabilities{MutatesData: false}
}

// ConsumeMetrics receives pmetric.Metrics for processing by the Metrics.
func (exp *ExampleExporterConsumer) ConsumeMetrics(_ context.Context, md pmetric.Metrics) error {
func (exp *ExampleExporter) ConsumeMetrics(_ context.Context, md pmetric.Metrics) error {
exp.Metrics = append(exp.Metrics, md)
return nil
}

func (exp *ExampleExporterConsumer) ConsumeLogs(_ context.Context, ld plog.Logs) error {
func (exp *ExampleExporter) ConsumeLogs(_ context.Context, ld plog.Logs) error {
exp.Logs = append(exp.Logs, ld)
return nil
}

// Shutdown is invoked during shutdown.
func (exp *ExampleExporterConsumer) Shutdown(context.Context) error {
exp.ExporterShutdown = true
func (exp *ExampleExporter) Shutdown(context.Context) error {
exp.Stopped = true
return nil
}
24 changes: 10 additions & 14 deletions internal/testcomponents/example_exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,22 @@ import (
"go.opentelemetry.io/collector/pdata/ptrace"
)

func TestExampleExporterConsumer(t *testing.T) {
exp := &ExampleExporterConsumer{}
func TestExampleExporter(t *testing.T) {
exp := &ExampleExporter{}
host := componenttest.NewNopHost()
assert.False(t, exp.ExporterStarted)
err := exp.Start(context.Background(), host)
assert.NoError(t, err)
assert.True(t, exp.ExporterStarted)
assert.False(t, exp.Started)
assert.NoError(t, exp.Start(context.Background(), host))
assert.True(t, exp.Started)

assert.Equal(t, 0, len(exp.Traces))
err = exp.ConsumeTraces(context.Background(), ptrace.Traces{})
assert.NoError(t, err)
assert.NoError(t, exp.ConsumeTraces(context.Background(), ptrace.Traces{}))
assert.Equal(t, 1, len(exp.Traces))

assert.Equal(t, 0, len(exp.Metrics))
err = exp.ConsumeMetrics(context.Background(), pmetric.Metrics{})
assert.NoError(t, err)
assert.NoError(t, exp.ConsumeMetrics(context.Background(), pmetric.Metrics{}))
assert.Equal(t, 1, len(exp.Metrics))

assert.False(t, exp.ExporterShutdown)
err = exp.Shutdown(context.Background())
assert.NoError(t, err)
assert.True(t, exp.ExporterShutdown)
assert.False(t, exp.Stopped)
assert.NoError(t, exp.Shutdown(context.Background()))
assert.True(t, exp.Stopped)
}
28 changes: 13 additions & 15 deletions internal/testcomponents/example_factories.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,20 @@ package testcomponents // import "go.opentelemetry.io/collector/internal/testcom

import (
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
)

// ExampleComponents registers example factories. This is only used by tests.
func ExampleComponents() (
factories component.Factories,
err error,
) {
if factories.Receivers, err = component.MakeReceiverFactoryMap(ExampleReceiverFactory); err != nil {
return
}

if factories.Exporters, err = component.MakeExporterFactoryMap(ExampleExporterFactory); err != nil {
return
}

factories.Processors, err = component.MakeProcessorFactoryMap(ExampleProcessorFactory)

return
func ExampleComponents() (component.Factories, error) {
return component.Factories{
Receivers: map[config.Type]component.ReceiverFactory{
ExampleReceiverFactory.Type(): ExampleReceiverFactory,
},
Processors: map[config.Type]component.ProcessorFactory{
ExampleProcessorFactory.Type(): ExampleProcessorFactory,
},
Exporters: map[config.Type]component.ExporterFactory{
ExampleExporterFactory.Type(): ExampleExporterFactory,
},
}, nil
}
31 changes: 17 additions & 14 deletions internal/testcomponents/example_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ import (
"go.opentelemetry.io/collector/consumer"
)

// ExampleProcessorCfg is for testing purposes. We are defining an example config and factory
// for "exampleprocessor" processor type.
type ExampleProcessorCfg struct {
const procType = "exampleprocessor"

// ExampleProcessorConfig config for ExampleProcessor.
type ExampleProcessorConfig struct {
config.ProcessorSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct
}

const procType = "exampleprocessor"

// ExampleProcessorFactory is factory for exampleProcessor.
// ExampleProcessorFactory is factory for ExampleProcessor.
var ExampleProcessorFactory = component.NewProcessorFactory(
procType,
createDefaultConfig,
Expand All @@ -40,37 +39,41 @@ var ExampleProcessorFactory = component.NewProcessorFactory(

// CreateDefaultConfig creates the default configuration for the Processor.
func createDefaultConfig() config.Processor {
return &ExampleProcessorCfg{
return &ExampleProcessorConfig{
ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(procType)),
}
}

func createTracesProcessor(_ context.Context, _ component.ProcessorCreateSettings, _ config.Processor, nextConsumer consumer.Traces) (component.TracesProcessor, error) {
return &exampleProcessor{Traces: nextConsumer}, nil
return &ExampleProcessor{Traces: nextConsumer}, nil
}

func createMetricsProcessor(_ context.Context, _ component.ProcessorCreateSettings, _ config.Processor, nextConsumer consumer.Metrics) (component.MetricsProcessor, error) {
return &exampleProcessor{Metrics: nextConsumer}, nil
return &ExampleProcessor{Metrics: nextConsumer}, nil
}

func createLogsProcessor(_ context.Context, _ component.ProcessorCreateSettings, _ config.Processor, nextConsumer consumer.Logs) (component.LogsProcessor, error) {
return &exampleProcessor{Logs: nextConsumer}, nil
return &ExampleProcessor{Logs: nextConsumer}, nil
}

type exampleProcessor struct {
type ExampleProcessor struct {
consumer.Traces
consumer.Metrics
consumer.Logs
Started bool
Stopped bool
}

func (ep *exampleProcessor) Start(_ context.Context, _ component.Host) error {
func (ep *ExampleProcessor) Start(_ context.Context, _ component.Host) error {
ep.Started = true
return nil
}

func (ep *exampleProcessor) Shutdown(_ context.Context) error {
func (ep *ExampleProcessor) Shutdown(_ context.Context) error {
ep.Stopped = true
return nil
}

func (ep *exampleProcessor) Capabilities() consumer.Capabilities {
func (ep *ExampleProcessor) Capabilities() consumer.Capabilities {
return consumer.Capabilities{MutatesData: false}
}
36 changes: 36 additions & 0 deletions internal/testcomponents/example_processor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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 testcomponents

import (
"context"
"testing"

"github.com/stretchr/testify/assert"

"go.opentelemetry.io/collector/component/componenttest"
)

func TestExampleProcessor(t *testing.T) {
prc := &ExampleProcessor{}
host := componenttest.NewNopHost()
assert.False(t, prc.Started)
assert.NoError(t, prc.Start(context.Background(), host))
assert.True(t, prc.Started)

assert.False(t, prc.Stopped)
assert.NoError(t, prc.Shutdown(context.Background()))
assert.True(t, prc.Stopped)
}
30 changes: 14 additions & 16 deletions internal/testcomponents/example_receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ import (
"go.opentelemetry.io/collector/consumer"
)

// ExampleReceiver is for testing purposes. We are defining an example config and factory
// for "examplereceiver" receiver type.
type ExampleReceiver struct {
const receiverType = config.Type("examplereceiver")

// ExampleReceiverConfig config for ExampleReceiver.
type ExampleReceiverConfig struct {
config.ReceiverSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct
}

const receiverType = config.Type("examplereceiver")

// ExampleReceiverFactory is factory for ExampleReceiver.
var ExampleReceiverFactory = component.NewReceiverFactory(
receiverType,
Expand All @@ -39,7 +38,7 @@ var ExampleReceiverFactory = component.NewReceiverFactory(
component.WithLogsReceiver(createLogsReceiver))

func createReceiverDefaultConfig() config.Receiver {
return &ExampleReceiver{
return &ExampleReceiverConfig{
ReceiverSettings: config.NewReceiverSettings(config.NewComponentID(receiverType)),
}
}
Expand Down Expand Up @@ -76,42 +75,41 @@ func createLogsReceiver(
) (component.LogsReceiver, error) {
receiver := createReceiver(cfg)
receiver.Logs = nextConsumer

return receiver, nil
}

func createReceiver(cfg config.Receiver) *ExampleReceiverProducer {
func createReceiver(cfg config.Receiver) *ExampleReceiver {
// There must be one receiver for all data types. We maintain a map of
// receivers per config.

// Check to see if there is already a receiver for this config.
receiver, ok := exampleReceivers[cfg]
if !ok {
receiver = &ExampleReceiverProducer{}
receiver = &ExampleReceiver{}
// Remember the receiver in the map
exampleReceivers[cfg] = receiver
}

return receiver
}

// ExampleReceiverProducer allows producing traces and metrics for testing purposes.
type ExampleReceiverProducer struct {
Started bool
Stopped bool
// ExampleReceiver allows producing traces and metrics for testing purposes.
type ExampleReceiver struct {
consumer.Traces
consumer.Metrics
consumer.Logs
Started bool
Stopped bool
}

// Start tells the receiver to start its processing.
func (erp *ExampleReceiverProducer) Start(_ context.Context, _ component.Host) error {
func (erp *ExampleReceiver) Start(_ context.Context, _ component.Host) error {
erp.Started = true
return nil
}

// Shutdown tells the receiver that should stop reception,
func (erp *ExampleReceiverProducer) Shutdown(context.Context) error {
func (erp *ExampleReceiver) Shutdown(context.Context) error {
erp.Stopped = true
return nil
}
Expand All @@ -120,4 +118,4 @@ func (erp *ExampleReceiverProducer) Shutdown(context.Context) error {
// We maintain this map because the ReceiverFactory is asked trace and metric receivers separately
// when it gets CreateTracesReceiver() and CreateMetricsReceiver() but they must not
// create separate objects, they must use one Receiver object per configuration.
var exampleReceivers = map[config.Receiver]*ExampleReceiverProducer{}
var exampleReceivers = map[config.Receiver]*ExampleReceiver{}
13 changes: 6 additions & 7 deletions internal/testcomponents/example_receiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@ import (
"go.opentelemetry.io/collector/component/componenttest"
)

func TestExampleReceiverProducer(t *testing.T) {
rcv := &ExampleReceiverProducer{}
func TestExampleReceiver(t *testing.T) {
rcv := &ExampleReceiver{}
host := componenttest.NewNopHost()
assert.False(t, rcv.Started)
err := rcv.Start(context.Background(), host)
assert.NoError(t, err)
assert.NoError(t, rcv.Start(context.Background(), host))
assert.True(t, rcv.Started)

err = rcv.Shutdown(context.Background())
assert.NoError(t, err)
assert.True(t, rcv.Started)
assert.False(t, rcv.Stopped)
assert.NoError(t, rcv.Shutdown(context.Background()))
assert.True(t, rcv.Stopped)
}
Loading

0 comments on commit a88d448

Please sign in to comment.