Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"resourceSpans": [
{
"resource": {
"attributes": [
{
"key": "service.name",
"value": {"stringValue": "otlp-test-service"}
},
{
"key": "service.version",
"value": {"stringValue": "1.0.0"}
},
{
"key": "deployment.environment",
"value": {"stringValue": "test"}
}
]
},
"scopeSpans": [
{
"scope": {
"name": "test-instrumentation-library",
"version": "2.1.0",
"attributes": [
{
"key": "otel.scope.name",
"value": {"stringValue": "custom-tracer"}
},
{
"key": "instrumentation.provider",
"value": {"stringValue": "opentelemetry"}
}
]
},
"spans": [
{
"traceId": "00000000000000000000000000000020",
"spanId": "0000000000000010",
"name": "otlp-scope-test-operation",
"kind": 2,
"startTimeUnixNano": "1485445591639875000",
"endTimeUnixNano": "1485445591739875000",
"attributes": [
{
"key": "http.method",
"value": {"stringValue": "GET"}
},
{
"key": "http.status_code",
"value": {"intValue": "200"}
}
],
"status": {
"code": 0
}
}
]
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"resourceSpans": [
{
"resource": {
"attributes": [
{
"key": "service.name",
"value": {"stringValue": "span-links-service"}
}
]
},
"scopeSpans": [
{
"scope": {
"name": "span-links-test",
"version": "1.0.0",
"attributes": [
{
"key": "otel.scope.test",
"value": {"stringValue": "true"}
}
]
},
"spans": [
{
"traceId": "00000000000000000000000000000040",
"spanId": "0000000000000030",
"name": "parent-span-with-links",
"kind": 1,
"startTimeUnixNano": "1485445591639875000",
"endTimeUnixNano": "1485445591939875000",
"attributes": [],
"links": [
{
"traceId": "00000000000000000000000000000050",
"spanId": "0000000000000040",
"attributes": [
{
"key": "link.type",
"value": {"stringValue": "parent_link"}
}
]
},
{
"traceId": "00000000000000000000000000000060",
"spanId": "0000000000000050",
"attributes": [
{
"key": "link.type",
"value": {"stringValue": "sibling_link"}
}
]
}
],
"status": {
"code": 0
}
}
]
}
]
}
]
}
89 changes: 81 additions & 8 deletions internal/storage/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/ptrace"

"github.com/jaegertracing/jaeger-idl/model/v1"
"github.com/jaegertracing/jaeger/internal/storage/v1/api/samplingstore"
Expand Down Expand Up @@ -368,7 +369,9 @@ func (s *StorageIntegration) testFindTraces(t *testing.T) {
trace, ok := allTraceFixtures[traceFixture]
if !ok {
trace = s.getTraceFixture(t, traceFixture)
s.writeTrace(t, trace)
otelTraces := v1adapter.V1TraceToOtelTrace(trace)
s.writeTrace(t, otelTraces)

allTraceFixtures[traceFixture] = trace
}
expected = append(expected, trace)
Expand Down Expand Up @@ -409,20 +412,21 @@ func (s *StorageIntegration) findTracesByQuery(t *testing.T, query *tracestore.T
return traces
}

func (s *StorageIntegration) writeTrace(t *testing.T, trace *model.Trace) {
t.Logf("%-23s Writing trace with %d spans", time.Now().Format("2006-01-02 15:04:05.999"), len(trace.Spans))
func (s *StorageIntegration) writeTrace(t *testing.T, traces ptrace.Traces) {
spanCount := traces.SpanCount()
t.Logf("%-23s Writing trace with %d spans", time.Now().Format("2006-01-02 15:04:05.999"), spanCount)
ctx, cx := context.WithTimeout(context.Background(), 5*time.Minute)
defer cx()
otelTraces := v1adapter.V1TraceToOtelTrace(trace)
err := s.TraceWriter.WriteTraces(ctx, otelTraces)
err := s.TraceWriter.WriteTraces(ctx, traces)
require.NoError(t, err, "Not expecting error when writing trace to storage")

t.Logf("%-23s Finished writing trace with %d spans", time.Now().Format("2006-01-02 15:04:05.999"), len(trace.Spans))
t.Logf("%-23s Finished writing trace with %d spans", time.Now().Format("2006-01-02 15:04:05.999"), spanCount)
}

func (s *StorageIntegration) loadParseAndWriteExampleTrace(t *testing.T) *model.Trace {
trace := s.getTraceFixture(t, "example_trace")
s.writeTrace(t, trace)
otelTraces := v1adapter.V1TraceToOtelTrace(trace)
s.writeTrace(t, otelTraces)
return trace
}

Expand All @@ -446,7 +450,9 @@ func (s *StorageIntegration) writeLargeTraceWithDuplicateSpanIds(
newSpan.StartTime = newSpan.StartTime.Add(time.Second * time.Duration(i+1))
trace.Spans[i] = newSpan
}
s.writeTrace(t, trace)
// Convert to OTLP for writing
otelTraces := v1adapter.V1TraceToOtelTrace(trace)
s.writeTrace(t, otelTraces)
return trace
}

Expand Down Expand Up @@ -627,6 +633,72 @@ func (s *StorageIntegration) insertThroughput(t *testing.T) {
require.NoError(t, err)
}

// === OTLP v2 API Tests ===

func (s *StorageIntegration) testOTLPScopePreservation(t *testing.T) {
s.skipIfNeeded(t)
defer s.cleanUp(t)

t.Log("Testing OTLP InstrumentationScope preservation through v2 API")

traces := loadOTLPFixture(t, "otlp_scope_attributes")

s.writeTrace(t, traces)

traceID := extractTraceID(t, traces)

var readTraces []*model.Trace
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the new test has old model.Trace? we want to upgrade the tests completely to use otlp traces. if new fixtures are added, why we need to convert them back to old models?

found := s.waitForCondition(t, func(t *testing.T) bool {
iterTraces := s.TraceReader.GetTraces(context.Background(), tracestore.GetTraceParams{TraceID: traceID})
var err error
readTraces, err = v1adapter.V1TracesFromSeq2(iterTraces)
if err != nil {
t.Log(err)
return false
}
return len(readTraces) > 0
})

require.True(t, found, "Failed to retrieve written trace")
require.NotEmpty(t, readTraces, "Should retrieve written trace")

// Convert back to ptrace to validate Scope metadata
retrievedTrace := v1adapter.V1TraceToOtelTrace(readTraces[0])
require.Positive(t, retrievedTrace.ResourceSpans().Len(), "Should have resource spans")

scopeSpans := retrievedTrace.ResourceSpans().At(0).ScopeSpans()
require.Positive(t, scopeSpans.Len(), "Should have scope spans")

scope := scopeSpans.At(0).Scope()
assert.Equal(t, "test-instrumentation-library", scope.Name(), "Scope name should be preserved")
assert.Equal(t, "2.1.0", scope.Version(), "Scope version should be preserved")

t.Log(" OTLP InstrumentationScope metadata preserved successfully")
}

// loadOTLPFixture loads an OTLP trace fixture by name from the fixtures directory.
func loadOTLPFixture(t *testing.T, fixtureName string) ptrace.Traces {
fileName := fmt.Sprintf("fixtures/traces/%s.json", fixtureName)
data, err := fixtures.ReadFile(fileName)
require.NoError(t, err, "Failed to read OTLP fixture %s", fileName)

unmarshaler := &ptrace.JSONUnmarshaler{}
traces, err := unmarshaler.UnmarshalTraces(data)
require.NoError(t, err, "Failed to unmarshal OTLP fixture %s", fixtureName)

return traces
}

// extractTraceID extracts the first trace ID from ptrace.Traces for retrieval testing.
func extractTraceID(t *testing.T, traces ptrace.Traces) pcommon.TraceID {
require.Positive(t, traces.ResourceSpans().Len(), "Trace must have resource spans")
rs := traces.ResourceSpans().At(0)
require.Positive(t, rs.ScopeSpans().Len(), "Resource must have scope spans")
ss := rs.ScopeSpans().At(0)
require.Positive(t, ss.Spans().Len(), "Scope must have spans")
return ss.Spans().At(0).TraceID()
}

// RunAll runs all integration tests
func (s *StorageIntegration) RunAll(t *testing.T) {
s.RunSpanStoreTests(t)
Expand All @@ -643,4 +715,5 @@ func (s *StorageIntegration) RunSpanStoreTests(t *testing.T) {
t.Run("GetLargeTrace", s.testGetLargeTrace)
t.Run("GetTraceWithDuplicateSpans", s.testGetTraceWithDuplicates)
t.Run("FindTraces", s.testFindTraces)
t.Run("OTLPScopePreservation", s.testOTLPScopePreservation)
}
Loading