diff --git a/model/ids.go b/model/ids.go index f911a7beb0e..5bf93dc43be 100644 --- a/model/ids.go +++ b/model/ids.go @@ -156,6 +156,13 @@ func (t *TraceID) ToOTELTraceID() pcommon.TraceID { return traceID } +func TraceIDFromOTEL(traceID pcommon.TraceID) TraceID { + return TraceID{ + High: binary.BigEndian.Uint64(traceID[:traceIDShortBytesLen]), + Low: binary.BigEndian.Uint64(traceID[traceIDShortBytesLen:]), + } +} + // ------- SpanID ------- // NewSpanID creates a new SpanID from a 64bit unsigned int. diff --git a/model/ids_test.go b/model/ids_test.go index 6bab7614b96..40c6f801a5c 100644 --- a/model/ids_test.go +++ b/model/ids_test.go @@ -128,3 +128,12 @@ func TestToOTELTraceID(t *testing.T) { expected := []byte{0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3} require.Equal(t, pcommon.TraceID(expected), otelTraceID) } + +func TestTraceIDFromOTEL(t *testing.T) { + otelTraceID := pcommon.TraceID([]byte{0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3}) + expected := model.TraceID{ + Low: 3, + High: 2, + } + require.Equal(t, expected, model.TraceIDFromOTEL(otelTraceID)) +} diff --git a/storage_v2/factoryadapter/reader.go b/storage_v2/factoryadapter/reader.go index ce6db086daf..85ebddab7e9 100644 --- a/storage_v2/factoryadapter/reader.go +++ b/storage_v2/factoryadapter/reader.go @@ -37,8 +37,13 @@ func NewTraceReader(spanReader spanstore.Reader) *TraceReader { } } -func (*TraceReader) GetTrace(_ context.Context, _ pcommon.TraceID) (ptrace.Traces, error) { - panic("not implemented") +func (tr *TraceReader) GetTrace(ctx context.Context, traceID pcommon.TraceID) (ptrace.Traces, error) { + t, err := tr.spanReader.GetTrace(ctx, model.TraceIDFromOTEL(traceID)) + if err != nil { + return ptrace.NewTraces(), err + } + batch := &model.Batch{Spans: t.GetSpans()} + return model2otel.ProtoToTraces([]*model.Batch{batch}) } func (tr *TraceReader) GetServices(ctx context.Context) ([]string, error) { diff --git a/storage_v2/factoryadapter/reader_test.go b/storage_v2/factoryadapter/reader_test.go index 288f16ccbf2..0559f7e5d94 100644 --- a/storage_v2/factoryadapter/reader_test.go +++ b/storage_v2/factoryadapter/reader_test.go @@ -61,12 +61,53 @@ func TestGetV1Reader_Error(t *testing.T) { require.ErrorIs(t, err, errV1ReaderNotAvailable) } -func TestTraceReader_GetTracePanics(t *testing.T) { - memstore := memory.NewStore() +func TestTraceReader_GetTraceDelegatesSuccessResponse(t *testing.T) { + sr := new(spanStoreMocks.Reader) + modelTrace := &model.Trace{ + Spans: []*model.Span{ + { + TraceID: model.NewTraceID(2, 3), + SpanID: model.SpanID(1), + OperationName: "operation-a", + }, + { + TraceID: model.NewTraceID(2, 3), + SpanID: model.SpanID(2), + OperationName: "operation-b", + }, + }, + } + sr.On("GetTrace", mock.Anything, model.NewTraceID(2, 3)).Return(modelTrace, nil) traceReader := &TraceReader{ - spanReader: memstore, + spanReader: sr, } - require.Panics(t, func() { traceReader.GetTrace(context.Background(), pcommon.NewTraceIDEmpty()) }) + trace, err := traceReader.GetTrace( + context.Background(), + pcommon.TraceID([]byte{0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3}), + ) + require.NoError(t, err) + traceSpans := trace.ResourceSpans().At(0).ScopeSpans().At(0).Spans() + require.EqualValues(t, []byte{0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3}, traceSpans.At(0).TraceID()) + require.EqualValues(t, []byte{0, 0, 0, 0, 0, 0, 0, 1}, traceSpans.At(0).SpanID()) + require.Equal(t, "operation-a", traceSpans.At(0).Name()) + require.EqualValues(t, []byte{0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3}, traceSpans.At(1).TraceID()) + require.EqualValues(t, []byte{0, 0, 0, 0, 0, 0, 0, 2}, traceSpans.At(1).SpanID()) + require.Equal(t, "operation-b", traceSpans.At(1).Name()) +} + +func TestTraceReader_GetTraceErrorResponse(t *testing.T) { + sr := new(spanStoreMocks.Reader) + testErr := errors.New("test error") + sr.On("GetTrace", mock.Anything, mock.Anything).Return(nil, testErr) + traceReader := &TraceReader{ + spanReader: sr, + } + trace, err := traceReader.GetTrace( + context.Background(), + pcommon.TraceID([]byte{0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3}), + ) + require.ErrorIs(t, err, testErr) + require.Equal(t, ptrace.NewTraces(), trace) } func TestTraceReader_GetServicesDelegatesToSpanReader(t *testing.T) {