Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve CollectAndCount #753

Merged
merged 1 commit into from May 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
58 changes: 35 additions & 23 deletions prometheus/testutil/testutil.go
Expand Up @@ -112,31 +112,43 @@ func ToFloat64(c prometheus.Collector) float64 {
panic(fmt.Errorf("collected a non-gauge/counter/untyped metric: %s", pb))
}

// CollectAndCount collects all Metrics from the provided Collector and returns their number.
//
// This can be used to assert the number of metrics collected by a given collector after certain operations.
//
// This function is only for testing purposes, and even for testing, other approaches
// are often more appropriate (see this package's documentation).
func CollectAndCount(c prometheus.Collector) int {
var (
mCount int
mChan = make(chan prometheus.Metric)
done = make(chan struct{})
)

go func() {
for range mChan {
mCount++
}
close(done)
}()
// CollectAndCount registers the provided Collector with a newly created
// pedantic Registry. It then calls GatherAndCount with that Registry and with
// the provided metricNames. In the unlikely case that the registration or the
// gathering fails, this function panics. (This is inconsistent with the other
// CollectAnd… functions in this package and has historical reasons. Changing
bwplotka marked this conversation as resolved.
Show resolved Hide resolved
// the function signature would be a breaking change and will therefore only
// happen with the next major version bump.)
func CollectAndCount(c prometheus.Collector, metricNames ...string) int {
bwplotka marked this conversation as resolved.
Show resolved Hide resolved
reg := prometheus.NewPedanticRegistry()
if err := reg.Register(c); err != nil {
panic(fmt.Errorf("registering collector failed: %s", err))
}
result, err := GatherAndCount(reg, metricNames...)
if err != nil {
panic(err)
}
return result
}

c.Collect(mChan)
close(mChan)
<-done
// GatherAndCount gathers all metrics from the provided Gatherer and counts
// them. It returns the number of metric children in all gathered metric
// families together. If any metricNames are provided, only metrics with those
// names are counted.
func GatherAndCount(g prometheus.Gatherer, metricNames ...string) (int, error) {
got, err := g.Gather()
if err != nil {
return 0, fmt.Errorf("gathering metrics failed: %s", err)
}
if metricNames != nil {
got = filterMetrics(got, metricNames)
}

return mCount
result := 0
for _, mf := range got {
result += len(mf.GetMetric())
}
return result, nil
}

// CollectAndCompare registers the provided Collector with a newly created
Expand Down
27 changes: 27 additions & 0 deletions prometheus/testutil/testutil_test.go
Expand Up @@ -306,3 +306,30 @@ some_total{label1="value1"} 1
t.Errorf("Expected\n%#+v\nGot:\n%#+v", expectedError, err.Error())
}
}

func TestCollectAndCount(t *testing.T) {
c := prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "some_total",
Help: "A value that represents a counter.",
},
[]string{"foo"},
)
if got, want := CollectAndCount(c), 0; got != want {
t.Errorf("unexpected metric count, got %d, want %d", got, want)
}
c.WithLabelValues("bar")
if got, want := CollectAndCount(c), 1; got != want {
t.Errorf("unexpected metric count, got %d, want %d", got, want)
}
c.WithLabelValues("baz")
if got, want := CollectAndCount(c), 2; got != want {
t.Errorf("unexpected metric count, got %d, want %d", got, want)
}
if got, want := CollectAndCount(c, "some_total"), 2; got != want {
t.Errorf("unexpected metric count, got %d, want %d", got, want)
}
if got, want := CollectAndCount(c, "some_other_total"), 0; got != want {
t.Errorf("unexpected metric count, got %d, want %d", got, want)
}
}