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 expected, + Throwable e + ) { + return (e != null) + && (expected.isInstance(e) || isCause(expected, e.getCause())); + } private void waitForLaunchedState(RMAppAttempt attempt) throws InterruptedException {