SLIDER-768 refactoring tests to work even when back door is closed (i.e. 0.70 
branch)


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

Branch: refs/heads/develop
Commit: 680d64dced565c68de398705072c192a6bb84c2e
Parents: 181c5e9
Author: Steve Loughran <ste...@apache.org>
Authored: Fri Jan 30 17:54:52 2015 +0000
Committer: Steve Loughran <ste...@apache.org>
Committed: Fri Jan 30 17:54:52 2015 +0000

----------------------------------------------------------------------
 .../common/SliderXMLConfKeysForTesting.java     |   1 +
 .../apache/slider/common/SliderXmlConfKeys.java |  16 +-
 .../server/appmaster/SliderAppMaster.java       |  13 +-
 .../agent/rest/AbstractRestTestDelegate.groovy  |  46 +++
 .../agent/rest/JerseyTestDelegates.groovy       |  16 +-
 .../agent/rest/LowLevelRestTestDelegates.groovy | 324 +++++++++++++++++++
 .../rest/RestAPIClientTestDelegates.groovy      | 248 ++++++++++++++
 .../slider/agent/rest/RestTestDelegates.groovy  | 322 ------------------
 .../rest/SliderRestClientTestDelegates.groovy   | 250 --------------
 .../slider/agent/rest/TestStandaloneREST.groovy |  50 +--
 .../funtest/lifecycle/AgentWebPagesIT.groovy    |  66 ++--
 11 files changed, 707 insertions(+), 645 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/680d64dc/slider-core/src/main/java/org/apache/slider/common/SliderXMLConfKeysForTesting.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/common/SliderXMLConfKeysForTesting.java
 
