You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@slider.apache.org by st...@apache.org on 2014/10/21 15:57:37 UTC

[3/9] git commit: SLIDER-509 registry funtests: change exceptions raised and standalone test to match, prior to functional tests

SLIDER-509 registry funtests: change exceptions raised and standalone test to match, prior to functional tests


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

Branch: refs/heads/develop
Commit: 432ef04d285882acb9f9098c257a64b90118bb81
Parents: 0b0f762
Author: Steve Loughran <st...@apache.org>
Authored: Mon Oct 20 15:27:23 2014 +0100
Committer: Steve Loughran <st...@apache.org>
Committed: Tue Oct 21 10:37:45 2014 +0100

----------------------------------------------------------------------
 .../org/apache/slider/client/SliderClient.java  |  71 +++++---
 .../apache/slider/common/tools/SliderUtils.java |  12 +-
 .../exceptions/BadClusterStateException.java    |   2 +-
 .../core/exceptions/MissingArgException.java    |  26 ---
 .../core/exceptions/NotFoundException.java      |  35 ++++
 .../standalone/TestStandaloneAMDestroy.groovy   |   2 +-
 .../standalone/TestStandaloneAMKill.groovy      |   2 +-
 .../standalone/TestStandaloneAgentAM.groovy     |   6 +-
 .../TestStandaloneYarnRegistryAM.groovy         | 102 +++++------
 .../apache/slider/test/SliderTestUtils.groovy   | 173 +++++++++++++------
 .../funtest/commands/RegistryCommandIT.groovy   |  36 ++++
 11 files changed, 305 insertions(+), 162 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/432ef04d/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
index 41210bd..772c222 100644
--- a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
+++ b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
@@ -31,7 +31,7 @@ import org.apache.hadoop.hdfs.DFSConfigKeys;
 import org.apache.hadoop.hdfs.HdfsConfiguration;
 import org.apache.hadoop.net.NetUtils;
 import org.apache.hadoop.registry.client.binding.RegistryPathUtils;
-import org.apache.hadoop.registry.client.exceptions.InvalidRecordException;
+import org.apache.hadoop.registry.client.types.RegistryPathStatus;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.alias.CredentialProvider;
 import org.apache.hadoop.security.alias.CredentialProviderFactory;
@@ -102,6 +102,7 @@ import org.apache.slider.core.exceptions.BadCommandArgumentsException;
 import org.apache.slider.core.exceptions.BadConfigException;
 import org.apache.slider.core.exceptions.ErrorStrings;
 import org.apache.slider.core.exceptions.NoSuchNodeException;
+import org.apache.slider.core.exceptions.NotFoundException;
 import org.apache.slider.core.exceptions.SliderException;
 import org.apache.slider.core.exceptions.UnknownApplicationInstanceException;
 import org.apache.slider.core.exceptions.WaitTimeoutException;
@@ -323,8 +324,31 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
   }
 
 */
+
+  /**
+   * Launched service execution. This runs {@link #exec()}
+   * then catches some exceptions and converts them to exit codes
+   * @return an exit code
+   * @throws Throwable
+   */
   @Override
   public int runService() throws Throwable {
+    try {
+      return exec();
+    } catch (FileNotFoundException nfe) {
+      throw new NotFoundException(nfe, nfe.toString());
+    } catch (PathNotFoundException nfe) {
+      throw new NotFoundException(nfe, nfe.toString());
+    }
+
+  }
+
+  /**
+   * Execute the command line
+   * @return an exit code
+   * @throws Throwable on a failure
+   */
+  public int exec() throws Throwable {
 
     // choose the action
     String action = serviceArgs.getAction();
@@ -2288,9 +2312,19 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
           destDir.mkdirs();
         }
 
-        Map<String, ServiceRecord> recordMap =
-            listServiceRecords(operations, path);
-
+        Map<String, ServiceRecord> recordMap;
+        try {
+          recordMap = listServiceRecords(operations, path);
+        } catch (PathNotFoundException e) {
+          // treat the root directory as if if is always there
+        
+          if ("/".equals(path)) {
+            recordMap = new HashMap<String, ServiceRecord>(0);
+          } else {
+            throw e;
+          }
+        }
+     
         for (Entry<String, ServiceRecord> recordEntry : recordMap.entrySet()) {
           String name = recordEntry.getKey();
           ServiceRecord instance = recordEntry.getValue();
@@ -2321,16 +2355,9 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
 //      TODO JDK7
     } catch (PathNotFoundException e) {
       // no record at this path
-      return EXIT_NOT_FOUND;
+      throw new NotFoundException(e, path);
     } catch (NoRecordException e) {
-      return EXIT_NOT_FOUND;
-    } catch (UnknownApplicationInstanceException e) {
-      return EXIT_NOT_FOUND;
-    } catch (InvalidRecordException e) {
-      // it is not a record
-      log.error("{}", e);
-      log.debug("{}", e, e);
-      return EXIT_EXCEPTION_THROWN;
+      throw new NotFoundException(e, path);
     }
     return EXIT_SUCCESS;
   }
