@@ -518,6 +518,122 @@ func TestVerticalShardingFuzz(t *testing.T) {
518
518
runQueryFuzzTestCases (t , ps , c1 , c2 , now , start , end , scrapeInterval , 1000 )
519
519
}
520
520
521
+ func TestProtobufCodecFuzz (t * testing.T ) {
522
+ s , err := e2e .NewScenario (networkName )
523
+ require .NoError (t , err )
524
+ defer s .Close ()
525
+
526
+ // Start dependencies.
527
+ consul1 := e2edb .NewConsulWithName ("consul1" )
528
+ consul2 := e2edb .NewConsulWithName ("consul2" )
529
+ require .NoError (t , s .StartAndWaitReady (consul1 , consul2 ))
530
+
531
+ flags := mergeFlags (
532
+ AlertmanagerLocalFlags (),
533
+ map [string ]string {
534
+ "-store.engine" : blocksStorageEngine ,
535
+ "-blocks-storage.backend" : "filesystem" ,
536
+ "-blocks-storage.tsdb.head-compaction-interval" : "4m" ,
537
+ "-blocks-storage.tsdb.block-ranges-period" : "2h" ,
538
+ "-blocks-storage.tsdb.ship-interval" : "1h" ,
539
+ "-blocks-storage.bucket-store.sync-interval" : "15m" ,
540
+ "-blocks-storage.tsdb.retention-period" : "2h" ,
541
+ "-blocks-storage.bucket-store.index-cache.backend" : tsdb .IndexCacheBackendInMemory ,
542
+ "-querier.query-store-for-labels-enabled" : "true" ,
543
+ // Ingester.
544
+ "-ring.store" : "consul" ,
545
+ "-consul.hostname" : consul1 .NetworkHTTPEndpoint (),
546
+ // Distributor.
547
+ "-distributor.replication-factor" : "1" ,
548
+ // Store-gateway.
549
+ "-store-gateway.sharding-enabled" : "false" ,
550
+ // alert manager
551
+ "-alertmanager.web.external-url" : "http://localhost/alertmanager" ,
552
+ },
553
+ )
554
+ // make alert manager config dir
555
+ require .NoError (t , writeFileToSharedDir (s , "alertmanager_configs" , []byte {}))
556
+
557
+ path1 := path .Join (s .SharedDir (), "cortex-1" )
558
+ path2 := path .Join (s .SharedDir (), "cortex-2" )
559
+
560
+ flags1 := mergeFlags (flags , map [string ]string {"-blocks-storage.filesystem.dir" : path1 })
561
+ // Start Cortex replicas.
562
+ cortex1 := e2ecortex .NewSingleBinary ("cortex-1" , flags1 , "" )
563
+ // Enable protobuf codec for the second Cortex instance.
564
+ flags2 := mergeFlags (flags , map [string ]string {
565
+ "-api.querier-default-codec" : "protobuf" ,
566
+ "-blocks-storage.filesystem.dir" : path2 ,
567
+ "-consul.hostname" : consul2 .NetworkHTTPEndpoint (),
568
+ })
569
+ cortex2 := e2ecortex .NewSingleBinary ("cortex-2" , flags2 , "" )
570
+ require .NoError (t , s .StartAndWaitReady (cortex1 , cortex2 ))
571
+
572
+ // Wait until Cortex replicas have updated the ring state.
573
+ require .NoError (t , cortex1 .WaitSumMetrics (e2e .Equals (float64 (512 )), "cortex_ring_tokens_total" ))
574
+ require .NoError (t , cortex2 .WaitSumMetrics (e2e .Equals (float64 (512 )), "cortex_ring_tokens_total" ))
575
+
576
+ c1 , err := e2ecortex .NewClient (cortex1 .HTTPEndpoint (), cortex1 .HTTPEndpoint (), "" , "" , "user-1" )
577
+ require .NoError (t , err )
578
+ c2 , err := e2ecortex .NewClient (cortex2 .HTTPEndpoint (), cortex2 .HTTPEndpoint (), "" , "" , "user-1" )
579
+ require .NoError (t , err )
580
+
581
+ now := time .Now ()
582
+ // Push some series to Cortex.
583
+ start := now .Add (- time .Minute * 10 )
584
+ end := now .Add (- time .Minute * 1 )
585
+ numSeries := 3
586
+ numSamples := 20
587
+ lbls := make ([]labels.Labels , numSeries * 2 )
588
+ serieses := make ([]prompb.TimeSeries , numSeries * 2 )
589
+ scrapeInterval := 30 * time .Second
590
+ for i := 0 ; i < numSeries ; i ++ {
591
+ 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 )})
592
+ serieses [i ] = series
593
+ builder := labels .NewBuilder (labels .EmptyLabels ())
594
+ for _ , lbl := range series .Labels {
595
+ builder .Set (lbl .Name , lbl .Value )
596
+ }
597
+ lbls [i ] = builder .Labels ()
598
+ }
599
+ // Generate another set of series for testing binary expression and vector matching.
600
+ for i := numSeries ; i < 2 * numSeries ; i ++ {
601
+ prompbLabels := []prompb.Label {{Name : "job" , Value : "test" }, {Name : "series" , Value : strconv .Itoa (i )}}
602
+ if i % 3 == 0 {
603
+ prompbLabels = append (prompbLabels , prompb.Label {Name : "status_code" , Value : "200" })
604
+ } else if i % 3 == 1 {
605
+ prompbLabels = append (prompbLabels , prompb.Label {Name : "status_code" , Value : "400" })
606
+ } else {
607
+ prompbLabels = append (prompbLabels , prompb.Label {Name : "status_code" , Value : "500" })
608
+ }
609
+ series := e2e .GenerateSeriesWithSamples ("test_series_b" , start , scrapeInterval , i * numSamples , numSamples , prompbLabels ... )
610
+ serieses [i ] = series
611
+ builder := labels .NewBuilder (labels .EmptyLabels ())
612
+ for _ , lbl := range series .Labels {
613
+ builder .Set (lbl .Name , lbl .Value )
614
+ }
615
+ lbls [i ] = builder .Labels ()
616
+ }
617
+ res , err := c1 .Push (serieses )
618
+ require .NoError (t , err )
619
+ require .Equal (t , 200 , res .StatusCode )
620
+ res , err = c2 .Push (serieses )
621
+ require .NoError (t , err )
622
+ require .Equal (t , 200 , res .StatusCode )
623
+
624
+ waitUntilReady (t , context .Background (), c1 , c2 , `{job="test"}` , start , end )
625
+
626
+ rnd := rand .New (rand .NewSource (now .Unix ()))
627
+ opts := []promqlsmith.Option {
628
+ promqlsmith .WithEnableOffset (true ),
629
+ promqlsmith .WithEnableAtModifier (true ),
630
+ promqlsmith .WithEnabledFunctions (enabledFunctions ),
631
+ }
632
+ ps := promqlsmith .New (rnd , lbls , opts ... )
633
+
634
+ runQueryFuzzTestCases (t , ps , c1 , c2 , now , start , end , scrapeInterval , 1000 )
635
+ }
636
+
521
637
// comparer should be used to compare promql results between engines.
522
638
var comparer = cmp .Comparer (func (x , y model.Value ) bool {
523
639
if x .Type () != y .Type () {
0 commit comments