(t *testing.T)
| 212 | } |
| 213 | |
| 214 | func Test_gauge_concurrencyDataRace(t *testing.T) { |
| 215 | c := newGauge("my_gauge", noopLimiter, map[string]string{}, 15*time.Minute) |
| 216 | |
| 217 | end := make(chan struct{}) |
| 218 | |
| 219 | accessor := func(f func()) { |
| 220 | for { |
| 221 | select { |
| 222 | case <-end: |
| 223 | return |
| 224 | default: |
| 225 | f() |
| 226 | } |
| 227 | } |
| 228 | } |
| 229 | |
| 230 | for i := 0; i < 4; i++ { |
| 231 | go accessor(func() { |
| 232 | c.Inc(buildTestLabels([]string{"label"}, []string{"value-1"}), 1.0) |
| 233 | c.Inc(buildTestLabels([]string{"label"}, []string{"value-2"}), 1.0) |
| 234 | }) |
| 235 | } |
| 236 | |
| 237 | // this goroutine constantly creates new series |
| 238 | letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") |
| 239 | go accessor(func() { |
| 240 | s := make([]rune, 6) |
| 241 | for i := range s { |
| 242 | s[i] = letters[rand.Intn(len(letters))] |
| 243 | } |
| 244 | c.Inc(buildTestLabels([]string{"label"}, []string{string(s)}), 1.0) |
| 245 | }) |
| 246 | |
| 247 | go accessor(func() { |
| 248 | err := c.collectMetrics(&noopAppender{}, 0) |
| 249 | assert.NoError(t, err) |
| 250 | }) |
| 251 | |
| 252 | go accessor(func() { |
| 253 | c.removeStaleSeries(time.Now().UnixMilli()) |
| 254 | }) |
| 255 | |
| 256 | time.Sleep(200 * time.Millisecond) |
| 257 | close(end) |
| 258 | } |
| 259 | |
| 260 | func Test_gauge_concurrencyCorrectness(t *testing.T) { |
| 261 | c := newGauge("my_gauge", noopLimiter, map[string]string{}, 15*time.Minute) |
nothing calls this directly
no test coverage detected