You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by gt...@apache.org on 2017/02/16 21:42:12 UTC
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.
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 <gt...@apache.org>
Authored: Thu Feb 16 13:40:26 2017 -0800
Committer: Li Lu <gt...@apache.org>
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