@@ -52,8 +52,116 @@ func init() {
52
52
}
53
53
}
54
54
55
+ func TestNativeHistogramFuzz (t * testing.T ) {
56
+ s , err := e2e .NewScenario (networkName )
57
+ require .NoError (t , err )
58
+ defer s .Close ()
59
+
60
+ // Start dependencies.
61
+ consul := e2edb .NewConsulWithName ("consul" )
62
+ require .NoError (t , s .StartAndWaitReady (consul ))
63
+
64
+ baseFlags := mergeFlags (AlertmanagerLocalFlags (), BlocksStorageFlags ())
65
+ flags := mergeFlags (
66
+ baseFlags ,
67
+ map [string ]string {
68
+ "-blocks-storage.tsdb.head-compaction-interval" : "4m" ,
69
+ "-blocks-storage.tsdb.block-ranges-period" : "2h" ,
70
+ "-blocks-storage.tsdb.ship-interval" : "1h" ,
71
+ "-blocks-storage.bucket-store.sync-interval" : "1s" ,
72
+ "-blocks-storage.tsdb.retention-period" : "24h" ,
73
+ "-blocks-storage.bucket-store.index-cache.backend" : tsdb .IndexCacheBackendInMemory ,
74
+ "-querier.query-store-for-labels-enabled" : "true" ,
75
+ // Ingester.
76
+ "-ring.store" : "consul" ,
77
+ "-consul.hostname" : consul .NetworkHTTPEndpoint (),
78
+ // Distributor.
79
+ "-distributor.replication-factor" : "1" ,
80
+ // alert manager
81
+ "-alertmanager.web.external-url" : "http://localhost/alertmanager" ,
82
+ },
83
+ )
84
+ // make alert manager config dir
85
+ require .NoError (t , writeFileToSharedDir (s , "alertmanager_configs" , []byte {}))
86
+
87
+ minio := e2edb .NewMinio (9000 , flags ["-blocks-storage.s3.bucket-name" ])
88
+ require .NoError (t , s .StartAndWaitReady (minio ))
89
+
90
+ cortex := e2ecortex .NewSingleBinary ("cortex" , flags , "" )
91
+ require .NoError (t , s .StartAndWaitReady (cortex ))
92
+
93
+ // Wait until Cortex replicas have updated the ring state.
94
+ require .NoError (t , cortex .WaitSumMetrics (e2e .Equals (float64 (512 )), "cortex_ring_tokens_total" ))
95
+
96
+ now := time .Now ()
97
+ start := now .Add (- time .Hour * 2 )
98
+ end := now .Add (- time .Hour )
99
+ numSeries := 10
100
+ numSamples := 60
101
+ lbls := make ([]labels.Labels , 0 , numSeries * 2 )
102
+ scrapeInterval := time .Minute
103
+ statusCodes := []string {"200" , "400" , "404" , "500" , "502" }
104
+ for i := 0 ; i < numSeries ; i ++ {
105
+ lbls = append (lbls , labels.Labels {
106
+ {Name : labels .MetricName , Value : "test_series_a" },
107
+ {Name : "job" , Value : "test" },
108
+ {Name : "series" , Value : strconv .Itoa (i % 3 )},
109
+ {Name : "status_code" , Value : statusCodes [i % 5 ]},
110
+ })
111
+
112
+ lbls = append (lbls , labels.Labels {
113
+ {Name : labels .MetricName , Value : "test_series_b" },
114
+ {Name : "job" , Value : "test" },
115
+ {Name : "series" , Value : strconv .Itoa ((i + 1 ) % 3 )},
116
+ {Name : "status_code" , Value : statusCodes [(i + 1 )% 5 ]},
117
+ })
118
+ }
119
+
120
+ ctx := context .Background ()
121
+ rnd := rand .New (rand .NewSource (time .Now ().Unix ()))
122
+
123
+ dir := filepath .Join (s .SharedDir (), "data" )
124
+ err = os .MkdirAll (dir , os .ModePerm )
125
+ require .NoError (t , err )
126
+ storage , err := e2ecortex .NewS3ClientForMinio (minio , flags ["-blocks-storage.s3.bucket-name" ])
127
+ require .NoError (t , err )
128
+ bkt := bucket .NewUserBucketClient ("user-1" , storage .GetBucket (), nil )
129
+ id , err := e2e .CreateNHBlock (ctx , rnd , dir , lbls , numSamples , start .UnixMilli (), end .UnixMilli (), scrapeInterval .Milliseconds (), 10 )
130
+ require .NoError (t , err )
131
+ err = block .Upload (ctx , log .Logger , bkt , filepath .Join (dir , id .String ()), metadata .NoneFunc )
132
+ require .NoError (t , err )
133
+
134
+ // Wait for querier and store to sync blocks.
135
+ require .NoError (t , cortex .WaitSumMetricsWithOptions (e2e .Equals (float64 (1 )), []string {"cortex_blocks_meta_synced" }, e2e .WaitMissingMetrics , e2e .WithLabelMatchers (labels .MustNewMatcher (labels .MatchEqual , "component" , "store-gateway" ))))
136
+ require .NoError (t , cortex .WaitSumMetricsWithOptions (e2e .Equals (float64 (1 )), []string {"cortex_blocks_meta_synced" }, e2e .WaitMissingMetrics , e2e .WithLabelMatchers (labels .MustNewMatcher (labels .MatchEqual , "component" , "querier" ))))
137
+ require .NoError (t , cortex .WaitSumMetricsWithOptions (e2e .Equals (float64 (1 )), []string {"cortex_bucket_store_blocks_loaded" }, e2e .WaitMissingMetrics ))
138
+
139
+ c1 , err := e2ecortex .NewClient ("" , cortex .HTTPEndpoint (), "" , "" , "user-1" )
140
+ require .NoError (t , err )
141
+
142
+ err = writeFileToSharedDir (s , "prometheus.yml" , []byte ("" ))
143
+ require .NoError (t , err )
144
+ prom := e2edb .NewPrometheus ("" , nil )
145
+ require .NoError (t , s .StartAndWaitReady (prom ))
146
+
147
+ c2 , err := e2ecortex .NewPromQueryClient (prom .HTTPEndpoint ())
148
+ require .NoError (t , err )
149
+
150
+ waitUntilReady (t , ctx , c1 , c2 , `{job="test"}` , start , end )
151
+
152
+ opts := []promqlsmith.Option {
153
+ promqlsmith .WithEnableOffset (true ),
154
+ promqlsmith .WithEnableAtModifier (true ),
155
+ promqlsmith .WithEnabledAggrs ([]parser.ItemType {
156
+ parser .SUM , parser .MIN , parser .MAX , parser .AVG , parser .GROUP , parser .COUNT , parser .COUNT_VALUES , parser .QUANTILE ,
157
+ }),
158
+ }
159
+ ps := promqlsmith .New (rnd , lbls , opts ... )
160
+
161
+ runQueryFuzzTestCases (t , ps , c1 , c2 , end , start , end , scrapeInterval , 1000 , false )
162
+ }
163
+
55
164
func TestExperimentalPromQLFuncsWithPrometheus (t * testing.T ) {
56
- prometheusLatestImage := "quay.io/prometheus/prometheus:v3.2.1"
57
165
s , err := e2e .NewScenario (networkName )
58
166
require .NoError (t , err )
59
167
defer s .Close ()
@@ -148,7 +256,7 @@ func TestExperimentalPromQLFuncsWithPrometheus(t *testing.T) {
148
256
149
257
err = writeFileToSharedDir (s , "prometheus.yml" , []byte ("" ))
150
258
require .NoError (t , err )
151
- prom := e2edb .NewPrometheus (prometheusLatestImage , map [string ]string {
259
+ prom := e2edb .NewPrometheus ("" , map [string ]string {
152
260
"--enable-feature" : "promql-experimental-functions" ,
153
261
})
154
262
require .NoError (t , s .StartAndWaitReady (prom ))
@@ -841,6 +949,10 @@ var comparer = cmp.Comparer(func(x, y model.Value) bool {
841
949
const fraction = 1.e-10 // 0.00000001%
842
950
return cmp .Equal (l , r , cmpopts .EquateNaNs (), cmpopts .EquateApprox (fraction , epsilon ))
843
951
}
952
+ compareHistograms := func (l , r * model.SampleHistogram ) bool {
953
+ return l .Equal (r )
954
+ }
955
+
844
956
// count_values returns a metrics with one label {"value": "1.012321"}
845
957
compareValueMetrics := func (l , r model.Metric ) (valueMetric bool , equals bool ) {
846
958
lLabels := model .LabelSet (l ).Clone ()
@@ -906,6 +1018,9 @@ var comparer = cmp.Comparer(func(x, y model.Value) bool {
906
1018
if ! compareFloats (float64 (vx [i ].Value ), float64 (vy [i ].Value )) {
907
1019
return false
908
1020
}
1021
+ if ! compareHistograms (vx [i ].Histogram , vy [i ].Histogram ) {
1022
+ return false
1023
+ }
909
1024
}
910
1025
return true
911
1026
}
@@ -942,6 +1057,21 @@ var comparer = cmp.Comparer(func(x, y model.Value) bool {
942
1057
return false
943
1058
}
944
1059
}
1060
+
1061
+ xhs := mxs .Histograms
1062
+ yhs := mys .Histograms
1063
+
1064
+ if len (xhs ) != len (yhs ) {
1065
+ return false
1066
+ }
1067
+ for j := 0 ; j < len (xhs ); j ++ {
1068
+ if xhs [j ].Timestamp != yhs [j ].Timestamp {
1069
+ return false
1070
+ }
1071
+ if ! compareHistograms (xhs [j ].Histogram , yhs [j ].Histogram ) {
1072
+ return false
1073
+ }
1074
+ }
945
1075
}
946
1076
return true
947
1077
}
@@ -1423,7 +1553,6 @@ func TestBackwardCompatibilityQueryFuzz(t *testing.T) {
1423
1553
1424
1554
// TestPrometheusCompatibilityQueryFuzz compares Cortex with latest Prometheus release.
1425
1555
func TestPrometheusCompatibilityQueryFuzz (t * testing.T ) {
1426
- prometheusLatestImage := "quay.io/prometheus/prometheus:v3.2.1"
1427
1556
s , err := e2e .NewScenario (networkName )
1428
1557
require .NoError (t , err )
1429
1558
defer s .Close ()
@@ -1516,7 +1645,7 @@ func TestPrometheusCompatibilityQueryFuzz(t *testing.T) {
1516
1645
1517
1646
err = writeFileToSharedDir (s , "prometheus.yml" , []byte ("" ))
1518
1647
require .NoError (t , err )
1519
- prom := e2edb .NewPrometheus (prometheusLatestImage , map [string ]string {})
1648
+ prom := e2edb .NewPrometheus ("" , map [string ]string {})
1520
1649
require .NoError (t , s .StartAndWaitReady (prom ))
1521
1650
1522
1651
c2 , err := e2ecortex .NewPromQueryClient (prom .HTTPEndpoint ())
0 commit comments