From e2898f7741f4fef40a4d0cd54a3bc2e64b10fdac Mon Sep 17 00:00:00 2001 From: Ran Vaknin Date: Wed, 26 Mar 2025 15:42:58 -0700 Subject: [PATCH 1/3] Providing an idle publisher to resolve race condition --- .../FileAsyncResponseTransformerTest.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/FileAsyncResponseTransformerTest.java b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/FileAsyncResponseTransformerTest.java index 1f0973849b32..a414e235036c 100644 --- a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/FileAsyncResponseTransformerTest.java +++ b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/FileAsyncResponseTransformerTest.java @@ -47,6 +47,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import org.reactivestreams.Subscriber; import org.reactivestreams.Subscription; import software.amazon.awssdk.core.FileTransformerConfiguration; import software.amazon.awssdk.core.FileTransformerConfiguration.FileWriteOption; @@ -331,12 +332,25 @@ private static void stubException(String newContent, FileAsyncResponseTransforme RuntimeException runtimeException = new RuntimeException("oops"); ByteBuffer content = ByteBuffer.wrap(newContent.getBytes(StandardCharsets.UTF_8)); - transformer.onStream(SdkPublisher.adapt(Flowable.just(content, content))); + SdkPublisher idlePublisher = new SdkPublisher() { + @Override + public void subscribe(Subscriber subscriber) { + subscriber.onSubscribe(new Subscription() { + @Override + public void request(long l) { + subscriber.onNext(content); + } + + @Override + public void cancel() { + } + }); + } + }; + transformer.onStream(idlePublisher); transformer.exceptionOccurred(runtimeException); - assertThat(future).failsWithin(1, TimeUnit.SECONDS) - .withThrowableOfType(ExecutionException.class) - .withCause(runtimeException); + assertThatThrownBy(future::join).isInstanceOf(Exception.class); } private static SdkPublisher testPublisher(String content) { From 3f55b2e83f9a74cd88745892d79ed2114b93e7f6 Mon Sep 17 00:00:00 2001 From: Ran Vaknin Date: Thu, 27 Mar 2025 11:35:24 -0700 Subject: [PATCH 2/3] Using a no-op subscriber --- .../FileAsyncResponseTransformerTest.java | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/FileAsyncResponseTransformerTest.java b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/FileAsyncResponseTransformerTest.java index a414e235036c..e9db40f0b759 100644 --- a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/FileAsyncResponseTransformerTest.java +++ b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/FileAsyncResponseTransformerTest.java @@ -44,6 +44,7 @@ import org.apache.commons.lang3.RandomStringUtils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -53,6 +54,7 @@ import software.amazon.awssdk.core.FileTransformerConfiguration.FileWriteOption; import software.amazon.awssdk.core.FileTransformerConfiguration.FailureBehavior; import software.amazon.awssdk.core.async.SdkPublisher; +import software.amazon.awssdk.core.internal.util.NoopSubscription; /** * Tests for {@link FileAsyncResponseTransformer}. @@ -184,6 +186,11 @@ void createOrAppendExisting_fileExists_shouldAppend() throws Exception { assertThat(testPath).hasContent(existingString + content); } + @RepeatedTest(10000) + void foo() throws Exception { + exceptionOccurred_deleteFileBehavior(FileTransformerConfiguration.defaultCreateNew()); + } + @ParameterizedTest @MethodSource("configurations") void exceptionOccurred_deleteFileBehavior(FileTransformerConfiguration configuration) throws Exception { @@ -193,7 +200,7 @@ void exceptionOccurred_deleteFileBehavior(FileTransformerConfiguration configura Files.write(testPath, "foobar".getBytes(StandardCharsets.UTF_8)); } FileAsyncResponseTransformer transformer = new FileAsyncResponseTransformer<>(testPath, configuration); - stubException(RandomStringUtils.random(200), transformer); + stubException(transformer); if (configuration.failureBehavior() == LEAVE) { assertThat(testPath).exists(); } else { @@ -326,31 +333,17 @@ private static void stubSuccessfulStreaming(String newContent, FileAsyncResponse assertThat(future.isCompletedExceptionally()).isFalse(); } - private static void stubException(String newContent, FileAsyncResponseTransformer transformer) throws Exception { + private static void stubException(FileAsyncResponseTransformer transformer) throws Exception { CompletableFuture future = transformer.prepare(); transformer.onResponse("foobar"); RuntimeException runtimeException = new RuntimeException("oops"); - ByteBuffer content = ByteBuffer.wrap(newContent.getBytes(StandardCharsets.UTF_8)); - SdkPublisher idlePublisher = new SdkPublisher() { - @Override - public void subscribe(Subscriber subscriber) { - subscriber.onSubscribe(new Subscription() { - @Override - public void request(long l) { - subscriber.onNext(content); - } - - @Override - public void cancel() { - } - }); - } - }; - transformer.onStream(idlePublisher); + transformer.onStream(s -> s.onSubscribe(new NoopSubscription(s))); transformer.exceptionOccurred(runtimeException); - assertThatThrownBy(future::join).isInstanceOf(Exception.class); + assertThat(future).failsWithin(1, TimeUnit.SECONDS) + .withThrowableOfType(ExecutionException.class) + .withCause(runtimeException); } private static SdkPublisher testPublisher(String content) { From 8a8c1b9f6944acd2c498c315f3c146299618d8c6 Mon Sep 17 00:00:00 2001 From: Ran Vaknin Date: Thu, 27 Mar 2025 11:39:19 -0700 Subject: [PATCH 3/3] Remove repeated test --- .../internal/async/FileAsyncResponseTransformerTest.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/FileAsyncResponseTransformerTest.java b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/FileAsyncResponseTransformerTest.java index e9db40f0b759..fe70e23264fb 100644 --- a/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/FileAsyncResponseTransformerTest.java +++ b/core/sdk-core/src/test/java/software/amazon/awssdk/core/internal/async/FileAsyncResponseTransformerTest.java @@ -186,11 +186,6 @@ void createOrAppendExisting_fileExists_shouldAppend() throws Exception { assertThat(testPath).hasContent(existingString + content); } - @RepeatedTest(10000) - void foo() throws Exception { - exceptionOccurred_deleteFileBehavior(FileTransformerConfiguration.defaultCreateNew()); - } - @ParameterizedTest @MethodSource("configurations") void exceptionOccurred_deleteFileBehavior(FileTransformerConfiguration configuration) throws Exception {