SLIDER-907 AgentWebPagesIT#testAgentWeb fails on wire encrypted clusters

Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/ab2193c8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/ab2193c8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/ab2193c8

Branch: refs/heads/develop
Commit: ab2193c811a9b5f225a0c89d0e16c08f7a094129
Parents: 5cee238
Author: Steve Loughran <[email protected]>
Authored: Tue Jun 30 16:11:27 2015 +0100
Committer: Steve Loughran <[email protected]>
Committed: Tue Jun 30 16:11:27 2015 +0100

----------------------------------------------------------------------
 .../restclient/UrlConnectionOperations.java     |  5 +-
 .../agent/rest/JerseyTestDelegates.groovy       | 28 ++++++++++
 .../funtest/framework/CommandTestBase.groovy    | 51 ++++++++++++++++-
 .../funtest/lifecycle/AgentWebPagesIT.groovy    | 59 ++++++++++++--------
 4 files changed, 117 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/ab2193c8/slider-core/src/main/java/org/apache/slider/core/restclient/UrlConnectionOperations.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/core/restclient/UrlConnectionOperations.java
 
b/slider-core/src/main/java/org/apache/slider/core/restclient/UrlConnectionOperations.java
index e0d2315..20ef198 100644
--- 
a/slider-core/src/main/java/org/apache/slider/core/restclient/UrlConnectionOperations.java
+++ 
b/slider-core/src/main/java/org/apache/slider/core/restclient/UrlConnectionOperations.java
@@ -30,6 +30,7 @@ import org.apache.hadoop.yarn.webapp.NotFoundException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.net.ssl.SSLException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -142,12 +143,14 @@ public class UrlConnectionOperations extends Configured  {
         log.debug("No body in response");
 
       }
