diff --git a/test/e2e/traces_service_name_test.go b/test/e2e/traces_service_name_test.go index 792db7ac8..f304cbe63 100644 --- a/test/e2e/traces_service_name_test.go +++ b/test/e2e/traces_service_name_test.go @@ -77,10 +77,10 @@ var _ = Describe(suite.ID(), Label(suite.LabelTraces), func() { g.Expect(err).NotTo(HaveOccurred()) g.Expect(resp).To(HaveHTTPStatus(http.StatusOK)) g.Expect(resp).To(HaveHTTPBody( - ContainTd(SatisfyAll( - ContainResourceAttrs(HaveKeyWithValue("service.name", expectedServiceName)), - ContainResourceAttrs(HaveKeyWithValue("k8s.pod.name", ContainSubstring(givenPodPrefix))), - )), + HaveFlatTraces(ContainElement(SatisfyAll( + HaveResourceAttributes(HaveKeyWithValue("service.name", expectedServiceName)), + HaveResourceAttributes(HaveKeyWithValue("k8s.pod.name", ContainSubstring(givenPodPrefix))), + ))), )) }, periodic.TelemetryEventuallyTimeout, periodic.TelemetryInterval).Should(Succeed()) } @@ -132,11 +132,11 @@ var _ = Describe(suite.ID(), Label(suite.LabelTraces), func() { resp, err := proxyClient.Get(backendExportURL) g.Expect(err).NotTo(HaveOccurred()) g.Expect(resp).To(HaveHTTPStatus(http.StatusOK)) - g.Expect(resp).To(HaveHTTPBody( - Not(ContainTd( - ContainResourceAttrs(HaveKey(ContainSubstring("kyma"))), + g.Expect(resp).To(HaveHTTPBody(HaveFlatTraces( + Not(ContainElement( + HaveResourceAttributes(HaveKey(ContainSubstring("kyma"))), )), - )) + ))) }, periodic.EventuallyTimeout, periodic.TelemetryInterval).Should(Succeed()) }) }) diff --git a/test/integration/istio/traces_test.go b/test/integration/istio/traces_test.go index c799352a2..fb3c9f441 100644 --- a/test/integration/istio/traces_test.go +++ b/test/integration/istio/traces_test.go @@ -194,11 +194,11 @@ func verifyIstioSpans(backendURL, namespace string) { g.Expect(err).NotTo(HaveOccurred()) g.Expect(resp).To(HaveHTTPStatus(http.StatusOK)) - g.Expect(resp).To(HaveHTTPBody(ContainTd(SatisfyAll( + g.Expect(resp).To(HaveHTTPBody(HaveFlatTraces(ContainElement(SatisfyAll( // Identify istio-proxy traces by component=proxy attribute - ContainSpan(WithSpanAttrs(HaveKeyWithValue("component", "proxy"))), - ContainSpan(WithSpanAttrs(HaveKeyWithValue("istio.namespace", namespace))), - )))) + HaveSpanAttributes(HaveKeyWithValue("component", "proxy")), + HaveSpanAttributes(HaveKeyWithValue("istio.namespace", namespace)), + ))))) }, periodic.TelemetryEventuallyTimeout, periodic.TelemetryInterval).Should(Succeed()) } @@ -207,13 +207,12 @@ func verifyCustomIstiofiedAppSpans(backendURL, name, namespace string) { resp, err := proxyClient.Get(backendURL) g.Expect(err).NotTo(HaveOccurred()) g.Expect(resp).To(HaveHTTPStatus(http.StatusOK)) - - g.Expect(resp).To(HaveHTTPBody(ContainTd(SatisfyAll( + g.Expect(resp).To(HaveHTTPBody(HaveFlatTraces(ContainElement(SatisfyAll( // Identify sample app by serviceName attribute - ContainResourceAttrs(HaveKeyWithValue("service.name", "monitoring-custom-metrics")), - ContainResourceAttrs(HaveKeyWithValue("k8s.pod.name", name)), - ContainResourceAttrs(HaveKeyWithValue("k8s.namespace.name", namespace)), - )))) + HaveResourceAttributes(HaveKeyWithValue("service.name", "monitoring-custom-metrics")), + HaveResourceAttributes(HaveKeyWithValue("k8s.pod.name", name)), + HaveResourceAttributes(HaveKeyWithValue("k8s.namespace.name", namespace)), + ))))) }, periodic.TelemetryEventuallyTimeout, periodic.TelemetryInterval).Should(Succeed()) } @@ -222,11 +221,11 @@ func verifyCustomAppSpans(backendURL, name, namespace string) { resp, err := proxyClient.Get(backendURL) g.Expect(err).NotTo(HaveOccurred()) g.Expect(resp).To(HaveHTTPStatus(http.StatusOK)) - g.Expect(resp).To(HaveHTTPBody(ContainTd(SatisfyAll( + g.Expect(resp).To(HaveHTTPBody(HaveFlatTraces(ContainElement(SatisfyAll( // Identify sample app by serviceName attribute - ContainResourceAttrs(HaveKeyWithValue("service.name", "monitoring-custom-metrics")), - ContainResourceAttrs(HaveKeyWithValue("k8s.pod.name", name)), - ContainResourceAttrs(HaveKeyWithValue("k8s.namespace.name", namespace)), - )))) + HaveResourceAttributes(HaveKeyWithValue("service.name", "monitoring-custom-metrics")), + HaveResourceAttributes(HaveKeyWithValue("k8s.pod.name", name)), + HaveResourceAttributes(HaveKeyWithValue("k8s.namespace.name", namespace)), + ))))) }, periodic.TelemetryEventuallyTimeout, periodic.TelemetryInterval).Should(Succeed()) } diff --git a/test/testkit/assert/traces.go b/test/testkit/assert/traces.go index 1f3449506..0ff721f56 100644 --- a/test/testkit/assert/traces.go +++ b/test/testkit/assert/traces.go @@ -26,7 +26,7 @@ func TracesFromNamespaceDelivered(proxyClient *apiserverproxy.Client, backendExp g.Expect(err).NotTo(HaveOccurred()) g.Expect(resp).To(HaveHTTPStatus(http.StatusOK)) g.Expect(resp).To(HaveHTTPBody( - ContainTd(ContainResourceAttrs(HaveKeyWithValue("k8s.namespace.name", namespace))), + HaveFlatTraces(ContainElement(HaveResourceAttributes(HaveKeyWithValue("k8s.namespace.name", namespace)))), )) err = resp.Body.Close() g.Expect(err).NotTo(HaveOccurred()) @@ -39,7 +39,7 @@ func TracesFromNamespacesNotDelivered(proxyClient *apiserverproxy.Client, backen g.Expect(err).NotTo(HaveOccurred()) g.Expect(resp).To(HaveHTTPStatus(http.StatusOK)) g.Expect(resp).To(HaveHTTPBody( - Not(ContainTd(ContainResourceAttrs(HaveKeyWithValue("k8s.namespace.name", BeElementOf(namespaces))))), + HaveFlatTraces(Not(ContainElement(HaveResourceAttributes(HaveKeyWithValue("k8s.namespace.name", BeElementOf(namespaces)))))), )) err = resp.Body.Close() g.Expect(err).NotTo(HaveOccurred()) diff --git a/test/testkit/matchers/metric/metric_matchers.go b/test/testkit/matchers/metric/metric_matchers.go index 6d29e6af0..ebb95c2a8 100644 --- a/test/testkit/matchers/metric/metric_matchers.go +++ b/test/testkit/matchers/metric/metric_matchers.go @@ -16,7 +16,7 @@ func HaveFlatMetrics(matcher types.GomegaMatcher) types.GomegaMatcher { return gomega.WithTransform(func(jsonMetrics []byte) ([]FlatMetric, error) { mds, err := unmarshalMetrics(jsonMetrics) if err != nil { - return nil, fmt.Errorf("WithMds requires a valid OTLP JSON document: %w", err) + return nil, fmt.Errorf("HaveFlatMetrics requires a valid OTLP JSON document: %w", err) } fm := flattenAllMetrics(mds) diff --git a/test/testkit/matchers/metric/metric_matchers_test.go b/test/testkit/matchers/metric/metric_matchers_test.go index 18e6b87a0..0d5fe5b64 100644 --- a/test/testkit/matchers/metric/metric_matchers_test.go +++ b/test/testkit/matchers/metric/metric_matchers_test.go @@ -9,7 +9,7 @@ import ( "go.opentelemetry.io/collector/pdata/pmetric" ) -var fmdps = []FlatMetric{ +var fms = []FlatMetric{ { Name: "container.cpu.time", Description: "time of container cpu", @@ -54,7 +54,7 @@ var _ = Describe("HaveFlatMetrics", func() { Expect(success).Should(BeFalse()) }) - It("should return a FlatMetricDataPoints structure", func() { + It("should return a FlatMetric struct", func() { md := pmetric.NewMetrics() rm := md.ResourceMetrics().AppendEmpty() @@ -79,37 +79,37 @@ var _ = Describe("HaveFlatMetrics", func() { pt.SetDoubleValue(1.5) pt.Attributes().PutStr("foo", "bar") - Expect(mustMarshalMetrics(md)).Should(HaveFlatMetrics(ContainElement(fmdps[0]))) + Expect(mustMarshalMetrics(md)).Should(HaveFlatMetrics(ContainElement(fms[0]))) }) }) var _ = Describe("HaveUniqueNames", func() { It("should return unique names", func() { - Expect(fmdps).Should(HaveUniqueNames(ConsistOf("container.cpu.time", "container.cpu.usage"))) + Expect(fms).Should(HaveUniqueNames(ConsistOf("container.cpu.time", "container.cpu.usage"))) }) }) var _ = Describe("HaveResourceAttributes", func() { It("should have the specified key", func() { - Expect(fmdps).Should(ContainElement(HaveResourceAttributes(HaveKey("k8s.cluster.name")))) + Expect(fms).Should(ContainElement(HaveResourceAttributes(HaveKey("k8s.cluster.name")))) }) }) var _ = Describe("HaveName", func() { It("should return the correct name", func() { - Expect(fmdps).Should(ContainElement(HaveName(ContainSubstring("container")))) + Expect(fms).Should(ContainElement(HaveName(ContainSubstring("container")))) }) }) var _ = Describe("HaveType", func() { It("should return the correct type", func() { - Expect(fmdps).Should(ContainElement(HaveType(Equal(pmetric.MetricTypeGauge.String())))) + Expect(fms).Should(ContainElement(HaveType(Equal(pmetric.MetricTypeGauge.String())))) }) }) var _ = Describe("HaveMetricAttributes", func() { It("should have the specified key", func() { - Expect(fmdps).Should( + Expect(fms).Should( ContainElement(HaveMetricAttributes(HaveKey("foo"))), ) }) @@ -117,19 +117,19 @@ var _ = Describe("HaveMetricAttributes", func() { var _ = Describe("HaveScopeName", func() { It("should contain the specified string", func() { - Expect(fmdps).Should(ContainElement(HaveScopeName(ContainSubstring("container")))) + Expect(fms).Should(ContainElement(HaveScopeName(ContainSubstring("container")))) }) }) var _ = Describe("HaveScopeVersion", func() { It("should contain the specified version", func() { - Expect(fmdps).Should(ContainElement(HaveScopeVersion(ContainSubstring("1.0")))) + Expect(fms).Should(ContainElement(HaveScopeVersion(ContainSubstring("1.0")))) }) }) var _ = Describe("HaveKeys", func() { It("should have all the keys within the specified list", func() { - Expect(fmdps).Should(ContainElement(HaveResourceAttributes(HaveKeys(ContainElements("k8s.cluster.name", "k8s.deployment.name"))))) + Expect(fms).Should(ContainElement(HaveResourceAttributes(HaveKeys(ContainElements("k8s.cluster.name", "k8s.deployment.name"))))) }) }) diff --git a/test/testkit/matchers/trace/ptrace_utils.go b/test/testkit/matchers/trace/ptrace_utils.go index 4f5237e47..f180d11d5 100644 --- a/test/testkit/matchers/trace/ptrace_utils.go +++ b/test/testkit/matchers/trace/ptrace_utils.go @@ -1,11 +1,21 @@ package trace import ( + "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/ptrace" "github.com/kyma-project/telemetry-manager/test/testkit/matchers" ) +// FlatTrace holds all needed information about a trace. +// Gomega doesn't handle deeply nested data structure very well and generates large, unreadable diffs when paired with the deeply nested structure of pmetrics. +// +// Introducing a go struct with a flat data structure by extracting necessary information from different levels of ptraces makes accessing the information easier than using ptrace.Traces directly and improves the readability of the test output logs. +type FlatTrace struct { + Name string + ResourceAttributes, SpanAttributes map[string]string +} + func unmarshalTraces(jsonlMetrics []byte) ([]ptrace.Traces, error) { return matchers.UnmarshalSignals[ptrace.Traces](jsonlMetrics, func(buf []byte) (ptrace.Traces, error) { var unmarshaler ptrace.JSONUnmarshaler @@ -13,18 +23,45 @@ func unmarshalTraces(jsonlMetrics []byte) ([]ptrace.Traces, error) { }) } -func getSpans(td ptrace.Traces) []ptrace.Span { - var spans []ptrace.Span +// flattenAllTraces flattens an array of ptrace.Traces to a slice of FlatTrace. +// It converts the deeply nested ptrace.Traces data structure to a flat struct, to make it more readable in the test output logs. +func flattenAllTraces(tds []ptrace.Traces) []FlatTrace { + var flatTraces []FlatTrace + + for _, td := range tds { + flatTraces = append(flatTraces, flattenTraces(td)...) + } + return flatTraces +} + +// flattenTraces converts a single ptrace.Traces to a slice of FlatTrace +// It takes relevant information from different levels of pdata and puts it into a FlatTrace go struct. +func flattenTraces(td ptrace.Traces) []FlatTrace { + var flatTraces []FlatTrace for i := 0; i < td.ResourceSpans().Len(); i++ { resourceSpans := td.ResourceSpans().At(i) for j := 0; j < resourceSpans.ScopeSpans().Len(); j++ { scopeSpans := resourceSpans.ScopeSpans().At(j) for k := 0; k < scopeSpans.Spans().Len(); k++ { - spans = append(spans, scopeSpans.Spans().At(k)) + span := scopeSpans.Spans().At(k) + flatTraces = append(flatTraces, FlatTrace{ + Name: span.Name(), + ResourceAttributes: attributeToMap(resourceSpans.Resource().Attributes()), + SpanAttributes: attributeToMap(span.Attributes()), + }) } } } + return flatTraces +} - return spans +// attributeToMap converts pdata.AttributeMap to a map using the string representation of the values. +func attributeToMap(attrs pcommon.Map) map[string]string { + attrMap := make(map[string]string) + attrs.Range(func(k string, v pcommon.Value) bool { + attrMap[k] = v.AsString() + return true + }) + return attrMap } diff --git a/test/testkit/matchers/trace/trace_matchers.go b/test/testkit/matchers/trace/trace_matchers.go index 4c4eca1ce..e7d8d9085 100644 --- a/test/testkit/matchers/trace/trace_matchers.go +++ b/test/testkit/matchers/trace/trace_matchers.go @@ -5,86 +5,38 @@ import ( "github.com/onsi/gomega" "github.com/onsi/gomega/types" - "go.opentelemetry.io/collector/pdata/pcommon" - "go.opentelemetry.io/collector/pdata/ptrace" ) -func WithTds(matcher types.GomegaMatcher) types.GomegaMatcher { - return gomega.WithTransform(func(jsonlTraces []byte) ([]ptrace.Traces, error) { - tds, err := unmarshalTraces(jsonlTraces) +func HaveFlatTraces(matcher types.GomegaMatcher) types.GomegaMatcher { + return gomega.WithTransform(func(jsonTraces []byte) ([]FlatTrace, error) { + tds, err := unmarshalTraces(jsonTraces) if err != nil { - return nil, fmt.Errorf("WithTds requires a valid OTLP JSON document: %w", err) + return nil, fmt.Errorf("HaveFlatTraces requires a valid OTLP JSON document: %w", err) } - return tds, nil + ft := flattenAllTraces(tds) + return ft, nil }, matcher) -} - -// ContainTd is an alias for WithTds(gomega.ContainElement()). -func ContainTd(matcher types.GomegaMatcher) types.GomegaMatcher { - return WithTds(gomega.ContainElement(matcher)) -} - -// ConsistOfTds is an alias for WithTds(gomega.ConsistOf()). -func ConsistOfTds(matcher types.GomegaMatcher) types.GomegaMatcher { - return WithTds(gomega.ConsistOf(matcher)) -} - -func WithResourceAttrs(matcher types.GomegaMatcher) types.GomegaMatcher { - return gomega.WithTransform(func(td ptrace.Traces) ([]map[string]any, error) { - var rawAttrs []map[string]any - for i := 0; i < td.ResourceSpans().Len(); i++ { - rawAttrs = append(rawAttrs, td.ResourceSpans().At(i).Resource().Attributes().AsRaw()) - } - return rawAttrs, nil - }, matcher) -} - -// ContainResourceAttrs is an alias for WithResourceAttrs(gomega.ContainElement()). -func ContainResourceAttrs(matcher types.GomegaMatcher) types.GomegaMatcher { - return WithResourceAttrs(gomega.ContainElement(matcher)) -} - -func WithSpans(matcher types.GomegaMatcher) types.GomegaMatcher { - return gomega.WithTransform(func(td ptrace.Traces) ([]ptrace.Span, error) { - return getSpans(td), nil - }, matcher) -} - -// ContainSpan is an alias for WithSpans(gomega.ContainElement()). -func ContainSpan(matcher types.GomegaMatcher) types.GomegaMatcher { - return WithSpans(gomega.ContainElement(matcher)) -} -// ConsistOfSpans is an alias for WithSpans(gomega.ConsistOf()). -func ConsistOfSpans(matcher types.GomegaMatcher) types.GomegaMatcher { - return WithSpans(gomega.ConsistOf(matcher)) } -func WithTraceID(matcher types.GomegaMatcher) types.GomegaMatcher { - return gomega.WithTransform(func(s ptrace.Span) pcommon.TraceID { - return s.TraceID() - }, matcher) -} - -func WithSpanIDs(matcher types.GomegaMatcher) types.GomegaMatcher { - return gomega.WithTransform(func(spans []ptrace.Span) []pcommon.SpanID { - var spansIDs []pcommon.SpanID - for _, span := range spans { - spansIDs = append(spansIDs, span.SpanID()) - } - return spansIDs +// HaveName extracts name from FlatTrace and applies the matcher to it. +func HaveName(matcher types.GomegaMatcher) types.GomegaMatcher { + return gomega.WithTransform(func(ft FlatTrace) string { + return ft.Name }, matcher) } -func WithSpanID(matcher types.GomegaMatcher) types.GomegaMatcher { - return gomega.WithTransform(func(s ptrace.Span) pcommon.SpanID { - return s.SpanID() +// HaveResourceAttributes extracts resource attributes from FlatTrace and applies the matcher to them. +func HaveResourceAttributes(matcher types.GomegaMatcher) types.GomegaMatcher { + return gomega.WithTransform(func(ft FlatTrace) map[string]string { + return ft.ResourceAttributes }, matcher) } -func WithSpanAttrs(matcher types.GomegaMatcher) types.GomegaMatcher { - return gomega.WithTransform(func(s ptrace.Span) map[string]any { - return s.Attributes().AsRaw() +// HaveSpanAttributes extracts span attributes from FlatTrace and applies the matcher to them. +func HaveSpanAttributes(matcher types.GomegaMatcher) types.GomegaMatcher { + return gomega.WithTransform(func(ft FlatTrace) map[string]string { + return ft.SpanAttributes }, matcher) } diff --git a/test/testkit/matchers/trace/trace_matchers_test.go b/test/testkit/matchers/trace/trace_matchers_test.go index baa184082..6c0c93903 100644 --- a/test/testkit/matchers/trace/trace_matchers_test.go +++ b/test/testkit/matchers/trace/trace_matchers_test.go @@ -1,114 +1,102 @@ package trace import ( - crand "crypto/rand" - "encoding/binary" - "math/rand" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/ptrace" ) -var _ = Describe("WithTds", func() { +var fts = []FlatTrace{ + { + Name: "ingress", + ResourceAttributes: map[string]string{ + "service.name": "backend", + "k8s.pod.ip": "10.42.1.76", + "k8s.deployment.name": "backend", + }, + SpanAttributes: map[string]string{ + "response_size": "31", + "upstream_cluster.name": "inbound|4317||", + "istio.canonical_service": "backend", + }, + }, + { + Name: "ingress-2", + ResourceAttributes: map[string]string{ + "service.name": "monitoring-custom-metrics", + "k8s.pod.ip": "10.42.1.73", + "k8s.deployment.name": "istio", + }, + SpanAttributes: map[string]string{ + "response_size": "32", + "upstream_cluster.name": "inbound|4318||", + "istio.canonical_service": "istio", + }, + }, +} + +var _ = Describe("HaveFlatTraces", func() { It("should apply matcher to valid trace data", func() { td := ptrace.NewTraces() - Expect(mustMarshalTraces(td)).Should(WithTds(ContainElements())) + Expect(mustMarshalTraces(td)).Should(HaveFlatTraces(ContainElements())) }) It("should fail when given empty byte slice", func() { - Expect([]byte{}).Should(WithTds(BeEmpty())) + Expect([]byte{}).Should(HaveFlatTraces(BeEmpty())) }) It("should return error for nil input", func() { - success, err := WithTds(BeEmpty()).Match(nil) + success, err := HaveFlatTraces(BeEmpty()).Match(nil) Expect(err).Should(HaveOccurred()) Expect(success).Should(BeFalse()) }) It("should return error for invalid input type", func() { - success, err := WithTds(BeEmpty()).Match(struct{}{}) + success, err := HaveFlatTraces(BeEmpty()).Match(struct{}{}) Expect(err).Should(HaveOccurred()) Expect(success).Should(BeFalse()) }) -}) - -var _ = Describe("WithResourceAttrs", func() { - It("should apply matcher", func() { - td := ptrace.NewTraces() - rm := td.ResourceSpans().AppendEmpty() - attrs := rm.Resource().Attributes() - attrs.PutStr("k8s.cluster.name", "cluster-01") - attrs.PutStr("k8s.deployment.name", "nginx") - - Expect(mustMarshalTraces(td)).Should(ContainTd(WithResourceAttrs(ContainElement(HaveKey("k8s.cluster.name"))))) - }) -}) -var _ = Describe("WithSpans", func() { - It("should apply matcher", func() { + It("should return a FlatTrace struct", func() { td := ptrace.NewTraces() - rs := td.ResourceSpans().AppendEmpty() - spans := rs.ScopeSpans().AppendEmpty().Spans() - spans.AppendEmpty() - spans.AppendEmpty() + //set resource attributes + rt := td.ResourceSpans().AppendEmpty() + attrs := rt.Resource().Attributes() + attrs.PutStr("service.name", "backend") + attrs.PutStr("k8s.pod.ip", "10.42.1.76") + attrs.PutStr("k8s.deployment.name", "backend") - Expect(mustMarshalTraces(td)).Should(ContainTd(WithSpans(HaveLen(2)))) - }) -}) + scope := rt.ScopeSpans().AppendEmpty() -var _ = Describe("WithTraceID", func() { - It("should apply matcher", func() { - td := ptrace.NewTraces() - rs := td.ResourceSpans().AppendEmpty() - spans := rs.ScopeSpans().AppendEmpty().Spans() + //set span name + s := scope.Spans().AppendEmpty() + s.SetName("ingress") - traceID := newTraceID() - spans.AppendEmpty().SetTraceID(traceID) + //set span attributes + s.Attributes().PutStr("response_size", "31") + s.Attributes().PutStr("upstream_cluster.name", "inbound|4317||") + s.Attributes().PutStr("istio.canonical_service", "backend") - Expect(mustMarshalTraces(td)).Should(ContainTd(ContainSpan(WithTraceID(Equal(traceID))))) + Expect(mustMarshalTraces(td)).Should(HaveFlatTraces(ContainElements(fts[0]))) }) }) -var _ = Describe("WithSpanID", func() { +var _ = Describe("HaveName", func() { It("should apply matcher", func() { - td := ptrace.NewTraces() - rs := td.ResourceSpans().AppendEmpty() - spans := rs.ScopeSpans().AppendEmpty().Spans() - - spanID := newSpanID() - spans.AppendEmpty().SetSpanID(spanID) - - Expect(mustMarshalTraces(td)).Should(ContainTd(ContainSpan(WithSpanID(Equal(spanID))))) + Expect(fts).Should(ContainElement(HaveName(Equal("ingress")))) }) }) -var _ = Describe("WithSpanIDs", func() { +var _ = Describe("HaveResourceAttributes", func() { It("should apply matcher", func() { - td := ptrace.NewTraces() - rs := td.ResourceSpans().AppendEmpty() - spans := rs.ScopeSpans().AppendEmpty().Spans() - - spanIDs := []pcommon.SpanID{newSpanID(), newSpanID()} - spans.AppendEmpty().SetSpanID(spanIDs[0]) - spans.AppendEmpty().SetSpanID(spanIDs[1]) - Expect(mustMarshalTraces(td)).Should(ContainTd(WithSpans(WithSpanIDs(ConsistOf(spanIDs))))) + Expect(fts).Should(ContainElement(HaveResourceAttributes(HaveKey("k8s.deployment.name")))) }) }) -var _ = Describe("WithSpanAttrs", func() { +var _ = Describe("HaveSpanAttributes", func() { It("should apply matcher", func() { - td := ptrace.NewTraces() - rs := td.ResourceSpans().AppendEmpty() - spans := rs.ScopeSpans().AppendEmpty().Spans() - - span := spans.AppendEmpty() - attrs := span.Attributes() - attrs.PutStr("color", "red") - - Expect(mustMarshalTraces(td)).Should(ContainTd(ContainSpan(WithSpanAttrs(HaveKey("color"))))) + Expect(fts).Should(ContainElement(HaveSpanAttributes(HaveKey("response_size")))) }) }) @@ -120,22 +108,3 @@ func mustMarshalTraces(td ptrace.Traces) []byte { } return bytes } - -func newSpanID() pcommon.SpanID { - var rngSeed int64 - _ = binary.Read(crand.Reader, binary.LittleEndian, &rngSeed) - randSource := rand.New(rand.NewSource(rngSeed)) //nolint:gosec // random number generator is sufficient. - sid := pcommon.SpanID{} - _, _ = randSource.Read(sid[:]) - return sid -} - -func newTraceID() pcommon.TraceID { - var rngSeed int64 - _ = binary.Read(crand.Reader, binary.LittleEndian, &rngSeed) - randSource := rand.New(rand.NewSource(rngSeed)) //nolint:gosec // random number generator is sufficient. - tid := pcommon.TraceID{} - _, _ = randSource.Read(tid[:]) - - return tid -}