From 4be0ab45ec4098482af24269ab424d0bcc0cc8bc Mon Sep 17 00:00:00 2001 From: Leo Antunes Date: Thu, 17 Oct 2019 12:34:06 +0200 Subject: [PATCH] ensure same collectorID calculated on reg and unreg Signed-off-by: Leo Antunes --- prometheus/registry.go | 4 ++-- prometheus/registry_test.go | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/prometheus/registry.go b/prometheus/registry.go index b1f8ed8..c05d6ee 100644 --- a/prometheus/registry.go +++ b/prometheus/registry.go @@ -361,7 +361,7 @@ func (r *Registry) Unregister(c Collector) bool { var ( descChan = make(chan *Desc, capDescChan) descIDs = map[uint64]struct{}{} - collectorID uint64 // Just a sum of the desc IDs. + collectorID uint64 // All desc IDs XOR'd together. ) go func() { c.Describe(descChan) @@ -369,7 +369,7 @@ func (r *Registry) Unregister(c Collector) bool { }() for desc := range descChan { if _, exists := descIDs[desc.id]; !exists { - collectorID += desc.id + collectorID ^= desc.id descIDs[desc.id] = struct{}{} } } diff --git a/prometheus/registry_test.go b/prometheus/registry_test.go index c06ee4b..67e4fcb 100644 --- a/prometheus/registry_test.go +++ b/prometheus/registry_test.go @@ -863,6 +863,23 @@ func TestAlreadyRegistered(t *testing.T) { } } +// TestRegisterUnregisterCollector ensures registering and unregistering a +// collector doesn't leave any dangling metrics. +// We use NewGoCollector as a nice concrete example of a collector with +// multiple metrics. +func TestRegisterUnregisterCollector(t *testing.T) { + col := prometheus.NewGoCollector() + + reg := prometheus.NewRegistry() + reg.MustRegister(col) + reg.Unregister(col) + if metrics, err := reg.Gather(); err != nil { + t.Error("error gathering sample metric") + } else if len(metrics) != 0 { + t.Error("should have unregistered metric") + } +} + // TestHistogramVecRegisterGatherConcurrency is an end-to-end test that // concurrently calls Observe on random elements of a HistogramVec while the // same HistogramVec is registered concurrently and the Gather method of the