@@ -41,12 +41,12 @@ import (
41
41
"bytes"
42
42
"fmt"
43
43
"io"
44
+ "net/http"
44
45
"reflect"
45
46
46
47
"github.com/davecgh/go-spew/spew"
47
- "github.com/prometheus/common/expfmt"
48
-
49
48
dto "github.com/prometheus/client_model/go"
49
+ "github.com/prometheus/common/expfmt"
50
50
51
51
"github.com/prometheus/client_golang/prometheus"
52
52
"github.com/prometheus/client_golang/prometheus/internal"
@@ -155,6 +155,34 @@ func GatherAndCount(g prometheus.Gatherer, metricNames ...string) (int, error) {
155
155
return result , nil
156
156
}
157
157
158
+ // ScrapeAndCompare calls a remote exporter's endpoint which is expected to return some metrics in
159
+ // plain text format. Then it compares it with the results that the `expected` would return.
160
+ // If the `metricNames` is not empty it would filter the comparison only to the given metric names.
161
+ func ScrapeAndCompare (url string , expected io.Reader , metricNames ... string ) error {
162
+ resp , err := http .Get (url )
163
+ if err != nil {
164
+ return fmt .Errorf ("scraping metrics failed: %w" , err )
165
+ }
166
+ defer resp .Body .Close ()
167
+
168
+ if resp .StatusCode != http .StatusOK {
169
+ return fmt .Errorf ("the scraping target returned a status code other than 200: %d" ,
170
+ resp .StatusCode )
171
+ }
172
+
173
+ scraped , err := convertReaderToMetricFamily (resp .Body )
174
+ if err != nil {
175
+ return err
176
+ }
177
+
178
+ wanted , err := convertReaderToMetricFamily (expected )
179
+ if err != nil {
180
+ return err
181
+ }
182
+
183
+ return compareMetricFamilies (scraped , wanted , metricNames ... )
184
+ }
185
+
158
186
// CollectAndCompare registers the provided Collector with a newly created
159
187
// pedantic Registry. It then calls GatherAndCompare with that Registry and with
160
188
// the provided metricNames.
@@ -184,17 +212,35 @@ func TransactionalGatherAndCompare(g prometheus.TransactionalGatherer, expected
184
212
if err != nil {
185
213
return fmt .Errorf ("gathering metrics failed: %w" , err )
186
214
}
187
- if metricNames != nil {
188
- got = filterMetrics (got , metricNames )
215
+
216
+ wanted , err := convertReaderToMetricFamily (expected )
217
+ if err != nil {
218
+ return err
189
219
}
220
+
221
+ return compareMetricFamilies (got , wanted , metricNames ... )
222
+ }
223
+
224
+ // convertReaderToMetricFamily would read from a io.Reader object and convert it to a slice of
225
+ // dto.MetricFamily.
226
+ func convertReaderToMetricFamily (reader io.Reader ) ([]* dto.MetricFamily , error ) {
190
227
var tp expfmt.TextParser
191
- wantRaw , err := tp .TextToMetricFamilies (expected )
228
+ notNormalized , err := tp .TextToMetricFamilies (reader )
192
229
if err != nil {
193
- return fmt .Errorf ("parsing expected metrics failed: %w" , err )
230
+ return nil , fmt .Errorf ("converting reader to metric families failed: %w" , err )
231
+ }
232
+
233
+ return internal .NormalizeMetricFamilies (notNormalized ), nil
234
+ }
235
+
236
+ // compareMetricFamilies would compare 2 slices of metric families, and optionally filters both of
237
+ // them to the `metricNames` provided.
238
+ func compareMetricFamilies (got , expected []* dto.MetricFamily , metricNames ... string ) error {
239
+ if metricNames != nil {
240
+ got = filterMetrics (got , metricNames )
194
241
}
195
- want := internal .NormalizeMetricFamilies (wantRaw )
196
242
197
- return compare (got , want )
243
+ return compare (got , expected )
198
244
}
199
245
200
246
// compare encodes both provided slices of metric families into the text format,
0 commit comments