mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-01 14:47:38 +00:00
4e922eb93b
* vmalert: use group's ID in UI to avoid collisions Identical group names are allowed. So we should used IDs for various groupings and aggregations in UI. Signed-off-by: hagen1778 <roman@victoriametrics.com> * vmalert: prevent disabling state updates tracking The minimum number of update states to track is now set to 1. Signed-off-by: hagen1778 <roman@victoriametrics.com> * vmalert: properly update `debug` and `update_entries_limit` params on hot-reload Signed-off-by: hagen1778 <roman@victoriametrics.com> * vmalert: display `debug` field for rule in UI Signed-off-by: hagen1778 <roman@victoriametrics.com> * vmalert: exclude `updates` field from json marhsaling This field isn't correctly marshaled right now. And implementing the correct marshaling for it doesn't seem right, since json representation is mostly used by systems like Grafana. And Grafana doesn't expect this field to be present. Signed-off-by: hagen1778 <roman@victoriametrics.com> * fix test for disabled state Signed-off-by: hagen1778 <roman@victoriametrics.com> * fix test for disabled state Signed-off-by: hagen1778 <roman@victoriametrics.com> --------- Signed-off-by: hagen1778 <roman@victoriametrics.com>
100 lines
2 KiB
Go
100 lines
2 KiB
Go
package main
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestRule_stateDisabled(t *testing.T) {
|
|
state := newRuleState(-1)
|
|
e := state.getLast()
|
|
if !e.at.IsZero() {
|
|
t.Fatalf("expected entry to be zero")
|
|
}
|
|
|
|
state.add(ruleStateEntry{at: time.Now()})
|
|
state.add(ruleStateEntry{at: time.Now()})
|
|
state.add(ruleStateEntry{at: time.Now()})
|
|
|
|
if len(state.getAll()) != 1 {
|
|
// state should store at least one update at any circumstances
|
|
t.Fatalf("expected for state to have %d entries; got %d",
|
|
1, len(state.getAll()),
|
|
)
|
|
}
|
|
}
|
|
func TestRule_state(t *testing.T) {
|
|
stateEntriesN := 20
|
|
state := newRuleState(stateEntriesN)
|
|
e := state.getLast()
|
|
if !e.at.IsZero() {
|
|
t.Fatalf("expected entry to be zero")
|
|
}
|
|
|
|
now := time.Now()
|
|
state.add(ruleStateEntry{at: now})
|
|
|
|
e = state.getLast()
|
|
if e.at != now {
|
|
t.Fatalf("expected entry at %v to be equal to %v",
|
|
e.at, now)
|
|
}
|
|
|
|
time.Sleep(time.Millisecond)
|
|
now2 := time.Now()
|
|
state.add(ruleStateEntry{at: now2})
|
|
|
|
e = state.getLast()
|
|
if e.at != now2 {
|
|
t.Fatalf("expected entry at %v to be equal to %v",
|
|
e.at, now2)
|
|
}
|
|
|
|
if len(state.getAll()) != 2 {
|
|
t.Fatalf("expected for state to have 2 entries only; got %d",
|
|
len(state.getAll()),
|
|
)
|
|
}
|
|
|
|
var last time.Time
|
|
for i := 0; i < stateEntriesN*2; i++ {
|
|
last = time.Now()
|
|
state.add(ruleStateEntry{at: last})
|
|
}
|
|
|
|
e = state.getLast()
|
|
if e.at != last {
|
|
t.Fatalf("expected entry at %v to be equal to %v",
|
|
e.at, last)
|
|
}
|
|
|
|
if len(state.getAll()) != stateEntriesN {
|
|
t.Fatalf("expected for state to have %d entries only; got %d",
|
|
stateEntriesN, len(state.getAll()),
|
|
)
|
|
}
|
|
}
|
|
|
|
// TestRule_stateConcurrent supposed to test concurrent
|
|
// execution of state updates.
|
|
// Should be executed with -race flag
|
|
func TestRule_stateConcurrent(t *testing.T) {
|
|
state := newRuleState(20)
|
|
|
|
const workers = 50
|
|
const iterations = 100
|
|
wg := sync.WaitGroup{}
|
|
wg.Add(workers)
|
|
for i := 0; i < workers; i++ {
|
|
go func() {
|
|
defer wg.Done()
|
|
for i := 0; i < iterations; i++ {
|
|
state.add(ruleStateEntry{at: time.Now()})
|
|
state.getAll()
|
|
state.getLast()
|
|
}
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
}
|