Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 86A95200C1D for ; Thu, 16 Feb 2017 22:42:14 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 854B7160B61; Thu, 16 Feb 2017 21:42:14 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id AD41C160B52 for ; Thu, 16 Feb 2017 22:42:13 +0100 (CET) Received: (qmail 53383 invoked by uid 500); 16 Feb 2017 21:42:12 -0000 Mailing-List: contact common-commits-help@hadoop.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Delivered-To: mailing list common-commits@hadoop.apache.org Received: (qmail 53374 invoked by uid 99); 16 Feb 2017 21:42:12 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 16 Feb 2017 21:42:12 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id B4FFADFC2F; Thu, 16 Feb 2017 21:42:12 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: gtcarrera9@apache.org To: common-commits@hadoop.apache.org Message-Id: <134759042b6d43feb5547cffaac96b46@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: hadoop git commit: YARN-6177. Yarn client should exit with an informative error message if an incompatible Jersey library is used at client. Contributed by Weiwei Yang. Date: Thu, 16 Feb 2017 21:42:12 +0000 (UTC) archived-at: Thu, 16 Feb 2017 21:42:14 -0000 Repository: hadoop Updated Branches: refs/heads/trunk 4fa1afdb8 -> 5d339c46f YARN-6177. Yarn client should exit with an informative error message if an incompatible Jersey library is used at client. Contributed by Weiwei Yang. Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/5d339c46 Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/5d339c46 Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/5d339c46 Branch: refs/heads/trunk Commit: 5d339c46f5b16b951afd82afd9e907b9aa2ded9a Parents: 4fa1afd Author: Li Lu Authored: Thu Feb 16 13:40:26 2017 -0800 Committer: Li Lu Committed: Thu Feb 16 13:41:42 2017 -0800 ---------------------------------------------------------------------- .../yarn/client/api/impl/YarnClientImpl.java | 10 ++ .../yarn/client/api/impl/TestYarnClient.java | 165 ++++++++++++++++--- 2 files changed, 155 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/5d339c46/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java index 4a27fee..23b128c 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java @@ -381,6 +381,16 @@ public class YarnClientImpl extends YarnClient { return null; } throw e; + } catch (NoClassDefFoundError e) { + NoClassDefFoundError wrappedError = new NoClassDefFoundError( + e.getMessage() + ". It appears that the timeline client " + + "failed to initiate because an incompatible dependency " + + "in classpath. If timeline service is optional to this " + + "client, try to work around by setting " + + YarnConfiguration.TIMELINE_SERVICE_ENABLED + + " to false in client configuration."); + wrappedError.setStackTrace(e.getStackTrace()); + throw wrappedError; } } http://git-wip-us.apache.org/repos/asf/hadoop/blob/5d339c46/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java index 240f31c..c2c9665 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java @@ -156,26 +156,6 @@ public class TestYarnClient { } @Test - public void testStartWithTimelineV15Failure() throws Exception{ - Configuration conf = new Configuration(); - conf.setBoolean(YarnConfiguration.TIMELINE_SERVICE_ENABLED, true); - conf.setFloat(YarnConfiguration.TIMELINE_SERVICE_VERSION, 1.5f); - conf.setBoolean(YarnConfiguration.TIMELINE_SERVICE_CLIENT_BEST_EFFORT, - true); - YarnClient client = YarnClient.createYarnClient(); - if(client instanceof YarnClientImpl) { - YarnClientImpl impl = (YarnClientImpl) client; - YarnClientImpl spyClient = spy(impl); - when(spyClient.createTimelineClient()).thenThrow( - new IOException("ATS v1.5 client initialization failed. ")); - spyClient.init(conf); - spyClient.start(); - spyClient.getTimelineDelegationToken(); - spyClient.stop(); - } - } - - @Test public void testStartWithTimelineV15() throws Exception { Configuration conf = new Configuration(); conf.setBoolean(YarnConfiguration.TIMELINE_SERVICE_ENABLED, true); @@ -186,6 +166,89 @@ public class TestYarnClient { client.stop(); } + @Test + public void testStartTimelineClientWithErrors() + throws Exception { + // If timeline client failed to init with a NoClassDefFoundError + // it should be wrapped with an informative error message + testCreateTimelineClientWithError( + 1.5f, + true, + false, + new NoClassDefFoundError("Mock a NoClassDefFoundError"), + new CreateTimelineClientErrorVerifier(1) { + @Override + public void verifyError(Throwable e) { + Assert.assertTrue(e instanceof NoClassDefFoundError); + Assert.assertTrue(e.getMessage() != null && + e.getMessage().contains( + YarnConfiguration.TIMELINE_SERVICE_ENABLED)); + } + }); + + // Disable timeline service for this client, + // yarn client will not fail when such error happens + testCreateTimelineClientWithError( + 1.5f, + false, + false, + new NoClassDefFoundError("Mock a NoClassDefFoundError"), + new CreateTimelineClientErrorVerifier(0) { + @Override public void verifyError(Throwable e) { + Assert.fail("NoClassDefFoundError while creating timeline client" + + "should be tolerated when timeline service is disabled."); + } + } + ); + + // Set best-effort to true, verify an error is still fatal + testCreateTimelineClientWithError( + 1.5f, + true, + true, + new NoClassDefFoundError("Mock a NoClassDefFoundError"), + new CreateTimelineClientErrorVerifier(1) { + @Override public void verifyError(Throwable e) { + Assert.assertTrue(e instanceof NoClassDefFoundError); + Assert.assertTrue(e.getMessage() != null && + e.getMessage().contains( + YarnConfiguration.TIMELINE_SERVICE_ENABLED)); + } + } + ); + + // Set best-effort to false, verify that an exception + // causes the client to fail + testCreateTimelineClientWithError( + 1.5f, + true, + false, + new IOException("ATS v1.5 client initialization failed."), + new CreateTimelineClientErrorVerifier(1) { + @Override + public void verifyError(Throwable e) { + Assert.assertTrue(e instanceof IOException); + } + } + ); + + // Set best-effort to true, verify that an normal exception + // won't fail the entire client + testCreateTimelineClientWithError( + 1.5f, + true, + true, + new IOException("ATS v1.5 client initialization failed."), + new CreateTimelineClientErrorVerifier(0) { + @Override + public void verifyError(Throwable e) { + Assert.fail("IOException while creating timeline client" + + "should be tolerated when best effort is true"); + } + } + ); + } + @SuppressWarnings("deprecation") @Test (timeout = 30000) public void testSubmitApplication() throws Exception { @@ -1680,4 +1743,66 @@ public class TestYarnClient { Assert.assertEquals(containerId, request.getContainerId()); Assert.assertEquals(command, request.getCommand()); } + + private void testCreateTimelineClientWithError( + float timelineVersion, + boolean timelineServiceEnabled, + boolean timelineClientBestEffort, + Throwable mockErr, + CreateTimelineClientErrorVerifier errVerifier) throws Exception { + Configuration conf = new Configuration(); + conf.setBoolean(YarnConfiguration.TIMELINE_SERVICE_ENABLED, + timelineServiceEnabled); + conf.setBoolean(YarnConfiguration.TIMELINE_SERVICE_CLIENT_BEST_EFFORT, + timelineClientBestEffort); + conf.setFloat(YarnConfiguration.TIMELINE_SERVICE_VERSION, + timelineVersion); + YarnClient client = new MockYarnClient(); + if (client instanceof YarnClientImpl) { + YarnClientImpl impl = (YarnClientImpl) client; + YarnClientImpl spyClient = spy(impl); + when(spyClient.createTimelineClient()).thenThrow(mockErr); + CreateTimelineClientErrorVerifier verifier = spy(errVerifier); + spyClient.init(conf); + spyClient.start(); + + ApplicationSubmissionContext context = + mock(ApplicationSubmissionContext.class); + ContainerLaunchContext containerContext = + mock(ContainerLaunchContext.class); + ApplicationId applicationId = + ApplicationId.newInstance(System.currentTimeMillis(), 1); + when(containerContext.getTokens()).thenReturn(null); + when(context.getApplicationId()).thenReturn(applicationId); + when(spyClient.isSecurityEnabled()).thenReturn(true); + when(context.getAMContainerSpec()).thenReturn(containerContext); + + try { + spyClient.submitApplication(context); + } catch (Throwable e) { + verifier.verifyError(e); + } finally { + // Make sure the verifier runs with expected times + // This is required because in case throwable is swallowed + // and verifyError never gets the chance to run + verify(verifier, times(verifier.getExpectedTimes())) + .verifyError(any(Throwable.class)); + spyClient.stop(); + } + } + } + + private abstract class CreateTimelineClientErrorVerifier { + // Verify verifyError gets executed with expected times + private int times = 0; + protected CreateTimelineClientErrorVerifier(int times) { + this.times = times; + } + public int getExpectedTimes() { + return this.times; + } + // Verification a throwable is in desired state + // E.g verify type and error message + public abstract void verifyError(Throwable e); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org For additional commands, e-mail: common-commits-help@hadoop.apache.org