From bd192a55d7d8afa9776bf9e6e8074dcdb0fadfec Mon Sep 17 00:00:00 2001 From: odubajDT <93584209+odubajDT@users.noreply.github.com> Date: Tue, 10 Sep 2024 13:56:21 +0200 Subject: [PATCH] [chore] clean up testbed (#291) Signed-off-by: odubajDT --- internal/testbed/go.mod | 2 +- .../integration/config_examples_test.go | 109 ++++++------- internal/testbed/integration/testutils.go | 57 ------- .../testbed/integration/trace_validation.go | 5 +- internal/testbed/load/tests/log_test.go | 5 - internal/testbed/load/tests/package_test.go | 16 ++ internal/testbed/load/tests/scenarios.go | 4 - internal/testbed/testutil/testutil.go | 147 ------------------ internal/testcommon/go.mod | 2 +- internal/testcommon/idutils/idutils.go | 27 ++++ internal/testcommon/testutil/testutil.go | 42 +++++ 11 files changed, 145 insertions(+), 271 deletions(-) delete mode 100644 internal/testbed/integration/testutils.go create mode 100644 internal/testbed/load/tests/package_test.go delete mode 100644 internal/testbed/testutil/testutil.go create mode 100644 internal/testcommon/idutils/idutils.go diff --git a/internal/testbed/go.mod b/internal/testbed/go.mod index bca83650..59c3f16c 100644 --- a/internal/testbed/go.mod +++ b/internal/testbed/go.mod @@ -9,7 +9,6 @@ require ( github.com/stretchr/testify v1.9.0 go.opentelemetry.io/collector/component v0.108.1 go.opentelemetry.io/collector/consumer/consumertest v0.108.1 - go.opentelemetry.io/collector/featuregate v1.14.1 go.opentelemetry.io/collector/pdata v1.14.1 go.opentelemetry.io/collector/semconv v0.108.1 gopkg.in/yaml.v3 v3.0.1 @@ -169,6 +168,7 @@ require ( go.opentelemetry.io/collector/extension v0.108.1 // indirect go.opentelemetry.io/collector/extension/auth v0.108.1 // indirect go.opentelemetry.io/collector/extension/zpagesextension v0.108.1 // indirect + go.opentelemetry.io/collector/featuregate v1.14.1 // indirect go.opentelemetry.io/collector/internal/globalgates v0.108.1 // indirect go.opentelemetry.io/collector/otelcol v0.108.1 // indirect go.opentelemetry.io/collector/pdata/pprofile v0.108.1 // indirect diff --git a/internal/testbed/integration/config_examples_test.go b/internal/testbed/integration/config_examples_test.go index aaaf9d56..b218c248 100644 --- a/internal/testbed/integration/config_examples_test.go +++ b/internal/testbed/integration/config_examples_test.go @@ -16,14 +16,15 @@ import ( "go.opentelemetry.io/collector/pdata/ptrace" semconv "go.opentelemetry.io/collector/semconv/v1.18.0" - "github.com/Dynatrace/dynatrace-otel-collector/internal/testbed/testutil" + "github.com/Dynatrace/dynatrace-otel-collector/internal/testcommon/idutils" + "github.com/Dynatrace/dynatrace-otel-collector/internal/testcommon/testutil" ) const ConfigExamplesDir = "../../../config_examples" func TestConfigTailSampling(t *testing.T) { // arrange - col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(CollectorTestsExecPath)) + col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(testutil.CollectorTestsExecPath)) cfg, err := os.ReadFile(path.Join(ConfigExamplesDir, "tail_sampling.yaml")) require.NoError(t, err) @@ -31,8 +32,8 @@ func TestConfigTailSampling(t *testing.T) { exporterPort := testutil.GetAvailablePort(t) parsedConfig := string(cfg) - parsedConfig = replaceOtlpGrpcReceiverPort(parsedConfig, receiverPort) - parsedConfig = replaceDynatraceExporterEndpoint(parsedConfig, exporterPort) + parsedConfig = testutil.ReplaceOtlpGrpcReceiverPort(parsedConfig, receiverPort) + parsedConfig = testutil.ReplaceDynatraceExporterEndpoint(parsedConfig, exporterPort) // replaces the sampling decision wait so the test doesn't timeout parsedConfig = strings.Replace(parsedConfig, "decision_wait: 30s", "decision_wait: 10ms", 1) @@ -50,8 +51,8 @@ func TestConfigTailSampling(t *testing.T) { // Error ers ers := actualSpans.AppendEmpty() - ers.SetTraceID(uInt64ToTraceID(0, uint64(1))) - ers.SetSpanID(uInt64ToSpanID(uint64(1))) + ers.SetTraceID(idutils.UInt64ToTraceID(0, uint64(1))) + ers.SetSpanID(idutils.UInt64ToSpanID(uint64(1))) ers.SetName("Error span") ers.SetKind(ptrace.SpanKindServer) ers.Status().SetCode(ptrace.StatusCodeError) @@ -60,8 +61,8 @@ func TestConfigTailSampling(t *testing.T) { // Ok span oks := actualSpans.AppendEmpty() - oks.SetTraceID(uInt64ToTraceID(0, uint64(2))) - oks.SetSpanID(uInt64ToSpanID(uint64(2))) + oks.SetTraceID(idutils.UInt64ToTraceID(0, uint64(2))) + oks.SetSpanID(idutils.UInt64ToSpanID(uint64(2))) oks.SetName("OK span") oks.SetKind(ptrace.SpanKindServer) oks.Status().SetCode(ptrace.StatusCodeOk) @@ -70,8 +71,8 @@ func TestConfigTailSampling(t *testing.T) { // Long-running span lrs := actualSpans.AppendEmpty() - lrs.SetTraceID(uInt64ToTraceID(0, uint64(3))) - lrs.SetSpanID(uInt64ToSpanID(uint64(3))) + lrs.SetTraceID(idutils.UInt64ToTraceID(0, uint64(3))) + lrs.SetSpanID(idutils.UInt64ToSpanID(uint64(3))) lrs.SetName("Long-running span") lrs.SetKind(ptrace.SpanKindServer) lrs.Status().SetCode(ptrace.StatusCodeOk) @@ -120,7 +121,7 @@ func TestConfigTailSampling(t *testing.T) { func TestConfigJaegerGrpc(t *testing.T) { // arrange - col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(CollectorTestsExecPath)) + col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(testutil.CollectorTestsExecPath)) cfg, err := os.ReadFile(path.Join(ConfigExamplesDir, "jaeger.yaml")) require.NoError(t, err) @@ -128,8 +129,8 @@ func TestConfigJaegerGrpc(t *testing.T) { exporterPort := testutil.GetAvailablePort(t) parsedConfig := string(cfg) - parsedConfig = replaceJaegerGrpcReceiverPort(parsedConfig, grpcReceiverPort) - parsedConfig = replaceDynatraceExporterEndpoint(parsedConfig, exporterPort) + parsedConfig = testutil.ReplaceJaegerGrpcReceiverPort(parsedConfig, grpcReceiverPort) + parsedConfig = testutil.ReplaceDynatraceExporterEndpoint(parsedConfig, exporterPort) configCleanup, err := col.PrepareConfig(parsedConfig) require.NoError(t, err) @@ -144,8 +145,8 @@ func TestConfigJaegerGrpc(t *testing.T) { // Error ers ers := actualSpans.AppendEmpty() - ers.SetTraceID(uInt64ToTraceID(0, uint64(1))) - ers.SetSpanID(uInt64ToSpanID(uint64(1))) + ers.SetTraceID(idutils.UInt64ToTraceID(0, uint64(1))) + ers.SetSpanID(idutils.UInt64ToSpanID(uint64(1))) ers.SetName("Error span") ers.SetKind(ptrace.SpanKindServer) ers.Status().SetCode(ptrace.StatusCodeError) @@ -154,8 +155,8 @@ func TestConfigJaegerGrpc(t *testing.T) { // Ok span oks := actualSpans.AppendEmpty() - oks.SetTraceID(uInt64ToTraceID(0, uint64(2))) - oks.SetSpanID(uInt64ToSpanID(uint64(2))) + oks.SetTraceID(idutils.UInt64ToTraceID(0, uint64(2))) + oks.SetSpanID(idutils.UInt64ToSpanID(uint64(2))) oks.SetName("OK span") oks.SetKind(ptrace.SpanKindServer) oks.Status().SetCode(ptrace.StatusCodeOk) @@ -164,8 +165,8 @@ func TestConfigJaegerGrpc(t *testing.T) { // Long-running span lrs := actualSpans.AppendEmpty() - lrs.SetTraceID(uInt64ToTraceID(0, uint64(3))) - lrs.SetSpanID(uInt64ToSpanID(uint64(3))) + lrs.SetTraceID(idutils.UInt64ToTraceID(0, uint64(3))) + lrs.SetSpanID(idutils.UInt64ToSpanID(uint64(3))) lrs.SetName("Long-running span") lrs.SetKind(ptrace.SpanKindServer) lrs.Status().SetCode(ptrace.StatusCodeOk) @@ -213,7 +214,7 @@ func TestConfigJaegerGrpc(t *testing.T) { func TestConfigZipkin(t *testing.T) { // arrange - col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(CollectorTestsExecPath)) + col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(testutil.CollectorTestsExecPath)) cfg, err := os.ReadFile(path.Join(ConfigExamplesDir, "zipkin.yaml")) require.NoError(t, err) @@ -221,8 +222,8 @@ func TestConfigZipkin(t *testing.T) { exporterPort := testutil.GetAvailablePort(t) parsedConfig := string(cfg) - parsedConfig = replaceZipkinReceiverPort(parsedConfig, zipkinReceiverPort) - parsedConfig = replaceDynatraceExporterEndpoint(parsedConfig, exporterPort) + parsedConfig = testutil.ReplaceZipkinReceiverPort(parsedConfig, zipkinReceiverPort) + parsedConfig = testutil.ReplaceDynatraceExporterEndpoint(parsedConfig, exporterPort) configCleanup, err := col.PrepareConfig(parsedConfig) require.NoError(t, err) @@ -237,8 +238,8 @@ func TestConfigZipkin(t *testing.T) { // Error ers ers := actualSpans.AppendEmpty() - ers.SetTraceID(uInt64ToTraceID(0, uint64(1))) - ers.SetSpanID(uInt64ToSpanID(uint64(1))) + ers.SetTraceID(idutils.UInt64ToTraceID(0, uint64(1))) + ers.SetSpanID(idutils.UInt64ToSpanID(uint64(1))) ers.SetName("Error span") ers.SetKind(ptrace.SpanKindServer) ers.Status().SetCode(ptrace.StatusCodeError) @@ -247,8 +248,8 @@ func TestConfigZipkin(t *testing.T) { // Ok span oks := actualSpans.AppendEmpty() - oks.SetTraceID(uInt64ToTraceID(0, uint64(2))) - oks.SetSpanID(uInt64ToSpanID(uint64(2))) + oks.SetTraceID(idutils.UInt64ToTraceID(0, uint64(2))) + oks.SetSpanID(idutils.UInt64ToSpanID(uint64(2))) oks.SetName("OK span") oks.SetKind(ptrace.SpanKindServer) oks.Status().SetCode(ptrace.StatusCodeOk) @@ -257,8 +258,8 @@ func TestConfigZipkin(t *testing.T) { // Long-running span lrs := actualSpans.AppendEmpty() - lrs.SetTraceID(uInt64ToTraceID(0, uint64(3))) - lrs.SetSpanID(uInt64ToSpanID(uint64(3))) + lrs.SetTraceID(idutils.UInt64ToTraceID(0, uint64(3))) + lrs.SetSpanID(idutils.UInt64ToSpanID(uint64(3))) lrs.SetName("Long-running span") lrs.SetKind(ptrace.SpanKindServer) lrs.Status().SetCode(ptrace.StatusCodeOk) @@ -306,7 +307,7 @@ func TestConfigZipkin(t *testing.T) { func TestConfigHistogramTransform(t *testing.T) { // arrange - col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(CollectorTestsExecPath)) + col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(testutil.CollectorTestsExecPath)) cfg, err := os.ReadFile(path.Join(ConfigExamplesDir, "split_histogram.yaml")) require.NoError(t, err) @@ -314,8 +315,8 @@ func TestConfigHistogramTransform(t *testing.T) { exporterPort := testutil.GetAvailablePort(t) parsedConfig := string(cfg) - parsedConfig = replaceOtlpGrpcReceiverPort(parsedConfig, receiverPort) - parsedConfig = replaceDynatraceExporterEndpoint(parsedConfig, exporterPort) + parsedConfig = testutil.ReplaceOtlpGrpcReceiverPort(parsedConfig, receiverPort) + parsedConfig = testutil.ReplaceDynatraceExporterEndpoint(parsedConfig, exporterPort) configCleanup, err := col.PrepareConfig(parsedConfig) require.NoError(t, err) @@ -416,7 +417,7 @@ func TestConfigHistogramTransform(t *testing.T) { func TestConfigMetricsFromPreSampledTraces(t *testing.T) { // arrange - col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(CollectorTestsExecPath)) + col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(testutil.CollectorTestsExecPath)) cfg, err := os.ReadFile(path.Join(ConfigExamplesDir, "spanmetrics.yaml")) require.NoError(t, err) @@ -424,8 +425,8 @@ func TestConfigMetricsFromPreSampledTraces(t *testing.T) { exporterPort := testutil.GetAvailablePort(t) parsedConfig := string(cfg) - parsedConfig = replaceOtlpGrpcReceiverPort(parsedConfig, receiverPort) - parsedConfig = replaceDynatraceExporterEndpoint(parsedConfig, exporterPort) + parsedConfig = testutil.ReplaceOtlpGrpcReceiverPort(parsedConfig, receiverPort) + parsedConfig = testutil.ReplaceDynatraceExporterEndpoint(parsedConfig, exporterPort) // replaces the sampling decision wait so the test doesn't timeout parsedConfig = strings.Replace(parsedConfig, "decision_wait: 30s", "decision_wait: 10ms", 1) @@ -449,8 +450,8 @@ func TestConfigMetricsFromPreSampledTraces(t *testing.T) { // Error ers ers := actualSpans.AppendEmpty() - ers.SetTraceID(uInt64ToTraceID(0, uint64(1))) - ers.SetSpanID(uInt64ToSpanID(uint64(1))) + ers.SetTraceID(idutils.UInt64ToTraceID(0, uint64(1))) + ers.SetSpanID(idutils.UInt64ToSpanID(uint64(1))) ers.SetName("Error span") ers.SetKind(ptrace.SpanKindServer) ers.Status().SetCode(ptrace.StatusCodeError) @@ -459,8 +460,8 @@ func TestConfigMetricsFromPreSampledTraces(t *testing.T) { // Ok span oks := actualSpans.AppendEmpty() - oks.SetTraceID(uInt64ToTraceID(0, uint64(2))) - oks.SetSpanID(uInt64ToSpanID(uint64(2))) + oks.SetTraceID(idutils.UInt64ToTraceID(0, uint64(2))) + oks.SetSpanID(idutils.UInt64ToSpanID(uint64(2))) oks.SetName("OK span") oks.SetKind(ptrace.SpanKindServer) oks.Status().SetCode(ptrace.StatusCodeOk) @@ -469,8 +470,8 @@ func TestConfigMetricsFromPreSampledTraces(t *testing.T) { // Long-running span lrs := actualSpans.AppendEmpty() - lrs.SetTraceID(uInt64ToTraceID(0, uint64(3))) - lrs.SetSpanID(uInt64ToSpanID(uint64(3))) + lrs.SetTraceID(idutils.UInt64ToTraceID(0, uint64(3))) + lrs.SetSpanID(idutils.UInt64ToSpanID(uint64(3))) lrs.SetName("Long-running span") lrs.SetKind(ptrace.SpanKindServer) lrs.Status().SetCode(ptrace.StatusCodeOk) @@ -518,7 +519,7 @@ func TestConfigMetricsFromPreSampledTraces(t *testing.T) { } func TestSyslog_WithF5Receiver(t *testing.T) { - col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(CollectorTestsExecPath)) + col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(testutil.CollectorTestsExecPath)) cfg, err := os.ReadFile(path.Join(ConfigExamplesDir, "syslog.yaml")) require.NoError(t, err) @@ -526,8 +527,8 @@ func TestSyslog_WithF5Receiver(t *testing.T) { exporterPort := testutil.GetAvailablePort(t) parsedConfig := string(cfg) - parsedConfig = replaceSyslogF5ReceiverPort(parsedConfig, syslogReceiverPort) - parsedConfig = replaceDynatraceExporterEndpoint(parsedConfig, exporterPort) + parsedConfig = testutil.ReplaceSyslogF5ReceiverPort(parsedConfig, syslogReceiverPort) + parsedConfig = testutil.ReplaceDynatraceExporterEndpoint(parsedConfig, exporterPort) configCleanup, err := col.PrepareConfig(parsedConfig) require.NoError(t, err) @@ -545,8 +546,8 @@ func TestSyslog_WithF5Receiver(t *testing.T) { actualSimpleLog.Body().SetStr("simple_1") actualSimpleLog.SetTimestamp(pcommon.NewTimestampFromTime(timestamp)) actualSimpleLog.SetObservedTimestamp(pcommon.NewTimestampFromTime(timestamp)) - actualSimpleLog.SetTraceID(uInt64ToTraceID(0, uint64(1))) - actualSimpleLog.SetSpanID(uInt64ToSpanID(uint64(2))) + actualSimpleLog.SetTraceID(idutils.UInt64ToTraceID(0, uint64(1))) + actualSimpleLog.SetSpanID(idutils.UInt64ToSpanID(uint64(2))) actualSimpleLog.Attributes().PutStr("foo", "bar") expectedSimpleLog := expectedLogs.AppendEmpty() @@ -560,8 +561,8 @@ func TestSyslog_WithF5Receiver(t *testing.T) { expectedSimpleLogAttrDevice := expectedSimpleLog.Attributes().PutEmptyMap("device") expectedSimpleLogAttrDevice.PutStr("type", "f5bigip") // Trace ID and Span ID are not auto-mapped to plog by the receiver, so we test for empty IDs - expectedSimpleLog.SetTraceID(uInt64ToTraceID(0, uint64(0))) - expectedSimpleLog.SetSpanID(uInt64ToSpanID(uint64(0))) + expectedSimpleLog.SetTraceID(idutils.UInt64ToTraceID(0, uint64(0))) + expectedSimpleLog.SetSpanID(idutils.UInt64ToSpanID(uint64(0))) expectedSimpleLog.Body().SetStr("<166> " + timestamp.Format(time.RFC3339Nano) + " 127.0.0.1 - - - [trace_id=\"00000000000000000000000000000001\" span_id=\"0000000000000002\" trace_flags=\"0\" foo=\"bar\" ] simple_1") // ObservedTimestamp will be the time the receiver "observes" the log, so we test that the timestamp is after what's defined here. expectedSimpleLog.SetObservedTimestamp(pcommon.NewTimestampFromTime(timestamp)) @@ -605,7 +606,7 @@ func TestSyslog_WithF5Receiver(t *testing.T) { } func TestSyslog_WithHostReceiver(t *testing.T) { - col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(CollectorTestsExecPath)) + col := testbed.NewChildProcessCollector(testbed.WithAgentExePath(testutil.CollectorTestsExecPath)) cfg, err := os.ReadFile(path.Join(ConfigExamplesDir, "syslog.yaml")) require.NoError(t, err) @@ -613,8 +614,8 @@ func TestSyslog_WithHostReceiver(t *testing.T) { exporterPort := testutil.GetAvailablePort(t) parsedConfig := string(cfg) - parsedConfig = replaceSyslogHostReceiverPort(parsedConfig, syslogReceiverPort) - parsedConfig = replaceDynatraceExporterEndpoint(parsedConfig, exporterPort) + parsedConfig = testutil.ReplaceSyslogHostReceiverPort(parsedConfig, syslogReceiverPort) + parsedConfig = testutil.ReplaceDynatraceExporterEndpoint(parsedConfig, exporterPort) configCleanup, err := col.PrepareConfig(parsedConfig) require.NoError(t, err) @@ -632,8 +633,8 @@ func TestSyslog_WithHostReceiver(t *testing.T) { actualSimpleLog.Body().SetStr("simple_1") actualSimpleLog.SetTimestamp(pcommon.NewTimestampFromTime(timestamp)) actualSimpleLog.SetObservedTimestamp(pcommon.NewTimestampFromTime(timestamp)) - actualSimpleLog.SetTraceID(uInt64ToTraceID(0, uint64(1))) - actualSimpleLog.SetSpanID(uInt64ToSpanID(uint64(2))) + actualSimpleLog.SetTraceID(idutils.UInt64ToTraceID(0, uint64(1))) + actualSimpleLog.SetSpanID(idutils.UInt64ToSpanID(uint64(2))) actualSimpleLog.Attributes().PutStr("foo", "bar") expectedSimpleLog := expectedLogs.AppendEmpty() @@ -643,8 +644,8 @@ func TestSyslog_WithHostReceiver(t *testing.T) { expectedSimpleLogAttrDevice := expectedSimpleLog.Attributes().PutEmptyMap("device") expectedSimpleLogAttrDevice.PutStr("type", "ubuntu-syslog") // Trace ID and Span ID are not auto-mapped to plog by the receiver, so we test for empty IDs - expectedSimpleLog.SetTraceID(uInt64ToTraceID(0, uint64(0))) - expectedSimpleLog.SetSpanID(uInt64ToSpanID(uint64(0))) + expectedSimpleLog.SetTraceID(idutils.UInt64ToTraceID(0, uint64(0))) + expectedSimpleLog.SetSpanID(idutils.UInt64ToSpanID(uint64(0))) expectedSimpleLog.Body().SetStr("<166> " + timestamp.Format(time.RFC3339Nano) + " 127.0.0.1 - - - [trace_id=\"00000000000000000000000000000001\" span_id=\"0000000000000002\" trace_flags=\"0\" foo=\"bar\" ] simple_1") // ObservedTimestamp will be the time the receiver "observes" the log, so we test that the timestamp is after what's defined here. expectedSimpleLog.SetObservedTimestamp(pcommon.NewTimestampFromTime(timestamp)) diff --git a/internal/testbed/integration/testutils.go b/internal/testbed/integration/testutils.go deleted file mode 100644 index 3bec89d9..00000000 --- a/internal/testbed/integration/testutils.go +++ /dev/null @@ -1,57 +0,0 @@ -package integration - -import ( - "encoding/binary" - "fmt" - "strconv" - "strings" - - "go.opentelemetry.io/collector/pdata/pcommon" -) - -const CollectorTestsExecPath string = "../../../bin/dynatrace-otel-collector" - -func replaceOtlpGrpcReceiverPort(cfg string, receiverPort int) string { - return strings.Replace(cfg, "4317", strconv.Itoa(receiverPort), 1) -} - -func replaceJaegerGrpcReceiverPort(cfg string, receiverPort int) string { - return strings.Replace(cfg, "14250", strconv.Itoa(receiverPort), 1) -} - -func replaceZipkinReceiverPort(cfg string, receiverPort int) string { - return strings.Replace(cfg, "9411", strconv.Itoa(receiverPort), 1) -} - -func replaceSyslogHostReceiverPort(cfg string, receiverPort int) string { - return strings.Replace(cfg, "54527", strconv.Itoa(receiverPort), 1) -} - -func replaceSyslogF5ReceiverPort(cfg string, receiverPort int) string { - return strings.Replace(cfg, "54526", strconv.Itoa(receiverPort), 1) -} - -func replaceDynatraceExporterEndpoint(cfg string, exporterPort int) string { - r := strings.NewReplacer( - "${env:DT_ENDPOINT}", fmt.Sprintf("http://0.0.0.0:%v", exporterPort), - "${env:API_TOKEN}", "", - ) - return r.Replace(cfg) -} - -func uInt64ToTraceID(high, low uint64) pcommon.TraceID { - traceID := [16]byte{} - binary.BigEndian.PutUint64(traceID[:8], high) - binary.BigEndian.PutUint64(traceID[8:], low) - return traceID -} - -func uInt64ToSpanID(id uint64) pcommon.SpanID { - spanID := [8]byte{} - binary.BigEndian.PutUint64(spanID[:], id) - return pcommon.SpanID(spanID) -} - -func traceIDAndSpanIDToString(traceID pcommon.TraceID, spanID pcommon.SpanID) string { - return fmt.Sprintf("%s-%s", traceID, spanID) -} diff --git a/internal/testbed/integration/trace_validation.go b/internal/testbed/integration/trace_validation.go index f96e2f6d..20fadb72 100644 --- a/internal/testbed/integration/trace_validation.go +++ b/internal/testbed/integration/trace_validation.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/Dynatrace/dynatrace-otel-collector/internal/testcommon/idutils" "github.com/open-telemetry/opentelemetry-collector-contrib/testbed/testbed" "github.com/stretchr/testify/assert" "go.opentelemetry.io/collector/pdata/ptrace" @@ -50,7 +51,7 @@ func assertExpectedSpansAreInReceived(t *testing.T, expected, actual []ptrace.Tr recdSpan := spans.At(k) assert.Contains(t, spansMap, - traceIDAndSpanIDToString(recdSpan.TraceID(), recdSpan.SpanID()), + idutils.TraceIDAndSpanIDToString(recdSpan.TraceID(), recdSpan.SpanID()), fmt.Sprintf("Span with ID: %q not found among expected spans", recdSpan.SpanID())) } } @@ -67,7 +68,7 @@ func populateSpansMap(spansMap map[string]ptrace.Span, tds []ptrace.Traces) { spans := ilss.At(j).Spans() for k := 0; k < spans.Len(); k++ { span := spans.At(k) - key := traceIDAndSpanIDToString(span.TraceID(), span.SpanID()) + key := idutils.TraceIDAndSpanIDToString(span.TraceID(), span.SpanID()) spansMap[key] = span } } diff --git a/internal/testbed/load/tests/log_test.go b/internal/testbed/load/tests/log_test.go index 1c5c638c..81ab4be0 100644 --- a/internal/testbed/load/tests/log_test.go +++ b/internal/testbed/load/tests/log_test.go @@ -7,11 +7,6 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/testbed/testbed" ) -// TestMain is used to initiate setup, execution and tear down of testbed. -func TestMain(m *testing.M) { - testbed.DoTestMain(m, performanceResultsSummary) -} - func TestLog10kDPS(t *testing.T) { tests := []struct { name string diff --git a/internal/testbed/load/tests/package_test.go b/internal/testbed/load/tests/package_test.go new file mode 100644 index 00000000..7f18c439 --- /dev/null +++ b/internal/testbed/load/tests/package_test.go @@ -0,0 +1,16 @@ +package loadtest + +import ( + "testing" + + "github.com/open-telemetry/opentelemetry-collector-contrib/testbed/testbed" +) + +var ( + performanceResultsSummary testbed.TestResultsSummary = &testbed.PerformanceResults{} +) + +// TestMain is used to initiate setup, execution and tear down of testbed. +func TestMain(m *testing.M) { + testbed.DoTestMain(m, performanceResultsSummary) +} diff --git a/internal/testbed/load/tests/scenarios.go b/internal/testbed/load/tests/scenarios.go index 1c4feb05..434f9127 100644 --- a/internal/testbed/load/tests/scenarios.go +++ b/internal/testbed/load/tests/scenarios.go @@ -11,10 +11,6 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/testbed/testbed" ) -var ( - performanceResultsSummary testbed.TestResultsSummary = &testbed.PerformanceResults{} -) - // createConfigYaml creates a collector config file that corresponds to the // sender and receiver used in the test and returns the config file name. // Map of processor names to their configs. Config is in YAML and must be diff --git a/internal/testbed/testutil/testutil.go b/internal/testbed/testutil/testutil.go deleted file mode 100644 index 1f958995..00000000 --- a/internal/testbed/testutil/testutil.go +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package testutil // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/common/testutil" - -import ( - "net" - "os/exec" - "runtime" - "strconv" - "strings" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/featuregate" -) - -type portpair struct { - first string - last string -} - -// GetAvailableLocalAddress finds an available local port on tcp network and returns an endpoint -// describing it. The port is available for opening when this function returns -// provided that there is no race by some other code to grab the same port -// immediately. -func GetAvailableLocalAddress(t testing.TB) string { - return GetAvailableLocalNetworkAddress(t, "tcp") -} - -// GetAvailableLocalNetworkAddress finds an available local port on specified network and returns an endpoint -// describing it. The port is available for opening when this function returns -// provided that there is no race by some other code to grab the same port -// immediately. -func GetAvailableLocalNetworkAddress(t testing.TB, network string) string { - // Retry has been added for windows as net.Listen can return a port that is not actually available. Details can be - // found in https://github.com/docker/for-win/issues/3171 but to summarize Hyper-V will reserve ranges of ports - // which do not show up under the "netstat -ano" but can only be found by - // "netsh interface ipv4 show excludedportrange protocol=tcp". We'll use []exclusions to hold those ranges and - // retry if the port returned by GetAvailableLocalAddress falls in one of those them. - var exclusions []portpair - - portFound := false - if runtime.GOOS == "windows" { - exclusions = getExclusionsList(t) - } - - var endpoint string - for !portFound { - endpoint = findAvailableAddress(t, network) - _, port, err := net.SplitHostPort(endpoint) - require.NoError(t, err) - portFound = true - if runtime.GOOS == "windows" { - for _, pair := range exclusions { - if port >= pair.first && port <= pair.last { - portFound = false - break - } - } - } - } - - return endpoint -} - -func findAvailableAddress(t testing.TB, network string) string { - switch network { - // net.Listen supported network strings - case "tcp", "tcp4", "tcp6", "unix", "unixpacket": - ln, err := net.Listen(network, "localhost:0") - require.NoError(t, err, "Failed to get a free local port") - // There is a possible race if something else takes this same port before - // the test uses it, however, that is unlikely in practice. - defer func() { - assert.NoError(t, ln.Close()) - }() - return ln.Addr().String() - // net.ListenPacket supported network strings - case "udp", "udp4", "udp6", "unixgram": - ln, err := net.ListenPacket(network, "localhost:0") - require.NoError(t, err, "Failed to get a free local port") - // There is a possible race if something else takes this same port before - // the test uses it, however, that is unlikely in practice. - defer func() { - assert.NoError(t, ln.Close()) - }() - return ln.LocalAddr().String() - } - return "" -} - -// Get excluded ports on Windows from the command: netsh interface ipv4 show excludedportrange protocol=tcp -func getExclusionsList(t testing.TB) []portpair { - cmdTCP := exec.Command("netsh", "interface", "ipv4", "show", "excludedportrange", "protocol=tcp") - outputTCP, errTCP := cmdTCP.CombinedOutput() - require.NoError(t, errTCP) - exclusions := createExclusionsList(t, string(outputTCP)) - - cmdUDP := exec.Command("netsh", "interface", "ipv4", "show", "excludedportrange", "protocol=udp") - outputUDP, errUDP := cmdUDP.CombinedOutput() - require.NoError(t, errUDP) - exclusions = append(exclusions, createExclusionsList(t, string(outputUDP))...) - - return exclusions -} - -func createExclusionsList(t testing.TB, exclusionsText string) []portpair { - var exclusions []portpair - - parts := strings.Split(exclusionsText, "--------") - require.Equal(t, len(parts), 3) - portsText := strings.Split(parts[2], "*") - require.Greater(t, len(portsText), 1) // original text may have a suffix like " - Administered port exclusions." - lines := strings.Split(portsText[0], "\n") - for _, line := range lines { - if strings.TrimSpace(line) != "" { - entries := strings.Fields(strings.TrimSpace(line)) - require.Equal(t, len(entries), 2) - pair := portpair{entries[0], entries[1]} - exclusions = append(exclusions, pair) - } - } - return exclusions -} - -// Force the state of feature gate for a test -// usage: defer SetFeatureGateForTest("gateName", true)() -func SetFeatureGateForTest(t testing.TB, gate *featuregate.Gate, enabled bool) func() { - originalValue := gate.IsEnabled() - require.NoError(t, featuregate.GlobalRegistry().Set(gate.ID(), enabled)) - return func() { - require.NoError(t, featuregate.GlobalRegistry().Set(gate.ID(), originalValue)) - } -} - -func GetAvailablePort(t testing.TB) int { - endpoint := GetAvailableLocalAddress(t) - _, port, err := net.SplitHostPort(endpoint) - require.NoError(t, err) - - portInt, err := strconv.Atoi(port) - require.NoError(t, err) - - return portInt -} diff --git a/internal/testcommon/go.mod b/internal/testcommon/go.mod index 68c50271..8d9749eb 100644 --- a/internal/testcommon/go.mod +++ b/internal/testcommon/go.mod @@ -7,6 +7,7 @@ require ( github.com/stretchr/testify v1.9.0 go.opentelemetry.io/collector/component v0.108.1 go.opentelemetry.io/collector/consumer/consumertest v0.108.1 + go.opentelemetry.io/collector/featuregate v1.14.1 go.opentelemetry.io/collector/pdata v1.14.1 go.opentelemetry.io/collector/receiver v0.108.1 go.opentelemetry.io/collector/receiver/otlpreceiver v0.108.1 @@ -87,7 +88,6 @@ require ( go.opentelemetry.io/collector/consumer/consumerprofiles v0.108.1 // indirect go.opentelemetry.io/collector/extension v0.108.1 // indirect go.opentelemetry.io/collector/extension/auth v0.108.1 // indirect - go.opentelemetry.io/collector/featuregate v1.14.1 // indirect go.opentelemetry.io/collector/pdata/pprofile v0.108.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect diff --git a/internal/testcommon/idutils/idutils.go b/internal/testcommon/idutils/idutils.go new file mode 100644 index 00000000..5d590bf4 --- /dev/null +++ b/internal/testcommon/idutils/idutils.go @@ -0,0 +1,27 @@ +package idutils + +import ( + "encoding/binary" + "fmt" + + "go.opentelemetry.io/collector/pdata/pcommon" +) + +// UInt64ToTraceID converts the pair of uint64 representation of a TraceID to pcommon.TraceID. +func UInt64ToTraceID(high, low uint64) pcommon.TraceID { + traceID := [16]byte{} + binary.BigEndian.PutUint64(traceID[:8], high) + binary.BigEndian.PutUint64(traceID[8:], low) + return traceID +} + +// UInt64ToSpanID converts the uint64 representation of a SpanID to pcommon.SpanID. +func UInt64ToSpanID(id uint64) pcommon.SpanID { + spanID := [8]byte{} + binary.BigEndian.PutUint64(spanID[:], id) + return pcommon.SpanID(spanID) +} + +func TraceIDAndSpanIDToString(traceID pcommon.TraceID, spanID pcommon.SpanID) string { + return fmt.Sprintf("%s-%s", traceID, spanID) +} diff --git a/internal/testcommon/testutil/testutil.go b/internal/testcommon/testutil/testutil.go index 447164de..f20d2ecc 100644 --- a/internal/testcommon/testutil/testutil.go +++ b/internal/testcommon/testutil/testutil.go @@ -1,6 +1,7 @@ package testutil import ( + "fmt" "net" "os/exec" "runtime" @@ -10,6 +11,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/featuregate" ) type portpair struct { @@ -131,3 +133,43 @@ func GetAvailablePort(t testing.TB) int { return portInt } + +// Force the state of feature gate for a test +// usage: defer SetFeatureGateForTest("gateName", true)() +func SetFeatureGateForTest(t testing.TB, gate *featuregate.Gate, enabled bool) func() { + originalValue := gate.IsEnabled() + require.NoError(t, featuregate.GlobalRegistry().Set(gate.ID(), enabled)) + return func() { + require.NoError(t, featuregate.GlobalRegistry().Set(gate.ID(), originalValue)) + } +} + +const CollectorTestsExecPath string = "../../../bin/dynatrace-otel-collector" + +func ReplaceOtlpGrpcReceiverPort(cfg string, receiverPort int) string { + return strings.Replace(cfg, "4317", strconv.Itoa(receiverPort), 1) +} + +func ReplaceJaegerGrpcReceiverPort(cfg string, receiverPort int) string { + return strings.Replace(cfg, "14250", strconv.Itoa(receiverPort), 1) +} + +func ReplaceZipkinReceiverPort(cfg string, receiverPort int) string { + return strings.Replace(cfg, "9411", strconv.Itoa(receiverPort), 1) +} + +func ReplaceSyslogHostReceiverPort(cfg string, receiverPort int) string { + return strings.Replace(cfg, "54527", strconv.Itoa(receiverPort), 1) +} + +func ReplaceSyslogF5ReceiverPort(cfg string, receiverPort int) string { + return strings.Replace(cfg, "54526", strconv.Itoa(receiverPort), 1) +} + +func ReplaceDynatraceExporterEndpoint(cfg string, exporterPort int) string { + r := strings.NewReplacer( + "${env:DT_ENDPOINT}", fmt.Sprintf("http://0.0.0.0:%v", exporterPort), + "${env:API_TOKEN}", "", + ) + return r.Replace(cfg) +}