Skip to content

Commit f6eeb29

Browse files
committed
HADOOP-18820. ITestS3AAWSCredentialsProvider enhancements
* use intercept() and InstantiationIOException where appropriate. * change method names to distinguish them better. * add test to verify that the static create() method is called. Change-Id: I88e6c4eed6153861b6bd83300e6c484eb4dda08e
1 parent 34beeea commit f6eeb29

File tree

1 file changed

+98
-45
lines changed

1 file changed

+98
-45
lines changed

hadoop-tools/hadoop-aws/src/test/java/org/apache/hadoop/fs/s3a/ITestS3AAWSCredentialsProvider.java

Lines changed: 98 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
import org.apache.hadoop.fs.FileSystem;
2828
import org.apache.hadoop.fs.Path;
2929
import org.apache.hadoop.fs.s3a.impl.InstantiationIOException;
30-
import org.apache.hadoop.test.GenericTestUtils;
3130

31+
import org.assertj.core.api.Assertions;
3232
import org.junit.Rule;
3333
import org.junit.Test;
3434
import org.junit.rules.Timeout;
@@ -43,10 +43,13 @@
4343
import static org.apache.hadoop.fs.s3a.S3ATestUtils.getCSVTestPath;
4444
import static org.apache.hadoop.fs.s3a.S3ATestUtils.removeBaseAndBucketOverrides;
4545
import 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;
4648
import 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
*/
5154
public 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

Comments
 (0)