From c0ff5e917d262b48ed60d8f03384febcbcbb9dba Mon Sep 17 00:00:00 2001 From: Ben Ye Date: Fri, 8 Nov 2024 17:01:58 -0800 Subject: [PATCH] add query fuzz test case for protobuf codec Signed-off-by: Ben Ye --- integration/query_fuzz_test.go | 116 +++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/integration/query_fuzz_test.go b/integration/query_fuzz_test.go index 6029582f0f..0c0cd1024d 100644 --- a/integration/query_fuzz_test.go +++ b/integration/query_fuzz_test.go @@ -518,6 +518,122 @@ func TestVerticalShardingFuzz(t *testing.T) { runQueryFuzzTestCases(t, ps, c1, c2, now, start, end, scrapeInterval, 1000) } +func TestProtobufCodecFuzz(t *testing.T) { + s, err := e2e.NewScenario(networkName) + require.NoError(t, err) + defer s.Close() + + // Start dependencies. + consul1 := e2edb.NewConsulWithName("consul1") + consul2 := e2edb.NewConsulWithName("consul2") + require.NoError(t, s.StartAndWaitReady(consul1, consul2)) + + flags := mergeFlags( + AlertmanagerLocalFlags(), + map[string]string{ + "-store.engine": blocksStorageEngine, + "-blocks-storage.backend": "filesystem", + "-blocks-storage.tsdb.head-compaction-interval": "4m", + "-blocks-storage.tsdb.block-ranges-period": "2h", + "-blocks-storage.tsdb.ship-interval": "1h", + "-blocks-storage.bucket-store.sync-interval": "15m", + "-blocks-storage.tsdb.retention-period": "2h", + "-blocks-storage.bucket-store.index-cache.backend": tsdb.IndexCacheBackendInMemory, + "-querier.query-store-for-labels-enabled": "true", + // Ingester. + "-ring.store": "consul", + "-consul.hostname": consul1.NetworkHTTPEndpoint(), + // Distributor. + "-distributor.replication-factor": "1", + // Store-gateway. + "-store-gateway.sharding-enabled": "false", + // alert manager + "-alertmanager.web.external-url": "http://localhost/alertmanager", + }, + ) + // make alert manager config dir + require.NoError(t, writeFileToSharedDir(s, "alertmanager_configs", []byte{})) + + path1 := path.Join(s.SharedDir(), "cortex-1") + path2 := path.Join(s.SharedDir(), "cortex-2") + + flags1 := mergeFlags(flags, map[string]string{"-blocks-storage.filesystem.dir": path1}) + // Start Cortex replicas. + cortex1 := e2ecortex.NewSingleBinary("cortex-1", flags1, "") + // Enable protobuf codec for the second Cortex instance. + flags2 := mergeFlags(flags, map[string]string{ + "-api.querier-default-codec": "protobuf", + "-blocks-storage.filesystem.dir": path2, + "-consul.hostname": consul2.NetworkHTTPEndpoint(), + }) + cortex2 := e2ecortex.NewSingleBinary("cortex-2", flags2, "") + require.NoError(t, s.StartAndWaitReady(cortex1, cortex2)) + + // Wait until Cortex replicas have updated the ring state. + require.NoError(t, cortex1.WaitSumMetrics(e2e.Equals(float64(512)), "cortex_ring_tokens_total")) + require.NoError(t, cortex2.WaitSumMetrics(e2e.Equals(float64(512)), "cortex_ring_tokens_total")) + + c1, err := e2ecortex.NewClient(cortex1.HTTPEndpoint(), cortex1.HTTPEndpoint(), "", "", "user-1") + require.NoError(t, err) + c2, err := e2ecortex.NewClient(cortex2.HTTPEndpoint(), cortex2.HTTPEndpoint(), "", "", "user-1") + require.NoError(t, err) + + now := time.Now() + // Push some series to Cortex. + start := now.Add(-time.Minute * 10) + end := now.Add(-time.Minute * 1) + numSeries := 3 + numSamples := 20 + lbls := make([]labels.Labels, numSeries*2) + serieses := make([]prompb.TimeSeries, numSeries*2) + scrapeInterval := 30 * time.Second + for i := 0; i < numSeries; i++ { + series := e2e.GenerateSeriesWithSamples("test_series_a", start, scrapeInterval, i*numSamples, numSamples, prompb.Label{Name: "job", Value: "test"}, prompb.Label{Name: "series", Value: strconv.Itoa(i)}) + serieses[i] = series + builder := labels.NewBuilder(labels.EmptyLabels()) + for _, lbl := range series.Labels { + builder.Set(lbl.Name, lbl.Value) + } + lbls[i] = builder.Labels() + } + // Generate another set of series for testing binary expression and vector matching. + for i := numSeries; i < 2*numSeries; i++ { + prompbLabels := []prompb.Label{{Name: "job", Value: "test"}, {Name: "series", Value: strconv.Itoa(i)}} + if i%3 == 0 { + prompbLabels = append(prompbLabels, prompb.Label{Name: "status_code", Value: "200"}) + } else if i%3 == 1 { + prompbLabels = append(prompbLabels, prompb.Label{Name: "status_code", Value: "400"}) + } else { + prompbLabels = append(prompbLabels, prompb.Label{Name: "status_code", Value: "500"}) + } + series := e2e.GenerateSeriesWithSamples("test_series_b", start, scrapeInterval, i*numSamples, numSamples, prompbLabels...) + serieses[i] = series + builder := labels.NewBuilder(labels.EmptyLabels()) + for _, lbl := range series.Labels { + builder.Set(lbl.Name, lbl.Value) + } + lbls[i] = builder.Labels() + } + res, err := c1.Push(serieses) + require.NoError(t, err) + require.Equal(t, 200, res.StatusCode) + res, err = c2.Push(serieses) + require.NoError(t, err) + require.Equal(t, 200, res.StatusCode) + + waitUntilReady(t, context.Background(), c1, c2, `{job="test"}`, start, end) + + rnd := rand.New(rand.NewSource(now.Unix())) + opts := []promqlsmith.Option{ + promqlsmith.WithEnableOffset(true), + promqlsmith.WithEnableAtModifier(true), + promqlsmith.WithEnabledFunctions(enabledFunctions), + } + ps := promqlsmith.New(rnd, lbls, opts...) + + runQueryFuzzTestCases(t, ps, c1, c2, now, start, end, scrapeInterval, 1000) +} + // comparer should be used to compare promql results between engines. var comparer = cmp.Comparer(func(x, y model.Value) bool { if x.Type() != y.Type() {