99import static org .assertj .core .api .Assertions .assertThat ;
1010import static org .assertj .core .api .Assertions .assertThatCode ;
1111import static org .assertj .core .api .Assertions .assertThatThrownBy ;
12- import static org .junit .jupiter .api .Assertions .*;
12+ import static org .junit .jupiter .api .Assertions .assertEquals ;
13+ import static org .junit .jupiter .api .Assertions .assertFalse ;
14+ import static org .junit .jupiter .api .Assertions .assertInstanceOf ;
15+ import static org .junit .jupiter .api .Assertions .assertNotNull ;
16+ import static org .junit .jupiter .api .Assertions .assertNotSame ;
17+ import static org .junit .jupiter .api .Assertions .assertNull ;
18+ import static org .junit .jupiter .api .Assertions .assertSame ;
19+ import static org .junit .jupiter .api .Assertions .assertThrows ;
20+ import static org .junit .jupiter .api .Assertions .assertTrue ;
1321import static org .mockito .ArgumentMatchers .any ;
14- import static org .mockito .Mockito .*;
22+ import static org .mockito .Mockito .lenient ;
23+ import static org .mockito .Mockito .spy ;
24+ import static org .mockito .Mockito .times ;
25+ import static org .mockito .Mockito .verify ;
26+ import static org .mockito .Mockito .when ;
1527import static software .amazon .nio .spi .s3 .S3Matchers .anyConsumer ;
1628
1729import java .io .IOException ;
1830import java .net .URI ;
31+ import java .nio .file .AccessDeniedException ;
1932import java .nio .file .AccessMode ;
2033import java .nio .file .DirectoryStream ;
2134import java .nio .file .FileAlreadyExistsException ;
3144import java .time .Instant ;
3245import java .util .Collections ;
3346import java .util .concurrent .CompletableFuture ;
34- import java .util .concurrent .atomic . AtomicInteger ;
47+ import java .util .concurrent .ExecutionException ;
3548import java .util .function .Consumer ;
3649import java .util .stream .Collectors ;
3750import java .util .stream .Stream ;
5467import software .amazon .awssdk .services .s3 .model .HeadObjectResponse ;
5568import software .amazon .awssdk .services .s3 .model .ListObjectsV2Request ;
5669import software .amazon .awssdk .services .s3 .model .ListObjectsV2Response ;
70+ import software .amazon .awssdk .services .s3 .model .NoSuchBucketException ;
5771import software .amazon .awssdk .services .s3 .model .ObjectIdentifier ;
5872import software .amazon .awssdk .services .s3 .model .PutObjectRequest ;
5973import software .amazon .awssdk .services .s3 .model .PutObjectResponse ;
74+ import software .amazon .awssdk .services .s3 .model .S3Exception ;
6075import software .amazon .awssdk .services .s3 .model .S3Object ;
6176import software .amazon .awssdk .services .s3 .paginators .ListObjectsV2Publisher ;
6277
@@ -184,6 +199,56 @@ public void newDirectoryStream() throws IOException {
184199 assertThat (stream ).hasSize (2 );
185200 }
186201
202+ @ Test
203+ public void newDirectoryStreamS3AccessDeniedException () {
204+ when (mockClient .listObjectsV2Paginator (anyConsumer ())).thenThrow (
205+ // this is what is thrown by the paginator in the case that access is denied
206+ new RuntimeException (new ExecutionException (
207+ S3Exception .builder ()
208+ .statusCode (403 )
209+ .message ("AccessDenied" )
210+ .build ()
211+ ))
212+ );
213+
214+ assertThatThrownBy (() -> provider .newDirectoryStream (fs .getPath (pathUri +"/" ), entry -> true ))
215+ .isInstanceOf (AccessDeniedException .class )
216+ .hasMessage ("Access to bucket 'foo' denied -> /baa/: AccessDenied" );
217+ }
218+
219+ @ Test
220+ public void newDirectoryStreamS3BucketNotFoundException () {
221+ when (mockClient .listObjectsV2Paginator (anyConsumer ())).thenThrow (
222+ // this is what is thrown by the paginator in the case that a bucket doesn't exist
223+ new RuntimeException (new ExecutionException (
224+ NoSuchBucketException .builder ()
225+ .statusCode (404 )
226+ .message ("NoSuchBucket" )
227+ .build ()
228+ ))
229+ );
230+
231+ assertThatThrownBy (() -> provider .newDirectoryStream (fs .getPath (pathUri +"/" ), entry -> true ))
232+ .isInstanceOf (FileSystemNotFoundException .class )
233+ .hasMessage ("Bucket 'foo' not found: NoSuchBucket" );
234+ }
235+
236+ @ Test
237+ public void newDirectoryStreamOtherExceptionsBecomeIOExceptions () {
238+ when (mockClient .listObjectsV2Paginator (anyConsumer ())).thenThrow (
239+ new RuntimeException (new ExecutionException (
240+ S3Exception .builder ()
241+ .statusCode (500 )
242+ .message ("software.amazon.awssdk.services.s3.model.S3Exception: InternalError" )
243+ .build ()
244+ ))
245+ );
246+
247+ assertThatThrownBy (() -> provider .newDirectoryStream (fs .getPath (pathUri +"/" ), entry -> true ))
248+ .isInstanceOf (IOException .class )
249+ .hasMessage ("software.amazon.awssdk.services.s3.model.S3Exception: InternalError" );
250+ }
251+
187252 @ Test
188253 public void newDirectoryStreamFiltersSelf () throws IOException {
189254 final var publisher = new ListObjectsV2Publisher (mockClient , ListObjectsV2Request .builder ().build ());
@@ -221,12 +286,6 @@ public void newDirectoryStreamFilters() throws IOException {
221286 }
222287 }
223288
224- private int countDirStreamItems (DirectoryStream <Path > stream ) {
225- var count = new AtomicInteger (0 );
226- stream .iterator ().forEachRemaining (item -> count .incrementAndGet ());
227- return count .get ();
228- }
229-
230289 @ Test
231290 public void createDirectory () throws Exception {
232291 when (mockClient .putObject (any (PutObjectRequest .class ), any (AsyncRequestBody .class ))).thenReturn (CompletableFuture .supplyAsync (() ->
@@ -390,15 +449,15 @@ public void checkAccessWithoutException() throws Exception {
390449 }
391450
392451 @ Test
393- public void checkAccessWithExceptionHeadObject () throws Exception {
452+ public void checkAccessWithExceptionHeadObject () {
394453 when (mockClient .headObject (anyConsumer ())).thenReturn (CompletableFuture .failedFuture (new IOException ()));
395454
396455 var foo = fs .getPath ("/foo" );
397456 assertThrows (IOException .class , () -> provider .checkAccess (foo , AccessMode .READ ));
398457 }
399458
400459 @ Test
401- public void checkAccessWithExceptionListObjectsV2 () throws Exception {
460+ public void checkAccessWithExceptionListObjectsV2 () {
402461 when (mockClient .listObjectsV2 (anyConsumer ())).thenReturn (CompletableFuture .failedFuture (new IOException ()));
403462
404463 var foo = fs .getPath ("/dir/" );
@@ -419,7 +478,7 @@ public void getFileAttributeView() {
419478 var foo = fs .getPath ("/foo" );
420479 final var fileAttributeView = provider .getFileAttributeView (foo , BasicFileAttributeView .class );
421480 assertNotNull (fileAttributeView );
422- assertTrue ( fileAttributeView instanceof S3BasicFileAttributeView );
481+ assertInstanceOf ( S3BasicFileAttributeView . class , fileAttributeView );
423482 }
424483
425484 @ Test
0 commit comments