Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 104 additions & 11 deletions prometheus/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ package prometheus_test

import (
"bytes"
"math/rand"
"net/http"
"net/http/httptest"
"sync"
"testing"
"time"

dto "github.com/prometheus/client_model/go"

Expand Down Expand Up @@ -738,14 +741,8 @@ func BenchmarkHandler(b *testing.B) {
}
}

func TestRegisterWithOrGet(t *testing.T) {
// Replace the default registerer just to be sure. This is bad, but this
// whole test will go away once RegisterOrGet is removed.
oldRegisterer := prometheus.DefaultRegisterer
defer func() {
prometheus.DefaultRegisterer = oldRegisterer
}()
prometheus.DefaultRegisterer = prometheus.NewRegistry()
func TestAlreadyRegistered(t *testing.T) {
reg := prometheus.NewRegistry()
original := prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "test",
Expand All @@ -761,11 +758,11 @@ func TestRegisterWithOrGet(t *testing.T) {
[]string{"foo", "bar"},
)
var err error
if err = prometheus.Register(original); err != nil {
if err = reg.Register(original); err != nil {
t.Fatal(err)
}
if err = prometheus.Register(equalButNotSame); err == nil {
t.Fatal("expected error when registringe equal collector")
if err = reg.Register(equalButNotSame); err == nil {
t.Fatal("expected error when registering equal collector")
}
if are, ok := err.(prometheus.AlreadyRegisteredError); ok {
if are.ExistingCollector != original {
Expand All @@ -778,3 +775,99 @@ func TestRegisterWithOrGet(t *testing.T) {
t.Error("unexpected error:", err)
}
}

// 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
// registry is called concurrently.
func TestHistogramVecRegisterGatherConcurrency(t *testing.T) {
var (
reg = prometheus.NewPedanticRegistry()
hv = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "test_histogram",
Help: "This helps testing.",
ConstLabels: prometheus.Labels{"foo": "bar"},
},
[]string{"one", "two", "three"},
)
labelValues = []string{"a", "b", "c", "alpha", "beta", "gamma", "aleph", "beth", "gimel"}
quit = make(chan struct{})
wg sync.WaitGroup
)

observe := func() {
defer wg.Done()
for {
select {
case <-quit:
return
default:
obs := rand.NormFloat64()*.1 + .2
hv.WithLabelValues(
labelValues[rand.Intn(len(labelValues))],
labelValues[rand.Intn(len(labelValues))],
labelValues[rand.Intn(len(labelValues))],
).Observe(obs)
}
}
}

register := func() {
defer wg.Done()
for {
select {
case <-quit:
return
default:
if err := reg.Register(hv); err != nil {
if _, ok := err.(prometheus.AlreadyRegisteredError); !ok {
t.Error("Registering failed:", err)
}
}
time.Sleep(7 * time.Millisecond)
}
}
}

gather := func() {
defer wg.Done()
for {
select {
case <-quit:
return
default:
if g, err := reg.Gather(); err != nil {
t.Error("Gathering failed:", err)
} else {
if len(g) == 0 {
continue
}
if len(g) != 1 {
t.Error("Gathered unexpected number of metric families:", len(g))
}
if len(g[0].Metric[0].Label) != 4 {
t.Error("Gathered unexpected number of label pairs:", len(g[0].Metric[0].Label))
}
}
time.Sleep(4 * time.Millisecond)
}
}
}

wg.Add(10)
go observe()
go observe()
go register()
go observe()
go gather()
go observe()
go register()
go observe()
go gather()
go observe()

time.Sleep(time.Second)
close(quit)
wg.Wait()
}