diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAMAuthorization.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAMAuthorization.java index a9f1c1a..c7f0d0a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAMAuthorization.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAMAuthorization.java @@ -32,6 +32,7 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.CommonConfigurationKeysPublic; import org.apache.hadoop.io.DataInputByteBuffer; +import org.apache.hadoop.security.AccessControlException; import org.apache.hadoop.security.Credentials; import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.UserGroupInformation; @@ -272,21 +273,62 @@ public ApplicationMasterProtocol run() { client.registerApplicationMaster(request); Assert.fail("Should fail with authorization error"); } catch (Exception e) { - // Because there are no tokens, the request should be rejected as the - // server side will assume we are trying simple auth. - String expectedMessage = ""; - if (UserGroupInformation.isSecurityEnabled()) { - expectedMessage = "Client cannot authenticate via:[TOKEN]"; + if (isCause(AccessControlException.class, e)) { + // Because there are no tokens, the request should be rejected as the + // server side will assume we are trying simple auth. + String expectedMessage = ""; + if (UserGroupInformation.isSecurityEnabled()) { + expectedMessage = "Client cannot authenticate via:[TOKEN]"; + } else { + expectedMessage = + "SIMPLE authentication is not enabled. Available:[TOKEN]"; + } + Assert.assertTrue(e.getCause().getMessage().contains(expectedMessage)); } else { - expectedMessage = - "SIMPLE authentication is not enabled. Available:[TOKEN]"; + throw e; } - Assert.assertTrue(e.getCause().getMessage().contains(expectedMessage)); } // TODO: Add validation of invalid authorization when there's more data in // the AMRMToken } + + /** + * Identify if an expected throwable included in an exception stack. We use + * this because sometimes, an exception will be wrapped to another exception + * before thrown. Like, + * + *
+ * {@code
+ * void methodA() throws IOException {
+ * try {
+ * // something
+ * } catch (AccessControlException e) {
+ * // do process
+ * throw new IOException(e)
+ * }
+ * }
+ *
+ *
+ * So we cannot simply catch AccessControlException by using
+ *
+ * {@code
+ * try {
+ * methodA()
+ * } catch (AccessControlException e) {
+ * // do something
+ * }
+ *
+ *
+ * This method is useful in such cases.
+ */
+ private static boolean isCause(
+ Class extends Throwable> expected,
+ Throwable e
+ ) {
+ return (e != null)
+ && (expected.isInstance(e) || isCause(expected, e.getCause()));
+ }
private void waitForLaunchedState(RMAppAttempt attempt)
throws InterruptedException {