b/slider-core/src/main/java/org/apache/slider/common/SliderXMLConfKeysForTesting.java
index 0a7f292..1e3cf64 100644
--- 
a/slider-core/src/main/java/org/apache/slider/common/SliderXMLConfKeysForTesting.java
+++ 
b/slider-core/src/main/java/org/apache/slider/common/SliderXMLConfKeysForTesting.java
@@ -73,4 +73,5 @@ public interface SliderXMLConfKeysForTesting {
    * Local path to AM keytab: {@value}
    */
   String KEY_TEST_AM_KEYTAB = "slider.test.am.keytab.local";
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/680d64dc/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java 
b/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java
index 0d1121d..712b821 100644
--- a/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java
+++ b/slider-core/src/main/java/org/apache/slider/common/SliderXmlConfKeys.java
@@ -145,5 +145,19 @@ public interface SliderXmlConfKeys {
   /**
    * Flag to enable the insecure AM filter: {@value}
    */
-  String X_DEV_INSECURE_WS = "slider.dev.ws.insecure";
+  String X_DEV_INSECURE_WS = "slider.feature.ws.insecure";
+
+  /**
+   * Flag to indicate the insecure AM filter is enabled by default: {@value}.
+   */
+  boolean X_DEV_INSECURE_DEFAULT = true;
+
+
+  /**
+   * Flag to indicate the insecure AM filter is required: {@value}.
+   * When Slider switches to being Hadoop 2.7+ only, this flag
+   * can be set to false
+   */
+  boolean X_DEV_INSECURE_REQUIRED = true;
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/680d64dc/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
index 2629a4d..9f0a357 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
@@ -83,7 +83,7 @@ import org.apache.slider.api.proto.Messages;
 import org.apache.slider.api.proto.SliderClusterAPI;
 import org.apache.slider.common.SliderExitCodes;
 import org.apache.slider.common.SliderKeys;
-import org.apache.slider.common.SliderXmlConfKeys;
+import static org.apache.slider.common.SliderXmlConfKeys.*;
 import org.apache.slider.common.params.AbstractActionArgs;
 import org.apache.slider.common.params.SliderAMArgs;
 import org.apache.slider.common.params.SliderAMCreateAction;
@@ -692,9 +692,9 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
 
       if (securityEnabled) {
         // fix up the ACLs if they are not set
-        String acls = getConfig().get(SliderXmlConfKeys.KEY_PROTOCOL_ACL);
+        String acls = getConfig().get(KEY_PROTOCOL_ACL);
         if (acls == null) {
-          getConfig().set(SliderXmlConfKeys.KEY_PROTOCOL_ACL, "*");
+          getConfig().set(KEY_PROTOCOL_ACL, "*");
         }
       }
       //bring up the Slider RPC service
@@ -1138,7 +1138,8 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
 
     // This is here until YARN supports proxy & redirect operations
     // on verbs other than GET, and is only supported for testing
-    if (serviceConf.getBoolean(SliderXmlConfKeys.X_DEV_INSECURE_WS, false)) {
+    if (X_DEV_INSECURE_REQUIRED && serviceConf.getBoolean(X_DEV_INSECURE_WS, 
+        X_DEV_INSECURE_DEFAULT)) {
       log.warn("Insecure filter enabled: REST operations are unauthenticated");
       amFilterName = InsecureAmFilterInitializer.NAME;
     }
@@ -1500,11 +1501,11 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
     boolean authorization = getConfig().getBoolean(
         CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHORIZATION,
         false);
-    String acls = getConfig().get(SliderXmlConfKeys.KEY_PROTOCOL_ACL);
+    String acls = getConfig().get(KEY_PROTOCOL_ACL);
     if (authorization && SliderUtils.isUnset(acls)) {
       throw new BadConfigException("Application has IPC authorization enabled 
in " +
           CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHORIZATION +
-          " but no ACLs in " + SliderXmlConfKeys.KEY_PROTOCOL_ACL);
+          " but no ACLs in " + KEY_PROTOCOL_ACL);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/680d64dc/slider-core/src/test/groovy/org/apache/slider/agent/rest/AbstractRestTestDelegate.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/AbstractRestTestDelegate.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/AbstractRestTestDelegate.groovy
new file mode 100644
index 0000000..15026e4
--- /dev/null
+++ 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/AbstractRestTestDelegate.groovy
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.agent.rest
+
+import org.apache.slider.test.SliderTestUtils
+
+/**
+ * Base class for anything we want common to all
+ */
+abstract class AbstractRestTestDelegate extends SliderTestUtils {
+  public static final String TEST_GLOBAL_OPTION = "test.global.option"
+  public static final String TEST_GLOBAL_OPTION_PRESENT = "present"
+  public final boolean enableComplexVerbs
+
+  AbstractRestTestDelegate(boolean enableComplexVerbs) {
+    this.enableComplexVerbs = enableComplexVerbs
+  }
+
+
+  public abstract void testSuiteGetOperations()
+
+  public abstract void testSuiteComplexVerbs()
+
+  public void testSuiteAll() {
+    testSuiteGetOperations()
+    if (enableComplexVerbs) {
+      testSuiteComplexVerbs()
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/680d64dc/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 1ff7eae..4a4fa7f 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,6 @@ 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.PingResource
-import org.apache.slider.test.SliderTestUtils
 
 import javax.ws.rs.core.MediaType
 
@@ -48,15 +47,15 @@ import static 
org.apache.slider.server.appmaster.web.rest.RestPaths.*
 /**
  * This class contains parts of tests that can be run
  * against a deployed AM: local or remote.
- * It uses Jersey ... and must be passed a client that is either secure
- * or not
+ * It uses Jersey WebResource... and must be passed a client
+ * that is either secure or not
+ * {@link WebResource}
+ * 
  * 
  */
 @CompileStatic
 @Slf4j
-class JerseyTestDelegates extends SliderTestUtils {
-  public static final String TEST_GLOBAL_OPTION = "test.global.option"
-  public static final String TEST_GLOBAL_OPTION_PRESENT = "present"
+class JerseyTestDelegates extends AbstractRestTestDelegate {
 
   final String appmaster;
   final String application;
@@ -65,7 +64,9 @@ class JerseyTestDelegates extends SliderTestUtils {
   final WebResource appResource
   
 
-  JerseyTestDelegates(String appmaster, Client jersey) {
+  JerseyTestDelegates(String appmaster, Client jersey,
+      boolean enableComplexVerbs = true) {
+    super(enableComplexVerbs)
     this.jersey = jersey
     this.appmaster = appmaster
     application = appendToURL(appmaster, SLIDER_PATH_APPLICATION)
@@ -473,4 +474,5 @@ class JerseyTestDelegates extends SliderTestUtils {
   public void testSuiteComplexVerbs() {
     testPing();
   }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/680d64dc/slider-core/src/test/groovy/org/apache/slider/agent/rest/LowLevelRestTestDelegates.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/LowLevelRestTestDelegates.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/LowLevelRestTestDelegates.groovy
new file mode 100644
index 0000000..be3de8c
--- /dev/null
+++ 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/LowLevelRestTestDelegates.groovy
@@ -0,0 +1,324 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.agent.rest
+
+import groovy.transform.CompileStatic
+import groovy.util.logging.Slf4j
+import org.apache.hadoop.yarn.webapp.NotFoundException
+import org.apache.slider.api.StateValues
+import org.apache.slider.api.types.ComponentInformation
+import org.apache.slider.api.types.ContainerInformation
+import org.apache.slider.core.conf.AggregateConf
+import org.apache.slider.core.conf.ConfTree
+import org.apache.slider.core.conf.ConfTreeOperations
+import org.apache.slider.core.restclient.HttpOperationResponse
+import org.apache.slider.core.restclient.HttpVerb
+import org.apache.slider.core.restclient.UrlConnectionOperations
+import 
org.apache.slider.server.appmaster.web.rest.application.ApplicationResource
+import org.apache.slider.api.types.PingResource
+import org.apache.slider.test.Outcome
+
+import javax.ws.rs.core.MediaType
+
+import static org.apache.slider.api.ResourceKeys.COMPONENT_INSTANCES
+import static org.apache.slider.api.StatusKeys.*
+import static org.apache.slider.common.SliderKeys.COMPONENT_AM
+import static org.apache.slider.server.appmaster.web.rest.RestPaths.*
+
+/**
+ * Low-level operations
+ */
+@CompileStatic
+@Slf4j
+class LowLevelRestTestDelegates extends AbstractRestTestDelegate {
+
+  private final String appmaster;
+  private final String application;
+  // flag to indicate complex verbs are enabled
+
+  LowLevelRestTestDelegates(String appmaster, boolean enableComplexVerbs = 
true) {
+    super(enableComplexVerbs)
+    this.appmaster = appmaster
+    application = appendToURL(appmaster, SLIDER_PATH_APPLICATION)
+  }
+
+
+  public void testCodahaleOperations() throws Throwable {
+    describe "Codahale operations"
+    getWebPage(appmaster)
+    getWebPage(appmaster, SYSTEM_THREADS)
+    getWebPage(appmaster, SYSTEM_HEALTHCHECK)
+    getWebPage(appmaster, SYSTEM_PING)
+    getWebPage(appmaster, SYSTEM_METRICS_JSON)
+  }
+  
+  public void logCodahaleMetrics() {
+    // query Coda Hale metrics
+    log.info getWebPage(appmaster, SYSTEM_HEALTHCHECK)
+    log.info getWebPage(appmaster, SYSTEM_METRICS)
+  }
+
+
+  public void testMimeTypes() throws Throwable {
+    describe "Mime Types"
+    HttpOperationResponse response= executeGet(
+        appendToURL(appmaster,
+        SLIDER_PATH_APPLICATION, LIVE_RESOURCES))
+    response.headers.each { key, val -> log.info("$key $val")}
+    log.info "Content type: ${response.contentType}"
+    assert 
response.contentType.contains(MediaType.APPLICATION_JSON_TYPE.toString())
+  }
+
+  
+  public void testLiveResources() throws Throwable {
+    describe "Live Resources"
+    ConfTreeOperations tree = fetchConfigTree(appmaster, LIVE_RESOURCES)
+
+    log.info tree.toString()
+    def liveAM = tree.getComponent(COMPONENT_AM)
+    def desiredInstances = liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES);
+    assert desiredInstances ==
+           liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_ACTUAL)
+
+    assert 1 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_STARTED)
+    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_REQUESTING)
+    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_FAILED)
+    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_COMPLETED)
+    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_RELEASING)
+  }
+
+  public void testLiveContainers() throws Throwable {
+    describe "Application REST ${LIVE_CONTAINERS}"
+
+    Map<String, ContainerInformation> containers =
+        fetchType(HashMap, appmaster, LIVE_CONTAINERS)
+    assert containers.size() == 1
+    log.info "${containers}"
+    ContainerInformation amContainerInfo =
+        (ContainerInformation) containers.values()[0]
+    assert amContainerInfo.containerId
+
+    def amContainerId = amContainerInfo.containerId
+    assert containers[amContainerId]
+
+    assert amContainerInfo.component == COMPONENT_AM
+    assert amContainerInfo.createTime > 0
+    assert amContainerInfo.exitCode == null
+    assert amContainerInfo.output == null
+    assert amContainerInfo.released == null
+    assert amContainerInfo.state == StateValues.STATE_LIVE
+
+    describe "containers"
+
+    ContainerInformation retrievedContainerInfo =
+        fetchType(ContainerInformation, appmaster,
+            LIVE_CONTAINERS + "/${amContainerId}")
+    assert retrievedContainerInfo.containerId == amContainerId
+
+    // fetch missing
+    try {
+      def result = fetchType(ContainerInformation, appmaster,
+          LIVE_CONTAINERS + "/unknown")
+      fail("expected an error, got $result")
+    } catch (NotFoundException e) {
+      // expected
+    }
+
+
+    describe "components"
+
+    Map<String, ComponentInformation> components =
+        fetchType(HashMap, appmaster, LIVE_COMPONENTS)
+    // two components
+    assert components.size() >= 1
+    log.info "${components}"
+
+    ComponentInformation amComponentInfo =
+        (ComponentInformation) components[COMPONENT_AM]
+
+    ComponentInformation amFullInfo = fetchType(
+        ComponentInformation,
+        appmaster,
+        LIVE_COMPONENTS + "/${COMPONENT_AM}")
+
+    assert amFullInfo.containers.size() == 1
+    assert amFullInfo.containers[0] == amContainerId
+
+  }
+
+  /**
+   * Test the rest model. For this to work the cluster has to be configured
+   * with the global option
+   * @param appmaster
+   */
+  public void testRESTModel() {
+    describe "model"
+
+    assertPathServesList(appmaster,
+        MODEL,
+        ApplicationResource.MODEL_ENTRIES)
+
+    def unresolvedConf = fetchType(AggregateConf, appmaster, MODEL_DESIRED)
+//    log.info "Unresolved \n$unresolvedConf"
+    def unresolvedAppConf = unresolvedConf.appConfOperations
+
+    def sam = "slider-appmaster"
+    assert unresolvedAppConf.getComponentOpt(sam,
+        TEST_GLOBAL_OPTION, "") == ""
+    def resolvedConf = fetchType(AggregateConf, appmaster, MODEL_RESOLVED)
+//    log.info "Resolved \n$resolvedConf"
+    assert resolvedConf.appConfOperations.getComponentOpt(
+        sam, TEST_GLOBAL_OPTION, "") == TEST_GLOBAL_OPTION_PRESENT
+
+    def unresolved = fetchTypeList(ConfTree, appmaster,
+        [MODEL_DESIRED_APPCONF, MODEL_DESIRED_RESOURCES])
+    assert unresolved[MODEL_DESIRED_APPCONF].components[sam]
+    [TEST_GLOBAL_OPTION] == null
+
+
+    def resolved = fetchTypeList(ConfTree, appmaster,
+        [MODEL_RESOLVED_APPCONF, MODEL_RESOLVED_RESOURCES])
+    assert resolved[MODEL_RESOLVED_APPCONF].components[sam]
+    [TEST_GLOBAL_OPTION] ==
+    TEST_GLOBAL_OPTION_PRESENT
+  }
+
+  /**
+   * Test the various ping operations
+   */
+  public void testPing() {
+    // GET
+    String ping = appendToURL(appmaster, SLIDER_PATH_APPLICATION, ACTION_PING)
+    describe "ping to AM URL $appmaster, ping URL $ping"
+    def pinged = fetchType(PingResource, appmaster, ACTION_PING + 
"?body=hello")
+    log.info "Ping GET: $pinged"
+
+    URL pingUrl = new URL(ping)
+    def message = "hello"
+
+    // HEAD
+    pingAction(HttpVerb.HEAD, pingUrl, message)
+
+    // Other verbs
+    pingAction(HttpVerb.POST, pingUrl, message)
+    pingAction(HttpVerb.PUT, pingUrl, message)
+    pingAction(HttpVerb.DELETE, pingUrl, message)
+
+  }
+
+
+  private HttpOperationResponse pingAction(
+      HttpVerb verb,
+      URL pingUrl,
+      String payload) {
+    return pingAction(connectionOperations, verb, pingUrl, payload)
+  }
+
+  private HttpOperationResponse pingAction(
+      UrlConnectionOperations ops, HttpVerb verb, URL pingUrl, String payload) 
{
+    def pinged
+    def outcome = ops.execHttpOperation(
+        verb,
+        pingUrl,
+        payload.bytes,
+        MediaType.TEXT_PLAIN)
+    byte[] bytes = outcome.data
+    if (verb.hasResponseBody()) {
+      assert bytes.length > 0, "0 bytes from ping $verb.verb"
+      pinged = deser(PingResource, bytes)
+      log.info "Ping $verb.verb: $pinged"
+      assert verb.verb == pinged.verb
+    } else {
+      assert bytes.length ==
+             0, "${bytes.length} bytes of data from ping $verb.verb"
+    }
+    return outcome
+  }
+
+  /**
+   * Test the stop command.
+   * Important: once executed, the AM is no longer there.
+   * This must be the last test in the sequence.
+   */
+  public void testStop() {
+    String target = appendToURL(appmaster, SLIDER_PATH_APPLICATION, 
ACTION_STOP)
+    describe "Stop URL $target"
+    URL targetUrl = new URL(target)
+    def outcome = connectionOperations.execHttpOperation(
+        HttpVerb.POST,
+        targetUrl,
+        new byte[0],
+        MediaType.TEXT_PLAIN)
+    log.info "Stopped: $outcome"
+
+    // await the shutdown
+    sleep(1000)
+    
+    // now a ping is expected to fail
+    String ping = appendToURL(appmaster, SLIDER_PATH_APPLICATION, ACTION_PING)
+    URL pingUrl = new URL(ping)
+
+    repeatUntilSuccess("probe for missing registry entry",
+        this.&probePingFailing, 30000, 500,
+        [url: ping],
+        true,
+        "AM failed to shut down") {
+      def pinged = fetchType(
+          PingResource,
+          appmaster,
+          ACTION_PING + "?body=hello")
+      fail("AM didn't shut down; Ping GET= $pinged")
+    }
+    
+  }
+
+  /**
+   * Probe that spins until the url specified by "url") refuses
+   * connections
+   * @param args argument map
+   * @return the outcome
+   */
+  Outcome probePingFailing(Map args) {
+    String ping = args["url"]
+    URL pingUrl = new URL(ping)
+    try {
+      def response = pingAction(HttpVerb.HEAD, pingUrl, "should not be 
running")
+      return Outcome.Retry
+    } catch (IOException e) {
+      // expected
+      return Outcome.Success
+    }
+  }
+
+
+  @Override
+  public void testSuiteGetOperations() {
+
+    testCodahaleOperations()
+    testMimeTypes()
+    testLiveResources()
+    testLiveContainers();
+    testRESTModel()
+  }
+
+  @Override
+  public void testSuiteComplexVerbs() {
+    testPing();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/680d64dc/slider-core/src/test/groovy/org/apache/slider/agent/rest/RestAPIClientTestDelegates.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/RestAPIClientTestDelegates.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/RestAPIClientTestDelegates.groovy
new file mode 100644
index 0000000..de89b8e
--- /dev/null
+++ 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/RestAPIClientTestDelegates.groovy
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.slider.agent.rest
+
+import com.sun.jersey.api.client.Client
+import com.sun.jersey.api.client.WebResource
+import groovy.transform.CompileStatic
+import groovy.util.logging.Slf4j
+import org.apache.slider.api.StateValues
+import org.apache.slider.api.types.ComponentInformation
+import org.apache.slider.api.types.ContainerInformation
+import org.apache.slider.client.rest.SliderApplicationAPI
+import org.apache.slider.core.conf.ConfTree
+import org.apache.slider.core.conf.ConfTreeOperations
+import 
org.apache.slider.server.appmaster.web.rest.application.ApplicationResource
+
+import javax.ws.rs.core.MediaType
+
+import static org.apache.slider.api.ResourceKeys.COMPONENT_INSTANCES
+import static org.apache.slider.api.StatusKeys.*
+import static org.apache.slider.common.SliderKeys.COMPONENT_AM
+import static org.apache.slider.server.appmaster.web.rest.RestPaths.*
+
+/**
+ * Uses the Slider Application API for the tests.
+ * {@link SliderApplicationAPI}
+ */
+@CompileStatic
+@Slf4j
+class RestAPIClientTestDelegates extends AbstractRestTestDelegate {
+  public static final String TEST_GLOBAL_OPTION = "test.global.option"
+  public static final String TEST_GLOBAL_OPTION_PRESENT = "present"
+
+  final String appmaster;
+  final String application;
+  final Client jersey;
+  final SliderApplicationAPI appAPI;
+
+
+  RestAPIClientTestDelegates(String appmaster, Client jersey,
+      boolean enableComplexVerbs = true) {
+    super(enableComplexVerbs)
+    this.jersey = jersey
+    this.appmaster = appmaster
+    application = appendToURL(appmaster, SLIDER_PATH_APPLICATION)
+    WebResource amResource = jersey.resource(appmaster)
+    amResource.type(MediaType.APPLICATION_JSON)
+    appAPI = new SliderApplicationAPI(jersey, amResource)
+  }
+
+
+  public void testGetDesiredModel() throws Throwable {
+      appAPI.getDesiredModel()  
+      appAPI.getDesiredAppconf()  
+      appAPI.getDesiredYarnResources()  
+  }
+
+  public void testGetResolvedModel() throws Throwable {
+      appAPI.getResolvedModel()  
+      appAPI.getResolvedAppconf()  
+      appAPI.getResolvedYarnResources()  
+  }
+
+  
+  public void testLiveResources() throws Throwable {
+    describe "Live Resources"
+
+    ConfTreeOperations tree = appAPI.getLiveYarnResources()
+
+    log.info tree.toString()
+    def liveAM = tree.getComponent(COMPONENT_AM)
+    def desiredInstances = liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES);
+    assert desiredInstances ==
+           liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_ACTUAL)
+
+    assert 1 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_STARTED)
+    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_REQUESTING)
+    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_FAILED)
+    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_COMPLETED)
+    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_RELEASING)
+  }
+
+  public void testLiveContainers() throws Throwable {
+    describe "Application REST ${LIVE_CONTAINERS}"
+
+    Map<String, ContainerInformation> containers = appAPI.enumContainers()
+    assert containers.size() == 1
+    log.info "${containers}"
+    ContainerInformation amContainerInfo =
+        (ContainerInformation) containers.values()[0]
+    assert amContainerInfo.containerId
+
+    def amContainerId = amContainerInfo.containerId
+    assert containers[amContainerId]
+
+    assert amContainerInfo.component == COMPONENT_AM
+    assert amContainerInfo.createTime > 0
+    assert amContainerInfo.exitCode == null
+    assert amContainerInfo.output == null
+    assert amContainerInfo.released == null
+    assert amContainerInfo.state == StateValues.STATE_LIVE
+
+    describe "containers"
+
+    ContainerInformation amContainerInfo2 =
+        appAPI.getContainer(amContainerId)
+    assert amContainerInfo2.containerId == amContainerId
+
+    // fetch missing
+    try {
+      def result = appAPI.getContainer("unknown")
+      fail("expected an error, got $result")
+    } catch (FileNotFoundException e) {
+      // expected
+    }
+
+
+    describe "components"
+
+    Map<String, ComponentInformation> components =
+        appAPI.enumComponents()
+
+    // two components
+    assert components.size() >= 1
+    log.info "${components}"
+
+    ComponentInformation amComponentInfo =
+        (ComponentInformation) components[COMPONENT_AM]
+
+    ComponentInformation amFullInfo = appAPI.getComponent(COMPONENT_AM) 
+
+    assert amFullInfo.containers.size() == 1
+    assert amFullInfo.containers[0] == amContainerId
+
+  }
+
+ 
+  /**
+   * Test the rest model. For this to work the cluster has to be configured
+   * with the global option
+   * @param appmaster
+   */
+  public void testRESTModel() {
+    describe "model"
+
+    assertPathServesList(appmaster,
+        MODEL,
+        ApplicationResource.MODEL_ENTRIES)
+
+    def unresolvedConf = appAPI.getDesiredModel() 
+//    log.info "Unresolved \n$unresolvedConf"
+    def unresolvedAppConf = unresolvedConf.appConfOperations
+
+    def sam = "slider-appmaster"
+    assert unresolvedAppConf.getComponentOpt(sam,
+        TEST_GLOBAL_OPTION, "") == ""
+    def resolvedConf = appAPI.getResolvedModel() 
+    assert resolvedConf.appConfOperations.getComponentOpt(
+        sam, TEST_GLOBAL_OPTION, "") == TEST_GLOBAL_OPTION_PRESENT
+
+    def unresolved = fetchTypeList(ConfTree, appmaster,
+        [MODEL_DESIRED_APPCONF, MODEL_DESIRED_RESOURCES])
+    assert unresolved[MODEL_DESIRED_APPCONF].components[sam]
+    [TEST_GLOBAL_OPTION] == null
+
+
+    
+    def resolvedAppconf = appAPI.getResolvedAppconf() 
+    assert resolvedAppconf.
+               components[sam][TEST_GLOBAL_OPTION] == 
TEST_GLOBAL_OPTION_PRESENT
+  }
+
+  public void testPing() {
+    // GET
+    describe "pinging"
+    
+    appAPI.ping("hello")
+  }
+
+
+  /**
+   * Test the stop command.
+   * Important: once executed, the AM is no longer there.
+   * This must be the last test in the sequence.
+   */
+/*
+
+  public void testStop() {
+    String target = appendToURL(appmaster, SLIDER_PATH_APPLICATION, 
ACTION_STOP)
+    describe "Stop URL $target"
+    URL targetUrl = new URL(target)
+    def outcome = connectionOperations.execHttpOperation(
+        HttpVerb.POST,
+        targetUrl,
+        new byte[0],
+        MediaType.TEXT_PLAIN)
+    log.info "Stopped: $outcome"
+
+    // await the shutdown
+    sleep(1000)
+    
+    // now a ping is expected to fail
+    String ping = appendToURL(appmaster, SLIDER_PATH_APPLICATION, ACTION_PING)
+    URL pingUrl = new URL(ping)
+
+    repeatUntilSuccess("probe for missing registry entry",
+        this.&probePingFailing, 30000, 500,
+        [url: ping],
+        true,
+        "AM failed to shut down") {
+      def pinged = jFetchType(ACTION_PING + "?body=hello",
+          PingResource
+      )
+      fail("AM didn't shut down; Ping GET= $pinged")
+    }
+    
+  }
+*/
+
+  public void testSuiteGetOperations() {
+
+    testGetDesiredModel()
+    testGetResolvedModel()
+    testLiveResources()
+    testLiveContainers();
+    testRESTModel()
+  }
+
+  public void testSuiteComplexVerbs() {
+    testPing();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/680d64dc/slider-core/src/test/groovy/org/apache/slider/agent/rest/RestTestDelegates.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/RestTestDelegates.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/RestTestDelegates.groovy
deleted file mode 100644
index be0b3d8..0000000
--- 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/RestTestDelegates.groovy
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.slider.agent.rest
-
-import groovy.transform.CompileStatic
-import groovy.util.logging.Slf4j
-import org.apache.hadoop.yarn.webapp.NotFoundException
-import org.apache.slider.api.StateValues
-import org.apache.slider.api.types.ComponentInformation
-import org.apache.slider.api.types.ContainerInformation
-import org.apache.slider.core.conf.AggregateConf
-import org.apache.slider.core.conf.ConfTree
-import org.apache.slider.core.conf.ConfTreeOperations
-import org.apache.slider.core.restclient.HttpOperationResponse
-import org.apache.slider.core.restclient.HttpVerb
-import org.apache.slider.core.restclient.UrlConnectionOperations
-import org.apache.slider.server.appmaster.web.rest.RestPaths
-import 
org.apache.slider.server.appmaster.web.rest.application.ApplicationResource
-import org.apache.slider.api.types.PingResource
-import org.apache.slider.test.Outcome
-import org.apache.slider.test.SliderTestUtils
-
-import javax.ws.rs.core.MediaType
-
-import static org.apache.slider.api.ResourceKeys.COMPONENT_INSTANCES
-import static org.apache.slider.api.StatusKeys.*
-import static org.apache.slider.common.SliderKeys.COMPONENT_AM
-import static org.apache.slider.server.appmaster.web.rest.RestPaths.*
-
-/**
- * This class contains parts of tests that can be run
- * against a deployed AM: local or remote
- */
-@CompileStatic
-@Slf4j
-class RestTestDelegates extends SliderTestUtils {
-  public static final String TEST_GLOBAL_OPTION = "test.global.option"
-  public static final String TEST_GLOBAL_OPTION_PRESENT = "present"
-
-  final String appmaster;
-  final String application;
-
-  RestTestDelegates(String appmaster) {
-    this.appmaster = appmaster
-    application = appendToURL(appmaster, RestPaths.SLIDER_PATH_APPLICATION)
-  }
-
-  
-  public void testCodahaleOperations() throws Throwable {
-    describe "Codahale operations"
-    getWebPage(appmaster)
-    getWebPage(appmaster, SYSTEM_THREADS)
-    getWebPage(appmaster, SYSTEM_HEALTHCHECK)
-    getWebPage(appmaster, SYSTEM_PING)
-    getWebPage(appmaster, SYSTEM_METRICS_JSON)
-  }
-  
-  public void logCodahaleMetrics() {
-    // query Coda Hale metrics
-    log.info getWebPage(appmaster, SYSTEM_HEALTHCHECK)
-    log.info getWebPage(appmaster, SYSTEM_METRICS)
-  }
-
-
-  public void testMimeTypes() throws Throwable {
-    describe "Mime Types"
-    HttpOperationResponse response= executeGet(
-        appendToURL(appmaster,
-        SLIDER_PATH_APPLICATION, LIVE_RESOURCES))
-    response.headers.each { key, val -> log.info("$key $val")}
-    log.info "Content type: ${response.contentType}"
-    assert 
response.contentType.contains(MediaType.APPLICATION_JSON_TYPE.toString())
-  }
-
-  
-  public void testLiveResources() throws Throwable {
-    describe "Live Resources"
-    ConfTreeOperations tree = fetchConfigTree(appmaster, LIVE_RESOURCES)
-
-    log.info tree.toString()
-    def liveAM = tree.getComponent(COMPONENT_AM)
-    def desiredInstances = liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES);
-    assert desiredInstances ==
-           liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_ACTUAL)
-
-    assert 1 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_STARTED)
-    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_REQUESTING)
-    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_FAILED)
-    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_COMPLETED)
-    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_RELEASING)
-  }
-
-  public void testLiveContainers() throws Throwable {
-    describe "Application REST ${LIVE_CONTAINERS}"
-
-    Map<String, ContainerInformation> containers =
-        fetchType(HashMap, appmaster, LIVE_CONTAINERS)
-    assert containers.size() == 1
-    log.info "${containers}"
-    ContainerInformation amContainerInfo =
-        (ContainerInformation) containers.values()[0]
-    assert amContainerInfo.containerId
-
-    def amContainerId = amContainerInfo.containerId
-    assert containers[amContainerId]
-
-    assert amContainerInfo.component == COMPONENT_AM
-    assert amContainerInfo.createTime > 0
-    assert amContainerInfo.exitCode == null
-    assert amContainerInfo.output == null
-    assert amContainerInfo.released == null
-    assert amContainerInfo.state == StateValues.STATE_LIVE
-
-    describe "containers"
-
-    ContainerInformation retrievedContainerInfo =
-        fetchType(ContainerInformation, appmaster,
-            LIVE_CONTAINERS + "/${amContainerId}")
-    assert retrievedContainerInfo.containerId == amContainerId
-
-    // fetch missing
-    try {
-      def result = fetchType(ContainerInformation, appmaster,
-          LIVE_CONTAINERS + "/unknown")
-      fail("expected an error, got $result")
-    } catch (NotFoundException e) {
-      // expected
-    }
-
-
-    describe "components"
-
-    Map<String, ComponentInformation> components =
-        fetchType(HashMap, appmaster, LIVE_COMPONENTS)
-    // two components
-    assert components.size() >= 1
-    log.info "${components}"
-
-    ComponentInformation amComponentInfo =
-        (ComponentInformation) components[COMPONENT_AM]
-
-    ComponentInformation amFullInfo = fetchType(
-        ComponentInformation,
-        appmaster,
-        LIVE_COMPONENTS + "/${COMPONENT_AM}")
-
-    assert amFullInfo.containers.size() == 1
-    assert amFullInfo.containers[0] == amContainerId
-
-  }
-
-  /**
-   * Test the rest model. For this to work the cluster has to be configured
-   * with the global option
-   * @param appmaster
-   */
-  public void testRESTModel() {
-    describe "model"
-
-    assertPathServesList(appmaster,
-        MODEL,
-        ApplicationResource.MODEL_ENTRIES)
-
-    def unresolvedConf = fetchType(AggregateConf, appmaster, MODEL_DESIRED)
-//    log.info "Unresolved \n$unresolvedConf"
-    def unresolvedAppConf = unresolvedConf.appConfOperations
-
-    def sam = "slider-appmaster"
-    assert unresolvedAppConf.getComponentOpt(sam,
-        TEST_GLOBAL_OPTION, "") == ""
-    def resolvedConf = fetchType(AggregateConf, appmaster, MODEL_RESOLVED)
-//    log.info "Resolved \n$resolvedConf"
-    assert resolvedConf.appConfOperations.getComponentOpt(
-        sam, TEST_GLOBAL_OPTION, "") == TEST_GLOBAL_OPTION_PRESENT
-
-    def unresolved = fetchTypeList(ConfTree, appmaster,
-        [MODEL_DESIRED_APPCONF, MODEL_DESIRED_RESOURCES])
-    assert unresolved[MODEL_DESIRED_APPCONF].components[sam]
-    [TEST_GLOBAL_OPTION] == null
-
-
-    def resolved = fetchTypeList(ConfTree, appmaster,
-        [MODEL_RESOLVED_APPCONF, MODEL_RESOLVED_RESOURCES])
-    assert resolved[MODEL_RESOLVED_APPCONF].components[sam]
-    [TEST_GLOBAL_OPTION] ==
-    TEST_GLOBAL_OPTION_PRESENT
-  }
-
-  public void testPing() {
-    // GET
-    String ping = appendToURL(appmaster, SLIDER_PATH_APPLICATION, ACTION_PING)
-    describe "ping to AM URL $appmaster, ping URL $ping"
-    def pinged = fetchType(PingResource, appmaster, ACTION_PING + 
"?body=hello")
-    log.info "Ping GET: $pinged"
-
-    URL pingUrl = new URL(ping)
-    def message = "hello"
-
-    // HEAD
-    pingAction(HttpVerb.HEAD, pingUrl, message)
-
-    // Other verbs
-    pingAction(HttpVerb.POST, pingUrl, message)
-    pingAction(HttpVerb.PUT, pingUrl, message)
-    pingAction(HttpVerb.DELETE, pingUrl, message)
-
-  }
-
-
-  private HttpOperationResponse pingAction(
-      HttpVerb verb,
-      URL pingUrl,
-      String payload) {
-    return pingAction(connectionOperations, verb, pingUrl, payload)
-  }
-
-  private HttpOperationResponse pingAction(
-      UrlConnectionOperations ops, HttpVerb verb, URL pingUrl, String payload) 
{
-    def pinged
-    def outcome = ops.execHttpOperation(
-        verb,
-        pingUrl,
-        payload.bytes,
-        MediaType.TEXT_PLAIN)
-    byte[] bytes = outcome.data
-    if (verb.hasResponseBody()) {
-      assert bytes.length > 0, "0 bytes from ping $verb.verb"
-      pinged = deser(PingResource, bytes)
-      log.info "Ping $verb.verb: $pinged"
-      assert verb.verb == pinged.verb
-    } else {
-      assert bytes.length ==
-             0, "${bytes.length} bytes of data from ping $verb.verb"
-    }
-    return outcome
-  }
-
-  /**
-   * Test the stop command.
-   * Important: once executed, the AM is no longer there.
-   * This must be the last test in the sequence.
-   */
-  public void testStop() {
-    String target = appendToURL(appmaster, SLIDER_PATH_APPLICATION, 
ACTION_STOP)
-    describe "Stop URL $target"
-    URL targetUrl = new URL(target)
-    def outcome = connectionOperations.execHttpOperation(
-        HttpVerb.POST,
-        targetUrl,
-        new byte[0],
-        MediaType.TEXT_PLAIN)
-    log.info "Stopped: $outcome"
-
-    // await the shutdown
-    sleep(1000)
-    
-    // now a ping is expected to fail
-    String ping = appendToURL(appmaster, SLIDER_PATH_APPLICATION, ACTION_PING)
-    URL pingUrl = new URL(ping)
-
-    repeatUntilSuccess("probe for missing registry entry",
-        this.&probePingFailing, 30000, 500,
-        [url: ping],
-        true,
-        "AM failed to shut down") {
-      def pinged = fetchType(
-          PingResource,
-          appmaster,
-          ACTION_PING + "?body=hello")
-      fail("AM didn't shut down; Ping GET= $pinged")
-    }
-    
-  }
-
-  /**
-   * Probe that spins until the url specified by "url") refuses
-   * connections
-   * @param args argument map
-   * @return the outcome
-   */
-  Outcome probePingFailing(Map args) {
-    String ping = args["url"]
-    URL pingUrl = new URL(ping)
-    try {
-      def response = pingAction(HttpVerb.HEAD, pingUrl, "should not be 
running")
-      return Outcome.Retry
-    } catch (IOException e) {
-      // expected
-      return Outcome.Success
-    }
-  }
-
-
-  public void testSuiteGetOperations() {
-
-    testCodahaleOperations()
-    testMimeTypes()
-    testLiveResources()
-    testLiveContainers();
-    testRESTModel()
-  }
-
-  public void testSuiteComplexVerbs() {
-    testPing();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/680d64dc/slider-core/src/test/groovy/org/apache/slider/agent/rest/SliderRestClientTestDelegates.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/SliderRestClientTestDelegates.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/SliderRestClientTestDelegates.groovy
deleted file mode 100644
index 95943f4..0000000
--- 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/SliderRestClientTestDelegates.groovy
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.slider.agent.rest
-
-import com.sun.jersey.api.client.Client
-import com.sun.jersey.api.client.WebResource
-import groovy.transform.CompileStatic
-import groovy.util.logging.Slf4j
-import org.apache.slider.api.StateValues
-import org.apache.slider.api.types.ComponentInformation
-import org.apache.slider.api.types.ContainerInformation
-import org.apache.slider.client.rest.SliderApplicationAPI
-import org.apache.slider.core.conf.ConfTree
-import org.apache.slider.core.conf.ConfTreeOperations
-import 
org.apache.slider.server.appmaster.web.rest.application.ApplicationResource
-import org.apache.slider.test.SliderTestUtils
-
-import javax.ws.rs.core.MediaType
-
-import static org.apache.slider.api.ResourceKeys.COMPONENT_INSTANCES
-import static org.apache.slider.api.StatusKeys.*
-import static org.apache.slider.common.SliderKeys.COMPONENT_AM
-import static org.apache.slider.server.appmaster.web.rest.RestPaths.*
-
-/**
- * This class contains parts of tests that can be run
- * against a deployed AM: local or remote.
- * It uses Jersey ... and must be passed a client that is either secure
- * or not
- * 
- */
-@CompileStatic
-@Slf4j
-class SliderRestClientTestDelegates extends SliderTestUtils {
-  public static final String TEST_GLOBAL_OPTION = "test.global.option"
-  public static final String TEST_GLOBAL_OPTION_PRESENT = "present"
-
-  final String appmaster;
-  final String application;
-  final Client jersey;
-  final SliderApplicationAPI appAPI;
-
-
-  SliderRestClientTestDelegates(String appmaster, Client jersey) {
-    this.jersey = jersey
-    this.appmaster = appmaster
-    application = appendToURL(appmaster, SLIDER_PATH_APPLICATION)
-    WebResource amResource = jersey.resource(appmaster)
-    amResource.type(MediaType.APPLICATION_JSON)
-    appAPI = new SliderApplicationAPI(jersey, amResource)
-  }
-
-
-  public void testGetDesiredModel() throws Throwable {
-      appAPI.getDesiredModel()  
-      appAPI.getDesiredAppconf()  
-      appAPI.getDesiredYarnResources()  
-  }
-
-  public void testGetResolvedModel() throws Throwable {
-      appAPI.getResolvedModel()  
-      appAPI.getResolvedAppconf()  
-      appAPI.getResolvedYarnResources()  
-  }
-
-  
-  public void testLiveResources() throws Throwable {
-    describe "Live Resources"
-
-    ConfTreeOperations tree = appAPI.getLiveYarnResources()
-
-    log.info tree.toString()
-    def liveAM = tree.getComponent(COMPONENT_AM)
-    def desiredInstances = liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES);
-    assert desiredInstances ==
-           liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_ACTUAL)
-
-    assert 1 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_STARTED)
-    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_REQUESTING)
-    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_FAILED)
-    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_COMPLETED)
-    assert 0 == liveAM.getMandatoryOptionInt(COMPONENT_INSTANCES_RELEASING)
-  }
-
-  public void testLiveContainers() throws Throwable {
-    describe "Application REST ${LIVE_CONTAINERS}"
-
-    Map<String, ContainerInformation> containers = appAPI.enumContainers()
-    assert containers.size() == 1
-    log.info "${containers}"
-    ContainerInformation amContainerInfo =
-        (ContainerInformation) containers.values()[0]
-    assert amContainerInfo.containerId
-
-    def amContainerId = amContainerInfo.containerId
-    assert containers[amContainerId]
-
-    assert amContainerInfo.component == COMPONENT_AM
-    assert amContainerInfo.createTime > 0
-    assert amContainerInfo.exitCode == null
-    assert amContainerInfo.output == null
-    assert amContainerInfo.released == null
-    assert amContainerInfo.state == StateValues.STATE_LIVE
-
-    describe "containers"
-
-    ContainerInformation amContainerInfo2 =
-        appAPI.getContainer(amContainerId)
-    assert amContainerInfo2.containerId == amContainerId
-
-    // fetch missing
-    try {
-      def result = appAPI.getContainer("unknown")
-      fail("expected an error, got $result")
-    } catch (FileNotFoundException e) {
-      // expected
-    }
-
-
-    describe "components"
-
-    Map<String, ComponentInformation> components =
-        appAPI.enumComponents()
-
-    // two components
-    assert components.size() >= 1
-    log.info "${components}"
-
-    ComponentInformation amComponentInfo =
-        (ComponentInformation) components[COMPONENT_AM]
-
-    ComponentInformation amFullInfo = appAPI.getComponent(COMPONENT_AM) 
-
-    assert amFullInfo.containers.size() == 1
-    assert amFullInfo.containers[0] == amContainerId
-
-  }
-
- 
-  /**
-   * Test the rest model. For this to work the cluster has to be configured
-   * with the global option
-   * @param appmaster
-   */
-  public void testRESTModel() {
-    describe "model"
-
-    assertPathServesList(appmaster,
-        MODEL,
-        ApplicationResource.MODEL_ENTRIES)
-
-    def unresolvedConf = appAPI.getDesiredModel() 
-//    log.info "Unresolved \n$unresolvedConf"
-    def unresolvedAppConf = unresolvedConf.appConfOperations
-
-    def sam = "slider-appmaster"
-    assert unresolvedAppConf.getComponentOpt(sam,
-        TEST_GLOBAL_OPTION, "") == ""
-    def resolvedConf = appAPI.getResolvedModel() 
-    assert resolvedConf.appConfOperations.getComponentOpt(
-        sam, TEST_GLOBAL_OPTION, "") == TEST_GLOBAL_OPTION_PRESENT
-
-    def unresolved = fetchTypeList(ConfTree, appmaster,
-        [MODEL_DESIRED_APPCONF, MODEL_DESIRED_RESOURCES])
-    assert unresolved[MODEL_DESIRED_APPCONF].components[sam]
-    [TEST_GLOBAL_OPTION] == null
-
-
-    
-    def resolvedAppconf = appAPI.getResolvedAppconf() 
-    assert resolvedAppconf.
-               components[sam][TEST_GLOBAL_OPTION] == 
TEST_GLOBAL_OPTION_PRESENT
-  }
-
-  public void testPing() {
-    // GET
-    describe "pinging"
-    
-    appAPI.ping("hello")
-  }
-
-
-  /**
-   * Test the stop command.
-   * Important: once executed, the AM is no longer there.
-   * This must be the last test in the sequence.
-   */
-/*
-
-  public void testStop() {
-    String target = appendToURL(appmaster, SLIDER_PATH_APPLICATION, 
ACTION_STOP)
-    describe "Stop URL $target"
-    URL targetUrl = new URL(target)
-    def outcome = connectionOperations.execHttpOperation(
-        HttpVerb.POST,
-        targetUrl,
-        new byte[0],
-        MediaType.TEXT_PLAIN)
-    log.info "Stopped: $outcome"
-
-    // await the shutdown
-    sleep(1000)
-    
-    // now a ping is expected to fail
-    String ping = appendToURL(appmaster, SLIDER_PATH_APPLICATION, ACTION_PING)
-    URL pingUrl = new URL(ping)
-
-    repeatUntilSuccess("probe for missing registry entry",
-        this.&probePingFailing, 30000, 500,
-        [url: ping],
-        true,
-        "AM failed to shut down") {
-      def pinged = jFetchType(ACTION_PING + "?body=hello",
-          PingResource
-      )
-      fail("AM didn't shut down; Ping GET= $pinged")
-    }
-    
-  }
-*/
-
-  public void testSuiteGetOperations() {
-
-    testGetDesiredModel()
-    testGetResolvedModel()
-    testLiveResources()
-    testLiveContainers();
-    testRESTModel()
-  }
-
-  public void testSuiteComplexVerbs() {
-    testPing();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/680d64dc/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy
 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy
index 3c3dd52..ab5f156 100644
--- 
a/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy
+++ 
b/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy
@@ -33,12 +33,10 @@ import org.apache.hadoop.yarn.api.records.ApplicationReport
 import org.apache.slider.agent.AgentMiniClusterTestBase
 import org.apache.slider.client.SliderClient
 import org.apache.slider.client.rest.RestClientFactory
-import org.apache.slider.client.rest.SliderApplicationAPI
 import org.apache.slider.common.SliderKeys
 import org.apache.slider.common.SliderXmlConfKeys
 import org.apache.slider.common.params.Arguments
 import org.apache.slider.core.main.ServiceLauncher
-import org.apache.slider.core.registry.info.CustomRegistryConstants
 import org.apache.slider.core.restclient.HttpOperationResponse
 import org.junit.Test
 
@@ -65,8 +63,8 @@ class TestStandaloneREST extends AgentMiniClusterTestBase {
     ServiceLauncher<SliderClient> launcher =
         createStandaloneAMWithArgs(clustername,
             [Arguments.ARG_OPTION,
-             RestTestDelegates.TEST_GLOBAL_OPTION, 
-             RestTestDelegates.TEST_GLOBAL_OPTION_PRESENT],
+             AbstractRestTestDelegate.TEST_GLOBAL_OPTION, 
+             AbstractRestTestDelegate.TEST_GLOBAL_OPTION_PRESENT],
             true, false)
     SliderClient client = launcher.service
     addToTeardown(client);
@@ -96,9 +94,18 @@ class TestStandaloneREST extends AgentMiniClusterTestBase {
     log.info GET(proxyAM, SYSTEM_HEALTHCHECK)
     log.info GET(proxyAM, SYSTEM_METRICS_JSON)
 
-    def wsBackDoorRequired = conf.getBoolean(
+    /*
+    Is the back door required? If so, don't test complex verbs via the proxy
+    */
+    def proxyComplexVerbs = !SliderXmlConfKeys.X_DEV_INSECURE_REQUIRED
+
+    /*
+     * Only do direct complex verbs if the no back door is needed, or if
+     * it is enabled
+     */
+    def directComplexVerbs = proxyComplexVerbs || SLIDER_CONFIG.getBoolean(
         SliderXmlConfKeys.X_DEV_INSECURE_WS,
-        true)
+        SliderXmlConfKeys.X_DEV_INSECURE_DEFAULT)
 
     describe "Direct response headers from AM Web resources"
     def liveResUrl = appendToURL(directAM,
@@ -117,44 +124,37 @@ class TestStandaloneREST extends AgentMiniClusterTestBase 
{
     def ugiClient = createUGIJerseyClient();
     
     describe "Proxy SliderRestClient Tests"
-    SliderRestClientTestDelegates proxySliderRestClient =
-        new SliderRestClientTestDelegates(proxyAM, ugiClient)
+    RestAPIClientTestDelegates proxySliderRestClient =
+        new RestAPIClientTestDelegates(proxyAM, ugiClient, proxyComplexVerbs)
     proxySliderRestClient.testSuiteGetOperations()
 
     describe "Direct SliderRestClient Tests"
-    SliderRestClientTestDelegates directSliderRestClient =
-        new SliderRestClientTestDelegates(directAM, ugiClient)
-    directSliderRestClient.testSuiteGetOperations()
-    directSliderRestClient.testSuiteComplexVerbs()
-
+    RestAPIClientTestDelegates directSliderRestClient =
+        new RestAPIClientTestDelegates(directAM, ugiClient, directComplexVerbs)
+    directSliderRestClient.testSuiteAll()
     
     
     describe "Proxy Jersey Tests"
     JerseyTestDelegates proxyJerseyTests =
-        new JerseyTestDelegates(proxyAM, ugiClient)
+        new JerseyTestDelegates(proxyAM, ugiClient, proxyComplexVerbs)
     proxyJerseyTests.testSuiteGetOperations()
 
     describe "Direct Jersey Tests"
 
     JerseyTestDelegates directJerseyTests =
         new JerseyTestDelegates(directAM, ugiClient)
-    directJerseyTests.testSuiteGetOperations()
-    directJerseyTests.testSuiteComplexVerbs()
+    directJerseyTests.testSuiteAll()
 
     describe "Direct Tests"
 
-    RestTestDelegates direct = new RestTestDelegates(directAM)
-    direct.testSuiteGetOperations()
-    direct.testSuiteComplexVerbs()
+    LowLevelRestTestDelegates direct =
+        new LowLevelRestTestDelegates(directAM, directComplexVerbs)
+    direct.testSuiteAll()
 
     describe "Proxy Tests"
 
-    RestTestDelegates proxied = new RestTestDelegates(proxyAM)
-    proxied.testSuiteGetOperations()
-    if (!wsBackDoorRequired) {
-      // and via the proxy
-      proxied.testSuiteComplexVerbs()
-    }
+    LowLevelRestTestDelegates proxied = new LowLevelRestTestDelegates(proxyAM, 
proxyComplexVerbs)
+    proxied.testSuiteAll()
 
     // create the Rest client via the registry
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/680d64dc/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 e6b8bc4..2cd13dd 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
@@ -25,8 +25,9 @@ import 
org.apache.hadoop.registry.client.api.RegistryOperations
 import org.apache.hadoop.security.UserGroupInformation
 import org.apache.hadoop.yarn.webapp.ForbiddenException
 import org.apache.slider.agent.rest.JerseyTestDelegates
-import org.apache.slider.agent.rest.RestTestDelegates
-import org.apache.slider.agent.rest.SliderRestClientTestDelegates
+import org.apache.slider.agent.rest.AbstractRestTestDelegate
+import org.apache.slider.agent.rest.LowLevelRestTestDelegates
+import org.apache.slider.agent.rest.RestAPIClientTestDelegates
 import org.apache.slider.client.SliderClient
 import org.apache.slider.client.rest.RestClientFactory
 import org.apache.slider.common.SliderExitCodes
@@ -69,21 +70,26 @@ public class AgentWebPagesIT extends AgentCommandTestBase
     // verify the ws/ path is open for all HTTP verbs
     def sliderConfiguration = ConfigHelper.loadSliderConfiguration();
 
-    def wsBackDoorRequired = SLIDER_CONFIG.getBoolean(
+    /*
+    Is the back door required? If so, don't test complex verbs via the proxy
+    */
+    def proxyComplexVerbs = !SliderXmlConfKeys.X_DEV_INSECURE_REQUIRED
+
+    /*
+     * Only do direct complex verbs if the no back door is needed, or if
+     * it is enabled
+     */
+    def directComplexVerbs = proxyComplexVerbs || SLIDER_CONFIG.getBoolean(
         SliderXmlConfKeys.X_DEV_INSECURE_WS,
-        true)
-    assert wsBackDoorRequired ==
-        sliderConfiguration.getBoolean(
-            SliderXmlConfKeys.X_DEV_INSECURE_WS,
-            false)
+        SliderXmlConfKeys.X_DEV_INSECURE_DEFAULT)
     def clusterpath = buildClusterPath(CLUSTER)
     File launchReportFile = createTempJsonFile();
     SliderShell shell = createTemplatedSliderApplication(CLUSTER,
         APP_TEMPLATE,
         APP_RESOURCE2,
         [ARG_OPTION,
-         RestTestDelegates.TEST_GLOBAL_OPTION,
-         RestTestDelegates.TEST_GLOBAL_OPTION_PRESENT],
+         AbstractRestTestDelegate.TEST_GLOBAL_OPTION,
+         AbstractRestTestDelegate.TEST_GLOBAL_OPTION_PRESENT],
         launchReportFile)
 
     logShell(shell)
@@ -108,46 +114,38 @@ public class AgentWebPagesIT extends AgentCommandTestBase
     
     def directAM = report.origTrackingUrl;
     // now attempt direct-to-AM pings
-    RestTestDelegates direct = new RestTestDelegates(directAM)
+    LowLevelRestTestDelegates direct = new LowLevelRestTestDelegates(directAM,
+        proxyComplexVerbs)
 
-    direct.testSuiteGetOperations()
-    direct.testSuiteComplexVerbs()
+    direct.testSuiteAll()
 
     // and via the proxy
-    RestTestDelegates proxied = new RestTestDelegates(proxyAM)
-    proxied.testSuiteGetOperations()
-    if (!wsBackDoorRequired) {
-      proxied.testSuiteComplexVerbs()
-    }
+    LowLevelRestTestDelegates proxied = new LowLevelRestTestDelegates(proxyAM,
+        directComplexVerbs)
+    proxied.testSuiteAll()
     proxied.logCodahaleMetrics();
 
     describe "Proxy Jersey Tests"
 
     Client ugiClient = createUGIJerseyClient()
     JerseyTestDelegates proxyJerseyTests =
-        new JerseyTestDelegates(proxyAM, ugiClient)
+        new JerseyTestDelegates(proxyAM, ugiClient, proxyComplexVerbs)
     proxyJerseyTests.testSuiteGetOperations()
 
     describe "Direct Jersey Tests"
     JerseyTestDelegates directJerseyTests =
-        new JerseyTestDelegates(directAM, ugiClient)
-    directJerseyTests.testSuiteGetOperations()
-    directJerseyTests.testSuiteComplexVerbs()
+        new JerseyTestDelegates(directAM, ugiClient, directComplexVerbs)
+    directJerseyTests.testSuiteAll()
 
     describe "Proxy SliderRestClient Tests"
-    SliderRestClientTestDelegates proxySliderRestClient =
-        new SliderRestClientTestDelegates(proxyAM, ugiClient)
-    proxySliderRestClient.testSuiteGetOperations()
-    if (!wsBackDoorRequired) {
-      proxySliderRestClient.testSuiteComplexVerbs()
-    }
-    describe "Direct SliderRestClient Tests"
-    SliderRestClientTestDelegates directSliderRestClient =
-        new SliderRestClientTestDelegates(directAM, ugiClient)
-    directSliderRestClient.testSuiteGetOperations()
-    directSliderRestClient.testSuiteComplexVerbs()
-
+    RestAPIClientTestDelegates proxySliderRestClient =
+        new RestAPIClientTestDelegates(proxyAM, ugiClient, proxyComplexVerbs)
+    proxySliderRestClient.testSuiteAll()
 
+    describe "Direct SliderRestClient Tests"
+    RestAPIClientTestDelegates directSliderRestClient =
+        new RestAPIClientTestDelegates(directAM, ugiClient, directComplexVerbs)
+    directSliderRestClient.testSuiteAll()
 
     if (UserGroupInformation.securityEnabled) {
       describe "Insecure Proxy Tests against a secure cluster"

Reply via email to