@@ -2410,7 +2437,7 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
         }
         serviceRecords = recordMap.values();
       } catch (PathNotFoundException e) {
-        throw new UnknownApplicationInstanceException(path, e);
+        throw new NotFoundException(path, e);
       }
     } else {
       ServiceRecord instance = lookupServiceRecord(registryArgs);
@@ -2945,7 +2972,7 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
   }
 
   /**
-   * Look up an instance
+   * Look up a service record of the current user
    * @param serviceType service type
    * @param id instance ID
    * @return instance data
@@ -2965,7 +2992,7 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
    * Look up an instance
    * @param path path
    * @return instance data
-   * @throws UnknownApplicationInstanceException no path or service record
+   * @throws NotFoundException no path/no service record
    * at the end of the path
    * @throws SliderException other failures
    * @throws IOException IO problems or wrapped exceptions
@@ -2973,13 +3000,11 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
   public ServiceRecord resolve(String path)
       throws IOException, SliderException {
     try {
-      return getRegistryOperations().resolve(
-          path);
-      // TODO JDK7 SWITCH
+      return getRegistryOperations().resolve(path);
     } catch (PathNotFoundException e) {
-      throw new UnknownApplicationInstanceException(e.getPath().toString(), e);
+      throw new NotFoundException(e.getPath().toString(), e);
     } catch (NoRecordException e) {
-      throw new UnknownApplicationInstanceException(e.getPath().toString(), e);
+      throw new NotFoundException(e.getPath().toString(), e);
     }
   }
 
@@ -2988,11 +3013,11 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
    * @return a list of slider registry instances
    * @throws IOException Any IO problem ... including no path in the registry
    * to slider service classes for this user
-   * @throws YarnException
+   * @throws SliderException other failures
    */
 
   public Map<String, ServiceRecord> listRegistryInstances()
