mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 23:48:06 -05:00
Fix counters data races in async tests (#11030)
* Fix counters data races in async/debounce tests Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu> * Fix counters data races in async/every tests Signed-off-by: Luca Georges Francois <luca.georges-francois@epitech.eu>
This commit is contained in:
@@ -3,6 +3,7 @@ package async_test
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ func TestDebounce_NoEvents(t *testing.T) {
|
|||||||
eventsChan := make(chan interface{}, 100)
|
eventsChan := make(chan interface{}, 100)
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
interval := time.Second
|
interval := time.Second
|
||||||
timesHandled := 0
|
timesHandled := int32(0)
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
@@ -26,21 +27,21 @@ func TestDebounce_NoEvents(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
async.Debounce(ctx, interval, eventsChan, func(event interface{}) {
|
async.Debounce(ctx, interval, eventsChan, func(event interface{}) {
|
||||||
timesHandled++
|
atomic.AddInt32(×Handled, 1)
|
||||||
})
|
})
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
if util.WaitTimeout(wg, interval*2) {
|
if util.WaitTimeout(wg, interval*2) {
|
||||||
t.Fatalf("Test should have exited by now, timed out")
|
t.Fatalf("Test should have exited by now, timed out")
|
||||||
}
|
}
|
||||||
assert.Equal(t, 0, timesHandled, "Wrong number of handled calls")
|
assert.Equal(t, int32(0), atomic.LoadInt32(×Handled), "Wrong number of handled calls")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDebounce_CtxClosing(t *testing.T) {
|
func TestDebounce_CtxClosing(t *testing.T) {
|
||||||
eventsChan := make(chan interface{}, 100)
|
eventsChan := make(chan interface{}, 100)
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
interval := time.Second
|
interval := time.Second
|
||||||
timesHandled := 0
|
timesHandled := int32(0)
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
@@ -62,23 +63,23 @@ func TestDebounce_CtxClosing(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
async.Debounce(ctx, interval, eventsChan, func(event interface{}) {
|
async.Debounce(ctx, interval, eventsChan, func(event interface{}) {
|
||||||
timesHandled++
|
atomic.AddInt32(×Handled, 1)
|
||||||
})
|
})
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
if util.WaitTimeout(wg, interval*2) {
|
if util.WaitTimeout(wg, interval*2) {
|
||||||
t.Fatalf("Test should have exited by now, timed out")
|
t.Fatalf("Test should have exited by now, timed out")
|
||||||
}
|
}
|
||||||
assert.Equal(t, 0, timesHandled, "Wrong number of handled calls")
|
assert.Equal(t, int32(0), atomic.LoadInt32(×Handled), "Wrong number of handled calls")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDebounce_SingleHandlerInvocation(t *testing.T) {
|
func TestDebounce_SingleHandlerInvocation(t *testing.T) {
|
||||||
eventsChan := make(chan interface{}, 100)
|
eventsChan := make(chan interface{}, 100)
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
interval := time.Second
|
interval := time.Second
|
||||||
timesHandled := 0
|
timesHandled := int32(0)
|
||||||
go async.Debounce(ctx, interval, eventsChan, func(event interface{}) {
|
go async.Debounce(ctx, interval, eventsChan, func(event interface{}) {
|
||||||
timesHandled++
|
atomic.AddInt32(×Handled, 1)
|
||||||
})
|
})
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
eventsChan <- struct{}{}
|
eventsChan <- struct{}{}
|
||||||
@@ -86,7 +87,7 @@ func TestDebounce_SingleHandlerInvocation(t *testing.T) {
|
|||||||
// We should expect 100 rapid fire changes to only have caused
|
// We should expect 100 rapid fire changes to only have caused
|
||||||
// 1 handler to trigger after the debouncing period.
|
// 1 handler to trigger after the debouncing period.
|
||||||
time.Sleep(interval * 2)
|
time.Sleep(interval * 2)
|
||||||
assert.Equal(t, 1, timesHandled, "Wrong number of handled calls")
|
assert.Equal(t, int32(1), atomic.LoadInt32(×Handled), "Wrong number of handled calls")
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,23 +95,23 @@ func TestDebounce_MultipleHandlerInvocation(t *testing.T) {
|
|||||||
eventsChan := make(chan interface{}, 100)
|
eventsChan := make(chan interface{}, 100)
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
interval := time.Second
|
interval := time.Second
|
||||||
timesHandled := 0
|
timesHandled := int32(0)
|
||||||
go async.Debounce(ctx, interval, eventsChan, func(event interface{}) {
|
go async.Debounce(ctx, interval, eventsChan, func(event interface{}) {
|
||||||
timesHandled++
|
atomic.AddInt32(×Handled, 1)
|
||||||
})
|
})
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
eventsChan <- struct{}{}
|
eventsChan <- struct{}{}
|
||||||
}
|
}
|
||||||
require.Equal(t, 0, timesHandled, "Events must prevent from handler execution")
|
require.Equal(t, int32(0), atomic.LoadInt32(×Handled), "Events must prevent from handler execution")
|
||||||
|
|
||||||
// By this time the first event should be triggered.
|
// By this time the first event should be triggered.
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
assert.Equal(t, 1, timesHandled, "Wrong number of handled calls")
|
assert.Equal(t, int32(1), atomic.LoadInt32(×Handled), "Wrong number of handled calls")
|
||||||
|
|
||||||
// Second event.
|
// Second event.
|
||||||
eventsChan <- struct{}{}
|
eventsChan <- struct{}{}
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
assert.Equal(t, 2, timesHandled, "Wrong number of handled calls")
|
assert.Equal(t, int32(2), atomic.LoadInt32(×Handled), "Wrong number of handled calls")
|
||||||
|
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package async_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -11,15 +12,15 @@ import (
|
|||||||
func TestEveryRuns(t *testing.T) {
|
func TestEveryRuns(t *testing.T) {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
i := 0
|
i := int32(0)
|
||||||
async.RunEvery(ctx, 100*time.Millisecond, func() {
|
async.RunEvery(ctx, 100*time.Millisecond, func() {
|
||||||
i++
|
atomic.AddInt32(&i, 1)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Sleep for a bit and ensure the value has increased.
|
// Sleep for a bit and ensure the value has increased.
|
||||||
time.Sleep(200 * time.Millisecond)
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
|
||||||
if i == 0 {
|
if atomic.LoadInt32(&i) == 0 {
|
||||||
t.Error("Counter failed to increment with ticker")
|
t.Error("Counter failed to increment with ticker")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,12 +29,12 @@ func TestEveryRuns(t *testing.T) {
|
|||||||
// Sleep for a bit to let the cancel take place.
|
// Sleep for a bit to let the cancel take place.
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
last := i
|
last := atomic.LoadInt32(&i)
|
||||||
|
|
||||||
// Sleep for a bit and ensure the value has not increased.
|
// Sleep for a bit and ensure the value has not increased.
|
||||||
time.Sleep(200 * time.Millisecond)
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
|
||||||
if i != last {
|
if atomic.LoadInt32(&i) != last {
|
||||||
t.Error("Counter incremented after stop")
|
t.Error("Counter incremented after stop")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user