@@ -41,12 +41,12 @@ import (
4141 "bytes"
4242 "fmt"
4343 "io"
44+ "net/http"
4445 "reflect"
4546
4647 "github.com/davecgh/go-spew/spew"
47- "github.com/prometheus/common/expfmt"
48-
4948 dto "github.com/prometheus/client_model/go"
49+ "github.com/prometheus/common/expfmt"
5050
5151 "github.com/prometheus/client_golang/prometheus"
5252 "github.com/prometheus/client_golang/prometheus/internal"
@@ -155,6 +155,34 @@ func GatherAndCount(g prometheus.Gatherer, metricNames ...string) (int, error) {
155155 return result , nil
156156}
157157
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+
158186// CollectAndCompare registers the provided Collector with a newly created
159187// pedantic Registry. It then calls GatherAndCompare with that Registry and with
160188// the provided metricNames.
@@ -184,17 +212,35 @@ func TransactionalGatherAndCompare(g prometheus.TransactionalGatherer, expected
184212 if err != nil {
185213 return fmt .Errorf ("gathering metrics failed: %w" , err )
186214 }
187- if metricNames != nil {
188- got = filterMetrics (got , metricNames )
215+
216+ wanted , err := convertReaderToMetricFamily (expected )
217+ if err != nil {
218+ return err
189219 }
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 ) {
190227 var tp expfmt.TextParser
191- wantRaw , err := tp .TextToMetricFamilies (expected )
228+ notNormalized , err := tp .TextToMetricFamilies (reader )
192229 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 )
194241 }
195- want := internal .NormalizeMetricFamilies (wantRaw )
196242
197- return compare (got , want )
243+ return compare (got , expected )
198244}
199245
200246// compare encodes both provided slices of metric families into the text format,
0 commit comments