Skip to content

Commit 336918b

Browse files
committed
refactor(querytee): move response comparator files to dedicated package
This change relocates response comparator logic to its own package to prevent cyclic imports and improve code organization. No functional changes.
1 parent 06da42a commit 336918b

File tree

7 files changed

+39
-30
lines changed

7 files changed

+39
-30
lines changed

cmd/querytee/main.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"github.com/prometheus/client_golang/prometheus"
1313
"github.com/prometheus/client_golang/prometheus/collectors"
1414

15+
"github.com/grafana/loki/v3/tools/querytee/responsecomparator"
16+
1517
loki_tracing "github.com/grafana/loki/v3/pkg/tracing"
1618
util_log "github.com/grafana/loki/v3/pkg/util/log"
1719
"github.com/grafana/loki/v3/tools/querytee"
@@ -85,7 +87,7 @@ func exit(code int) {
8587
}
8688

8789
func lokiReadRoutes(cfg Config) []querytee.Route {
88-
samplesComparator := querytee.NewSamplesComparator(querytee.SampleComparisonOptions{
90+
samplesComparator := responsecomparator.NewSamplesComparator(responsecomparator.SampleComparisonOptions{
8991
Tolerance: cfg.ProxyConfig.ValueComparisonTolerance,
9092
UseRelativeError: cfg.ProxyConfig.UseRelativeError,
9193
SkipRecentSamples: cfg.ProxyConfig.SkipRecentSamples,

tools/querytee/proxy.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/gorilla/mux"
2020
"github.com/grafana/dskit/flagext"
2121
"github.com/grafana/dskit/middleware"
22+
"github.com/grafana/loki/v3/tools/querytee/responsecomparator"
2223
"github.com/pkg/errors"
2324
"github.com/prometheus/client_golang/prometheus"
2425

@@ -71,7 +72,7 @@ type Route struct {
7172
Path string
7273
RouteName string
7374
Methods []string
74-
ResponseComparator ResponsesComparator
75+
ResponseComparator responsecomparator.ResponsesComparator
7576
}
7677

7778
type Proxy struct {
@@ -240,7 +241,7 @@ func (p *Proxy) Start() error {
240241

241242
// register read routes
242243
for _, route := range p.readRoutes {
243-
var comparator ResponsesComparator
244+
var comparator responsecomparator.ResponsesComparator
244245
if p.cfg.CompareResponses {
245246
comparator = route.ResponseComparator
246247
}

tools/querytee/proxy_endpoint.go

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,14 @@ import (
1414
"github.com/go-kit/log"
1515
"github.com/go-kit/log/level"
1616
"github.com/grafana/loki/v3/tools/querytee/goldfish"
17+
"github.com/grafana/loki/v3/tools/querytee/responsecomparator"
1718
)
1819

19-
type ResponsesComparator interface {
20-
Compare(expected, actual []byte, queryEvaluationTime time.Time) (*ComparisonSummary, error)
21-
}
22-
23-
type ComparisonSummary struct {
24-
skipped bool
25-
missingMetrics int
26-
}
27-
2820
type ProxyEndpoint struct {
2921
backends []*ProxyBackend
3022
metrics *ProxyMetrics
3123
logger log.Logger
32-
comparator ResponsesComparator
24+
comparator responsecomparator.ResponsesComparator
3325

3426
instrumentCompares bool
3527

@@ -43,7 +35,7 @@ type ProxyEndpoint struct {
4335
goldfishManager *goldfish.Manager
4436
}
4537

46-
func NewProxyEndpoint(backends []*ProxyBackend, routeName string, metrics *ProxyMetrics, logger log.Logger, comparator ResponsesComparator, instrumentCompares bool) *ProxyEndpoint {
38+
func NewProxyEndpoint(backends []*ProxyBackend, routeName string, metrics *ProxyMetrics, logger log.Logger, comparator responsecomparator.ResponsesComparator, instrumentCompares bool) *ProxyEndpoint {
4739
hasPreferredBackend := false
4840
for _, backend := range backends {
4941
if backend.preferred {
@@ -195,12 +187,12 @@ func (p *ProxyEndpoint) executeBackendRequests(r *http.Request, resCh chan *Back
195187
"route-name", p.routeName,
196188
"query", r.URL.RawQuery, "err", err)
197189
result = comparisonFailed
198-
} else if summary != nil && summary.skipped {
190+
} else if summary != nil && summary.Skipped {
199191
result = comparisonSkipped
200192
}
201193

202194
if p.instrumentCompares && summary != nil {
203-
p.metrics.missingMetrics.WithLabelValues(p.backends[i].name, p.routeName, result, issuer).Observe(float64(summary.missingMetrics))
195+
p.metrics.missingMetrics.WithLabelValues(p.backends[i].name, p.routeName, result, issuer).Observe(float64(summary.MissingMetrics))
204196
}
205197
p.metrics.responsesComparedTotal.WithLabelValues(p.backends[i].name, p.routeName, result, issuer).Inc()
206198
}
@@ -275,9 +267,9 @@ func (p *ProxyEndpoint) waitBackendResponseForDownstream(resCh chan *BackendResp
275267
return responses[0]
276268
}
277269

278-
func (p *ProxyEndpoint) compareResponses(expectedResponse, actualResponse *BackendResponse, queryEvalTime time.Time) (*ComparisonSummary, error) {
270+
func (p *ProxyEndpoint) compareResponses(expectedResponse, actualResponse *BackendResponse, queryEvalTime time.Time) (*responsecomparator.ComparisonSummary, error) {
279271
if expectedResponse.err != nil {
280-
return &ComparisonSummary{skipped: true}, nil
272+
return &responsecomparator.ComparisonSummary{Skipped: true}, nil
281273
}
282274

283275
if actualResponse.err != nil {
@@ -286,7 +278,7 @@ func (p *ProxyEndpoint) compareResponses(expectedResponse, actualResponse *Backe
286278

287279
// compare response body only if we get a 200
288280
if expectedResponse.status != 200 {
289-
return &ComparisonSummary{skipped: true}, nil
281+
return &responsecomparator.ComparisonSummary{Skipped: true}, nil
290282
}
291283

292284
if actualResponse.status != 200 {

tools/querytee/proxy_endpoint_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/go-kit/log"
1616
"github.com/grafana/loki/v3/pkg/goldfish"
1717
querytee_goldfish "github.com/grafana/loki/v3/tools/querytee/goldfish"
18+
"github.com/grafana/loki/v3/tools/querytee/responsecomparator"
1819
"github.com/pkg/errors"
1920
"github.com/prometheus/client_golang/prometheus"
2021
prom_testutil "github.com/prometheus/client_golang/prometheus/testutil"
@@ -425,8 +426,8 @@ func Test_BackendResponse_statusCode(t *testing.T) {
425426

426427
type mockComparator struct{}
427428

428-
func (c *mockComparator) Compare(_, _ []byte, _ time.Time) (*ComparisonSummary, error) {
429-
return &ComparisonSummary{missingMetrics: 12}, nil
429+
func (c *mockComparator) Compare(_, _ []byte, _ time.Time) (*responsecomparator.ComparisonSummary, error) {
430+
return &responsecomparator.ComparisonSummary{MissingMetrics: 12}, nil
430431
}
431432

432433
func Test_endToEnd_traceIDFlow(t *testing.T) {

tools/querytee/proxy_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"github.com/go-kit/log"
1515
"github.com/gorilla/mux"
16+
"github.com/grafana/loki/v3/tools/querytee/responsecomparator"
1617
"github.com/stretchr/testify/assert"
1718
"github.com/stretchr/testify/require"
1819
)
@@ -25,7 +26,9 @@ var testWriteRoutes = []Route{}
2526

2627
type testComparator struct{}
2728

28-
func (testComparator) Compare(_, _ []byte, _ time.Time) (*ComparisonSummary, error) { return nil, nil }
29+
func (testComparator) Compare(_, _ []byte, _ time.Time) (*responsecomparator.ComparisonSummary, error) {
30+
return nil, nil
31+
}
2932

3033
func Test_NewProxy(t *testing.T) {
3134
cfg := ProxyConfig{}

tools/querytee/response_comparator.go renamed to tools/querytee/responsecomparator/response_comparator.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package querytee
1+
package responsecomparator
22

33
import (
44
"encoding/json"
@@ -8,6 +8,7 @@ import (
88
"time"
99

1010
"github.com/go-kit/log/level"
11+
1112
jsoniter "github.com/json-iterator/go"
1213
"github.com/pkg/errors"
1314
"github.com/prometheus/common/model"
@@ -16,6 +17,15 @@ import (
1617
util_log "github.com/grafana/loki/v3/pkg/util/log"
1718
)
1819

20+
type ResponsesComparator interface {
21+
Compare(expected, actual []byte, queryEvaluationTime time.Time) (*ComparisonSummary, error)
22+
}
23+
24+
type ComparisonSummary struct {
25+
Skipped bool
26+
MissingMetrics int
27+
}
28+
1929
// SamplesComparatorFunc helps with comparing different types of samples coming from /api/v1/query and /api/v1/query_range routes.
2030
type SamplesComparatorFunc func(expected, actual json.RawMessage, evaluationTime time.Time, opts SampleComparisonOptions) (*ComparisonSummary, error)
2131

@@ -122,7 +132,7 @@ func compareMatrix(expectedRaw, actualRaw json.RawMessage, evaluationTime time.T
122132

123133
// If both matrices are empty after filtering, we can skip comparison
124134
if len(expected) == 0 && len(actual) == 0 {
125-
return &ComparisonSummary{skipped: true}, nil
135+
return &ComparisonSummary{Skipped: true}, nil
126136
}
127137

128138
if len(expected) != len(actual) {
@@ -233,7 +243,7 @@ func compareVector(expectedRaw, actualRaw json.RawMessage, evaluationTime time.T
233243
}
234244

235245
if len(expected) == 0 && len(actual) == 0 {
236-
return &ComparisonSummary{skipped: true}, nil
246+
return &ComparisonSummary{Skipped: true}, nil
237247
}
238248

239249
if len(expected) != len(actual) {
@@ -279,7 +289,7 @@ func compareVector(expectedRaw, actualRaw json.RawMessage, evaluationTime time.T
279289
err = fmt.Errorf("expected metric(s) [%s] missing from actual response", b.String())
280290
}
281291

282-
return &ComparisonSummary{missingMetrics: len(missingMetrics)}, err
292+
return &ComparisonSummary{MissingMetrics: len(missingMetrics)}, err
283293
}
284294

285295
func compareScalar(expectedRaw, actualRaw json.RawMessage, evaluationTime time.Time, opts SampleComparisonOptions) (*ComparisonSummary, error) {
@@ -295,7 +305,7 @@ func compareScalar(expectedRaw, actualRaw json.RawMessage, evaluationTime time.T
295305
}
296306

297307
if opts.SkipSample(expected.Timestamp.Time(), evaluationTime) && opts.SkipSample(actual.Timestamp.Time(), evaluationTime) {
298-
return &ComparisonSummary{skipped: true}, nil
308+
return &ComparisonSummary{Skipped: true}, nil
299309
}
300310

301311
return nil, compareSamplePair(model.SamplePair{
@@ -359,7 +369,7 @@ func compareStreams(expectedRaw, actualRaw json.RawMessage, evaluationTime time.
359369

360370
// If both streams are empty after filtering, we can skip comparison
361371
if len(expected) == 0 && len(actual) == 0 {
362-
return &ComparisonSummary{skipped: true}, nil
372+
return &ComparisonSummary{Skipped: true}, nil
363373
}
364374

365375
if len(expected) != len(actual) {

tools/querytee/response_comparator_test.go renamed to tools/querytee/responsecomparator/response_comparator_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package querytee
1+
package responsecomparator
22

33
import (
44
"encoding/json"
@@ -693,7 +693,7 @@ func TestCompareStreams_SamplesOutsideComparableWindow(t *testing.T) {
693693
if tc.err == nil {
694694
require.NoError(t, err)
695695
if summary != nil {
696-
require.True(t, summary.skipped)
696+
require.True(t, summary.Skipped)
697697
}
698698
return
699699
}

0 commit comments

Comments
 (0)