Skip to content

Commit afb67da

Browse files
authored
utils: fix flaky tests (#1863)
1 parent 0e50970 commit afb67da

File tree

2 files changed

+46
-57
lines changed

2 files changed

+46
-57
lines changed

utils/tasks/exec_timeout.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"time"
66

77
"github.com/pkg/errors"
8-
"go.uber.org/zap"
98
)
109

1110
// Func is the interface of functions to trigger
@@ -18,7 +17,7 @@ type funcResult struct {
1817
}
1918

2019
// ExecWithTimeout triggers some function in the given time frame, returns true if completed
21-
func ExecWithTimeout(ctx context.Context, logger *zap.Logger, fn Func, t time.Duration) (bool, interface{}, error) {
20+
func ExecWithTimeout(ctx context.Context, fn Func, timeout time.Duration) (bool, interface{}, error) {
2221
c := make(chan funcResult, 1)
2322
stopper := newStopper()
2423

@@ -40,7 +39,7 @@ func ExecWithTimeout(ctx context.Context, logger *zap.Logger, fn Func, t time.Du
4039
stopper.stop()
4140
}()
4241
return false, struct{}{}, nil
43-
case <-time.After(t):
42+
case <-time.After(timeout):
4443
go func() {
4544
stopper.stop()
4645
}()

utils/tasks/exec_timeout_test.go

Lines changed: 44 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,61 @@ package tasks
22

33
import (
44
"context"
5-
"sync"
65
"sync/atomic"
76
"testing"
87
"time"
98

10-
"github.com/ssvlabs/ssv/logging"
119
"github.com/stretchr/testify/require"
1210
)
1311

1412
func TestExecWithTimeout(t *testing.T) {
15-
ctxWithTimeout, cancel := context.WithTimeout(context.TODO(), 10*time.Millisecond)
16-
defer cancel()
17-
tests := []struct {
18-
name string
19-
ctx context.Context
20-
t time.Duration
21-
expectedCount uint32
22-
}{
23-
{
24-
"Cancelled_context",
25-
ctxWithTimeout,
26-
20 * time.Millisecond,
27-
3,
28-
},
29-
{
30-
"Long_function",
31-
context.TODO(),
32-
8 * time.Millisecond,
33-
3,
34-
},
35-
}
13+
t.Run("success", func(t *testing.T) {
14+
longExec := func(stopper Stopper) (interface{}, error) {
15+
time.Sleep(2 * time.Millisecond)
16+
return true, nil
17+
}
18+
completed, res, err := ExecWithTimeout(context.TODO(), longExec, 1*time.Minute)
19+
require.True(t, completed)
20+
require.True(t, res.(bool))
21+
require.NoError(t, err)
22+
})
23+
t.Run("ctx timed out", func(t *testing.T) {
24+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
25+
defer cancel()
3626

37-
for _, test := range tests {
38-
test := test
39-
t.Run(test.name, func(t *testing.T) {
40-
var count uint32
41-
var stopped sync.WaitGroup
27+
var started atomic.Bool
4228

43-
stopped.Add(1)
44-
fn := func(stopper Stopper) (interface{}, error) {
45-
for {
46-
if stopper.IsStopped() {
47-
stopped.Done()
48-
return true, nil
49-
}
50-
atomic.AddUint32(&count, 1)
51-
time.Sleep(2 * time.Millisecond)
29+
fn := func(stopper Stopper) (interface{}, error) {
30+
started.Store(true)
31+
for {
32+
if stopper.IsStopped() {
33+
return true, nil
5234
}
35+
time.Sleep(time.Millisecond)
5336
}
54-
completed, _, err := ExecWithTimeout(test.ctx, logging.TestLogger(t), fn, test.t)
55-
stopped.Wait()
56-
require.False(t, completed)
57-
require.NoError(t, err)
58-
require.GreaterOrEqual(t, count, test.expectedCount)
59-
})
60-
}
61-
}
37+
}
38+
completed, _, err := ExecWithTimeout(ctx, fn, 1*time.Hour)
39+
require.True(t, started.Load())
40+
require.False(t, completed)
41+
require.NoError(t, err)
42+
})
43+
t.Run("timed out", func(t *testing.T) {
44+
ctx := context.Background()
45+
46+
var started atomic.Bool
6247

63-
func TestExecWithTimeout_ShortFunc(t *testing.T) {
64-
longExec := func(stopper Stopper) (interface{}, error) {
65-
time.Sleep(2 * time.Millisecond)
66-
return true, nil
67-
}
68-
completed, res, err := ExecWithTimeout(context.TODO(), logging.TestLogger(t), longExec, 10*time.Millisecond)
69-
require.True(t, completed)
70-
require.True(t, res.(bool))
71-
require.NoError(t, err)
48+
fn := func(stopper Stopper) (interface{}, error) {
49+
started.Store(true)
50+
for {
51+
if stopper.IsStopped() {
52+
return true, nil
53+
}
54+
time.Sleep(time.Millisecond)
55+
}
56+
}
57+
completed, _, err := ExecWithTimeout(ctx, fn, 10*time.Millisecond)
58+
require.True(t, started.Load())
59+
require.False(t, completed)
60+
require.NoError(t, err)
61+
})
7262
}

0 commit comments

Comments
 (0)