+    } catch (SSLException e) {
+      throw e;
     } catch (IOException e) {
       throw NetUtils.wrapException(url.toString(),
           url.getPort(), "localhost", 0, e);
 
     } catch (AuthenticationException e) {
-      throw new IOException("From " + url + ": " + e, e);
+      throw new AuthenticationException("From " + url + ": " + e, e);
 
     } finally {
       if (conn != null) {

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/ab2193c8/slider-core/src/test/groovy/org/apache/slider/agent/rest/JerseyTestDelegates.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/JerseyTestDelegates.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/JerseyTestDelegates.groovy
index 5eb14e3..857d15c 100644
--- 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/JerseyTestDelegates.groovy
+++ 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/JerseyTestDelegates.groovy
@@ -36,7 +36,9 @@ import org.apache.slider.core.conf.ConfTreeOperations
 import org.apache.slider.core.restclient.HttpVerb
 import 
org.apache.slider.server.appmaster.web.rest.application.ApplicationResource
 import org.apache.slider.api.types.PingInformation
+import org.apache.slider.test.Outcome
 
+import javax.net.ssl.SSLException
 import javax.ws.rs.core.MediaType
 
 import static org.apache.slider.api.ResourceKeys.COMPONENT_INSTANCES
@@ -479,4 +481,30 @@ class JerseyTestDelegates extends AbstractRestTestDelegate 
{
     testPing();
   }
 
+  /**
+   * Probe callback for is the web service live; currently
+   * checks the "/system/health" path.
+   * Raising an SSL exception is considered a sign of liveness.
+   * @param args args: ignored
+   * @return the outcome
+   */
+  Outcome probeServiceLive(Map<String, String> args) {
+    try {
+      jerseyGet(SYSTEM_HEALTHCHECK)
+      return Outcome.Success
+    } catch (SSLException e) {
+      // SSL exception => success
+      return Outcome.Success
+    } catch (IOException e) {
+      def cause = e.getCause()
+      if (cause && cause instanceof SSLException) {
+        // nested SSL exception => success
+        return Outcome.Success
+      }
+      // any other IOE is a retry
+      return Outcome.Retry
+    }
+  }
+
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/ab2193c8/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/CommandTestBase.groovy
----------------------------------------------------------------------
diff --git 
a/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/CommandTestBase.groovy
 
b/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/CommandTestBase.groovy
index edc4826..4c02289 100644
--- 
a/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/CommandTestBase.groovy
+++ 
b/slider-funtest/src/main/groovy/org/apache/slider/funtest/framework/CommandTestBase.groovy
@@ -48,6 +48,9 @@ import org.junit.Rule
 import org.junit.rules.Timeout
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
+
+import javax.net.ssl.SSLException
+
 import static org.apache.slider.common.SliderExitCodes.*
 import static org.apache.slider.core.main.LauncherExitCodes.*
 import static org.apache.slider.funtest.framework.FuntestProperties.*
@@ -1463,7 +1466,8 @@ abstract class CommandTestBase extends SliderTestUtils {
   }
 
   /**
-   * Probe callback for is the the app root web page up
+   * Probe callback for is the the app root web page up.
+   * Having a securty exception is in fact legit.
    * @param args map where 'applicationId' must be set
    * @return the outcome
    */
@@ -1480,6 +1484,12 @@ abstract class CommandTestBase extends SliderTestUtils {
     try {
       getWebPage(sar.url)
       return Outcome.Success
+    } catch (SSLException e) {
+      // SSL exception -implies negotiation failure. At this point there is 
clearly something
+      // at the far end -we just don't have the credentials to trust it.
+      return Outcome.Success;
+    } catch (IOException e) {
+      return Outcome.Retry;
     } catch (Exception e) {
       return Outcome.Retry;
     }
@@ -1511,4 +1521,43 @@ abstract class CommandTestBase extends SliderTestUtils {
       getWebPage(sar.url)
     }
   }
+
+  /**
+   * Probe callback for the the app root web page up.
+   * Raising an SSL exception is considered a sign of liveness.
+   * @param args map where 'applicationId' must be set
+   * @return the outcome
+   */
+  protected static Outcome isApplicationURLPublished(
+      Map<String, String> args) {
+
+    assert args['applicationId'] != null
+    String applicationId = args['applicationId'];
+    def sar = lookupApplication(applicationId)
+    assert sar != null;
+    return sar.url? Outcome.Success : Outcome.Retry
+  }
+
+  /**
+   * Await for the URL of an app to be listed in the application report
+   * @param applicationId app ID
+   * @param launch_timeout launch timeout
+   */
+  void awaitApplicationURLPublished(String applicationId, int launch_timeout) {
+    repeatUntilSuccess(
+        "await application URL published",
+        this.&isApplicationURLPublished,
+        launch_timeout,
+        PROBE_SLEEP_TIME,
+        [
+            applicationId: applicationId
+        ],
+        true,
+        "application URL not published") {
+
+      def sar = lookupApplication(applicationId)
+      log.error("$applicationId => $sar")
+    }
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/ab2193c8/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AgentWebPagesIT.groovy
----------------------------------------------------------------------
diff --git 
a/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AgentWebPagesIT.groovy
 
b/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AgentWebPagesIT.groovy
index 0bce63e..5e234a4 100644
--- 
a/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AgentWebPagesIT.groovy
+++ 
b/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AgentWebPagesIT.groovy
@@ -48,6 +48,8 @@ import org.junit.After
 import org.junit.Before
 import org.junit.Test
 
+import static 
org.apache.slider.server.appmaster.web.rest.RestPaths.SYSTEM_HEALTHCHECK
+
 @CompileStatic
 @Slf4j
 public class AgentWebPagesIT extends AgentCommandTestBase
@@ -105,53 +107,45 @@ public class AgentWebPagesIT extends AgentCommandTestBase
 
     def appId = ensureYarnApplicationIsUp(launchReportFile)
     assert appId
-    expectRootWebPageUp(appId, instanceLaunchTime)
+    awaitApplicationURLPublished(appId, instanceLaunchTime)
     File liveReportFile = createTempJsonFile();
 
-    lookup(appId,liveReportFile)
+    lookup(appId, liveReportFile)
     def report = loadAppReport(liveReportFile)
     assert report.url
 
     def proxyAM = report.url
 
-    // get the root page, 
-    getWebPage(proxyAM)
-    
-    def directAM = report.origTrackingUrl;
-/*
-    // now attempt direct-to-AM pings
-    LowLevelRestTestDelegates direct = new LowLevelRestTestDelegates(directAM,
-        directComplexVerbs)
-
-    direct.testSuiteAll()
+    // here the URL has been published, but it may not be live yet, due to the 
time
+    // it takes the AM to build app state and boostrap the Web UI
 
-    // and via the proxy
-    LowLevelRestTestDelegates proxied = new LowLevelRestTestDelegates(proxyAM,
-        proxyComplexVerbs)
-    proxied.testSuiteAll()
-    proxied.logCodahaleMetrics();
-*/
+    def directAM = report.origTrackingUrl;
 
     describe "Proxy Jersey Tests"
 
-    Client ugiClient = createUGIJerseyClient()
+    Client jerseyClient = createUGIJerseyClient()
+
     JerseyTestDelegates proxyJerseyTests =
-        new JerseyTestDelegates(proxyAM, ugiClient, proxyComplexVerbs)
+        new JerseyTestDelegates(proxyAM, jerseyClient, proxyComplexVerbs)
+
+    // wait it coming up
+    awaitRestEndpointLive(proxyJerseyTests, instanceLaunchTime)
+
     proxyJerseyTests.testSuiteGetOperations()
 
     describe "Direct Jersey Tests"
     JerseyTestDelegates directJerseyTests =
-        new JerseyTestDelegates(directAM, ugiClient, directComplexVerbs)
+        new JerseyTestDelegates(directAM, jerseyClient, directComplexVerbs)
     directJerseyTests.testSuiteAll()
 
     describe "Proxy SliderRestClient Tests"
     RestAPIClientTestDelegates proxySliderRestAPI =
-        new RestAPIClientTestDelegates(proxyAM, ugiClient, proxyComplexVerbs)
+        new RestAPIClientTestDelegates(proxyAM, jerseyClient, 
proxyComplexVerbs)
     proxySliderRestAPI.testSuiteAll()
 
     describe "Direct SliderRestClient Tests"
     RestAPIClientTestDelegates directSliderRestAPI =
-        new RestAPIClientTestDelegates(directAM, ugiClient, directComplexVerbs)
+        new RestAPIClientTestDelegates(directAM, jerseyClient, 
directComplexVerbs)
     directSliderRestAPI.testSuiteAll()
 
     if (UserGroupInformation.securityEnabled) {
@@ -171,7 +165,7 @@ public class AgentWebPagesIT extends AgentCommandTestBase
     SliderClient sliderClient = bondToCluster(SLIDER_CONFIG, CLUSTER)
     RegistryOperations operations = sliderClient.registryOperations;
     def restClientFactory = new RestClientFactory(
-        operations, ugiClient,
+        operations, jerseyClient,
         "~", SliderKeys.APP_TYPE, CLUSTER)
     def sliderApplicationApi = restClientFactory.createSliderAppApiClient();
     sliderApplicationApi.desiredModel
@@ -209,4 +203,21 @@ public class AgentWebPagesIT extends AgentCommandTestBase
     }
   }
 
+  /**
+   * Await for the URL of an app to be listed in the application report
+   * @param applicationId app ID
+   * @param launch_timeout launch timeout
+   */
+  void awaitRestEndpointLive(JerseyTestDelegates jersey, int launch_timeout) {
+    repeatUntilSuccess(
+        "await application URL published",
+        jersey.&probeServiceLive,
+        launch_timeout,
+        PROBE_SLEEP_TIME,
+        [:],
+        false,
+        "GET of $SYSTEM_HEALTHCHECK failed") {
+      jersey.jerseyGet(SYSTEM_HEALTHCHECK)
+    }
+  }
 }

Reply via email to