From c87856083e3afa11cd35dbd9cbb8fbda0194fbf4 Mon Sep 17 00:00:00 2001 From: sakulali Date: Wed, 18 Oct 2023 04:57:54 +0800 Subject: [PATCH] [pkg/pdatatest] Ignore span timestamps (#27798) **Description:** Support ignore timestamps in span comparisons for pdatatest. **Link to tracking Issue:** https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/27688 **Testing:** make chlog-validate go test for pkg/pdatatest **Documentation:** Add usage for `ptracetest.IgnoreStartTimestamp()` and `ptracetest.IgnoreEndTimestamp()` --- .../pdatatest-ignore-span-timestamps.yaml | 27 +++++++++++ pkg/pdatatest/README.md | 5 +- pkg/pdatatest/ptracetest/options.go | 46 +++++++++++++++++++ .../testdata/ignore-end-timestamp/actual.yaml | 22 +++++++++ .../ignore-end-timestamp/expected.yaml | 20 ++++++++ .../ignore-start-timestamp/actual.yaml | 22 +++++++++ .../ignore-start-timestamp/expected.yaml | 20 ++++++++ pkg/pdatatest/ptracetest/traces_test.go | 20 ++++++++ 8 files changed, 180 insertions(+), 2 deletions(-) create mode 100755 .chloggen/pdatatest-ignore-span-timestamps.yaml create mode 100644 pkg/pdatatest/ptracetest/testdata/ignore-end-timestamp/actual.yaml create mode 100644 pkg/pdatatest/ptracetest/testdata/ignore-end-timestamp/expected.yaml create mode 100644 pkg/pdatatest/ptracetest/testdata/ignore-start-timestamp/actual.yaml create mode 100644 pkg/pdatatest/ptracetest/testdata/ignore-start-timestamp/expected.yaml diff --git a/.chloggen/pdatatest-ignore-span-timestamps.yaml b/.chloggen/pdatatest-ignore-span-timestamps.yaml new file mode 100755 index 000000000000..d65f66afe883 --- /dev/null +++ b/.chloggen/pdatatest-ignore-span-timestamps.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: pkg/pdatatest + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "support ignore timestamps in span comparisons for pdatatest" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [27688] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [] diff --git a/pkg/pdatatest/README.md b/pkg/pdatatest/README.md index adebe9ca89dd..05a5c4337ef8 100644 --- a/pkg/pdatatest/README.md +++ b/pkg/pdatatest/README.md @@ -24,7 +24,7 @@ func TestMetricsScraper(t *testing.T) { require.NoError(err) require.NoError(t, pmetrictest.CompareMetrics(expectedMetrics, actualMetrics, pmetrictest.IgnoreStartTimestamp(), - pmetrictest.IgnoreTimestamp())))) + pmetrictest.IgnoreTimestamp())) } ``` @@ -59,6 +59,7 @@ func TestTraceProcessor(t *testing.T) { expectedTraces, err := readTraces(filepath.Join("testdata", "traces", "expected.json")) require.NoError(t, err) - require.NoError(t, ptracetest.CompareTraces(expectedTraces, actualTraces)) + require.NoError(t, ptracetest.CompareTraces(expectedTraces, actualTraces, ptracetest.IgnoreStartTimestamp(), + ptracetest.IgnoreEndTimestamp())) } ``` \ No newline at end of file diff --git a/pkg/pdatatest/ptracetest/options.go b/pkg/pdatatest/ptracetest/options.go index 00f84162cd02..57a278ec4dda 100644 --- a/pkg/pdatatest/ptracetest/options.go +++ b/pkg/pdatatest/ptracetest/options.go @@ -5,7 +5,9 @@ package ptracetest // import "github.com/open-telemetry/opentelemetry-collector- import ( "bytes" + "time" + "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/ptrace" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/internal" @@ -126,3 +128,47 @@ func sortSpanSlices(ts ptrace.Traces) { } } } + +// IgnoreStartTimestamp is a CompareTracesOption that clears StartTimestamp fields on all spans. +func IgnoreStartTimestamp() CompareTracesOption { + return compareTracesOptionFunc(func(expected, actual ptrace.Traces) { + now := pcommon.NewTimestampFromTime(time.Now()) + maskStartTimestamp(expected, now) + maskStartTimestamp(actual, now) + }) +} + +func maskStartTimestamp(traces ptrace.Traces, ts pcommon.Timestamp) { + for i := 0; i < traces.ResourceSpans().Len(); i++ { + rs := traces.ResourceSpans().At(i) + for j := 0; j < rs.ScopeSpans().Len(); j++ { + ss := rs.ScopeSpans().At(j) + for k := 0; k < ss.Spans().Len(); k++ { + span := ss.Spans().At(k) + span.SetStartTimestamp(ts) + } + } + } +} + +// IgnoreEndTimestamp is a CompareTracesOption that clears EndTimestamp fields on all spans. +func IgnoreEndTimestamp() CompareTracesOption { + return compareTracesOptionFunc(func(expected, actual ptrace.Traces) { + now := pcommon.NewTimestampFromTime(time.Now()) + maskEndTimestamp(expected, now) + maskEndTimestamp(actual, now) + }) +} + +func maskEndTimestamp(traces ptrace.Traces, ts pcommon.Timestamp) { + for i := 0; i < traces.ResourceSpans().Len(); i++ { + rs := traces.ResourceSpans().At(i) + for j := 0; j < rs.ScopeSpans().Len(); j++ { + ss := rs.ScopeSpans().At(j) + for k := 0; k < ss.Spans().Len(); k++ { + span := ss.Spans().At(k) + span.SetEndTimestamp(ts) + } + } + } +} diff --git a/pkg/pdatatest/ptracetest/testdata/ignore-end-timestamp/actual.yaml b/pkg/pdatatest/ptracetest/testdata/ignore-end-timestamp/actual.yaml new file mode 100644 index 000000000000..d6602fc6fc53 --- /dev/null +++ b/pkg/pdatatest/ptracetest/testdata/ignore-end-timestamp/actual.yaml @@ -0,0 +1,22 @@ +resourceSpans: + - resource: + attributes: + - key: host.name + value: + stringValue: node1 + scopeSpans: + - scope: + name: collector + version: v0.1.0 + spans: + - attributes: + - key: key1 + value: + stringValue: value1 + name: span1 + parentSpanId: "" + spanId: fd0da883bb27cd6b + endTimeUnixNano: "11651379494838206464" + status: {} + traceId: 8c8b1765a7b0acf0b66aa4623fcb7bd5 + diff --git a/pkg/pdatatest/ptracetest/testdata/ignore-end-timestamp/expected.yaml b/pkg/pdatatest/ptracetest/testdata/ignore-end-timestamp/expected.yaml new file mode 100644 index 000000000000..8191dc41f6f8 --- /dev/null +++ b/pkg/pdatatest/ptracetest/testdata/ignore-end-timestamp/expected.yaml @@ -0,0 +1,20 @@ +resourceSpans: + - resource: + attributes: + - key: host.name + value: + stringValue: node1 + scopeSpans: + - scope: + name: collector + version: v0.1.0 + spans: + - attributes: + - key: key1 + value: + stringValue: value1 + name: span1 + parentSpanId: "" + spanId: fd0da883bb27cd6b + status: {} + traceId: 8c8b1765a7b0acf0b66aa4623fcb7bd5 diff --git a/pkg/pdatatest/ptracetest/testdata/ignore-start-timestamp/actual.yaml b/pkg/pdatatest/ptracetest/testdata/ignore-start-timestamp/actual.yaml new file mode 100644 index 000000000000..d87405374e69 --- /dev/null +++ b/pkg/pdatatest/ptracetest/testdata/ignore-start-timestamp/actual.yaml @@ -0,0 +1,22 @@ +resourceSpans: + - resource: + attributes: + - key: host.name + value: + stringValue: node1 + scopeSpans: + - scope: + name: collector + version: v0.1.0 + spans: + - attributes: + - key: key1 + value: + stringValue: value1 + name: span1 + parentSpanId: "" + spanId: fd0da883bb27cd6b + startTimeUnixNano: "11651379494838206464" + status: {} + traceId: 8c8b1765a7b0acf0b66aa4623fcb7bd5 + diff --git a/pkg/pdatatest/ptracetest/testdata/ignore-start-timestamp/expected.yaml b/pkg/pdatatest/ptracetest/testdata/ignore-start-timestamp/expected.yaml new file mode 100644 index 000000000000..8191dc41f6f8 --- /dev/null +++ b/pkg/pdatatest/ptracetest/testdata/ignore-start-timestamp/expected.yaml @@ -0,0 +1,20 @@ +resourceSpans: + - resource: + attributes: + - key: host.name + value: + stringValue: node1 + scopeSpans: + - scope: + name: collector + version: v0.1.0 + spans: + - attributes: + - key: key1 + value: + stringValue: value1 + name: span1 + parentSpanId: "" + spanId: fd0da883bb27cd6b + status: {} + traceId: 8c8b1765a7b0acf0b66aa4623fcb7bd5 diff --git a/pkg/pdatatest/ptracetest/traces_test.go b/pkg/pdatatest/ptracetest/traces_test.go index 2bdc12b6c297..f088d8889bbe 100644 --- a/pkg/pdatatest/ptracetest/traces_test.go +++ b/pkg/pdatatest/ptracetest/traces_test.go @@ -48,6 +48,26 @@ func TestCompareTraces(t *testing.T) { ), withOptions: nil, }, + { + name: "ignore-start-timestamp", + compareOptions: []CompareTracesOption{ + IgnoreStartTimestamp(), + }, + withoutOptions: multierr.Combine( + errors.New("resource \"map[host.name:node1]\": scope \"collector\": span \"span1\": start timestamp doesn't match expected: 11651379494838206464, actual: 0"), + ), + withOptions: nil, + }, + { + name: "ignore-end-timestamp", + compareOptions: []CompareTracesOption{ + IgnoreEndTimestamp(), + }, + withoutOptions: multierr.Combine( + errors.New("resource \"map[host.name:node1]\": scope \"collector\": span \"span1\": end timestamp doesn't match expected: 11651379494838206464, actual: 0"), + ), + withOptions: nil, + }, { name: "resourcespans-amount-unequal", withoutOptions: multierr.Combine(