-      throws IOException, YarnException {
+      throws IOException, SliderException {
     Map<String, ServiceRecord> recordMap = listServiceRecords(
         getRegistryOperations(),
         serviceclassPath(currentUser(), SliderKeys.APP_TYPE));

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/432ef04d/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java b/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
index 72aa4fe..c034e98 100644
--- a/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
+++ b/slider-core/src/main/java/org/apache/slider/common/tools/SliderUtils.java
@@ -55,7 +55,6 @@ import org.apache.slider.core.exceptions.BadClusterStateException;
 import org.apache.slider.core.exceptions.BadCommandArgumentsException;
 import org.apache.slider.core.exceptions.BadConfigException;
 import org.apache.slider.core.exceptions.ErrorStrings;
-import org.apache.slider.core.exceptions.MissingArgException;
 import org.apache.slider.core.exceptions.SliderException;
 import org.apache.slider.core.launch.ClasspathConstructor;
 import org.apache.slider.core.main.LauncherExitCodes;
@@ -565,10 +564,17 @@ public final class SliderUtils {
     return b.toString();
   }
 
-  public static String mandatoryEnvVariable(String key) {
+  /**
+   * Resolve a mandatory environment variable
+   * @param key env var
+   * @return the resolved value
+   * @throws BadClusterStateException
+   */
+  public static String mandatoryEnvVariable(String key) throws
+      BadClusterStateException {
     String v = System.getenv(key);
     if (v == null) {
-      throw new MissingArgException("Missing Environment variable " + key);
+      throw new BadClusterStateException("Missing Environment variable " + key);
     }
     return v;
   }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/432ef04d/slider-core/src/main/java/org/apache/slider/core/exceptions/BadClusterStateException.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/core/exceptions/BadClusterStateException.java b/slider-core/src/main/java/org/apache/slider/core/exceptions/BadClusterStateException.java
index fdedd20..e73ce57 100644
--- a/slider-core/src/main/java/org/apache/slider/core/exceptions/BadClusterStateException.java
+++ b/slider-core/src/main/java/org/apache/slider/core/exceptions/BadClusterStateException.java
@@ -20,7 +20,7 @@ package org.apache.slider.core.exceptions;
 
 
 /**
- * YARN cluster itself is in a bad state
+ * The system is in a bad state
  */
 public class BadClusterStateException extends SliderException {
   public BadClusterStateException(String message,

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/432ef04d/slider-core/src/main/java/org/apache/slider/core/exceptions/MissingArgException.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/core/exceptions/MissingArgException.java b/slider-core/src/main/java/org/apache/slider/core/exceptions/MissingArgException.java
deleted file mode 100644
index 0faffa9..0000000
--- a/slider-core/src/main/java/org/apache/slider/core/exceptions/MissingArgException.java
+++ /dev/null
@@ -1,26 +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.core.exceptions;
-
-
-public class MissingArgException extends RuntimeException {
-  public MissingArgException(String s) {
-    super(s);
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/432ef04d/slider-core/src/main/java/org/apache/slider/core/exceptions/NotFoundException.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/core/exceptions/NotFoundException.java b/slider-core/src/main/java/org/apache/slider/core/exceptions/NotFoundException.java
new file mode 100644
index 0000000..40cb94d
--- /dev/null
+++ b/slider-core/src/main/java/org/apache/slider/core/exceptions/NotFoundException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.core.exceptions;
+
+
+/**
+ * Whatever was being resolved: it was not found
+ */
+public class NotFoundException extends SliderException {
+  public NotFoundException(String message,
+      Object... args) {
+    super(EXIT_NOT_FOUND, message, args);
+  }
+
+  public NotFoundException(Throwable throwable,
+      String message, Object... args) {
+    super(EXIT_NOT_FOUND, throwable, message, args);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/432ef04d/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMDestroy.groovy
----------------------------------------------------------------------
diff --git a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMDestroy.groovy b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMDestroy.groovy
index 463c4c0..49814e7 100644
--- a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMDestroy.groovy
+++ b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMDestroy.groovy
@@ -35,7 +35,7 @@ import org.apache.slider.core.main.ServiceLauncher
 import org.junit.Test
 
 /**
- * destroy a masterless AM
+ * destroy a standalone AM
  */
 @CompileStatic
 @Slf4j

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/432ef04d/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMKill.groovy
----------------------------------------------------------------------
diff --git a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMKill.groovy b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMKill.groovy
index 7552394..bad2715 100644
--- a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMKill.groovy
+++ b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAMKill.groovy
@@ -30,7 +30,7 @@ import org.apache.slider.core.main.ServiceLauncher
 import org.junit.Test
 
 /**
- * kill a masterless AM and verify it shuts down. This test
+ * kill a standalone AM and verify it shuts down. This test
  * also sets the retry count to 1 to stop recreation attempts
  */
 @CompileStatic

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/432ef04d/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy
----------------------------------------------------------------------
diff --git a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy
index d68f87a..60b4dd8 100644
--- a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy
+++ b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneAgentAM.groovy
@@ -40,7 +40,7 @@ class TestStandaloneAgentAM  extends AgentMiniClusterTestBase {
   @Test
   public void testStandaloneAgentAM() throws Throwable {
 
-    describe "create a masterless AM then perform actions on it"
+    describe "create a standalone AM then perform actions on it"
 
     //launch fake master
     String clustername = createMiniCluster("", configuration, 1, true)
@@ -54,7 +54,7 @@ class TestStandaloneAgentAM  extends AgentMiniClusterTestBase {
     List<ApplicationReport> apps = client.applications;
 
     //get some of its status
-    dumpClusterStatus(client, "masterless application status")
+    dumpClusterStatus(client, "standalone application status")
     List<ClusterNode> clusterNodes = client.listClusterNodesInRole(
         SliderKeys.COMPONENT_AM)
     assert clusterNodes.size() == 1
@@ -130,7 +130,7 @@ class TestStandaloneAgentAM  extends AgentMiniClusterTestBase {
     //now try to create instance #3, and expect an in-use failure
     try {
       createStandaloneAM(clustername, false, true)
-      fail("expected a failure, got a masterless AM")
+      fail("expected a failure, got a standalone AM")
     } catch (SliderException e) {
       assertFailureClusterInUse(e);
     }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/432ef04d/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneYarnRegistryAM.groovy
----------------------------------------------------------------------
diff --git a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneYarnRegistryAM.groovy b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneYarnRegistryAM.groovy
index 59494e4..c5e7190 100644
--- a/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneYarnRegistryAM.groovy
+++ b/slider-core/src/test/groovy/org/apache/slider/agent/standalone/TestStandaloneYarnRegistryAM.groovy
@@ -31,10 +31,9 @@ import org.apache.hadoop.registry.client.impl.RegistryOperationsClient
 import org.apache.hadoop.registry.client.types.RegistryPathStatus
 import org.apache.hadoop.registry.client.types.ServiceRecord
 import org.apache.hadoop.registry.client.types.yarn.YarnRegistryAttributes
+import org.apache.slider.common.SliderExitCodes
 import org.apache.slider.common.params.ActionResolveArgs
 import org.apache.slider.common.params.Arguments
-import org.apache.slider.core.exceptions.BadCommandArgumentsException
-import org.apache.slider.core.exceptions.UnknownApplicationInstanceException
 import org.apache.slider.core.main.LauncherExitCodes
 
 import static org.apache.hadoop.registry.client.binding.RegistryUtils.*
@@ -61,10 +60,8 @@ import static org.apache.slider.core.registry.info.CustomRegistryConstants.*
  */
 //@CompileStatic
 @Slf4j
-
 class TestStandaloneYarnRegistryAM extends AgentMiniClusterTestBase {
 
-
   public static final String ARTIFACT_NAME = PublishedArtifacts.COMPLETE_CONFIG
   public static final String HBASE = "hbase/localhost@HADOOP.APACHE.ORG"
 
@@ -72,7 +69,7 @@ class TestStandaloneYarnRegistryAM extends AgentMiniClusterTestBase {
   public void testStandaloneYarnRegistryAM() throws Throwable {
     
 
-    describe "create a masterless AM then perform YARN registry operations on it"
+    describe "create a standalone AM then perform YARN registry operations on it"
 
     
     String clustername = createMiniCluster(configuration, 1, true)
@@ -83,7 +80,7 @@ class TestStandaloneYarnRegistryAM extends AgentMiniClusterTestBase {
       registryOperations.stat(RegistryConstants.PATH_SYSTEM_SERVICES)
     } catch (PathNotFoundException e) {
       log.warn(" RM is not apparently running registry services: {}", e, e)
-    }
+    }  
     
     ServiceLauncher<SliderClient> launcher
     launcher = createStandaloneAM(clustername, true, false)
@@ -192,13 +189,12 @@ class TestStandaloneYarnRegistryAM extends AgentMiniClusterTestBase {
     assert 0 == client.actionResolve(resolveList)
     // to a file
     resolveList.out = resolveListDir;
-    try {
+
+    assertFailsWithException(
+        LauncherExitCodes.EXIT_COMMAND_ARGUMENT_ERROR,
+        Arguments.ARG_OUTPUT) {
       client.actionResolve(resolveList)
-    } catch (BadCommandArgumentsException ex) {
-      assertExceptionDetails(ex, LauncherExitCodes.EXIT_COMMAND_ARGUMENT_ERROR,
-          Arguments.ARG_OUTPUT)
     }
-    
     // list to a destination dir
     resolveList.out = null
     resolveList.destdir = resolveListDir
@@ -219,22 +215,34 @@ class TestStandaloneYarnRegistryAM extends AgentMiniClusterTestBase {
     assert 0 == listParentDir.list().length
 
     // look for a record a path not in the registry expect failure
-    ActionResolveArgs listUnknownPath = new ActionResolveArgs(
-        path: recordsPath +"/unknown",
-        list: true)
+    def unknownPath = recordsPath + "/unknown"
     // the record is not there, even if the path is
-    assert LauncherExitCodes.EXIT_NOT_FOUND == client.actionResolve(
-        listUnknownPath)
-    
-    
+    assertFailsWithException(LauncherExitCodes.EXIT_NOT_FOUND, unknownPath) {
+      client.actionResolve(new ActionResolveArgs(
+          path: unknownPath,
+          list: true))
+    }
+
+    // there's always a root path for listing 
+    client.actionResolve(new ActionResolveArgs(
+        path: "/",
+        list: true))
+
+    // but not usually a root entry
+    assertFailsWithException(LauncherExitCodes.EXIT_NOT_FOUND, "") {
+      client.actionResolve(new ActionResolveArgs(
+          path: "/"))
+    }
+
+
     // look for a record at the same path as the listing; expect failure
-    ActionResolveArgs resolveRecordAtListPath = new ActionResolveArgs(
-        path: recordsPath,
-        list: false)
     // the record is not there, even if the path is
-    assert LauncherExitCodes.EXIT_NOT_FOUND == client.actionResolve(
-        resolveRecordAtListPath)
-
+    assertFailsWithException(LauncherExitCodes.EXIT_NOT_FOUND, recordsPath) {
+      client.actionResolve(new ActionResolveArgs(
+          path: recordsPath,
+          list: false))
+    }
+    
     // look at a single record
     def instanceRecordPath = recordsPath + "/" + clustername
     ActionResolveArgs resolveRecordCommand = new ActionResolveArgs(
@@ -373,22 +381,18 @@ class TestStandaloneYarnRegistryAM extends AgentMiniClusterTestBase {
     assert rmAddrViaClientSideXML == rmAddrFromDownloadedProperties
     
     describe "fetch missing artifact"
-    try {
+    assertFailsWithExceptionClass(
+        FileNotFoundException, "") {
       retriever.retrieveConfiguration(externalConfSet, "no-such-artifact", true)
-      fail("expected a failure")
-    } catch (FileNotFoundException expected) {
-      // expected
     }
+
     describe "Internal configurations"
     assert !retriever.hasConfigurations(false)
-    try {
+    assertFailsWithExceptionClass(
+        FileNotFoundException, "") {
       retriever.getConfigurations(false)
-      fail("expected a failure")
-    } catch (FileNotFoundException expected) {
-      // expected
     }
 
-
     // retrieval via API
     ActionRegistryArgs registryArgs = new ActionRegistryArgs()
     registryArgs.verbose = true
@@ -401,20 +405,16 @@ class TestStandaloneYarnRegistryAM extends AgentMiniClusterTestBase {
     // list a named instance and expect a  failure
     registryArgs.list = true;
     registryArgs.name = "unknown"
-    try {
+    assertFailsWithException(LauncherExitCodes.EXIT_NOT_FOUND, "") {
       client.actionRegistryList(registryArgs)
-    } catch (UnknownApplicationInstanceException expected) {
-      // expected 
     }
 
     // list all instances of an alternate type and expect failure
     registryArgs.list = true;
     registryArgs.name = null
     registryArgs.serviceType = "org-apache-hadoop"
-    try {
+    assertFailsWithException(LauncherExitCodes.EXIT_NOT_FOUND,"") {
       client.actionRegistryList(registryArgs)
-    } catch (UnknownApplicationInstanceException expected) {
-      // expected 
     }
 
     registryArgs.serviceType = ""
@@ -487,7 +487,7 @@ class TestStandaloneYarnRegistryAM extends AgentMiniClusterTestBase {
     assert LauncherExitCodes.EXIT_NOT_FOUND == client.actionRegistry(registryArgs)
 
     //look for a different user
-    try {
+    assertFailsWithException(SliderExitCodes.EXIT_NOT_FOUND, "") {
       def args = new ActionRegistryArgs(
           name: clustername,
           user: "unknown",
@@ -496,9 +496,7 @@ class TestStandaloneYarnRegistryAM extends AgentMiniClusterTestBase {
           verbose: true
       )
       client.actionRegistry(args)
-      fail("registry operation succeeded unexpectedly on $args")
-    } catch (UnknownApplicationInstanceException expected) {
-      // expected
+      log.warn("Success on $args")
     }
     
     describe "stop cluster"
@@ -517,12 +515,18 @@ class TestStandaloneYarnRegistryAM extends AgentMiniClusterTestBase {
 
     // only check this if the YARN registry renaming logic is in
     if (!hbase.contains("@")) {
-      assert LauncherExitCodes.EXIT_NOT_FOUND == client.actionResolve(
-          new ActionResolveArgs(
-              path: hbaseServices,
-              list: true))
-      assert LauncherExitCodes.EXIT_NOT_FOUND == client.actionResolve(
-          new ActionResolveArgs(path: hbaseServices))
+      assertFailsWithException(LauncherExitCodes.EXIT_NOT_FOUND, "") {
+        client.actionResolve(
+            new ActionResolveArgs(
+                path: hbaseServices,
+                list: true))
+      }
+      assertFailsWithException(LauncherExitCodes.EXIT_NOT_FOUND, "") {
+        client.actionResolve(
+            new ActionResolveArgs(
+                path: hbaseServices))
+      }
+
     }
 
   }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/432ef04d/slider-core/src/test/groovy/org/apache/slider/test/SliderTestUtils.groovy
----------------------------------------------------------------------
diff --git a/slider-core/src/test/groovy/org/apache/slider/test/SliderTestUtils.groovy b/slider-core/src/test/groovy/org/apache/slider/test/SliderTestUtils.groovy
index 42ec9de..2af0a2f 100644
--- a/slider-core/src/test/groovy/org/apache/slider/test/SliderTestUtils.groovy
+++ b/slider-core/src/test/groovy/org/apache/slider/test/SliderTestUtils.groovy
@@ -104,7 +104,6 @@ class SliderTestUtils extends Assert {
     }
   }
 
-  
   /**
    * Assert a list has a given length
    * @param list list
@@ -115,14 +114,13 @@ class SliderTestUtils extends Assert {
     assertEquals(lval, size, list.size())
   }
 
-  
   /**
    * Stringify a collection with [ ] at either end
    * @param collection collection
    * @return string value
    */
   public static String collectionToString(List collection) {
-    return "[" + SliderUtils.join(collection,", ", false) +"]"
+    return "[" + SliderUtils.join(collection, ", ", false) + "]"
   }
 
   /**
@@ -135,8 +133,7 @@ class SliderTestUtils extends Assert {
       skip("Configuration key $key not set")
     }
   }
-  
-  
+
   /**
    * assert that a string option is set and not equal to ""
    * @param conf configuration file
@@ -145,8 +142,6 @@ class SliderTestUtils extends Assert {
   public static void assertStringOptionSet(Configuration conf, String key) {
     getRequiredConfOption(conf, key)
   }
-  
-  
 
   /**
    * Assume that a boolean option is set and true.
@@ -167,8 +162,8 @@ class SliderTestUtils extends Assert {
    */
   public static void assumeBoolOption(
       Configuration conf, String key, boolean defval) {
-    assume(conf.getBoolean(key, defval), 
-      "Configuration key $key is false")
+    assume(conf.getBoolean(key, defval),
+        "Configuration key $key is false")
   }
 
   /**
@@ -198,7 +193,9 @@ class SliderTestUtils extends Assert {
    * @param sliderClient client
    * @return the app report of the live cluster
    */
-  public static ApplicationReport waitForClusterLive(SliderClient sliderClient,int goLiveTime) {
+  public static ApplicationReport waitForClusterLive(
+      SliderClient sliderClient,
+      int goLiveTime) {
     ApplicationReport report = sliderClient.monitorAppToRunning(
         new Duration(goLiveTime));
     assertNotNull(
@@ -314,7 +311,7 @@ class SliderTestUtils extends Assert {
         duration.finish();
         describe("$operation: role count not met after $duration: $details")
         log.info(prettyPrint(status.toJsonString()))
-        fail("$operation: role counts not met after $duration: "  +
+        fail("$operation: role counts not met after $duration: " +
              details.toString() +
              " in \n$status ")
       }
@@ -332,35 +329,42 @@ class SliderTestUtils extends Assert {
    * @throws IOException
    * @throws SliderException
    */
-  public static boolean spinForClusterStartup(SliderClient client, long spintime,
+  public static boolean spinForClusterStartup(
+      SliderClient client,
+      long spintime,
       String role)
-      throws WaitTimeoutException, IOException, SliderException {
+  throws WaitTimeoutException, IOException, SliderException {
     int state = client.waitForRoleInstanceLive(role, spintime);
     return state == ClusterDescription.STATE_LIVE;
   }
 
-  public static ClusterDescription dumpClusterStatus(SliderClient client, String text) {
+  public static ClusterDescription dumpClusterStatus(
+      SliderClient client,
+      String text) {
     ClusterDescription status = client.clusterDescription;
     dumpClusterDescription(text, status)
     return status;
   }
 
-  public static List<ClusterNode> listNodesInRole(SliderClient client, String role) {
+  public static List<ClusterNode> listNodesInRole(
+      SliderClient client,
+      String role) {
     return client.listClusterNodesInRole(role)
   }
 
-  public static void dumpClusterDescription(String text, ClusterDescription status) {
+  public static void dumpClusterDescription(
+      String text,
+      ClusterDescription status) {
     describe(text)
     log.info(prettyPrint(status.toJsonString()))
   }
 
-  
+
   public static void dumpClusterDescription(String text, AggregateConf status) {
     describe(text)
     log.info(status.toString())
   }
 
-  
   /**
    * Fetch the current site config from the Slider AM, from the 
    * <code>clientProperties</code> field of the ClusterDescription
@@ -386,15 +390,15 @@ class SliderTestUtils extends Assert {
   public static String GET(URL url) {
     return fetchWebPageWithoutError(url.toString())
   }
-  
+
   public static String GET(URL url, String path) {
     return GET(url.toString(), path)
   }
-  
+
   public static String GET(String base, String path) {
     String s = appendToURL(base, path)
     return GET(s)
-    
+
   }
 
   def static String GET(String s) {
@@ -425,17 +429,17 @@ class SliderTestUtils extends Assert {
     int resultCode
     try {
       resultCode = httpclient.executeMethod(get);
-      if (resultCode!=200) {
+      if (resultCode != 200) {
         log.warn("Result code of $resultCode")
       }
     } catch (IOException e) {
-      log.error("Failed on $url: $e",e)
+      log.error("Failed on $url: $e", e)
       throw e;
     }
     String body = get.responseBodyAsString;
     return body;
   }
-  
+
   /**
    * Fetches a web page asserting that the response code is between 200 and 400.
    * Will error on 400 and 500 series response codes and let 200 and 300 through. 
@@ -444,13 +448,13 @@ class SliderTestUtils extends Assert {
    */
   public static String fetchWebPageWithoutError(String url) {
     assert null != url
-    
+
     log.info("Fetching HTTP content at " + url);
-    
+
     def client = new HttpClient(new MultiThreadedHttpConnectionManager());
     client.httpConnectionManager.params.connectionTimeout = 10000;
     GetMethod get = new GetMethod(url);
-    
+
     get.followRedirects = true;
     int resultCode = client.executeMethod(get);
 
@@ -472,6 +476,42 @@ class SliderTestUtils extends Assert {
   }
 
   /**
+   * Execute a closure, assert it fails with a given exit code and text
+   * @param exitCode exit code
+   * @param text text (can be "")
+   * @param action action
+   * @return
+   */
+  def assertFailsWithException(int exitCode,
+      String text,
+      Closure action) {
+    try {
+      action()
+      fail("Operation was expected to fail —but it succeeded")
+    } catch (ServiceLaunchException e) {
+      assertExceptionDetails(e, exitCode, text)
+    }
+  }
+  
+  /**
+   * Execute a closure, assert it fails with a given exit code and text
+   * @param exitCode exit code
+   * @param text text (can be "")
+   * @param action action
+   * @return
+   */
+  def assertFailsWithExceptionClass(Class clazz,
+      String text,
+      Closure action) {
+    try {
+      action()
+      fail("Operation was expected to fail —but it succeeded")
+    } catch (Exception e) {
+      assertExceptionDetails(e, clazz, text)
+    }
+  }
+
+  /**
    * Make an assertion about the exit code of an exception
    * @param ex exception
    * @param exitCode exit code
@@ -489,11 +529,28 @@ class SliderTestUtils extends Assert {
     }
     if (text) {
       if (!(ex.toString().contains(text))) {
-        log.warn("String match failed in $ex", ex)
+        log.warn("String match for \"${text}\"failed in $ex", ex)
         assert ex.toString().contains(text);
       }
     }
   }
+  /**
+   * Make an assertion about the exit code of an exception
+   * @param ex exception
+   * @param exitCode exit code
+   * @param text error text to look for in the exception
+   */
+  static void assertExceptionDetails(
+      Exception ex,
+      Class clazz,
+      String text = "") {
+    if (ex.class != clazz) {
+      throw ex;
+    }
+    if (text && !(ex.toString().contains(text))) {
+      throw ex;
+    }
+  }
 
   /**
    * Launch the slider client with the specific args; no validation
@@ -516,8 +573,8 @@ class SliderTestUtils extends Assert {
   }
 
   public static ServiceLauncher launch(Class serviceClass,
-                                       Configuration conf,
-                                       List<Object> args) throws
+      Configuration conf,
+      List<Object> args) throws
       Throwable {
     ServiceLauncher serviceLauncher =
         new ServiceLauncher(serviceClass.name);
@@ -530,20 +587,21 @@ class SliderTestUtils extends Assert {
   }
 
   public static Throwable launchExpectingException(Class serviceClass,
-                                              Configuration conf,
-                                              String expectedText,
-                                              List args)
-      throws Throwable {
+      Configuration conf,
+      String expectedText,
+      List args)
+  throws Throwable {
     try {
       ServiceLauncher launch = launch(serviceClass, conf, args);
-      throw new AssertionError("Expected an exception with text containing " + expectedText
-               + " -but the service completed with exit code "
-               + launch.serviceExitCode);
+      throw new AssertionError(
+          "Expected an exception with text containing " + expectedText
+              + " -but the service completed with exit code "
+              + launch.serviceExitCode);
     } catch (Throwable thrown) {
       if (expectedText && !thrown.toString().contains(expectedText)) {
         //not the right exception -rethrow
         log.warn("Caught Exception did not contain expected text" +
-                 "\""+ expectedText +"\"")
+                 "\"" + expectedText + "\"")
         throw thrown;
       }
       return thrown;
@@ -574,10 +632,10 @@ class SliderTestUtils extends Assert {
       List<String> extraArgs,
       YarnConfiguration conf,
       String option) {
-    
+
     conf.getTrimmed(option);
     extraArgs << ARG_OPTION << option << getRequiredConfOption(conf, option)
-    
+
   }
 
   /**
@@ -587,7 +645,7 @@ class SliderTestUtils extends Assert {
    * @throws IOException on File IO problems
    */
   public static void assertIsDirectory(HadoopFS fs,
-                                       Path path) throws IOException {
+      Path path) throws IOException {
     FileStatus fileStatus = fs.getFileStatus(path);
     assertIsDirectory(fileStatus);
   }
@@ -598,7 +656,7 @@ class SliderTestUtils extends Assert {
    */
   public static void assertIsDirectory(FileStatus fileStatus) {
     assertTrue("Should be a dir -but isn't: " + fileStatus,
-               fileStatus.isDirectory());
+        fileStatus.isDirectory());
   }
 
   /**
@@ -616,8 +674,10 @@ class SliderTestUtils extends Assert {
       Path path) throws IOException {
     if (!fileSystem.exists(path)) {
       //failure, report it
-      fail(message + ": not found \"" + path + "\" in " + path.getParent() + "-" +
-        ls(fileSystem, path.getParent()));
+      fail(
+          message + ": not found \"" + path + "\" in " + path.getParent() +
+          "-" +
+          ls(fileSystem, path.getParent()));
     }
   }
 
@@ -651,8 +711,8 @@ class SliderTestUtils extends Assert {
    * @throws IOException IO probles
    */
   public static void assertListStatusFinds(HadoopFS fs,
-                                           Path dir,
-                                           Path subdir) throws IOException {
+      Path dir,
+      Path subdir) throws IOException {
     FileStatus[] stats = fs.listStatus(dir);
     boolean found = false;
     StringBuilder builder = new StringBuilder();
@@ -663,8 +723,8 @@ class SliderTestUtils extends Assert {
       }
     }
     assertTrue("Path " + subdir
-                   + " not found in directory " + dir + ":" + builder,
-               found);
+        + " not found in directory " + dir + ":" + builder,
+        found);
   }
 
   /**
@@ -721,7 +781,7 @@ class SliderTestUtils extends Assert {
     describe "end list service registry slider instances"
   }
 
-  
+
   public static void dumpRegistryInstanceIDs(List<String> instanceIds) {
     describe "service registry instance IDs"
     dumpCollection(instanceIds)
@@ -734,7 +794,7 @@ class SliderTestUtils extends Assert {
 
   def static void dumpCollection(Collection entries) {
     log.info("number of entries: ${entries.size()}")
-    entries.each {  log.info(it.toString()) }
+    entries.each { log.info(it.toString()) }
   }
 
   def static void dumpArray(Object[] entries) {
@@ -747,7 +807,7 @@ class SliderTestUtils extends Assert {
       log.info("\"${it.key.toString()}\": \"${it.value.toString()}\"")
     }
   }
-  
+
   /**
    * Get a time option in seconds if set, otherwise the default value (also in seconds).
    * This operation picks up the time value as a system property if set -that
@@ -757,7 +817,10 @@ class SliderTestUtils extends Assert {
    * @param defVal
    * @return
    */
-  public static int getTimeOptionMillis(Configuration conf, String key, int defValMillis) {
+  public static int getTimeOptionMillis(
+      Configuration conf,
+      String key,
+      int defValMillis) {
     int val = conf.getInt(key, 0)
     val = Integer.getInteger(key, val)
     int time = 1000 * val
@@ -783,7 +846,7 @@ class SliderTestUtils extends Assert {
     def commandString
     if (!Shell.WINDOWS) {
       GString killCommand = "jps -l| grep ${grepString} | awk '{print \$1}' | xargs kill $signal"
-      log.info("Command command = $killCommand" )
+      log.info("Command command = $killCommand")
 
       commandString = ["bash", "-c", killCommand]
     } else {
@@ -808,7 +871,7 @@ class SliderTestUtils extends Assert {
    */
   public void killJavaProcesses(List<String> greps, int signal) {
     for (String grep : greps) {
-      killJavaProcesses(grep,signal)
+      killJavaProcesses(grep, signal)
     }
   }
 
@@ -833,7 +896,7 @@ class SliderTestUtils extends Assert {
       def files = parent.list()
       StringBuilder builder = new StringBuilder()
       builder.append("${parent.absolutePath}:\n")
-      files.each { String name-> builder.append("  $name\n")}
+      files.each { String name -> builder.append("  $name\n") }
       throw new FileNotFoundException("$text: $file not found in $builder")
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/432ef04d/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/RegistryCommandIT.groovy
----------------------------------------------------------------------
diff --git a/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/RegistryCommandIT.groovy b/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/RegistryCommandIT.groovy
new file mode 100644
index 0000000..9e9bd7e
--- /dev/null
+++ b/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/RegistryCommandIT.groovy
@@ -0,0 +1,36 @@
+/*
+ * 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.funtest.commands
+
+import groovy.transform.CompileStatic
+import groovy.util.logging.Slf4j
+import org.apache.slider.funtest.framework.CommandTestBase
+import org.junit.BeforeClass
+import org.junit.Test
+
+@CompileStatic
+@Slf4j
+public class RegistryCommandIT extends CommandTestBase {
+
+  @Test
+  public void testListAll() throws Throwable {
+    assertSuccess(list(null))
+  }
+
+}