(t *testing.T)
| 97 | } |
| 98 | |
| 99 | func TestGaugeVecConcurrency(t *testing.T) { |
| 100 | it := func(n uint32) bool { |
| 101 | mutations := int(n % 10000) |
| 102 | concLevel := int(n%15 + 1) |
| 103 | vecLength := int(n%5 + 1) |
| 104 | |
| 105 | var start, end sync.WaitGroup |
| 106 | start.Add(1) |
| 107 | end.Add(concLevel) |
| 108 | |
| 109 | sStreams := make([]chan float64, vecLength) |
| 110 | results := make([]chan float64, vecLength) |
| 111 | done := make(chan struct{}) |
| 112 | |
| 113 | for i := 0; i < vecLength; i++ { |
| 114 | sStreams[i] = make(chan float64, mutations*concLevel) |
| 115 | results[i] = make(chan float64) |
| 116 | go listenGaugeStream(sStreams[i], results[i], done) |
| 117 | } |
| 118 | |
| 119 | go func() { |
| 120 | end.Wait() |
| 121 | close(done) |
| 122 | }() |
| 123 | |
| 124 | gge := NewGaugeVec( |
| 125 | GaugeOpts{ |
| 126 | Name: "test_gauge", |
| 127 | Help: "no help can be found here", |
| 128 | }, |
| 129 | []string{"label"}, |
| 130 | ) |
| 131 | for i := 0; i < concLevel; i++ { |
| 132 | vals := make([]float64, mutations) |
| 133 | pick := make([]int, mutations) |
| 134 | for j := 0; j < mutations; j++ { |
| 135 | vals[j] = rand.Float64() - 0.5 |
| 136 | pick[j] = rand.Intn(vecLength) |
| 137 | } |
| 138 | |
| 139 | go func(vals []float64) { |
| 140 | start.Wait() |
| 141 | for i, v := range vals { |
| 142 | sStreams[pick[i]] <- v |
| 143 | gge.WithLabelValues(string('A' + rune(pick[i]))).Add(v) |
| 144 | } |
| 145 | end.Done() |
| 146 | }(vals) |
| 147 | } |
| 148 | start.Done() |
| 149 | |
| 150 | for i := range sStreams { |
| 151 | if expected, got := <-results[i], math.Float64frombits(gge.WithLabelValues(string('A'+rune(i))).(*gauge).valBits); math.Abs(expected-got) > 0.000001 { |
| 152 | t.Fatalf("expected approx. %f, got %f", expected, got) |
| 153 | return false |
| 154 | } |
| 155 | } |
| 156 | return true |
nothing calls this directly
no test coverage detected