diff --git a/internal/stats/stats_test.go b/internal/stats/stats_test.go index 9af4079f9a0..264bf356b79 100644 --- a/internal/stats/stats_test.go +++ b/internal/stats/stats_test.go @@ -165,10 +165,8 @@ func TestStatsCollector(t *testing.T) { } func TestStats_races(t *testing.T) { - const unitUpdIvl = time.Second / 2 - - idGen := func() (id uint32) { return uint32(time.Now().UnixNano() / int64(unitUpdIvl)) } - + var r uint32 + idGen := func() (id uint32) { return atomic.LoadUint32(&r) } conf := Config{ UnitID: idGen, Filename: "./stats.db", @@ -187,7 +185,11 @@ func TestStats_races(t *testing.T) { return os.Remove(conf.Filename) }) - writeFunc := func(wg *sync.WaitGroup, i int) { + waitAtomically := func(control *uint32) { + for atomic.LoadUint32(control) == 0 { + } + } + writeFunc := func(wg *sync.WaitGroup, control *uint32, i int) { e := Entry{ Domain: fmt.Sprintf("example-%d.org", i), Client: fmt.Sprintf("client_%d", i), @@ -196,40 +198,41 @@ func TestStats_races(t *testing.T) { } wg.Done() - wg.Wait() + waitAtomically(control) s.Update(e) } - readFunc := func(wg *sync.WaitGroup) { + readFunc := func(wg *sync.WaitGroup, control *uint32) { wg.Done() - wg.Wait() + waitAtomically(control) _, _ = s.getData() } const ( roundsNum = 3 - roundsIvl = time.Second writersNum = 10 readersNum = 5 ) for round := 0; round < roundsNum; round++ { - time.Sleep(roundsIvl) + atomic.StoreUint32(&r, uint32(round)) wg := &sync.WaitGroup{} - wg.Add(writersNum + readersNum) - - name := fmt.Sprintf("round-%d_%s_since_start", round+1, time.Since(startTime)) - t.Run(name, func(_ *testing.T) { - for i := 0; i < writersNum; i++ { - go writeFunc(wg, i) - } - - for i := 0; i < readersNum; i++ { - go readFunc(wg) - } - }) + var control uint32 + + for i := 0; i < writersNum; i++ { + wg.Add(1) + go writeFunc(wg, &control, i) + } + + for i := 0; i < readersNum; i++ { + wg.Add(1) + go readFunc(wg, &control) + } + + wg.Wait() + atomic.StoreUint32(&control, 1) } }