2727import org .apache .hadoop .fs .FileSystem ;
2828import org .apache .hadoop .fs .Path ;
2929import org .apache .hadoop .fs .s3a .impl .InstantiationIOException ;
30- import org .apache .hadoop .test .GenericTestUtils ;
3130
31+ import org .assertj .core .api .Assertions ;
3232import org .junit .Rule ;
3333import org .junit .Test ;
3434import org .junit .rules .Timeout ;
4343import static org .apache .hadoop .fs .s3a .S3ATestUtils .getCSVTestPath ;
4444import static org .apache .hadoop .fs .s3a .S3ATestUtils .removeBaseAndBucketOverrides ;
4545import static org .apache .hadoop .fs .s3a .auth .delegation .DelegationConstants .DELEGATION_TOKEN_BINDING ;
46+ import static org .apache .hadoop .fs .s3a .impl .InstantiationIOException .CONSTRUCTOR_EXCEPTION ;
47+ import static org .apache .hadoop .test .LambdaTestUtils .intercept ;
4648import static org .junit .Assert .*;
4749
4850/**
49- * Integration tests for {@link Constants#AWS_CREDENTIALS_PROVIDER} logic.
51+ * Integration tests for {@link Constants#AWS_CREDENTIALS_PROVIDER} logic
52+ * through the S3A Filesystem instantiation process.
5053 */
5154public class ITestS3AAWSCredentialsProvider {
5255 private static final Logger LOG =
@@ -55,32 +58,36 @@ public class ITestS3AAWSCredentialsProvider {
5558 @ Rule
5659 public Timeout testTimeout = new Timeout (60_1000 , TimeUnit .MILLISECONDS );
5760
61+ /**
62+ * Expecting a wrapped ClassNotFoundException.
63+ */
5864 @ Test
59- public void testBadConfiguration () throws IOException {
60- Configuration conf = createConf ();
61- conf .set (AWS_CREDENTIALS_PROVIDER , "no.such.class" );
62- try {
63- createFailingFS (conf );
64- } catch (IOException e ) {
65- if (!(e .getCause () instanceof ClassNotFoundException )) {
66- LOG .error ("Unexpected nested cause: {} in {}" , e .getCause (), e , e );
67- throw e ;
68- }
65+ public void testProviderClassNotFound () throws Exception {
66+ Configuration conf = createConf ("no.such.class" );
67+ final InstantiationIOException e =
68+ intercept (InstantiationIOException .class , "java.lang.ClassNotFoundException" , () ->
69+ createFailingFS (conf ));
70+ if (InstantiationIOException .Kind .InstantiationFailure != e .getKind ()) {
71+ throw e ;
72+ }
73+ if (!(e .getCause () instanceof ClassNotFoundException )) {
74+ LOG .error ("Unexpected nested cause: {} in {}" , e .getCause (), e , e );
75+ throw e ;
6976 }
7077 }
7178
7279 /**
7380 * A bad CredentialsProvider which has no suitable constructor.
7481 *
7582 * This class does not provide a public constructor accepting Configuration,
76- * or a public factory method named getInstance that accepts no arguments,
83+ * or a public factory method named create() that accepts no arguments,
7784 * or a public default constructor.
7885 */
79- static class BadCredentialsProviderConstructor
86+ public static class BadCredentialsProviderConstructor
8087 implements AwsCredentialsProvider {
8188
8289 @ SuppressWarnings ("unused" )
83- BadCredentialsProviderConstructor (String fsUri , Configuration conf ) {
90+ public BadCredentialsProviderConstructor (String fsUri , Configuration conf ) {
8491 }
8592
8693 @ Override
@@ -92,40 +99,60 @@ public AwsCredentials resolveCredentials() {
9299
93100 @ Test
94101 public void testBadCredentialsConstructor () throws Exception {
95- Configuration conf = createConf ();
96- conf .set (AWS_CREDENTIALS_PROVIDER ,
97- BadCredentialsProviderConstructor .class .getName ());
98- try {
99- createFailingFS (conf );
100- } catch (IOException e ) {
101- GenericTestUtils .assertExceptionContains (InstantiationIOException .CONSTRUCTOR_EXCEPTION , e );
102+ Configuration conf = createConf (BadCredentialsProviderConstructor .class );
103+ final InstantiationIOException ex =
104+ intercept (InstantiationIOException .class , CONSTRUCTOR_EXCEPTION , () ->
105+ createFailingFS (conf ));
106+ if (InstantiationIOException .Kind .UnsupportedConstructor != ex .getKind ()) {
107+ throw ex ;
102108 }
103109 }
104110
105- protected Configuration createConf () {
111+ /**
112+ * Create a configuration bonded to the given provider classname.
113+ * @param provider provider to bond to
114+ * @return a configuration
115+ */
116+ protected Configuration createConf (String provider ) {
106117 Configuration conf = new Configuration ();
107118 removeBaseAndBucketOverrides (conf ,
108119 DELEGATION_TOKEN_BINDING ,
109120 AWS_CREDENTIALS_PROVIDER );
121+ conf .set (AWS_CREDENTIALS_PROVIDER , provider );
122+ conf .set (DELEGATION_TOKEN_BINDING , "" );
110123 return conf ;
111124 }
112125
126+ /**
127+ * Create a configuration bonded to the given provider class.
128+ * @param provider provider to bond to
129+ * @return a configuration
130+ */
131+ protected Configuration createConf (Class provider ) {
132+ return createConf (provider .getName ());
133+ }
134+
113135 /**
114136 * Create a filesystem, expect it to fail by raising an IOException.
115137 * Raises an assertion exception if in fact the FS does get instantiated.
138+ * The FS is always deleted.
116139 * @param conf configuration
117140 * @throws IOException an expected exception.
118141 */
119142 private void createFailingFS (Configuration conf ) throws IOException {
120- S3AFileSystem fs = S3ATestUtils .createTestFileSystem (conf );
121- fs .listStatus (new Path ("/" ));
122- fail ("Expected exception - got " + fs );
143+ try (S3AFileSystem fs = S3ATestUtils .createTestFileSystem (conf )) {
144+ fs .listStatus (new Path ("/" ));
145+ fail ("Expected exception - got " + fs );
146+ }
123147 }
124148
125- static class BadCredentialsProvider implements AwsCredentialsProvider {
149+ /**
150+ * Returns an invalid set of credentials.
151+ */
152+ public static class BadCredentialsProvider implements AwsCredentialsProvider {
126153
127154 @ SuppressWarnings ("unused" )
128- BadCredentialsProvider (Configuration conf ) {
155+ public BadCredentialsProvider (Configuration conf ) {
129156 }
130157
131158 @ Override
@@ -137,34 +164,60 @@ public AwsCredentials resolveCredentials() {
137164
138165 @ Test
139166 public void testBadCredentials () throws Exception {
140- Configuration conf = new Configuration ();
141- conf .set (AWS_CREDENTIALS_PROVIDER , BadCredentialsProvider .class .getName ());
142- try {
143- createFailingFS (conf );
144- } catch (AccessDeniedException e ) {
145- // expected
146- } catch (AWSServiceIOException e ) {
147- GenericTestUtils .assertExceptionContains (
148- "UnrecognizedClientException" , e );
149- // expected
150- }
167+ Configuration conf = createConf (BadCredentialsProvider .class );
168+ intercept (AccessDeniedException .class , "" , () ->
169+ createFailingFS (conf ));
151170 }
152171
172+ /**
173+ * Test using the anonymous credential provider with the public csv
174+ * test file; if the test file path is unset then it will be skipped.
175+ */
153176 @ Test
154177 public void testAnonymousProvider () throws Exception {
155- Configuration conf = new Configuration ();
156- conf .set (AWS_CREDENTIALS_PROVIDER ,
157- AnonymousAWSCredentialsProvider .class .getName ());
178+ Configuration conf = createConf (AnonymousAWSCredentialsProvider .class );
158179 Path testFile = getCSVTestPath (conf );
159180 try (FileSystem fs = FileSystem .newInstance (testFile .toUri (), conf )) {
160- assertNotNull ("S3AFileSystem instance must not be null" , fs );
161- assertTrue ("FileSystem must be the instance of S3AFileSystem" , fs instanceof S3AFileSystem );
181+ Assertions .assertThat (fs )
182+ .describedAs ("Filesystem" )
183+ .isNotNull ();
162184 FileStatus stat = fs .getFileStatus (testFile );
163- assertNotNull ("FileStatus with qualified path must not be null" , stat );
164185 assertEquals (
165186 "The qualified path returned by getFileStatus should be same as the original file" ,
166187 testFile , stat .getPath ());
167188 }
168189 }
169190
191+ /**
192+ * Create credentials via the create() method.
193+ * They are invalid credentials, so IO will fail as access denied.
194+ */
195+ @ Test
196+ public void testCredentialsWithCreateMethod () throws Exception {
197+ Configuration conf = createConf (CredentialsProviderWithCreateMethod .class );
198+ intercept (AccessDeniedException .class , "" , () ->
199+ createFailingFS (conf ));
200+ }
201+
202+ /**
203+ * Credentials via the create() method.
204+ */
205+ public static class CredentialsProviderWithCreateMethod implements AwsCredentialsProvider {
206+
207+ public static AwsCredentialsProvider create () {
208+ LOG .info ("creating CredentialsProviderWithCreateMethod" );
209+ return new CredentialsProviderWithCreateMethod ();
210+ }
211+
212+ /** Private: cannot be created directly. */
213+ private CredentialsProviderWithCreateMethod () {
214+ }
215+
216+ @ Override
217+ public AwsCredentials resolveCredentials () {
218+ return AwsBasicCredentials .create ("bad_key" , "bad_secret" );
219+ }
220+
221+ }
222+
170223}
0 commit comments