diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt index 00d33c14549..7b712e13886 100644 --- a/hadoop-yarn-project/CHANGES.txt +++ b/hadoop-yarn-project/CHANGES.txt @@ -170,6 +170,9 @@ Release 2.4.1 - UNRELEASED YARN-1929. Fixed a deadlock in ResourceManager that occurs when failover happens right at the time of shutdown. (Karthik Kambatla via vinodkv) + YARN-1201. TestAMAuthorization fails with local hostname cannot be resolved. + (Wangda Tan via junping_du) + Release 2.4.0 - 2014-04-07 INCOMPATIBLE CHANGES 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 a9f1c1a0a1f..c7f0d0a2510 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.commons.logging.LogFactory; 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 class TestAMAuthorization { 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 {