Skip to content

Commit

Permalink
Test PTracesSeq2ToModel
Browse files Browse the repository at this point in the history
Signed-off-by: Emmanuel Emonueje Ebenezer <eebenezer949@gmail.com>
  • Loading branch information
ekefan committed Dec 25, 2024
1 parent 4727e37 commit ad46425
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 9 deletions.
8 changes: 4 additions & 4 deletions plugin/storage/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func (s *StorageIntegration) testArchiveTrace(t *testing.T) {
return err == nil && len(actual.Spans) == 1
})
require.True(t, found)
CompareTraces(t, &model.Trace{Spans: []*model.Span{expected}}, actual)
v1adapter.CompareTraces(t, &model.Trace{Spans: []*model.Span{expected}}, actual)
}

func (s *StorageIntegration) testGetLargeSpan(t *testing.T) {
Expand All @@ -227,7 +227,7 @@ func (s *StorageIntegration) testGetLargeSpan(t *testing.T) {
})

if !assert.True(t, found) {
CompareTraces(t, expected, actual)
v1adapter.CompareTraces(t, expected, actual)
return
}

Expand Down Expand Up @@ -304,7 +304,7 @@ func (s *StorageIntegration) testGetTrace(t *testing.T) {
return err == nil && len(actual.Spans) == len(expected.Spans)
})
if !assert.True(t, found) {
CompareTraces(t, expected, actual)
v1adapter.CompareTraces(t, expected, actual)
}

t.Run("NotFound error", func(t *testing.T) {
Expand Down Expand Up @@ -345,7 +345,7 @@ func (s *StorageIntegration) testFindTraces(t *testing.T) {
s.skipIfNeeded(t)
expected := expectedTracesPerTestCase[i]
actual := s.findTracesByQuery(t, queryTestCase.Query, expected)
CompareSliceOfTraces(t, expected, actual)
v1adapter.CompareSliceOfTraces(t, expected, actual)
})
}
}
Expand Down
9 changes: 6 additions & 3 deletions storage_v2/v1adapter/ptrace2model.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import (
otel2model "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger"
)

