diff --git a/internal/storage/v2/clickhouse/tracestore/driver_test.go b/internal/storage/v2/clickhouse/tracestore/driver_test.go index 5d0862aeed9..388a30dbdc3 100644 --- a/internal/storage/v2/clickhouse/tracestore/driver_test.go +++ b/internal/storage/v2/clickhouse/tracestore/driver_test.go @@ -6,12 +6,41 @@ package tracestore import ( "context" "errors" + "os" + "path/filepath" + "strings" "testing" "github.com/ClickHouse/clickhouse-go/v2/lib/driver" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +const ( + snapshotLocation = "./snapshots/" +) + +// Snapshots can be regenerated via: +// +// REGENERATE_SNAPSHOTS=true go test -v ./internal/storage/v2/clickhouse/tracestore/... +var regenerateSnapshots = os.Getenv("REGENERATE_SNAPSHOTS") == "true" + +func verifyQuerySnapshot(t *testing.T, query string) { + testName := t.Name() + snapshotFile := filepath.Join(snapshotLocation, testName+".sql") + query = strings.TrimSpace(query) + if regenerateSnapshots { + dir := filepath.Dir(snapshotFile) + if err := os.MkdirAll(dir, 0o755); err != nil { + t.Fatalf("failed to create snapshot directory: %v", err) + } + os.WriteFile(snapshotFile, []byte(query+"\n"), 0o644) + } + snapshot, err := os.ReadFile(snapshotFile) + require.NoError(t, err) + assert.Equal(t, strings.TrimSpace(string(snapshot)), query, "comparing against stored snapshot. Use REGENERATE_SNAPSHOTS=true to rebuild snapshots.") +} + type testBatch struct { driver.Batch t *testing.T @@ -46,13 +75,13 @@ type testDriver struct { t *testing.T rows driver.Rows - expectedQuery string err error batch *testBatch + recordedQuery string } func (t *testDriver) Query(_ context.Context, query string, _ ...any) (driver.Rows, error) { - require.Equal(t.t, t.expectedQuery, query) + t.recordedQuery = query return t.rows, t.err } @@ -109,7 +138,7 @@ func (t *testDriver) PrepareBatch( query string, _ ...driver.PrepareBatchOption, ) (driver.Batch, error) { - require.Equal(t.t, t.expectedQuery, query) + t.recordedQuery = query if t.err != nil { return nil, t.err } diff --git a/internal/storage/v2/clickhouse/tracestore/reader_test.go b/internal/storage/v2/clickhouse/tracestore/reader_test.go index d95136882c9..62b8a8eafb6 100644 --- a/internal/storage/v2/clickhouse/tracestore/reader_test.go +++ b/internal/storage/v2/clickhouse/tracestore/reader_test.go @@ -18,7 +18,6 @@ import ( "github.com/jaegertracing/jaeger/internal/jiter" "github.com/jaegertracing/jaeger/internal/storage/v2/api/tracestore" - "github.com/jaegertracing/jaeger/internal/storage/v2/clickhouse/sql" "github.com/jaegertracing/jaeger/internal/storage/v2/clickhouse/tracestore/dbmodel" ) @@ -27,9 +26,7 @@ var ( DefaultSearchDepth: 100, MaxSearchDepth: 1000, } - testSearchTraceIDsQuery = sql.SearchTraceIDs + " LIMIT ?" - testFindTracesQuery = buildFindTracesQuery(testSearchTraceIDsQuery) - testTraceIDsData = [][]any{ + testTraceIDsData = [][]any{ { traceIDHex1, now.Add(-1 * time.Hour), @@ -183,8 +180,7 @@ func TestGetTraces_Success(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { conn := &testDriver{ - t: t, - expectedQuery: sql.SelectSpansByTraceID, + t: t, rows: &testRows[*dbmodel.SpanRow]{ data: tt.data, scanFn: scanSpanRowFn(), @@ -198,6 +194,7 @@ func TestGetTraces_Success(t *testing.T) { traces, err := jiter.FlattenWithErrors(getTracesIter) require.NoError(t, err) + verifyQuerySnapshot(t, conn.recordedQuery) requireTracesEqual(t, tt.data, traces) }) } @@ -212,17 +209,15 @@ func TestGetTraces_ErrorCases(t *testing.T) { { name: "QueryError", driver: &testDriver{ - t: t, - expectedQuery: sql.SelectSpansByTraceID, - err: assert.AnError, + t: t, + err: assert.AnError, }, expectedErr: "failed to query trace", }, { name: "ScanError", driver: &testDriver{ - t: t, - expectedQuery: sql.SelectSpansByTraceID, + t: t, rows: &testRows[*dbmodel.SpanRow]{ data: singleSpan, scanErr: assert.AnError, @@ -233,8 +228,7 @@ func TestGetTraces_ErrorCases(t *testing.T) { { name: "CloseError", driver: &testDriver{ - t: t, - expectedQuery: sql.SelectSpansByTraceID, + t: t, rows: &testRows[*dbmodel.SpanRow]{ data: singleSpan, scanFn: scanSpanRowFn(), @@ -269,8 +263,7 @@ func TestGetTraces_ScanErrorContinues(t *testing.T) { } conn := &testDriver{ - t: t, - expectedQuery: sql.SelectSpansByTraceID, + t: t, rows: &testRows[*dbmodel.SpanRow]{ data: multipleSpans, scanFn: scanFn, @@ -294,8 +287,7 @@ func TestGetTraces_ScanErrorContinues(t *testing.T) { func TestGetTraces_YieldFalseOnSuccessStopsIteration(t *testing.T) { conn := &testDriver{ - t: t, - expectedQuery: sql.SelectSpansByTraceID, + t: t, rows: &testRows[*dbmodel.SpanRow]{ data: multipleSpans, scanFn: scanSpanRowFn(), @@ -328,8 +320,7 @@ func TestGetServices(t *testing.T) { { name: "successfully returns services", conn: &testDriver{ - t: t, - expectedQuery: sql.SelectServices, + t: t, rows: &testRows[dbmodel.Service]{ data: []dbmodel.Service{ {Name: "serviceA"}, @@ -351,17 +342,15 @@ func TestGetServices(t *testing.T) { { name: "query error", conn: &testDriver{ - t: t, - expectedQuery: sql.SelectServices, - err: assert.AnError, + t: t, + err: assert.AnError, }, expectError: "failed to query services", }, { name: "scan error", conn: &testDriver{ - t: t, - expectedQuery: sql.SelectServices, + t: t, rows: &testRows[dbmodel.Service]{ data: []dbmodel.Service{ {Name: "serviceA"}, @@ -393,6 +382,7 @@ func TestGetServices(t *testing.T) { require.ErrorContains(t, err, test.expectError) } else { require.NoError(t, err) + verifyQuerySnapshot(t, test.conn.recordedQuery) require.Equal(t, test.expected, result) } }) @@ -410,8 +400,7 @@ func TestGetOperations(t *testing.T) { { name: "successfully returns operations for all kinds", conn: &testDriver{ - t: t, - expectedQuery: sql.SelectOperationsAllKinds, + t: t, rows: &testRows[dbmodel.Operation]{ data: []dbmodel.Operation{ {Name: "operationA"}, @@ -446,8 +435,7 @@ func TestGetOperations(t *testing.T) { { name: "successfully returns operations by kind", conn: &testDriver{ - t: t, - expectedQuery: sql.SelectOperationsByKind, + t: t, rows: &testRows[dbmodel.Operation]{ data: []dbmodel.Operation{ {Name: "operationA", SpanKind: "server"}, @@ -486,17 +474,15 @@ func TestGetOperations(t *testing.T) { { name: "query error", conn: &testDriver{ - t: t, - expectedQuery: sql.SelectOperationsAllKinds, - err: assert.AnError, + t: t, + err: assert.AnError, }, expectError: "failed to query operations", }, { name: "scan error", conn: &testDriver{ - t: t, - expectedQuery: sql.SelectOperationsAllKinds, + t: t, rows: &testRows[dbmodel.Operation]{ data: []dbmodel.Operation{ {Name: "operationA"}, @@ -528,6 +514,7 @@ func TestGetOperations(t *testing.T) { require.ErrorContains(t, err, test.expectError) } else { require.NoError(t, err) + verifyQuerySnapshot(t, test.conn.recordedQuery) require.Equal(t, test.expected, result) } }) @@ -552,8 +539,7 @@ func TestFindTraces_Success(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { conn := &testDriver{ - t: t, - expectedQuery: testFindTracesQuery, + t: t, rows: &testRows[*dbmodel.SpanRow]{ data: tt.data, scanFn: scanSpanRowFn(), @@ -567,6 +553,7 @@ func TestFindTraces_Success(t *testing.T) { traces, err := jiter.FlattenWithErrors(findTracesIter) require.NoError(t, err) + verifyQuerySnapshot(t, conn.recordedQuery) requireTracesEqual(t, tt.data, traces) }) } @@ -575,30 +562,6 @@ func TestFindTraces_Success(t *testing.T) { func TestFindTraces_WithFilters(t *testing.T) { conn := &testDriver{ t: t, - expectedQuery: buildFindTracesQuery( - sql.SearchTraceIDs + - " AND s.service_name = ?" + - " AND s.name = ?" + - " AND s.duration >= ?" + - " AND s.duration <= ?" + - " AND s.start_time >= ?" + - " AND s.start_time <= ?" + - " AND (arrayExists((key, value) -> key = ? AND value = ?, s.bool_attributes.key, s.bool_attributes.value)" + - " OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_bool_attributes.key, s.resource_bool_attributes.value))" + - " AND (arrayExists((key, value) -> key = ? AND value = ?, s.double_attributes.key, s.double_attributes.value)" + - " OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_double_attributes.key, s.resource_double_attributes.value))" + - " AND (arrayExists((key, value) -> key = ? AND value = ?, s.int_attributes.key, s.int_attributes.value)" + - " OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_int_attributes.key, s.resource_int_attributes.value))" + - " AND (arrayExists((key, value) -> key = ? AND value = ?, s.str_attributes.key, s.str_attributes.value)" + - " OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_str_attributes.key, s.resource_str_attributes.value))" + - " AND (arrayExists((key, value) -> key = ? AND value = ?, s.complex_attributes.key, s.complex_attributes.value)" + - " OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_complex_attributes.key, s.resource_complex_attributes.value))" + - " AND (arrayExists((key, value) -> key = ? AND value = ?, s.complex_attributes.key, s.complex_attributes.value)" + - " OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_complex_attributes.key, s.resource_complex_attributes.value))" + - " AND (arrayExists((key, value) -> key = ? AND value = ?, s.complex_attributes.key, s.complex_attributes.value)" + - " OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_complex_attributes.key, s.resource_complex_attributes.value))" + - " LIMIT ?", - ), rows: &testRows[*dbmodel.SpanRow]{ data: multipleSpans, scanFn: scanSpanRowFn(), @@ -631,6 +594,7 @@ func TestFindTraces_WithFilters(t *testing.T) { }) traces, err := jiter.FlattenWithErrors(iter) require.NoError(t, err) + verifyQuerySnapshot(t, conn.recordedQuery) requireTracesEqual(t, multipleSpans, traces) } @@ -653,8 +617,7 @@ func TestFindTraces_SearchDepthExceedsMax(t *testing.T) { func TestFindTraces_YieldFalseOnSuccessStopsIteration(t *testing.T) { conn := &testDriver{ - t: t, - expectedQuery: testFindTracesQuery, + t: t, rows: &testRows[*dbmodel.SpanRow]{ data: multipleSpans, scanFn: scanSpanRowFn(), @@ -689,8 +652,7 @@ func TestFindTraces_ScanErrorContinues(t *testing.T) { } conn := &testDriver{ - t: t, - expectedQuery: testFindTracesQuery, + t: t, rows: &testRows[*dbmodel.SpanRow]{ data: multipleSpans, scanFn: scanFn, @@ -721,17 +683,15 @@ func TestFindTraces_ErrorCases(t *testing.T) { { name: "QueryError", driver: &testDriver{ - t: t, - expectedQuery: testFindTracesQuery, - err: assert.AnError, + t: t, + err: assert.AnError, }, expectedErr: "failed to query traces", }, { name: "ScanError", driver: &testDriver{ - t: t, - expectedQuery: testFindTracesQuery, + t: t, rows: &testRows[*dbmodel.SpanRow]{ data: singleSpan, scanErr: assert.AnError, @@ -776,28 +736,6 @@ func TestFindTraces_BuildQueryError(t *testing.T) { func TestFindTraceIDs(t *testing.T) { driver := &testDriver{ t: t, - expectedQuery: sql.SearchTraceIDs + - ` AND s.service_name = ?` + - ` AND s.name = ?` + - ` AND s.duration >= ?` + - ` AND s.duration <= ?` + - ` AND s.start_time >= ?` + - ` AND s.start_time <= ?` + - ` AND (arrayExists((key, value) -> key = ? AND value = ?, s.bool_attributes.key, s.bool_attributes.value)` + - ` OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_bool_attributes.key, s.resource_bool_attributes.value))` + - ` AND (arrayExists((key, value) -> key = ? AND value = ?, s.double_attributes.key, s.double_attributes.value)` + - ` OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_double_attributes.key, s.resource_double_attributes.value))` + - ` AND (arrayExists((key, value) -> key = ? AND value = ?, s.int_attributes.key, s.int_attributes.value)` + - ` OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_int_attributes.key, s.resource_int_attributes.value))` + - ` AND (arrayExists((key, value) -> key = ? AND value = ?, s.str_attributes.key, s.str_attributes.value)` + - ` OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_str_attributes.key, s.resource_str_attributes.value))` + - ` AND (arrayExists((key, value) -> key = ? AND value = ?, s.complex_attributes.key, s.complex_attributes.value)` + - ` OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_complex_attributes.key, s.resource_complex_attributes.value))` + - ` AND (arrayExists((key, value) -> key = ? AND value = ?, s.complex_attributes.key, s.complex_attributes.value)` + - ` OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_complex_attributes.key, s.resource_complex_attributes.value))` + - ` AND (arrayExists((key, value) -> key = ? AND value = ?, s.complex_attributes.key, s.complex_attributes.value)` + - ` OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_complex_attributes.key, s.resource_complex_attributes.value))` + - ` LIMIT ?`, rows: &testRows[[]any]{ data: testTraceIDsData, scanFn: scanTraceIDFn(), @@ -829,6 +767,7 @@ func TestFindTraceIDs(t *testing.T) { }) ids, err := jiter.FlattenWithErrors(iter) require.NoError(t, err) + verifyQuerySnapshot(t, driver.recordedQuery) require.Equal(t, []tracestore.FoundTraceID{ { TraceID: pcommon.TraceID([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), @@ -843,8 +782,7 @@ func TestFindTraceIDs(t *testing.T) { func TestFindTraceIDs_SearchDepthExceedsMax(t *testing.T) { driver := &testDriver{ - t: t, - expectedQuery: testSearchTraceIDsQuery, + t: t, rows: &testRows[[]any]{ data: [][]any{ { @@ -871,8 +809,7 @@ func TestFindTraceIDs_SearchDepthExceedsMax(t *testing.T) { func TestFindTraceIDs_YieldFalseOnSuccessStopsIteration(t *testing.T) { conn := &testDriver{ - t: t, - expectedQuery: testSearchTraceIDsQuery, + t: t, rows: &testRows[[]any]{ data: testTraceIDsData, scanFn: scanTraceIDFn(), @@ -913,8 +850,7 @@ func TestFindTraceIDs_ScanErrorContinues(t *testing.T) { } conn := &testDriver{ - t: t, - expectedQuery: testSearchTraceIDsQuery, + t: t, rows: &testRows[[]any]{ data: testTraceIDsData, scanFn: scanFn, @@ -943,8 +879,7 @@ func TestFindTraceIDs_ScanErrorContinues(t *testing.T) { func TestFindTraceIDs_DecodeErrorContinues(t *testing.T) { conn := &testDriver{ - t: t, - expectedQuery: testSearchTraceIDsQuery, + t: t, rows: &testRows[[]any]{ data: [][]any{ testTraceIDsData[0], @@ -1005,17 +940,15 @@ func TestFindTraceIDs_ErrorCases(t *testing.T) { { name: "QueryError", driver: &testDriver{ - t: t, - expectedQuery: testSearchTraceIDsQuery, - err: assert.AnError, + t: t, + err: assert.AnError, }, expectedErr: "failed to query trace IDs", }, { name: "ScanError", driver: &testDriver{ - t: t, - expectedQuery: testSearchTraceIDsQuery, + t: t, rows: &testRows[[]any]{ data: testTraceIDsData, scanErr: assert.AnError, @@ -1026,8 +959,7 @@ func TestFindTraceIDs_ErrorCases(t *testing.T) { { name: "DecodeError", driver: &testDriver{ - t: t, - expectedQuery: testSearchTraceIDsQuery, + t: t, rows: &testRows[[]any]{ data: [][]any{ { diff --git a/internal/storage/v2/clickhouse/tracestore/snapshots/TestFindTraceIDs.sql b/internal/storage/v2/clickhouse/tracestore/snapshots/TestFindTraceIDs.sql new file mode 100644 index 00000000000..dcb4d75b624 --- /dev/null +++ b/internal/storage/v2/clickhouse/tracestore/snapshots/TestFindTraceIDs.sql @@ -0,0 +1,7 @@ +SELECT DISTINCT + s.trace_id, + t.start, + t.end +FROM spans s +LEFT JOIN trace_id_timestamps t ON s.trace_id = t.trace_id +WHERE 1=1 AND s.service_name = ? AND s.name = ? AND s.duration >= ? AND s.duration <= ? AND s.start_time >= ? AND s.start_time <= ? AND (arrayExists((key, value) -> key = ? AND value = ?, s.bool_attributes.key, s.bool_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_bool_attributes.key, s.resource_bool_attributes.value)) AND (arrayExists((key, value) -> key = ? AND value = ?, s.double_attributes.key, s.double_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_double_attributes.key, s.resource_double_attributes.value)) AND (arrayExists((key, value) -> key = ? AND value = ?, s.int_attributes.key, s.int_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_int_attributes.key, s.resource_int_attributes.value)) AND (arrayExists((key, value) -> key = ? AND value = ?, s.str_attributes.key, s.str_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_str_attributes.key, s.resource_str_attributes.value)) AND (arrayExists((key, value) -> key = ? AND value = ?, s.complex_attributes.key, s.complex_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_complex_attributes.key, s.resource_complex_attributes.value)) AND (arrayExists((key, value) -> key = ? AND value = ?, s.complex_attributes.key, s.complex_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_complex_attributes.key, s.resource_complex_attributes.value)) AND (arrayExists((key, value) -> key = ? AND value = ?, s.complex_attributes.key, s.complex_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_complex_attributes.key, s.resource_complex_attributes.value)) LIMIT ? diff --git a/internal/storage/v2/clickhouse/tracestore/snapshots/TestFindTraces_Success/multiple_spans.sql b/internal/storage/v2/clickhouse/tracestore/snapshots/TestFindTraces_Success/multiple_spans.sql new file mode 100644 index 00000000000..0650df4444c --- /dev/null +++ b/internal/storage/v2/clickhouse/tracestore/snapshots/TestFindTraces_Success/multiple_spans.sql @@ -0,0 +1,79 @@ +SELECT + id, + trace_id, + trace_state, + parent_span_id, + name, + kind, + start_time, + status_code, + status_message, + duration, + bool_attributes.key, + bool_attributes.value, + double_attributes.key, + double_attributes.value, + int_attributes.key, + int_attributes.value, + str_attributes.key, + str_attributes.value, + complex_attributes.key, + complex_attributes.value, + events.name, + events.timestamp, + events.bool_attributes.key, + events.bool_attributes.value, + events.double_attributes.key, + events.double_attributes.value, + events.int_attributes.key, + events.int_attributes.value, + events.str_attributes.key, + events.str_attributes.value, + events.complex_attributes.key, + events.complex_attributes.value, + links.trace_id, + links.span_id, + links.trace_state, + links.bool_attributes.key, + links.bool_attributes.value, + links.double_attributes.key, + links.double_attributes.value, + links.int_attributes.key, + links.int_attributes.value, + links.str_attributes.key, + links.str_attributes.value, + links.complex_attributes.key, + links.complex_attributes.value, + service_name, + resource_bool_attributes.key, + resource_bool_attributes.value, + resource_double_attributes.key, + resource_double_attributes.value, + resource_int_attributes.key, + resource_int_attributes.value, + resource_str_attributes.key, + resource_str_attributes.value, + resource_complex_attributes.key, + resource_complex_attributes.value, + scope_name, + scope_version, + scope_bool_attributes.key, + scope_bool_attributes.value, + scope_double_attributes.key, + scope_double_attributes.value, + scope_int_attributes.key, + scope_int_attributes.value, + scope_str_attributes.key, + scope_str_attributes.value, + scope_complex_attributes.key, + scope_complex_attributes.value +FROM + spans s + WHERE s.trace_id IN (SELECT trace_id FROM ( +SELECT DISTINCT + s.trace_id, + t.start, + t.end +FROM spans s +LEFT JOIN trace_id_timestamps t ON s.trace_id = t.trace_id +WHERE 1=1 LIMIT ?)) ORDER BY s.trace_id diff --git a/internal/storage/v2/clickhouse/tracestore/snapshots/TestFindTraces_Success/single_span.sql b/internal/storage/v2/clickhouse/tracestore/snapshots/TestFindTraces_Success/single_span.sql new file mode 100644 index 00000000000..0650df4444c --- /dev/null +++ b/internal/storage/v2/clickhouse/tracestore/snapshots/TestFindTraces_Success/single_span.sql @@ -0,0 +1,79 @@ +SELECT + id, + trace_id, + trace_state, + parent_span_id, + name, + kind, + start_time, + status_code, + status_message, + duration, + bool_attributes.key, + bool_attributes.value, + double_attributes.key, + double_attributes.value, + int_attributes.key, + int_attributes.value, + str_attributes.key, + str_attributes.value, + complex_attributes.key, + complex_attributes.value, + events.name, + events.timestamp, + events.bool_attributes.key, + events.bool_attributes.value, + events.double_attributes.key, + events.double_attributes.value, + events.int_attributes.key, + events.int_attributes.value, + events.str_attributes.key, + events.str_attributes.value, + events.complex_attributes.key, + events.complex_attributes.value, + links.trace_id, + links.span_id, + links.trace_state, + links.bool_attributes.key, + links.bool_attributes.value, + links.double_attributes.key, + links.double_attributes.value, + links.int_attributes.key, + links.int_attributes.value, + links.str_attributes.key, + links.str_attributes.value, + links.complex_attributes.key, + links.complex_attributes.value, + service_name, + resource_bool_attributes.key, + resource_bool_attributes.value, + resource_double_attributes.key, + resource_double_attributes.value, + resource_int_attributes.key, + resource_int_attributes.value, + resource_str_attributes.key, + resource_str_attributes.value, + resource_complex_attributes.key, + resource_complex_attributes.value, + scope_name, + scope_version, + scope_bool_attributes.key, + scope_bool_attributes.value, + scope_double_attributes.key, + scope_double_attributes.value, + scope_int_attributes.key, + scope_int_attributes.value, + scope_str_attributes.key, + scope_str_attributes.value, + scope_complex_attributes.key, + scope_complex_attributes.value +FROM + spans s + WHERE s.trace_id IN (SELECT trace_id FROM ( +SELECT DISTINCT + s.trace_id, + t.start, + t.end +FROM spans s +LEFT JOIN trace_id_timestamps t ON s.trace_id = t.trace_id +WHERE 1=1 LIMIT ?)) ORDER BY s.trace_id diff --git a/internal/storage/v2/clickhouse/tracestore/snapshots/TestFindTraces_WithFilters.sql b/internal/storage/v2/clickhouse/tracestore/snapshots/TestFindTraces_WithFilters.sql new file mode 100644 index 00000000000..64ba2866e4f --- /dev/null +++ b/internal/storage/v2/clickhouse/tracestore/snapshots/TestFindTraces_WithFilters.sql @@ -0,0 +1,79 @@ +SELECT + id, + trace_id, + trace_state, + parent_span_id, + name, + kind, + start_time, + status_code, + status_message, + duration, + bool_attributes.key, + bool_attributes.value, + double_attributes.key, + double_attributes.value, + int_attributes.key, + int_attributes.value, + str_attributes.key, + str_attributes.value, + complex_attributes.key, + complex_attributes.value, + events.name, + events.timestamp, + events.bool_attributes.key, + events.bool_attributes.value, + events.double_attributes.key, + events.double_attributes.value, + events.int_attributes.key, + events.int_attributes.value, + events.str_attributes.key, + events.str_attributes.value, + events.complex_attributes.key, + events.complex_attributes.value, + links.trace_id, + links.span_id, + links.trace_state, + links.bool_attributes.key, + links.bool_attributes.value, + links.double_attributes.key, + links.double_attributes.value, + links.int_attributes.key, + links.int_attributes.value, + links.str_attributes.key, + links.str_attributes.value, + links.complex_attributes.key, + links.complex_attributes.value, + service_name, + resource_bool_attributes.key, + resource_bool_attributes.value, + resource_double_attributes.key, + resource_double_attributes.value, + resource_int_attributes.key, + resource_int_attributes.value, + resource_str_attributes.key, + resource_str_attributes.value, + resource_complex_attributes.key, + resource_complex_attributes.value, + scope_name, + scope_version, + scope_bool_attributes.key, + scope_bool_attributes.value, + scope_double_attributes.key, + scope_double_attributes.value, + scope_int_attributes.key, + scope_int_attributes.value, + scope_str_attributes.key, + scope_str_attributes.value, + scope_complex_attributes.key, + scope_complex_attributes.value +FROM + spans s + WHERE s.trace_id IN (SELECT trace_id FROM ( +SELECT DISTINCT + s.trace_id, + t.start, + t.end +FROM spans s +LEFT JOIN trace_id_timestamps t ON s.trace_id = t.trace_id +WHERE 1=1 AND s.service_name = ? AND s.name = ? AND s.duration >= ? AND s.duration <= ? AND s.start_time >= ? AND s.start_time <= ? AND (arrayExists((key, value) -> key = ? AND value = ?, s.bool_attributes.key, s.bool_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_bool_attributes.key, s.resource_bool_attributes.value)) AND (arrayExists((key, value) -> key = ? AND value = ?, s.double_attributes.key, s.double_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_double_attributes.key, s.resource_double_attributes.value)) AND (arrayExists((key, value) -> key = ? AND value = ?, s.int_attributes.key, s.int_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_int_attributes.key, s.resource_int_attributes.value)) AND (arrayExists((key, value) -> key = ? AND value = ?, s.str_attributes.key, s.str_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_str_attributes.key, s.resource_str_attributes.value)) AND (arrayExists((key, value) -> key = ? AND value = ?, s.complex_attributes.key, s.complex_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_complex_attributes.key, s.resource_complex_attributes.value)) AND (arrayExists((key, value) -> key = ? AND value = ?, s.complex_attributes.key, s.complex_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_complex_attributes.key, s.resource_complex_attributes.value)) AND (arrayExists((key, value) -> key = ? AND value = ?, s.complex_attributes.key, s.complex_attributes.value) OR arrayExists((key, value) -> key = ? AND value = ?, s.resource_complex_attributes.key, s.resource_complex_attributes.value)) LIMIT ?)) ORDER BY s.trace_id diff --git a/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetOperations/successfully_returns_operations_by_kind.sql b/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetOperations/successfully_returns_operations_by_kind.sql new file mode 100644 index 00000000000..46ba35e06be --- /dev/null +++ b/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetOperations/successfully_returns_operations_by_kind.sql @@ -0,0 +1,9 @@ +SELECT + name, + span_kind +FROM + operations +WHERE + service_name = ? + AND span_kind = ? +GROUP BY name, span_kind diff --git a/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetOperations/successfully_returns_operations_for_all_kinds.sql b/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetOperations/successfully_returns_operations_for_all_kinds.sql new file mode 100644 index 00000000000..4e55b702a45 --- /dev/null +++ b/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetOperations/successfully_returns_operations_for_all_kinds.sql @@ -0,0 +1,8 @@ +SELECT + name, + span_kind +FROM + operations +WHERE + service_name = ? +GROUP BY name, span_kind diff --git a/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetServices/successfully_returns_services.sql b/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetServices/successfully_returns_services.sql new file mode 100644 index 00000000000..c32f90fd035 --- /dev/null +++ b/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetServices/successfully_returns_services.sql @@ -0,0 +1,5 @@ +SELECT + name +FROM + services +GROUP BY name diff --git a/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetTraces_Success/multiple_spans.sql b/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetTraces_Success/multiple_spans.sql new file mode 100644 index 00000000000..56eac4e0ea2 --- /dev/null +++ b/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetTraces_Success/multiple_spans.sql @@ -0,0 +1,72 @@ +SELECT + id, + trace_id, + trace_state, + parent_span_id, + name, + kind, + start_time, + status_code, + status_message, + duration, + bool_attributes.key, + bool_attributes.value, + double_attributes.key, + double_attributes.value, + int_attributes.key, + int_attributes.value, + str_attributes.key, + str_attributes.value, + complex_attributes.key, + complex_attributes.value, + events.name, + events.timestamp, + events.bool_attributes.key, + events.bool_attributes.value, + events.double_attributes.key, + events.double_attributes.value, + events.int_attributes.key, + events.int_attributes.value, + events.str_attributes.key, + events.str_attributes.value, + events.complex_attributes.key, + events.complex_attributes.value, + links.trace_id, + links.span_id, + links.trace_state, + links.bool_attributes.key, + links.bool_attributes.value, + links.double_attributes.key, + links.double_attributes.value, + links.int_attributes.key, + links.int_attributes.value, + links.str_attributes.key, + links.str_attributes.value, + links.complex_attributes.key, + links.complex_attributes.value, + service_name, + resource_bool_attributes.key, + resource_bool_attributes.value, + resource_double_attributes.key, + resource_double_attributes.value, + resource_int_attributes.key, + resource_int_attributes.value, + resource_str_attributes.key, + resource_str_attributes.value, + resource_complex_attributes.key, + resource_complex_attributes.value, + scope_name, + scope_version, + scope_bool_attributes.key, + scope_bool_attributes.value, + scope_double_attributes.key, + scope_double_attributes.value, + scope_int_attributes.key, + scope_int_attributes.value, + scope_str_attributes.key, + scope_str_attributes.value, + scope_complex_attributes.key, + scope_complex_attributes.value +FROM + spans s + WHERE s.trace_id = ? diff --git a/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetTraces_Success/single_span.sql b/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetTraces_Success/single_span.sql new file mode 100644 index 00000000000..56eac4e0ea2 --- /dev/null +++ b/internal/storage/v2/clickhouse/tracestore/snapshots/TestGetTraces_Success/single_span.sql @@ -0,0 +1,72 @@ +SELECT + id, + trace_id, + trace_state, + parent_span_id, + name, + kind, + start_time, + status_code, + status_message, + duration, + bool_attributes.key, + bool_attributes.value, + double_attributes.key, + double_attributes.value, + int_attributes.key, + int_attributes.value, + str_attributes.key, + str_attributes.value, + complex_attributes.key, + complex_attributes.value, + events.name, + events.timestamp, + events.bool_attributes.key, + events.bool_attributes.value, + events.double_attributes.key, + events.double_attributes.value, + events.int_attributes.key, + events.int_attributes.value, + events.str_attributes.key, + events.str_attributes.value, + events.complex_attributes.key, + events.complex_attributes.value, + links.trace_id, + links.span_id, + links.trace_state, + links.bool_attributes.key, + links.bool_attributes.value, + links.double_attributes.key, + links.double_attributes.value, + links.int_attributes.key, + links.int_attributes.value, + links.str_attributes.key, + links.str_attributes.value, + links.complex_attributes.key, + links.complex_attributes.value, + service_name, + resource_bool_attributes.key, + resource_bool_attributes.value, + resource_double_attributes.key, + resource_double_attributes.value, + resource_int_attributes.key, + resource_int_attributes.value, + resource_str_attributes.key, + resource_str_attributes.value, + resource_complex_attributes.key, + resource_complex_attributes.value, + scope_name, + scope_version, + scope_bool_attributes.key, + scope_bool_attributes.value, + scope_double_attributes.key, + scope_double_attributes.value, + scope_int_attributes.key, + scope_int_attributes.value, + scope_str_attributes.key, + scope_str_attributes.value, + scope_complex_attributes.key, + scope_complex_attributes.value +FROM + spans s + WHERE s.trace_id = ? diff --git a/internal/storage/v2/clickhouse/tracestore/snapshots/TestWriter_Success.sql b/internal/storage/v2/clickhouse/tracestore/snapshots/TestWriter_Success.sql new file mode 100644 index 00000000000..93cc9c5769b --- /dev/null +++ b/internal/storage/v2/clickhouse/tracestore/snapshots/TestWriter_Success.sql @@ -0,0 +1,122 @@ +INSERT INTO + spans ( + id, + trace_id, + trace_state, + parent_span_id, + name, + kind, + start_time, + status_code, + status_message, + duration, + bool_attributes.key, + bool_attributes.value, + double_attributes.key, + double_attributes.value, + int_attributes.key, + int_attributes.value, + str_attributes.key, + str_attributes.value, + complex_attributes.key, + complex_attributes.value, + events.name, + events.timestamp, + events.bool_attributes, + events.double_attributes, + events.int_attributes, + events.str_attributes, + events.complex_attributes, + links.trace_id, + links.span_id, + links.trace_state, + links.bool_attributes, + links.double_attributes, + links.int_attributes, + links.str_attributes, + links.complex_attributes, + service_name, + resource_bool_attributes.key, + resource_bool_attributes.value, + resource_double_attributes.key, + resource_double_attributes.value, + resource_int_attributes.key, + resource_int_attributes.value, + resource_str_attributes.key, + resource_str_attributes.value, + resource_complex_attributes.key, + resource_complex_attributes.value, + scope_name, + scope_version, + scope_bool_attributes.key, + scope_bool_attributes.value, + scope_double_attributes.key, + scope_double_attributes.value, + scope_int_attributes.key, + scope_int_attributes.value, + scope_str_attributes.key, + scope_str_attributes.value, + scope_complex_attributes.key, + scope_complex_attributes.value + ) +VALUES + ( + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ?, + ? + ) diff --git a/internal/storage/v2/clickhouse/tracestore/writer_test.go b/internal/storage/v2/clickhouse/tracestore/writer_test.go index b088647cbd4..381b5860d89 100644 --- a/internal/storage/v2/clickhouse/tracestore/writer_test.go +++ b/internal/storage/v2/clickhouse/tracestore/writer_test.go @@ -12,7 +12,6 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/ptrace" - "github.com/jaegertracing/jaeger/internal/storage/v2/clickhouse/sql" "github.com/jaegertracing/jaeger/internal/storage/v2/clickhouse/tracestore/dbmodel" ) @@ -31,9 +30,8 @@ func tracesFromSpanRows(rows []*dbmodel.SpanRow) ptrace.Traces { func TestWriter_Success(t *testing.T) { conn := &testDriver{ - t: t, - expectedQuery: sql.InsertSpan, - batch: &testBatch{t: t}, + t: t, + batch: &testBatch{t: t}, } w := NewWriter(conn) @@ -42,6 +40,7 @@ func TestWriter_Success(t *testing.T) { err := w.WriteTraces(context.Background(), td) require.NoError(t, err) + verifyQuerySnapshot(t, conn.recordedQuery) require.True(t, conn.batch.sendCalled) require.Len(t, conn.batch.appended, len(multipleSpans)) @@ -141,10 +140,9 @@ func TestWriter_Success(t *testing.T) { func TestWriter_PrepareBatchError(t *testing.T) { conn := &testDriver{ - t: t, - expectedQuery: sql.InsertSpan, - err: assert.AnError, - batch: &testBatch{t: t}, + t: t, + err: assert.AnError, + batch: &testBatch{t: t}, } w := NewWriter(conn) err := w.WriteTraces(context.Background(), tracesFromSpanRows(multipleSpans)) @@ -155,9 +153,8 @@ func TestWriter_PrepareBatchError(t *testing.T) { func TestWriter_AppendBatchError(t *testing.T) { conn := &testDriver{ - t: t, - expectedQuery: sql.InsertSpan, - batch: &testBatch{t: t, appendErr: assert.AnError}, + t: t, + batch: &testBatch{t: t, appendErr: assert.AnError}, } w := NewWriter(conn) err := w.WriteTraces(context.Background(), tracesFromSpanRows(multipleSpans)) @@ -168,9 +165,8 @@ func TestWriter_AppendBatchError(t *testing.T) { func TestWriter_SendError(t *testing.T) { conn := &testDriver{ - t: t, - expectedQuery: sql.InsertSpan, - batch: &testBatch{t: t, sendErr: assert.AnError}, + t: t, + batch: &testBatch{t: t, sendErr: assert.AnError}, } w := NewWriter(conn) err := w.WriteTraces(context.Background(), tracesFromSpanRows(multipleSpans))