4
4
"context"
5
5
"errors"
6
6
"testing"
7
+ "time"
7
8
8
9
"github.com/stretchr/testify/require"
9
10
)
@@ -13,10 +14,11 @@ func TestDo(t *testing.T) {
13
14
type R = int // result type
14
15
15
16
type args struct {
16
- ctx context.Context
17
- tasks []T
18
- executor func (t T ) (R , error )
19
- opts []DoOpt
17
+ ctx context.Context
18
+ ctxTimeout time.Duration
19
+ tasks []T
20
+ executor func (ctx context.Context , t T ) (R , error )
21
+ opts []DoOpt
20
22
}
21
23
tests := []struct {
22
24
name string
@@ -59,29 +61,62 @@ func TestDo(t *testing.T) {
59
61
require .Equal (t , errors .New ("negative" ), err )
60
62
},
61
63
},
64
+ {
65
+ name : "slow function with sleeps should run concurrently without context deadline error" ,
66
+ args : args {
67
+ ctx : context .Background (),
68
+ ctxTimeout : 50 * time .Millisecond ,
69
+ tasks : []T {
70
+ 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 ,
71
+ 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 ,
72
+ 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 ,
73
+ 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 ,
74
+ 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 , 10 ,
75
+ },
76
+ executor : func (ctx context.Context , t T ) (R , error ) {
77
+ time .Sleep (time .Duration (t ) * time .Millisecond )
78
+ return 1 , nil
79
+ },
80
+ opts : []DoOpt {WithWorkerNum (20 )},
81
+ },
82
+ want : []R {
83
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
84
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
85
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
86
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
87
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
88
+ },
89
+ requireErr : require .NoError ,
90
+ },
62
91
}
63
92
for _ , tt := range tests {
64
93
t .Run (tt .name , func (t * testing.T ) {
65
- got , err := Do (tt .args .ctx , tt .args .tasks , tt .args .executor , tt .args .opts ... )
94
+ ctx := tt .args .ctx
95
+ if tt .args .ctxTimeout > 0 {
96
+ var cancel context.CancelFunc
97
+ ctx , cancel = context .WithTimeout (ctx , tt .args .ctxTimeout )
98
+ defer cancel ()
99
+ }
100
+ got , err := Do (ctx , tt .args .tasks , tt .args .executor , tt .args .opts ... )
66
101
tt .requireErr (t , err )
67
102
require .Equal (t , tt .want , got )
68
103
})
69
104
}
70
105
}
71
106
72
- func fibonacci (n int ) (int , error ) {
107
+ func fibonacci (ctx context. Context , n int ) (int , error ) {
73
108
if n < 0 {
74
109
return 0 , errors .New ("negative" )
75
110
}
76
111
if n < 2 {
77
112
return 1 , nil
78
113
}
79
- r1 , err := fibonacci (n - 1 )
114
+ r1 , err := fibonacci (ctx , n - 1 )
80
115
if err != nil {
81
116
return 0 , err
82
117
}
83
118
84
- r2 , err := fibonacci (n - 2 )
119
+ r2 , err := fibonacci (ctx , n - 2 )
85
120
if err != nil {
86
121
return 0 , err
87
122
}
0 commit comments