// PTracesSeq2ToModel consumes an otel trace iterator and returns a model trace.
// PTracesSeq2ToModel consumes an iterator seqTrace. When necessary,
// it groups spans from *consecutive* chunks of ptrace.Traces into a single model.Trace
//
// When necessary, it groups chunks of a trace into a single model trace
// Returns nil, and spanstore.ErrTraceNotFound for empty iterators
func PTracesSeq2ToModel(seqTrace iter.Seq2[[]ptrace.Traces, error]) ([]*model.Trace, error) {
var (
err error
Expand Down Expand Up @@ -63,7 +64,9 @@ func modelSpansFromOtelTrace(otelTrace ptrace.Traces) []*model.Span {
batches := otel2model.ProtoFromTraces(otelTrace)
for _, batch := range batches {
for _, span := range batch.Spans {
span.Process = batch.Process
span.Process = &model.Process{}
span.Process.ServiceName = batch.GetProcess().GetServiceName()
span.Process.Tags = batch.GetProcess().GetTags()
spans = append(spans, span)
}
}
Expand Down
149 changes: 149 additions & 0 deletions storage_v2/v1adapter/ptrace2model_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright (c) 2024 The Jaeger Authors.
// SPDX-License-Identifier: Apache-2.0

package v1adapter

import (
"errors"
"testing"
"time"

"go.opentelemetry.io/collector/pdata/ptrace"

"github.com/crossdock/crossdock-go/require"
"github.com/jaegertracing/jaeger/model"
"github.com/jaegertracing/jaeger/pkg/iter"
"github.com/jaegertracing/jaeger/storage/spanstore"
)

func TestPTracesSeq2ToModel_SuccessWithSinglePTraceInSeq(t *testing.T) {
var (
ProcessNoServiceName string = "OTLPResourceNoServiceName"
StartTime time.Time = time.Unix(0, 0) // 1970-01-01T00:00:00Z, matches the default for otel span's start time
)

testCases := []struct {
name string
expectedModelTraces []*model.Trace
seqTrace iter.Seq2[[]ptrace.Traces, error]
expectedErr error
}{
{
name: "seq with one ptrace.Traces",
expectedModelTraces: []*model.Trace{
{
Spans: []*model.Span{
{
TraceID: model.NewTraceID(2, 3),
SpanID: model.NewSpanID(1),
OperationName: "op-success-a",
Process: model.NewProcess(ProcessNoServiceName, nil),
StartTime: StartTime,
},
},
},
},
seqTrace: func(yield func([]ptrace.Traces, error) bool) {
testTrace := ptrace.NewTraces()
rSpans := testTrace.ResourceSpans().AppendEmpty()
sSpans := rSpans.ScopeSpans().AppendEmpty()
spans := sSpans.Spans()

// Add a new span and set attributes
modelTraceID := model.NewTraceID(2, 3)
span1 := spans.AppendEmpty()
span1.SetTraceID(modelTraceID.ToOTELTraceID())
span1.SetName("op-success-a")
span1.SetSpanID(model.NewSpanID(1).ToOTELSpanID())

// Yield the test trace
yield([]ptrace.Traces{testTrace}, nil)
},
expectedErr: nil,
},
{
name: "seq with two chunks of ptrace.Traces",
expectedModelTraces: []*model.Trace{
{
Spans: []*model.Span{
{
TraceID: model.NewTraceID(2, 3),
SpanID: model.NewSpanID(1),
OperationName: "op-two-chunks-a",
Process: model.NewProcess(ProcessNoServiceName, nil),
StartTime: StartTime,
}, {
TraceID: model.NewTraceID(2, 3),
SpanID: model.NewSpanID(2),
OperationName: "op-two-chunks-b",
Process: model.NewProcess(ProcessNoServiceName, nil),
StartTime: StartTime,
},
},
},
},
seqTrace: func(yield func([]ptrace.Traces, error) bool) {
traceChunk1 := ptrace.NewTraces()
rSpans1 := traceChunk1.ResourceSpans().AppendEmpty()
sSpans1 := rSpans1.ScopeSpans().AppendEmpty()
spans1 := sSpans1.Spans()
modelTraceID := model.NewTraceID(2, 3)
span1 := spans1.AppendEmpty()
span1.SetTraceID(modelTraceID.ToOTELTraceID())
span1.SetName("op-two-chunks-a")
span1.SetSpanID(model.NewSpanID(1).ToOTELSpanID())

traceChunk2 := ptrace.NewTraces()
rSpans2 := traceChunk2.ResourceSpans().AppendEmpty()
sSpans2 := rSpans2.ScopeSpans().AppendEmpty()
spans2 := sSpans2.Spans()
span2 := spans2.AppendEmpty()
span2.SetTraceID(modelTraceID.ToOTELTraceID())
span2.SetName("op-two-chunks-b")
span2.SetSpanID(model.NewSpanID(2).ToOTELSpanID())
// Yield the test trace
yield([]ptrace.Traces{traceChunk1, traceChunk2}, nil)
},
expectedErr: nil,
},
{
// a case that occurs when no trace is contained in the iterator
name: "empty seq for ptrace.Traces",
expectedModelTraces: nil,
seqTrace: func(yield func([]ptrace.Traces, error) bool) {
},
expectedErr: spanstore.ErrTraceNotFound,
},
{
name: "seq of one ptrace and one error",
expectedModelTraces: nil,
seqTrace: func(yield func([]ptrace.Traces, error) bool) {
testTrace := ptrace.NewTraces()
rSpans := testTrace.ResourceSpans().AppendEmpty()
sSpans := rSpans.ScopeSpans().AppendEmpty()
spans := sSpans.Spans()

modelTraceID := model.NewTraceID(2, 3)
span1 := spans.AppendEmpty()
span1.SetTraceID(modelTraceID.ToOTELTraceID())
span1.SetName("op-error-a")
span1.SetSpanID(model.NewSpanID(1).ToOTELSpanID())

// Yield the test trace
if !yield([]ptrace.Traces{testTrace}, nil) {
return
}
yield(nil, errors.New("unexpected-op-err"))
},
expectedErr: errors.New("unexpected-op-err"),
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
actualTraces, err := PTracesSeq2ToModel(tc.seqTrace)
require.Equal(t, tc.expectedErr, err)
CompareSliceOfTraces(t, tc.expectedModelTraces, actualTraces)
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Copyright (c) 2017 Uber Technologies, Inc.
// SPDX-License-Identifier: Apache-2.0

package integration
package v1adapter

import (
"encoding/json"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2024 The Jaeger Authors.
// SPDX-License-Identifier: Apache-2.0

package integration
package v1adapter

import (
"testing"
Expand Down

0 comments on commit ad46425

Please sign in to comment.