31
31
import java .nio .file .Path ;
32
32
import java .util .ArrayList ;
33
33
import java .util .Arrays ;
34
+ import java .util .Collection ;
34
35
import java .util .List ;
36
+ import java .util .concurrent .Callable ;
35
37
import java .util .concurrent .CompletableFuture ;
38
+ import java .util .concurrent .ExecutionException ;
39
+ import java .util .concurrent .ExecutorService ;
40
+ import java .util .concurrent .Executors ;
41
+ import java .util .concurrent .Future ;
36
42
import java .util .concurrent .TimeUnit ;
43
+ import java .util .concurrent .TimeoutException ;
37
44
import org .apache .commons .lang3 .RandomStringUtils ;
38
45
import org .junit .jupiter .api .AfterEach ;
39
46
import org .junit .jupiter .api .BeforeEach ;
@@ -213,6 +220,32 @@ private static List<FileTransformerConfiguration> configurations() {
213
220
.failureBehavior (LEAVE ).build ());
214
221
}
215
222
223
+ @ Test
224
+ void explicitExecutor_shouldUseExecutor () throws Exception {
225
+ Path testPath = testFs .getPath ("test_file.txt" );
226
+ assertThat (testPath ).doesNotExist ();
227
+ String newContent = RandomStringUtils .randomAlphanumeric (2000 );
228
+
229
+ ExecutorService executor = Executors .newSingleThreadExecutor ();
230
+ try {
231
+ SpyingExecutorService spyingExecutorService = new SpyingExecutorService (executor );
232
+ FileTransformerConfiguration configuration = FileTransformerConfiguration
233
+ .builder ()
234
+ .fileWriteOption (FileWriteOption .CREATE_NEW )
235
+ .failureBehavior (DELETE )
236
+ .executorService (spyingExecutorService )
237
+ .build ();
238
+ FileAsyncResponseTransformer <String > transformer = new FileAsyncResponseTransformer <>(testPath , configuration );
239
+
240
+ stubSuccessfulStreaming (newContent , transformer );
241
+ assertThat (testPath ).hasContent (newContent );
242
+ assertThat (spyingExecutorService .hasReceivedTasks ()).isTrue ();
243
+ } finally {
244
+ executor .shutdown ();
245
+ assertThat (executor .awaitTermination (1 , TimeUnit .MINUTES )).isTrue ();
246
+ }
247
+ }
248
+
216
249
private static void stubSuccessfulStreaming (String newContent , FileAsyncResponseTransformer <String > transformer ) throws Exception {
217
250
CompletableFuture <String > future = transformer .prepare ();
218
251
transformer .onResponse ("foobar" );
@@ -240,4 +273,90 @@ private static void stubException(String newContent, FileAsyncResponseTransforme
240
273
private static SdkPublisher <ByteBuffer > testPublisher (String content ) {
241
274
return SdkPublisher .adapt (Flowable .just (ByteBuffer .wrap (content .getBytes (StandardCharsets .UTF_8 ))));
242
275
}
276
+
277
+ private static final class SpyingExecutorService implements ExecutorService {
278
+ private final ExecutorService executorService ;
279
+ private boolean receivedTasks = false ;
280
+
281
+ private SpyingExecutorService (ExecutorService executorService ) {
282
+ this .executorService = executorService ;
283
+ }
284
+
285
+ public boolean hasReceivedTasks () {
286
+ return receivedTasks ;
287
+ }
288
+
289
+ @ Override
290
+ public void shutdown () {
291
+ executorService .shutdown ();
292
+ }
293
+
294
+ @ Override
295
+ public List <Runnable > shutdownNow () {
296
+ return executorService .shutdownNow ();
297
+ }
298
+
299
+ @ Override
300
+ public boolean isShutdown () {
301
+ return executorService .isShutdown ();
302
+ }
303
+
304
+ @ Override
305
+ public boolean isTerminated () {
306
+ return executorService .isTerminated ();
307
+ }
308
+
309
+ @ Override
310
+ public boolean awaitTermination (long timeout , TimeUnit unit ) throws InterruptedException {
311
+ return executorService .awaitTermination (timeout , unit );
312
+ }
313
+
314
+ @ Override
315
+ public <T > Future <T > submit (Callable <T > task ) {
316
+ receivedTasks = true ;
317
+ return executorService .submit (task );
318
+ }
319
+
320
+ @ Override
321
+ public <T > Future <T > submit (Runnable task , T result ) {
322
+ receivedTasks = true ;
323
+ return executorService .submit (task , result );
324
+ }
325
+
326
+ @ Override
327
+ public Future <?> submit (Runnable task ) {
328
+ receivedTasks = true ;
329
+ return executorService .submit (task );
330
+ }
331
+
332
+ @ Override
333
+ public <T > List <Future <T >> invokeAll (Collection <? extends Callable <T >> tasks ) throws InterruptedException {
334
+ receivedTasks = true ;
335
+ return executorService .invokeAll (tasks );
336
+ }
337
+
338
+ @ Override
339
+ public <T > List <Future <T >> invokeAll (Collection <? extends Callable <T >> tasks , long timeout , TimeUnit unit ) throws InterruptedException {
340
+ receivedTasks = true ;
341
+ return executorService .invokeAll (tasks , timeout , unit );
342
+ }
343
+
344
+ @ Override
345
+ public <T > T invokeAny (Collection <? extends Callable <T >> tasks ) throws InterruptedException , ExecutionException {
346
+ receivedTasks = true ;
347
+ return executorService .invokeAny (tasks );
348
+ }
349
+
350
+ @ Override
351
+ public <T > T invokeAny (Collection <? extends Callable <T >> tasks , long timeout , TimeUnit unit ) throws InterruptedException , ExecutionException , TimeoutException {
352
+ receivedTasks = true ;
353
+ return executorService .invokeAny (tasks , timeout , unit );
354
+ }
355
+
356
+ @ Override
357
+ public void execute (Runnable command ) {
358
+ receivedTasks = true ;
359
+ executorService .execute (command );
360
+ }
361
+ }
243
362
}
0 commit comments