package main import ( "sync" "testing" "time" ) func TestRule_state(t *testing.T) { state := newRuleState() 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 < defaultStateEntriesLimit*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()) != defaultStateEntriesLimit { t.Fatalf("expected for state to have %d entries only; got %d", defaultStateEntriesLimit, 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() 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() }