271 lines
8.4 KiB
Go
271 lines
8.4 KiB
Go
// 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 builder
|
|
|
|
import (
|
|
"context"
|
|
"path"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/zap"
|
|
|
|
"go.opentelemetry.io/collector/component"
|
|
"go.opentelemetry.io/collector/component/componenttest"
|
|
"go.opentelemetry.io/collector/config/configmodels"
|
|
"go.opentelemetry.io/collector/config/configtest"
|
|
"go.opentelemetry.io/collector/consumer"
|
|
"go.opentelemetry.io/collector/consumer/pdata"
|
|
"go.opentelemetry.io/collector/internal/testcomponents"
|
|
"go.opentelemetry.io/collector/internal/testdata"
|
|
)
|
|
|
|
func TestBuildPipelines(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
pipelineName string
|
|
exporterNames []string
|
|
}{
|
|
{
|
|
name: "one-exporter",
|
|
pipelineName: "traces",
|
|
exporterNames: []string{"exampleexporter"},
|
|
},
|
|
{
|
|
name: "multi-exporter",
|
|
pipelineName: "traces/2",
|
|
exporterNames: []string{"exampleexporter", "exampleexporter/2"},
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
testPipeline(t, test.pipelineName, test.exporterNames)
|
|
})
|
|
}
|
|
}
|
|
|
|
func createExampleConfig(dataType string) *configmodels.Config {
|
|
exampleReceiverFactory := testcomponents.ExampleReceiverFactory
|
|
exampleProcessorFactory := testcomponents.ExampleProcessorFactory
|
|
exampleExporterFactory := testcomponents.ExampleExporterFactory
|
|
|
|
cfg := &configmodels.Config{
|
|
Receivers: map[string]configmodels.Receiver{
|
|
string(exampleReceiverFactory.Type()): exampleReceiverFactory.CreateDefaultConfig(),
|
|
},
|
|
Processors: map[string]configmodels.Processor{
|
|
string(exampleProcessorFactory.Type()): exampleProcessorFactory.CreateDefaultConfig(),
|
|
},
|
|
Exporters: map[string]configmodels.Exporter{
|
|
string(exampleExporterFactory.Type()): exampleExporterFactory.CreateDefaultConfig(),
|
|
},
|
|
Service: configmodels.Service{
|
|
Pipelines: map[string]*configmodels.Pipeline{
|
|
dataType: {
|
|
Name: dataType,
|
|
InputType: configmodels.DataType(dataType),
|
|
Receivers: []string{string(exampleReceiverFactory.Type())},
|
|
Processors: []string{string(exampleProcessorFactory.Type())},
|
|
Exporters: []string{string(exampleExporterFactory.Type())},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
func TestBuildPipelines_BuildVarious(t *testing.T) {
|
|
|
|
factories := createTestFactories()
|
|
|
|
tests := []struct {
|
|
dataType string
|
|
shouldFail bool
|
|
}{
|
|
{
|
|
dataType: "logs",
|
|
shouldFail: false,
|
|
},
|
|
{
|
|
dataType: "nosuchdatatype",
|
|
shouldFail: true,
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.dataType, func(t *testing.T) {
|
|
dataType := test.dataType
|
|
|
|
cfg := createExampleConfig(dataType)
|
|
|
|
// BuildProcessors the pipeline
|
|
allExporters, err := BuildExporters(zap.NewNop(), component.DefaultApplicationStartInfo(), cfg, factories.Exporters)
|
|
if test.shouldFail {
|
|
assert.Error(t, err)
|
|
return
|
|
}
|
|
|
|
require.NoError(t, err)
|
|
require.EqualValues(t, 1, len(allExporters))
|
|
pipelineProcessors, err := BuildPipelines(zap.NewNop(), component.DefaultApplicationStartInfo(), cfg, allExporters, factories.Processors)
|
|
|
|
assert.NoError(t, err)
|
|
require.NotNil(t, pipelineProcessors)
|
|
|
|
err = pipelineProcessors.StartProcessors(context.Background(), componenttest.NewNopHost())
|
|
assert.NoError(t, err)
|
|
|
|
pipelineName := dataType
|
|
processor := pipelineProcessors[cfg.Service.Pipelines[pipelineName]]
|
|
|
|
// Ensure pipeline has its fields correctly populated.
|
|
require.NotNil(t, processor)
|
|
assert.Nil(t, processor.firstTC)
|
|
assert.Nil(t, processor.firstMC)
|
|
assert.NotNil(t, processor.firstLC)
|
|
|
|
// Compose the list of created exporters.
|
|
exporterNames := []string{"exampleexporter"}
|
|
var exporters []*builtExporter
|
|
for _, name := range exporterNames {
|
|
// Ensure exporter is created.
|
|
exp := allExporters[cfg.Exporters[name]]
|
|
require.NotNil(t, exp)
|
|
exporters = append(exporters, exp)
|
|
}
|
|
|
|
// Send Logs via processor and verify that all exporters of the pipeline receive it.
|
|
|
|
// First check that there are no logs in the exporters yet.
|
|
var exporterConsumers []*testcomponents.ExampleExporterConsumer
|
|
for _, exporter := range exporters {
|
|
expConsumer := exporter.getLogExporter().(*testcomponents.ExampleExporterConsumer)
|
|
exporterConsumers = append(exporterConsumers, expConsumer)
|
|
require.Equal(t, len(expConsumer.Logs), 0)
|
|
}
|
|
|
|
// Send one custom data.
|
|
log := pdata.Logs{}
|
|
processor.firstLC.(consumer.Logs).ConsumeLogs(context.Background(), log)
|
|
|
|
// Now verify received data.
|
|
for _, expConsumer := range exporterConsumers {
|
|
// Check that the trace is received by exporter.
|
|
require.Equal(t, 1, len(expConsumer.Logs))
|
|
|
|
// Verify that span is successfully delivered.
|
|
assert.EqualValues(t, log, expConsumer.Logs[0])
|
|
}
|
|
|
|
err = pipelineProcessors.ShutdownProcessors(context.Background())
|
|
assert.NoError(t, err)
|
|
})
|
|
}
|
|
}
|
|
|
|
func testPipeline(t *testing.T, pipelineName string, exporterNames []string) {
|
|
factories, err := testcomponents.ExampleComponents()
|
|
assert.NoError(t, err)
|
|
cfg, err := configtest.LoadConfigFile(t, "testdata/pipelines_builder.yaml", factories)
|
|
// Load the config
|
|
require.Nil(t, err)
|
|
|
|
// BuildProcessors the pipeline
|
|
allExporters, err := BuildExporters(zap.NewNop(), component.DefaultApplicationStartInfo(), cfg, factories.Exporters)
|
|
assert.NoError(t, err)
|
|
pipelineProcessors, err := BuildPipelines(zap.NewNop(), component.DefaultApplicationStartInfo(), cfg, allExporters, factories.Processors)
|
|
|
|
assert.NoError(t, err)
|
|
require.NotNil(t, pipelineProcessors)
|
|
|
|
assert.NoError(t, pipelineProcessors.StartProcessors(context.Background(), componenttest.NewNopHost()))
|
|
|
|
processor := pipelineProcessors[cfg.Service.Pipelines[pipelineName]]
|
|
|
|
// Ensure pipeline has its fields correctly populated.
|
|
require.NotNil(t, processor)
|
|
assert.NotNil(t, processor.firstTC)
|
|
assert.Nil(t, processor.firstMC)
|
|
|
|
// Compose the list of created exporters.
|
|
var exporters []*builtExporter
|
|
for _, name := range exporterNames {
|
|
// Ensure exporter is created.
|
|
exp := allExporters[cfg.Exporters[name]]
|
|
require.NotNil(t, exp)
|
|
exporters = append(exporters, exp)
|
|
}
|
|
|
|
// Send TraceData via processor and verify that all exporters of the pipeline receive it.
|
|
|
|
// First check that there are no traces in the exporters yet.
|
|
var exporterConsumers []*testcomponents.ExampleExporterConsumer
|
|
for _, exporter := range exporters {
|
|
expConsumer := exporter.getTraceExporter().(*testcomponents.ExampleExporterConsumer)
|
|
exporterConsumers = append(exporterConsumers, expConsumer)
|
|
require.Equal(t, len(expConsumer.Traces), 0)
|
|
}
|
|
|
|
td := testdata.GenerateTraceDataOneSpan()
|
|
processor.firstTC.(consumer.Traces).ConsumeTraces(context.Background(), td)
|
|
|
|
// Now verify received data.
|
|
for _, expConsumer := range exporterConsumers {
|
|
// Check that the trace is received by exporter.
|
|
require.Equal(t, 1, len(expConsumer.Traces))
|
|
|
|
// Verify that span is successfully delivered.
|
|
assert.EqualValues(t, td, expConsumer.Traces[0])
|
|
}
|
|
|
|
err = pipelineProcessors.ShutdownProcessors(context.Background())
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestBuildPipelines_NotSupportedDataType(t *testing.T) {
|
|
factories := createTestFactories()
|
|
|
|
tests := []struct {
|
|
configFile string
|
|
}{
|
|
{
|
|
configFile: "not_supported_processor_logs.yaml",
|
|
},
|
|
{
|
|
configFile: "not_supported_processor_metrics.yaml",
|
|
},
|
|
{
|
|
configFile: "not_supported_processor_traces.yaml",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.configFile, func(t *testing.T) {
|
|
|
|
cfg, err := configtest.LoadConfigFile(t, path.Join("testdata", test.configFile), factories)
|
|
require.Nil(t, err)
|
|
|
|
allExporters, err := BuildExporters(zap.NewNop(), component.DefaultApplicationStartInfo(), cfg, factories.Exporters)
|
|
assert.NoError(t, err)
|
|
|
|
pipelineProcessors, err := BuildPipelines(zap.NewNop(), component.DefaultApplicationStartInfo(), cfg, allExporters, factories.Processors)
|
|
assert.Error(t, err)
|
|
assert.Zero(t, len(pipelineProcessors))
|
|
})
|
|
}
|
|
}
|