4
4
import com .evanlennick .retry4j .config .RetryConfigBuilder ;
5
5
import com .evanlennick .retry4j .exception .RetriesExhaustedException ;
6
6
import com .evanlennick .retry4j .exception .UnexpectedException ;
7
+ import org .testng .annotations .AfterClass ;
7
8
import org .testng .annotations .BeforeClass ;
8
9
import org .testng .annotations .Test ;
9
10
10
11
import java .time .Duration ;
11
12
import java .util .concurrent .Callable ;
12
13
import java .util .concurrent .CompletableFuture ;
13
14
import java .util .concurrent .ExecutionException ;
15
+ import java .util .concurrent .ExecutorService ;
16
+ import java .util .concurrent .Executors ;
14
17
15
18
import static org .assertj .core .api .Assertions .assertThat ;
16
19
import static org .assertj .core .api .Assertions .assertThatThrownBy ;
@@ -21,6 +24,8 @@ public class AsyncCallExecutorTest {
21
24
22
25
private RetryConfig failOnAnyExceptionConfig ;
23
26
27
+ private ExecutorService executorService ;
28
+
24
29
@ BeforeClass
25
30
public void setup () {
26
31
retryOnAnyExceptionConfig = new RetryConfigBuilder ()
@@ -36,10 +41,17 @@ public void setup() {
36
41
.withMaxNumberOfTries (1 )
37
42
.withDelayBetweenTries (Duration .ofMillis (0 ))
38
43
.build ();
44
+
45
+ executorService = Executors .newFixedThreadPool (5 );
46
+ }
47
+
48
+ @ AfterClass
49
+ public void teardown () {
50
+ executorService .shutdown ();
39
51
}
40
52
41
53
@ Test
42
- public void verifyMultipleCalls () throws Exception {
54
+ public void verifyMultipleCalls_noExecutorService () throws Exception {
43
55
Callable <Boolean > callable = () -> true ;
44
56
45
57
AsyncCallExecutor <Boolean > executor = new AsyncCallExecutor <>(retryOnAnyExceptionConfig );
@@ -58,7 +70,7 @@ public void verifyMultipleCalls() throws Exception {
58
70
}
59
71
60
72
@ Test
61
- public void verifyOneCall_success () throws Exception {
73
+ public void verifyOneCall_success_noExecutorService () throws Exception {
62
74
Callable <Boolean > callable = () -> true ;
63
75
64
76
AsyncCallExecutor <Boolean > executor = new AsyncCallExecutor <>(retryOnAnyExceptionConfig );
@@ -71,7 +83,7 @@ public void verifyOneCall_success() throws Exception {
71
83
}
72
84
73
85
@ Test
74
- public void verifyOneCall_failDueToTooManyRetries () throws Exception {
86
+ public void verifyOneCall_failDueToTooManyRetries_noExecutorService () throws Exception {
75
87
Callable <Boolean > callable = () -> { throw new RuntimeException (); };
76
88
77
89
AsyncCallExecutor <Boolean > executor = new AsyncCallExecutor <>(retryOnAnyExceptionConfig );
@@ -84,7 +96,7 @@ public void verifyOneCall_failDueToTooManyRetries() throws Exception {
84
96
}
85
97
86
98
@ Test
87
- public void verifyOneCall_failDueToUnexpectedException () throws Exception {
99
+ public void verifyOneCall_failDueToUnexpectedException_noExecutorService () throws Exception {
88
100
Callable <Boolean > callable = () -> { throw new RuntimeException (); };
89
101
90
102
AsyncCallExecutor <Boolean > executor = new AsyncCallExecutor <>(failOnAnyExceptionConfig );
@@ -95,4 +107,70 @@ public void verifyOneCall_failDueToUnexpectedException() throws Exception {
95
107
.isExactlyInstanceOf (ExecutionException .class )
96
108
.hasCauseExactlyInstanceOf (UnexpectedException .class );
97
109
}
110
+
111
+ @ Test
112
+ public void verifyMultipleCalls_withExecutorService () throws Exception {
113
+ Callable <Boolean > callable = () -> true ;
114
+
115
+ AsyncCallExecutor <Boolean > executor = new AsyncCallExecutor <>(
116
+ retryOnAnyExceptionConfig ,
117
+ executorService );
118
+
119
+ CompletableFuture <Status <Boolean >> future1 = executor .execute (callable );
120
+ CompletableFuture <Status <Boolean >> future2 = executor .execute (callable );
121
+ CompletableFuture <Status <Boolean >> future3 = executor .execute (callable );
122
+
123
+ CompletableFuture combinedFuture
124
+ = CompletableFuture .allOf (future1 , future2 , future3 );
125
+ combinedFuture .get ();
126
+
127
+ assertThat (future1 ).isDone ();
128
+ assertThat (future2 ).isDone ();
129
+ assertThat (future3 ).isDone ();
130
+ }
131
+
132
+ @ Test
133
+ public void verifyOneCall_success_withExecutorService () throws Exception {
134
+ Callable <Boolean > callable = () -> true ;
135
+
136
+ AsyncCallExecutor <Boolean > executor = new AsyncCallExecutor <>(
137
+ retryOnAnyExceptionConfig ,
138
+ executorService );
139
+
140
+ CompletableFuture <Status <Boolean >> future = executor .execute (callable );
141
+
142
+ Status <Boolean > status = future .get ();
143
+ assertThat (future ).isDone ();
144
+ assertThat (status .wasSuccessful ()).isTrue ();
145
+ }
146
+
147
+ @ Test
148
+ public void verifyOneCall_failDueToTooManyRetries_withExecutorService () throws Exception {
149
+ Callable <Boolean > callable = () -> { throw new RuntimeException (); };
150
+
151
+ AsyncCallExecutor <Boolean > executor = new AsyncCallExecutor <>(
152
+ retryOnAnyExceptionConfig ,
153
+ executorService );
154
+
155
+ CompletableFuture <Status <Boolean >> future = executor .execute (callable );
156
+
157
+ assertThatThrownBy (future ::get )
158
+ .isExactlyInstanceOf (ExecutionException .class )
159
+ .hasCauseExactlyInstanceOf (RetriesExhaustedException .class );
160
+ }
161
+
162
+ @ Test
163
+ public void verifyOneCall_failDueToUnexpectedException_withExecutorService () throws Exception {
164
+ Callable <Boolean > callable = () -> { throw new RuntimeException (); };
165
+
166
+ AsyncCallExecutor <Boolean > executor = new AsyncCallExecutor <>(
167
+ failOnAnyExceptionConfig ,
168
+ executorService );
169
+
170
+ CompletableFuture <Status <Boolean >> future = executor .execute (callable );
171
+
172
+ assertThatThrownBy (future ::get )
173
+ .isExactlyInstanceOf (ExecutionException .class )
174
+ .hasCauseExactlyInstanceOf (UnexpectedException .class );
175
+ }
98
176
}
0 commit comments