You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by cs...@apache.org on 2017/09/18 14:55:39 UTC

[incubator-openwhisk-cli] 11/16: Apply standard scala formatting. (#2650)

This is an automated email from the ASF dual-hosted git repository.

csantanapr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-cli.git

commit 5e39d4bbaba4be93b027afc2d145395dd05257cf
Author: Markus Thömmes <ma...@me.com>
AuthorDate: Wed Sep 6 20:53:48 2017 +0200

    Apply standard scala formatting. (#2650)
    
    Formats all .scala files according to `scalafmt`'s (opinionated) style.
    Adds Travis checks for correctly formatted code.
---
 .../apigw/healthtests/ApiGwEndToEndTests.scala     |  227 +-
 .../test/scala/system/basic/WskActionTests.scala   |  539 ++--
 .../test/scala/system/basic/WskBasicTests.scala    | 1628 +++++-----
 .../test/scala/system/basic/WskConsoleTests.scala  |   84 +-
 .../test/scala/system/basic/WskPackageTests.scala  |  169 +-
 .../src/test/scala/system/basic/WskRuleTests.scala |  706 ++---
 .../src/test/scala/system/basic/WskSdkTests.scala  |  152 +-
 .../test/scala/system/basic/WskSequenceTests.scala |  933 +++---
 .../scala/whisk/core/admin/WskAdminTests.scala     |  275 +-
 .../actions/test/ApiGwRoutemgmtActionTests.scala   |  781 +++--
 .../scala/whisk/core/cli/test/ApiGwTests.scala     | 1839 ++++++------
 .../core/cli/test/WskActionSequenceTests.scala     |   81 +-
 .../whisk/core/cli/test/WskBasicUsageTests.scala   | 3140 ++++++++++----------
 .../scala/whisk/core/cli/test/WskConfigTests.scala |  448 +--
 .../whisk/core/cli/test/WskEntitlementTests.scala  |  557 ++--
 .../whisk/core/cli/test/WskWebActionsTests.scala   |  530 ++--
 16 files changed, 6217 insertions(+), 5872 deletions(-)

diff --git a/tests/src/test/scala/apigw/healthtests/ApiGwEndToEndTests.scala b/tests/src/test/scala/apigw/healthtests/ApiGwEndToEndTests.scala
index 332a5ca..4c95bf5 100644
--- a/tests/src/test/scala/apigw/healthtests/ApiGwEndToEndTests.scala
+++ b/tests/src/test/scala/apigw/healthtests/ApiGwEndToEndTests.scala
@@ -53,118 +53,119 @@ class ApiGwEndToEndTests
     with WskTestHelpers
     with BeforeAndAfterAll {
 
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-    val clinamespace = wsk.namespace.whois()
-
-    // Custom CLI properties file
-    val cliWskPropsFile = File.createTempFile("wskprops", ".tmp")
-
-    /*
-     * Create a CLI properties file for use by the tests
-     */
-    override def beforeAll() = {
-        cliWskPropsFile.deleteOnExit()
-        val wskprops = WskProps(token = "SOME TOKEN")
-        wskprops.writeFile(cliWskPropsFile)
-        println(s"wsk temporary props file created here: ${cliWskPropsFile.getCanonicalPath()}")
-    }
-
-    behavior of "Wsk api"
-
-    it should s"create an API and successfully invoke that API" in {
-        val testName = "APIGW_HEALTHTEST1"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_echo"
-        val urlqueryparam = "name"
-        val urlqueryvalue = testName
-
-        try {
-            println("cli namespace: " + clinamespace)
-
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo-web-http.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson))
-
-            // Create the API
-            var rr = wsk.api.create(
-                basepath = Some(testbasepath),
-                relpath = Some(testrelpath),
-                operation = Some(testurlop),
-                action = Some(actionName),
-                apiname = Some(testapiname),
-                responsetype = Some("http"),
-                cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
-            rr.stdout should include("ok: created API")
-            val apiurl = rr.stdout.split("\n")(1)
-            println(s"apiurl: '$apiurl'")
-
-            // Validate the API was successfully created
-            // List result will look like:
-            // ok: APIs
-            // Action                            Verb             API Name  URL
-            // /_//whisk.system/utils/echo          get  APIGW_HEALTHTEST1 API Name  http://172.17.0.1:9001/api/ab9082cd-ea8e-465a-8a65-b491725cc4ef/APIGW_HEALTHTEST1_bp/path
-            rr = wsk.api.list(
-                basepathOrApiName = Some(testbasepath),
-                relpath = Some(testrelpath),
-                operation = Some(testurlop),
-                cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
-            rr.stdout should include("ok: APIs")
-            rr.stdout should include regex (s"$actionName\\s+$testurlop\\s+$testapiname\\s+")
-            rr.stdout should include(testbasepath + testrelpath)
-
-            // Recreate the API using a JSON swagger file
-            rr = wsk.api.get(
-                basepathOrApiName = Some(testbasepath),
-                cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
-            val swaggerfile = File.createTempFile("api", ".json")
-            swaggerfile.deleteOnExit()
-            val bw = new BufferedWriter(new FileWriter(swaggerfile))
-            bw.write(rr.stdout)
-            bw.close()
-
-            // Delete API to that it can be recreated again using the generated swagger file
-            val deleteApiResult = wsk.api.delete(
-                basepathOrApiName = testbasepath,
-                expectedExitCode = DONTCARE_EXIT,
-                cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
-
-            // Create the API again, but use the swagger file this time
-            rr = wsk.api.create(
-                swagger = Some(swaggerfile.getAbsolutePath()),
-                cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
-            rr.stdout should include("ok: created API")
-            val swaggerapiurl = rr.stdout.split("\n")(1)
-            println(s"Returned api url: '${swaggerapiurl}'")
-
-            // Call the API URL and validate the results
-            val start = java.lang.System.currentTimeMillis
-            val apiToInvoke = s"$swaggerapiurl?$urlqueryparam=$urlqueryvalue&guid=$start"
-            println(s"Invoking: '${apiToInvoke}'")
-            val response = whisk.utils.retry({
-                val response = RestAssured.given().config(sslconfig).get(s"$apiToInvoke")
-                println("URL invocation response status: " + response.statusCode)
-                response.statusCode should be(200)
-                response
-            }, 6, Some(2.second))
-            val end = java.lang.System.currentTimeMillis
-            val elapsed = end - start
-            println("Elapsed time (milliseconds) for a successful response: " + elapsed)
-            val responseString = response.body.asString
-            println("URL invocation response: " + responseString)
-            responseString.parseJson.asJsObject.fields(urlqueryparam).convertTo[String] should be(urlqueryvalue)
-
-        } finally {
-            println("Deleting action: " + actionName)
-            val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            println("Deleting API: " + testbasepath)
-            val finallydeleteApiResult = wsk.api.delete(
-                basepathOrApiName = testbasepath,
-                expectedExitCode = DONTCARE_EXIT,
-                cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
-        }
+  implicit val wskprops = WskProps()
+  val wsk = new Wsk
+  val clinamespace = wsk.namespace.whois()
+
+  // Custom CLI properties file
+  val cliWskPropsFile = File.createTempFile("wskprops", ".tmp")
+
+  /*
+   * Create a CLI properties file for use by the tests
+   */
+  override def beforeAll() = {
+    cliWskPropsFile.deleteOnExit()
+    val wskprops = WskProps(token = "SOME TOKEN")
+    wskprops.writeFile(cliWskPropsFile)
+    println(s"wsk temporary props file created here: ${cliWskPropsFile.getCanonicalPath()}")
+  }
+
+  behavior of "Wsk api"
+
+  it should s"create an API and successfully invoke that API" in {
+    val testName = "APIGW_HEALTHTEST1"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_echo"
+    val urlqueryparam = "name"
+    val urlqueryvalue = testName
+
+    try {
+      println("cli namespace: " + clinamespace)
+
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo-web-http.js")
+      wsk.action.create(
+        name = actionName,
+        artifact = Some(file),
+        expectedExitCode = SUCCESS_EXIT,
+        annotations = Map("web-export" -> true.toJson))
+
+      // Create the API
+      var rr = wsk.api.create(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname),
+        responsetype = Some("http"),
+        cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
+      rr.stdout should include("ok: created API")
+      val apiurl = rr.stdout.split("\n")(1)
+      println(s"apiurl: '$apiurl'")
+
+      // Validate the API was successfully created
+      // List result will look like:
+      // ok: APIs
+      // Action                            Verb             API Name  URL
+      // /_//whisk.system/utils/echo          get  APIGW_HEALTHTEST1 API Name  http://172.17.0.1:9001/api/ab9082cd-ea8e-465a-8a65-b491725cc4ef/APIGW_HEALTHTEST1_bp/path
+      rr = wsk.api.list(
+        basepathOrApiName = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
+      rr.stdout should include("ok: APIs")
+      rr.stdout should include regex (s"$actionName\\s+$testurlop\\s+$testapiname\\s+")
+      rr.stdout should include(testbasepath + testrelpath)
+
+      // Recreate the API using a JSON swagger file
+      rr = wsk.api.get(basepathOrApiName = Some(testbasepath), cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
+      val swaggerfile = File.createTempFile("api", ".json")
+      swaggerfile.deleteOnExit()
+      val bw = new BufferedWriter(new FileWriter(swaggerfile))
+      bw.write(rr.stdout)
+      bw.close()
+
+      // Delete API to that it can be recreated again using the generated swagger file
+      val deleteApiResult = wsk.api.delete(
+        basepathOrApiName = testbasepath,
+        expectedExitCode = DONTCARE_EXIT,
+        cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
+
+      // Create the API again, but use the swagger file this time
+      rr = wsk.api
+        .create(swagger = Some(swaggerfile.getAbsolutePath()), cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
+      rr.stdout should include("ok: created API")
+      val swaggerapiurl = rr.stdout.split("\n")(1)
+      println(s"Returned api url: '${swaggerapiurl}'")
+
+      // Call the API URL and validate the results
+      val start = java.lang.System.currentTimeMillis
+      val apiToInvoke = s"$swaggerapiurl?$urlqueryparam=$urlqueryvalue&guid=$start"
+      println(s"Invoking: '${apiToInvoke}'")
+      val response = whisk.utils.retry({
+        val response = RestAssured.given().config(sslconfig).get(s"$apiToInvoke")
+        println("URL invocation response status: " + response.statusCode)
+        response.statusCode should be(200)
+        response
+      }, 6, Some(2.second))
+      val end = java.lang.System.currentTimeMillis
+      val elapsed = end - start
+      println("Elapsed time (milliseconds) for a successful response: " + elapsed)
+      val responseString = response.body.asString
+      println("URL invocation response: " + responseString)
+      responseString.parseJson.asJsObject.fields(urlqueryparam).convertTo[String] should be(urlqueryvalue)
+
+    } finally {
+      println("Deleting action: " + actionName)
+      val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      println("Deleting API: " + testbasepath)
+      val finallydeleteApiResult = wsk.api.delete(
+        basepathOrApiName = testbasepath,
+        expectedExitCode = DONTCARE_EXIT,
+        cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
     }
+  }
 }
diff --git a/tests/src/test/scala/system/basic/WskActionTests.scala b/tests/src/test/scala/system/basic/WskActionTests.scala
index 06778a3..fb65f2c 100644
--- a/tests/src/test/scala/system/basic/WskActionTests.scala
+++ b/tests/src/test/scala/system/basic/WskActionTests.scala
@@ -34,327 +34,274 @@ import spray.json.JsObject
 import spray.json.pimpAny
 
 @RunWith(classOf[JUnitRunner])
-class WskActionTests
-    extends TestHelpers
-    with WskTestHelpers
-    with JsHelpers {
-
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-
-    val testString = "this is a test"
-    val testResult = JsObject("count" -> testString.split(" ").length.toJson)
-    val guestNamespace = wskprops.namespace
-
-    behavior of "Whisk actions"
-
-    it should "invoke an action returning a promise" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "hello promise"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("helloPromise.js")))
-            }
-
-            val run = wsk.action.invoke(name)
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.status shouldBe "success"
-                    activation.response.result shouldBe Some(JsObject("done" -> true.toJson))
-                    activation.logs.get.mkString(" ") shouldBe empty
-            }
+class WskActionTests extends TestHelpers with WskTestHelpers with JsHelpers {
+
+  implicit val wskprops = WskProps()
+  val wsk = new Wsk
+
+  val testString = "this is a test"
+  val testResult = JsObject("count" -> testString.split(" ").length.toJson)
+  val guestNamespace = wskprops.namespace
+
+  behavior of "Whisk actions"
+
+  it should "invoke an action returning a promise" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "hello promise"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("helloPromise.js")))
+    }
+
+    val run = wsk.action.invoke(name)
+    withActivation(wsk.activation, run) { activation =>
+      activation.response.status shouldBe "success"
+      activation.response.result shouldBe Some(JsObject("done" -> true.toJson))
+      activation.logs.get.mkString(" ") shouldBe empty
+    }
+  }
+
+  it should "invoke an action with a space in the name" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "hello Async"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("helloAsync.js")))
+    }
+
+    val run = wsk.action.invoke(name, Map("payload" -> testString.toJson))
+    withActivation(wsk.activation, run) { activation =>
+      activation.response.status shouldBe "success"
+      activation.response.result shouldBe Some(testResult)
+      activation.logs.get.mkString(" ") should include(testString)
+    }
+  }
+
+  it should "pass parameters bound on creation-time to the action" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "printParams"
+    val params = Map("param1" -> "test1", "param2" -> "test2")
+
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(
+        name,
+        Some(TestUtils.getTestActionFilename("printParams.js")),
+        parameters = params.mapValues(_.toJson))
+    }
+
+    val invokeParams = Map("payload" -> testString)
+    val run = wsk.action.invoke(name, invokeParams.mapValues(_.toJson))
+    withActivation(wsk.activation, run) { activation =>
+      val logs = activation.logs.get.mkString(" ")
+
+      (params ++ invokeParams).foreach {
+        case (key, value) =>
+          logs should include(s"params.$key: $value")
+      }
+    }
+  }
+
+  it should "copy an action and invoke it successfully" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "copied"
+    val packageName = "samples"
+    val actionName = "wordcount"
+    val fullQualifiedName = s"/$guestNamespace/$packageName/$actionName"
+
+    assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
+      pkg.create(packageName, shared = Some(true))
     }
 
-    it should "invoke an action with a space in the name" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "hello Async"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("helloAsync.js")))
-            }
-
-            val run = wsk.action.invoke(name, Map("payload" -> testString.toJson))
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.status shouldBe "success"
-                    activation.response.result shouldBe Some(testResult)
-                    activation.logs.get.mkString(" ") should include(testString)
-            }
+    assetHelper.withCleaner(wsk.action, fullQualifiedName) {
+      val file = Some(TestUtils.getTestActionFilename("wc.js"))
+      (action, _) =>
+        action.create(fullQualifiedName, file)
     }
 
-    it should "pass parameters bound on creation-time to the action" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "printParams"
-            val params = Map(
-                "param1" -> "test1",
-                "param2" -> "test2")
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(
-                        name,
-                        Some(TestCLIUtils.getTestActionFilename("printParams.js")),
-                        parameters = params.mapValues(_.toJson))
-            }
-
-            val invokeParams = Map("payload" -> testString)
-            val run = wsk.action.invoke(name, invokeParams.mapValues(_.toJson))
-            withActivation(wsk.activation, run) {
-                activation =>
-                    val logs = activation.logs.get.mkString(" ")
-
-                    (params ++ invokeParams).foreach {
-                        case (key, value) =>
-                            logs should include(s"params.$key: $value")
-                    }
-            }
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(fullQualifiedName), Some("copy"))
     }
 
-    it should "copy an action and invoke it successfully" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "copied"
-            val packageName = "samples"
-            val actionName = "wordcount"
-            val fullQualifiedName = s"/$guestNamespace/$packageName/$actionName"
-
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, _) => pkg.create(packageName, shared = Some(true))
-            }
-
-            assetHelper.withCleaner(wsk.action, fullQualifiedName) {
-                val file = Some(TestCLIUtils.getTestActionFilename("wc.js"))
-                (action, _) => action.create(fullQualifiedName, file)
-            }
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(fullQualifiedName), Some("copy"))
-            }
-
-            val run = wsk.action.invoke(name, Map("payload" -> testString.toJson))
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.status shouldBe "success"
-                    activation.response.result shouldBe Some(testResult)
-                    activation.logs.get.mkString(" ") should include(testString)
-            }
+    val run = wsk.action.invoke(name, Map("payload" -> testString.toJson))
+    withActivation(wsk.activation, run) { activation =>
+      activation.response.status shouldBe "success"
+      activation.response.result shouldBe Some(testResult)
+      activation.logs.get.mkString(" ") should include(testString)
+    }
+  }
+
+  it should "copy an action and ensure exec, parameters, and annotations copied" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val origActionName = "origAction"
+      val copiedActionName = "copiedAction"
+      val params = Map("a" -> "A".toJson)
+      val annots = Map("b" -> "B".toJson)
+
+      assetHelper.withCleaner(wsk.action, origActionName) {
+        val file = Some(TestUtils.getTestActionFilename("wc.js"))
+        (action, _) =>
+          action.create(origActionName, file, parameters = params, annotations = annots)
+      }
+
+      assetHelper.withCleaner(wsk.action, copiedActionName) { (action, _) =>
+        action.create(copiedActionName, Some(origActionName), Some("copy"))
+      }
+
+      val copiedAction = getJSONFromCLIResponse(wsk.action.get(copiedActionName).stdout)
+      val origAction = getJSONFromCLIResponse(wsk.action.get(copiedActionName).stdout)
+
+      copiedAction.fields("annotations") shouldBe origAction.fields("annotations")
+      copiedAction.fields("parameters") shouldBe origAction.fields("parameters")
+      copiedAction.fields("exec") shouldBe origAction.fields("exec")
+      copiedAction.fields("version") shouldBe JsString("0.0.1")
+  }
+
+  it should "add new parameters and annotations while copying an action" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val origName = "origAction"
+      val copiedName = "copiedAction"
+      val origParams = Map("origParam1" -> "origParamValue1".toJson, "origParam2" -> 999.toJson)
+      val copiedParams = Map("copiedParam1" -> "copiedParamValue1".toJson, "copiedParam2" -> 123.toJson)
+      val origAnnots = Map("origAnnot1" -> "origAnnotValue1".toJson, "origAnnot2" -> true.toJson)
+      val copiedAnnots = Map("copiedAnnot1" -> "copiedAnnotValue1".toJson, "copiedAnnot2" -> false.toJson)
+      val resParams = Seq(
+        JsObject("key" -> JsString("copiedParam1"), "value" -> JsString("copiedParamValue1")),
+        JsObject("key" -> JsString("copiedParam2"), "value" -> JsNumber(123)),
+        JsObject("key" -> JsString("origParam1"), "value" -> JsString("origParamValue1")),
+        JsObject("key" -> JsString("origParam2"), "value" -> JsNumber(999)))
+      val resAnnots = Seq(
+        JsObject("key" -> JsString("origAnnot1"), "value" -> JsString("origAnnotValue1")),
+        JsObject("key" -> JsString("copiedAnnot2"), "value" -> JsBoolean(false)),
+        JsObject("key" -> JsString("copiedAnnot1"), "value" -> JsString("copiedAnnotValue1")),
+        JsObject("key" -> JsString("origAnnot2"), "value" -> JsBoolean(true)),
+        JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6")))
+
+      assetHelper.withCleaner(wsk.action, origName) {
+        val file = Some(TestUtils.getTestActionFilename("echo.js"))
+        (action, _) =>
+          action.create(origName, file, parameters = origParams, annotations = origAnnots)
+      }
+
+      assetHelper.withCleaner(wsk.action, copiedName) { (action, _) =>
+        action.create(copiedName, Some(origName), Some("copy"), parameters = copiedParams, annotations = copiedAnnots)
+      }
+
+      val copiedAction = getJSONFromCLIResponse(wsk.action.get(copiedName).stdout)
+
+      // CLI does not guarantee order of annotations and parameters so do a diff to compare the values
+      copiedAction.fields("parameters").convertTo[Seq[JsObject]] diff resParams shouldBe List()
+      copiedAction.fields("annotations").convertTo[Seq[JsObject]] diff resAnnots shouldBe List()
+  }
+
+  it should "recreate and invoke a new action with different code" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "recreatedAction"
+    assetHelper.withCleaner(wsk.action, name, false) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("wc.js")))
     }
 
-    it should "copy an action and ensure exec, parameters, and annotations copied" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val origActionName = "origAction"
-            val copiedActionName = "copiedAction"
-            val params = Map("a" -> "A".toJson)
-            val annots = Map("b" -> "B".toJson)
-
-            assetHelper.withCleaner(wsk.action, origActionName) {
-                val file = Some(TestCLIUtils.getTestActionFilename("wc.js"))
-                (action, _) => action.create(origActionName, file, parameters = params, annotations = annots)
-            }
-
-            assetHelper.withCleaner(wsk.action, copiedActionName) {
-                (action, _) => action.create(copiedActionName, Some(origActionName), Some("copy"))
-            }
-
-            val copiedAction = getJSONFromCLIResponse(wsk.action.get(copiedActionName).stdout)
-            val origAction = getJSONFromCLIResponse(wsk.action.get(copiedActionName).stdout)
-
-            copiedAction.fields("annotations") shouldBe origAction.fields("annotations")
-            copiedAction.fields("parameters") shouldBe origAction.fields("parameters")
-            copiedAction.fields("exec") shouldBe origAction.fields("exec")
-            copiedAction.fields("version") shouldBe JsString("0.0.1")
+    val run1 = wsk.action.invoke(name, Map("payload" -> testString.toJson))
+    withActivation(wsk.activation, run1) { activation =>
+      activation.response.status shouldBe "success"
+      activation.logs.get.mkString(" ") should include(s"The message '$testString' has")
     }
 
-    it should "add new parameters and annotations while copying an action" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val origName = "origAction"
-            val copiedName = "copiedAction"
-            val origParams = Map("origParam1" -> "origParamValue1".toJson, "origParam2" -> 999.toJson)
-            val copiedParams = Map("copiedParam1" -> "copiedParamValue1".toJson, "copiedParam2" -> 123.toJson)
-            val origAnnots = Map("origAnnot1" -> "origAnnotValue1".toJson, "origAnnot2" -> true.toJson)
-            val copiedAnnots = Map("copiedAnnot1" -> "copiedAnnotValue1".toJson, "copiedAnnot2" -> false.toJson)
-            val resParams = Seq(
-                JsObject(
-                    "key" -> JsString("copiedParam1"),
-                    "value" -> JsString("copiedParamValue1")
-                ),
-                JsObject(
-                    "key" -> JsString("copiedParam2"),
-                    "value" -> JsNumber(123)
-                ),
-                JsObject(
-                    "key" -> JsString("origParam1"),
-                    "value" -> JsString("origParamValue1")
-                ),
-                JsObject(
-                    "key" -> JsString("origParam2"),
-                    "value" -> JsNumber(999)
-                )
-            )
-            val resAnnots = Seq(
-                JsObject(
-                    "key" -> JsString("origAnnot1"),
-                    "value" -> JsString("origAnnotValue1")
-                ),
-                JsObject(
-                    "key" -> JsString("copiedAnnot2"),
-                    "value" -> JsBoolean(false)
-                ),
-                JsObject(
-                    "key" -> JsString("copiedAnnot1"),
-                    "value" -> JsString("copiedAnnotValue1")
-                ),
-                JsObject(
-                    "key" -> JsString("origAnnot2"),
-                    "value" -> JsBoolean(true)
-                ),
-                JsObject(
-                    "key" -> JsString("exec"),
-                    "value" -> JsString("nodejs:6")
-                )
-            )
-
-            assetHelper.withCleaner(wsk.action, origName) {
-                val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
-                (action, _) => action.create(origName, file, parameters = origParams, annotations = origAnnots)
-            }
-
-            assetHelper.withCleaner(wsk.action, copiedName) {
-                (action, _) => action.create(copiedName, Some(origName), Some("copy"), parameters = copiedParams, annotations = copiedAnnots)
-            }
-
-            val copiedAction = getJSONFromCLIResponse(wsk.action.get(copiedName).stdout)
-
-            // CLI does not guarantee order of annotations and parameters so do a diff to compare the values
-            copiedAction.fields("parameters").convertTo[Seq[JsObject]] diff resParams shouldBe List()
-            copiedAction.fields("annotations").convertTo[Seq[JsObject]] diff resAnnots shouldBe List()
+    wsk.action.delete(name)
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("hello.js")))
     }
 
-    it should "recreate and invoke a new action with different code" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "recreatedAction"
-            assetHelper.withCleaner(wsk.action, name, false) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("wc.js")))
-            }
-
-            val run1 = wsk.action.invoke(name, Map("payload" -> testString.toJson))
-            withActivation(wsk.activation, run1) {
-                activation =>
-                    activation.response.status shouldBe "success"
-                    activation.logs.get.mkString(" ") should include(s"The message '$testString' has")
-            }
-
-            wsk.action.delete(name)
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("hello.js")))
-            }
-
-            val run2 = wsk.action.invoke(name, Map("payload" -> testString.toJson))
-            withActivation(wsk.activation, run2) {
-                activation =>
-                    activation.response.status shouldBe "success"
-                    activation.logs.get.mkString(" ") should include(s"hello, $testString")
-            }
+    val run2 = wsk.action.invoke(name, Map("payload" -> testString.toJson))
+    withActivation(wsk.activation, run2) { activation =>
+      activation.response.status shouldBe "success"
+      activation.logs.get.mkString(" ") should include(s"hello, $testString")
     }
+  }
 
-    it should "fail to invoke an action with an empty file" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "empty"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("empty.js")))
-            }
-            val run = wsk.action.invoke(name)
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.status shouldBe "action developer error"
-                    activation.response.result shouldBe Some(JsObject("error" -> "Missing main/no code to execute.".toJson))
-            }
+  it should "fail to invoke an action with an empty file" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "empty"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("empty.js")))
+    }
+    val run = wsk.action.invoke(name)
+    withActivation(wsk.activation, run) { activation =>
+      activation.response.status shouldBe "action developer error"
+      activation.response.result shouldBe Some(JsObject("error" -> "Missing main/no code to execute.".toJson))
     }
+  }
 
-    it should "create an action with an empty file" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "empty"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("empty.js")))
-            }
-            val rr = wsk.action.get(name)
-            wsk.parseJsonString(rr.stdout).getFieldPath("exec", "code") shouldBe Some(JsString(""))
+  it should "create an action with an empty file" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "empty"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("empty.js")))
     }
+    val rr = wsk.action.get(name)
+    wsk.parseJsonString(rr.stdout).getFieldPath("exec", "code") shouldBe Some(JsString(""))
+  }
 
-    it should "blocking invoke of nested blocking actions" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "nestedBlockingAction"
-            val child = "wc"
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("wcbin.js")))
-            }
-            assetHelper.withCleaner(wsk.action, child) {
-                (action, _) => action.create(child, Some(TestCLIUtils.getTestActionFilename("wc.js")))
-            }
-
-            val run = wsk.action.invoke(name, Map("payload" -> testString.toJson), blocking = true)
-            val activation = wsk.parseJsonString(run.stdout).convertTo[ActivationResult]
-
-            withClue(s"check failed for activation: $activation") {
-                val wordCount = testString.split(" ").length
-                activation.response.result.get shouldBe JsObject("binaryCount" -> s"${wordCount.toBinaryString} (base 2)".toJson)
-            }
+  it should "blocking invoke of nested blocking actions" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "nestedBlockingAction"
+    val child = "wc"
+
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("wcbin.js")))
+    }
+    assetHelper.withCleaner(wsk.action, child) { (action, _) =>
+      action.create(child, Some(TestUtils.getTestActionFilename("wc.js")))
     }
 
-    it should "blocking invoke an asynchronous action" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "helloAsync"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("helloAsync.js")))
-            }
-
-            val run = wsk.action.invoke(name, Map("payload" -> testString.toJson), blocking = true)
-            val activation = wsk.parseJsonString(run.stdout).convertTo[ActivationResult]
-
-            withClue(s"check failed for activation: $activation") {
-                activation.response.status shouldBe "success"
-                activation.response.result shouldBe Some(testResult)
-                activation.logs shouldBe Some(List())
-            }
+    val run = wsk.action.invoke(name, Map("payload" -> testString.toJson), blocking = true)
+    val activation = wsk.parseJsonString(run.stdout).convertTo[ActivationResult]
+
+    withClue(s"check failed for activation: $activation") {
+      val wordCount = testString.split(" ").length
+      activation.response.result.get shouldBe JsObject("binaryCount" -> s"${wordCount.toBinaryString} (base 2)".toJson)
+    }
+  }
+
+  it should "blocking invoke an asynchronous action" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "helloAsync"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("helloAsync.js")))
+    }
+
+    val run = wsk.action.invoke(name, Map("payload" -> testString.toJson), blocking = true)
+    val activation = wsk.parseJsonString(run.stdout).convertTo[ActivationResult]
+
+    withClue(s"check failed for activation: $activation") {
+      activation.response.status shouldBe "success"
+      activation.response.result shouldBe Some(testResult)
+      activation.logs shouldBe Some(List())
+    }
+  }
+
+  it should "reject an invoke with the wrong parameters set" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val fullQualifiedName = s"/$guestNamespace/samples/helloWorld"
+    val payload = "bob"
+    val rr = wsk.cli(
+      Seq("action", "invoke", fullQualifiedName, payload) ++ wskprops.overrides,
+      expectedExitCode = TestUtils.ERROR_EXIT)
+    rr.stderr should include("Run 'wsk --help' for usage.")
+    rr.stderr should include(s"error: Invalid argument(s): $payload")
+  }
+
+  it should "not be able to use 'ping' in an action" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "ping"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("ping.js")))
     }
 
-    it should "reject an invoke with the wrong parameters set" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val fullQualifiedName = s"/$guestNamespace/samples/helloWorld"
-            val payload = "bob"
-            val rr = wsk.cli(Seq("action", "invoke", fullQualifiedName, payload) ++ wskprops.overrides,
-                expectedExitCode = TestUtils.ERROR_EXIT)
-            rr.stderr should include("Run 'wsk --help' for usage.")
-            rr.stderr should include(s"error: Invalid argument(s): $payload")
+    val run = wsk.action.invoke(name, Map("payload" -> "google.com".toJson))
+    withActivation(wsk.activation, run) { activation =>
+      activation.response.result shouldBe Some(
+        JsObject("stderr" -> "ping: icmp open socket: Operation not permitted\n".toJson, "stdout" -> "".toJson))
     }
+  }
 
-    it should "not be able to use 'ping' in an action" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "ping"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("ping.js")))
-            }
-
-            val run = wsk.action.invoke(name, Map("payload" -> "google.com".toJson))
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.result shouldBe Some(JsObject(
-                        "stderr" -> "ping: icmp open socket: Operation not permitted\n".toJson,
-                        "stdout" -> "".toJson))
-            }
+  ignore should "support UTF-8 as input and output format" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "utf8Test"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("hello.js")))
     }
 
-    ignore should "support UTF-8 as input and output format" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "utf8Test"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("hello.js")))
-            }
-
-            val utf8 = "«ταБЬℓσö»: 1<2 & 4+1>³, now 20%€§$ off!"
-            val run = wsk.action.invoke(name, Map("payload" -> utf8.toJson))
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.status shouldBe "success"
-                    activation.logs.get.mkString(" ") should include(s"hello $utf8")
-            }
+    val utf8 = "«ταБЬℓσö»: 1<2 & 4+1>³, now 20%€§$ off!"
+    val run = wsk.action.invoke(name, Map("payload" -> utf8.toJson))
+    withActivation(wsk.activation, run) { activation =>
+      activation.response.status shouldBe "success"
+      activation.logs.get.mkString(" ") should include(s"hello $utf8")
     }
+  }
 }
diff --git a/tests/src/test/scala/system/basic/WskBasicTests.scala b/tests/src/test/scala/system/basic/WskBasicTests.scala
index d83cf6f..4ee00cb 100644
--- a/tests/src/test/scala/system/basic/WskBasicTests.scala
+++ b/tests/src/test/scala/system/basic/WskBasicTests.scala
@@ -37,823 +37,831 @@ import spray.json.DefaultJsonProtocol._
 import spray.json.pimpAny
 
 @RunWith(classOf[JUnitRunner])
-class WskBasicTests
-    extends TestHelpers
-    with WskTestHelpers {
-
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-    val defaultAction = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-
-    behavior of "Wsk CLI"
-
-    it should "reject creating duplicate entity" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "testDuplicateCreate"
-            assetHelper.withCleaner(wsk.trigger, name) {
-                (trigger, _) => trigger.create(name)
-            }
-            assetHelper.withCleaner(wsk.action, name, confirmDelete = false) {
-                (action, _) => action.create(name, defaultAction, expectedExitCode = CONFLICT)
-            }
+class WskBasicTests extends TestHelpers with WskTestHelpers {
+
+  implicit val wskprops = WskProps()
+  val wsk = new Wsk
+  val defaultAction = Some(TestUtils.getTestActionFilename("hello.js"))
+
+  behavior of "Wsk CLI"
+
+  it should "reject creating duplicate entity" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "testDuplicateCreate"
+    assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+      trigger.create(name)
+    }
+    assetHelper.withCleaner(wsk.action, name, confirmDelete = false) { (action, _) =>
+      action.create(name, defaultAction, expectedExitCode = CONFLICT)
+    }
+  }
+
+  it should "reject deleting entity in wrong collection" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "testCrossDelete"
+    assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+      trigger.create(name)
+    }
+    wsk.action.delete(name, expectedExitCode = CONFLICT)
+  }
+
+  it should "reject unauthenticated access" in {
+    implicit val wskprops = WskProps("xxx") // shadow properties
+    val errormsg = "The supplied authentication is invalid"
+    wsk.namespace.list(expectedExitCode = UNAUTHORIZED).stderr should include(errormsg)
+    wsk.namespace.get(expectedExitCode = UNAUTHORIZED).stderr should include(errormsg)
+  }
+
+  behavior of "Wsk Package CLI"
+
+  it should "create, update, get and list a package" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "testPackage"
+    val params = Map("a" -> "A".toJson)
+    assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+      pkg.create(name, parameters = params, shared = Some(true))
+      pkg.create(name, update = true)
+    }
+    val stdout = wsk.pkg.get(name).stdout
+    stdout should include regex (""""key": "a"""")
+    stdout should include regex (""""value": "A"""")
+    stdout should include regex (""""publish": true""")
+    stdout should include regex (""""version": "0.0.2"""")
+    wsk.pkg.list().stdout should include(name)
+  }
+
+  it should "create, and get a package summary" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val packageName = "packageName"
+    val actionName = "actionName"
+    val packageAnnots = Map(
+      "description" -> JsString("Package description"),
+      "parameters" -> JsArray(
+        JsObject("name" -> JsString("paramName1"), "description" -> JsString("Parameter description 1")),
+        JsObject("name" -> JsString("paramName2"), "description" -> JsString("Parameter description 2"))))
+    val actionAnnots = Map(
+      "description" -> JsString("Action description"),
+      "parameters" -> JsArray(
+        JsObject("name" -> JsString("paramName1"), "description" -> JsString("Parameter description 1")),
+        JsObject("name" -> JsString("paramName2"), "description" -> JsString("Parameter description 2"))))
+
+    assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
+      pkg.create(packageName, annotations = packageAnnots)
+    }
+
+    wsk.action.create(packageName + "/" + actionName, defaultAction, annotations = actionAnnots)
+    val stdout = wsk.pkg.get(packageName, summary = true).stdout
+    val ns = wsk.namespace.whois()
+    wsk.action.delete(packageName + "/" + actionName)
+
+    stdout should include regex (s"(?i)package /$ns/$packageName: Package description\\s*\\(parameters: paramName1, paramName2\\)")
+    stdout should include regex (s"(?i)action /$ns/$packageName/$actionName: Action description\\s*\\(parameters: paramName1, paramName2\\)")
+  }
+
+  it should "create a package with a name that contains spaces" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "package with spaces"
+
+    val res = assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+      pkg.create(name)
+    }
+
+    res.stdout should include(s"ok: created package $name")
+  }
+
+  it should "create a package, and get its individual fields" in withAssetCleaner(wskprops) {
+    val name = "packageFields"
+    val paramInput = Map("payload" -> "test".toJson)
+    val successMsg = s"ok: got package $name, displaying field"
+
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+        pkg.create(name, parameters = paramInput)
+      }
+
+      val expectedParam = JsObject("payload" -> JsString("test"))
+      val ns = wsk.namespace.whois()
+
+      wsk.pkg
+        .get(name, fieldFilter = Some("namespace"))
+        .stdout should include regex (s"""(?i)$successMsg namespace\n"$ns"""")
+      wsk.pkg.get(name, fieldFilter = Some("name")).stdout should include(s"""$successMsg name\n"$name"""")
+      wsk.pkg.get(name, fieldFilter = Some("version")).stdout should include(s"""$successMsg version\n"0.0.1"""")
+      wsk.pkg.get(name, fieldFilter = Some("publish")).stdout should include(s"""$successMsg publish\nfalse""")
+      wsk.pkg.get(name, fieldFilter = Some("binding")).stdout should include regex (s"""\\{\\}""")
+      wsk.pkg.get(name, fieldFilter = Some("invalid"), expectedExitCode = ERROR_EXIT).stderr should include(
+        "error: Invalid field filter 'invalid'.")
+  }
+
+  it should "reject creation of duplication packages" in withAssetCleaner(wskprops) {
+    val name = "dupePackage"
+
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+        pkg.create(name)
+      }
+
+      val stderr = wsk.pkg.create(name, expectedExitCode = CONFLICT).stderr
+      stderr should include regex (s"""Unable to create package '$name': resource already exists \\(code \\d+\\)""")
+  }
+
+  it should "reject delete of package that does not exist" in {
+    val name = "nonexistentPackage"
+    val stderr = wsk.pkg.delete(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to delete package '$name'. The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "reject get of package that does not exist" in {
+    val name = "nonexistentPackage"
+    val stderr = wsk.pkg.get(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to get package '$name': The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  behavior of "Wsk Action CLI"
+
+  it should "create the same action twice with different cases" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    assetHelper.withCleaner(wsk.action, "TWICE") { (action, name) =>
+      action.create(name, defaultAction)
+    }
+    assetHelper.withCleaner(wsk.action, "twice") { (action, name) =>
+      action.create(name, defaultAction)
+    }
+  }
+
+  it should "create, update, get and list an action" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "createAndUpdate"
+    val file = Some(TestUtils.getTestActionFilename("hello.js"))
+    val params = Map("a" -> "A".toJson)
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file, parameters = params)
+      action.create(name, None, parameters = Map("b" -> "B".toJson), update = true)
+    }
+
+    val stdout = wsk.action.get(name).stdout
+    stdout should not include regex(""""key": "a"""")
+    stdout should not include regex(""""value": "A"""")
+    stdout should include regex (""""key": "b""")
+    stdout should include regex (""""value": "B"""")
+    stdout should include regex (""""publish": false""")
+    stdout should include regex (""""version": "0.0.2"""")
+    wsk.action.list().stdout should include(name)
+  }
+
+  it should "reject create of an action that already exists" in withAssetCleaner(wskprops) {
+    val name = "dupeAction"
+    val file = Some(TestUtils.getTestActionFilename("echo.js"))
+
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, file)
+      }
+
+      val stderr = wsk.action.create(name, file, expectedExitCode = CONFLICT).stderr
+      stderr should include regex (s"""Unable to create action '$name': resource already exists \\(code \\d+\\)""")
+  }
+
+  it should "reject delete of action that does not exist" in {
+    val name = "nonexistentAction"
+    val stderr = wsk.action.delete(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to delete action '$name'. The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "reject invocation of action that does not exist" in {
+    val name = "nonexistentAction"
+    val stderr = wsk.action.invoke(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to invoke action '$name': The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "reject get of an action that does not exist" in {
+    val name = "nonexistentAction"
+    val stderr = wsk.action.get(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to get action '$name': The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "create, and invoke an action that utilizes a docker container" in withAssetCleaner(wskprops) {
+    val name = "dockerContainer"
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.action, name) {
+        // this docker image will be need to be pulled from dockerhub and hence has to be published there first
+        (action, _) =>
+          action.create(name, None, docker = Some("openwhisk/example"))
+      }
+
+      val args = Map("payload" -> "test".toJson)
+      val run = wsk.action.invoke(name, args)
+      withActivation(wsk.activation, run) { activation =>
+        activation.response.result shouldBe Some(
+          JsObject("args" -> args.toJson, "msg" -> "Hello from arbitrary C program!".toJson))
+      }
+  }
+
+  it should "create, and invoke an action that utilizes dockerskeleton with native zip" in withAssetCleaner(wskprops) {
+    val name = "dockerContainerWithZip"
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.action, name) {
+        // this docker image will be need to be pulled from dockerhub and hence has to be published there first
+        (action, _) =>
+          action.create(name, Some(TestUtils.getTestActionFilename("blackbox.zip")), kind = Some("native"))
+      }
+
+      val run = wsk.action.invoke(name, Map())
+      withActivation(wsk.activation, run) { activation =>
+        activation.response.result shouldBe Some(JsObject("msg" -> "hello zip".toJson))
+        activation.logs shouldBe defined
+        val logs = activation.logs.get.toString
+        logs should include("This is an example zip used with the docker skeleton action.")
+        logs should not include ("XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX")
+      }
+  }
+
+  it should "create, and invoke an action using a parameter file" in withAssetCleaner(wskprops) {
+    val name = "paramFileAction"
+    val file = Some(TestUtils.getTestActionFilename("argCheck.js"))
+    val argInput = Some(TestUtils.getTestActionFilename("validInput2.json"))
+
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, file)
+      }
+
+      val expectedOutput = JsObject("payload" -> JsString("test"))
+      val run = wsk.action.invoke(name, parameterFile = argInput)
+      withActivation(wsk.activation, run) { activation =>
+        activation.response.result shouldBe Some(expectedOutput)
+      }
+  }
+
+  it should "create an action, and get its individual fields" in withAssetCleaner(wskprops) {
+    val name = "actionFields"
+    val paramInput = Map("payload" -> "test".toJson)
+    val successMsg = s"ok: got action $name, displaying field"
+
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, defaultAction, parameters = paramInput)
+      }
+
+      val expectedParam = JsObject("payload" -> JsString("test"))
+      val ns = wsk.namespace.whois()
+
+      wsk.action.get(name, fieldFilter = Some("name")).stdout should include(s"""$successMsg name\n"$name"""")
+      wsk.action.get(name, fieldFilter = Some("version")).stdout should include(s"""$successMsg version\n"0.0.1"""")
+      wsk.action.get(name, fieldFilter = Some("exec")).stdout should include(s"""$successMsg""")
+      wsk.action
+        .get(name, fieldFilter = Some("exec"))
+        .stdout should include regex (s"""$successMsg exec\n\\{\\s+"kind":\\s+"nodejs:6",\\s+"code":\\s+"\\/\\*\\*[\\\\r]*\\\\n \\* Hello, world.[\\\\r]*\\\\n \\*\\/[\\\\r]*\\\\nfunction main\\(params\\) \\{[\\\\r]*\\\\n    greeting \\= 'hello, ' \\+ params.payload \\+ '!'[\\\\r]*\\\\n    console.log\\(greeting\\);[\\\\r]*\\\\n    return \\{payload: greeting\\}[\\\\r]*\\\\n\\}""")
+      wsk.action
+        .get(name, fieldFilter = Some("parameters"))
+        .stdout should include regex (s"""$successMsg parameters\n\\[\\s+\\{\\s+"key":\\s+"payload",\\s+"value":\\s+"test"\\s+\\}\\s+\\]""")
+      wsk.action
+        .get(name, fieldFilter = Some("annotations"))
+        .stdout should include regex (s"""$successMsg annotations\n\\[\\s+\\{\\s+"key":\\s+"exec",\\s+"value":\\s+"nodejs:6"\\s+\\}\\s+\\]""")
+      wsk.action
+        .get(name, fieldFilter = Some("limits"))
+        .stdout should include regex (s"""$successMsg limits\n\\{\\s+"timeout":\\s+60000,\\s+"memory":\\s+256,\\s+"logs":\\s+10\\s+\\}""")
+      wsk.action
+        .get(name, fieldFilter = Some("namespace"))
+        .stdout should include regex (s"""(?i)$successMsg namespace\n"$ns"""")
+      wsk.action.get(name, fieldFilter = Some("invalid"), expectedExitCode = MISUSE_EXIT).stderr should include(
+        "error: Invalid field filter 'invalid'.")
+      wsk.action.get(name, fieldFilter = Some("publish")).stdout should include(s"""$successMsg publish\nfalse""")
+  }
+
+  /**
+   * Tests creating an action from a malformed js file. This should fail in
+   * some way - preferably when trying to create the action. If not, then
+   * surely when it runs there should be some indication in the logs. Don't
+   * think this is true currently.
+   */
+  it should "create and invoke action with malformed js resulting in activation error" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "MALFORMED"
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, Some(TestUtils.getTestActionFilename("malformed.js")))
+      }
+
+      val run = wsk.action.invoke(name, Map("payload" -> "whatever".toJson))
+      withActivation(wsk.activation, run) { activation =>
+        activation.response.status shouldBe "action developer error"
+        // representing nodejs giving an error when given malformed.js
+        activation.response.result.get.toString should include("ReferenceError")
+      }
+  }
+
+  it should "create and invoke a blocking action resulting in an application error response" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "applicationError"
+    val strErrInput = Map("error" -> "Error message".toJson)
+    val numErrInput = Map("error" -> 502.toJson)
+    val boolErrInput = Map("error" -> true.toJson)
+
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("echo.js")))
+    }
+
+    Seq(strErrInput, numErrInput, boolErrInput) foreach { input =>
+      getJSONFromCLIResponse(
+        wsk.action.invoke(name, parameters = input, blocking = true, expectedExitCode = 246).stderr)
+        .fields("response")
+        .asJsObject
+        .fields("result")
+        .asJsObject shouldBe input.toJson.asJsObject
+
+      wsk.action
+        .invoke(name, parameters = input, blocking = true, result = true, expectedExitCode = 246)
+        .stderr
+        .parseJson
+        .asJsObject shouldBe input.toJson.asJsObject
+    }
+  }
+
+  it should "create and invoke a blocking action resulting in an failed promise" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "errorResponseObject"
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, Some(TestUtils.getTestActionFilename("asyncError.js")))
+      }
+
+      val stderr = wsk.action.invoke(name, blocking = true, expectedExitCode = 246).stderr
+      ActivationResult.serdes.read(removeCLIHeader(stderr).parseJson).response.result shouldBe Some {
+        JsObject("error" -> JsObject("msg" -> "failed activation on purpose".toJson))
+      }
+  }
+
+  it should "invoke a blocking action and get only the result" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "basicInvoke"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("wc.js")))
+    }
+
+    wsk.action
+      .invoke(name, Map("payload" -> "one two three".toJson), result = true)
+      .stdout should include regex (""""count": 3""")
+  }
+
+  it should "create, and get an action summary" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "actionName"
+    val annots = Map(
+      "description" -> JsString("Action description"),
+      "parameters" -> JsArray(
+        JsObject("name" -> JsString("paramName1"), "description" -> JsString("Parameter description 1")),
+        JsObject("name" -> JsString("paramName2"), "description" -> JsString("Parameter description 2"))))
+
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, defaultAction, annotations = annots)
+    }
+
+    val stdout = wsk.action.get(name, summary = true).stdout
+    val ns = wsk.namespace.whois()
+
+    stdout should include regex (s"(?i)action /$ns/$name: Action description\\s*\\(parameters: paramName1, paramName2\\)")
+  }
+
+  it should "create an action with a name that contains spaces" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "action with spaces"
+
+    val res = assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, defaultAction)
+    }
+
+    res.stdout should include(s"ok: created action $name")
+  }
+
+  it should "create an action, and invoke an action that returns an empty JSON object" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "emptyJSONAction"
+
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, Some(TestUtils.getTestActionFilename("emptyJSONResult.js")))
+      }
+
+      val stdout = wsk.action.invoke(name, result = true).stdout
+      stdout.parseJson.asJsObject shouldBe JsObject()
+  }
+
+  it should "create, and invoke an action that times out to ensure the proper response is received" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "sleepAction"
+    val params = Map("payload" -> "100000".toJson)
+    val allowedActionDuration = 120 seconds
+    val res = assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("timeout.js")), timeout = Some(allowedActionDuration))
+      action.invoke(name, parameters = params, result = true, expectedExitCode = ACCEPTED)
     }
 
-    it should "reject deleting entity in wrong collection" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "testCrossDelete"
-            assetHelper.withCleaner(wsk.trigger, name) {
-                (trigger, _) => trigger.create(name)
-            }
-            wsk.action.delete(name, expectedExitCode = CONFLICT)
+    res.stderr should include("""but the request has not yet finished""")
+  }
+
+  it should "create, and get docker action get ensure exec code is omitted" in withAssetCleaner(wskprops) {
+    val name = "dockerContainer"
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, None, docker = Some("fake-container"))
+      }
+
+      wsk.action.get(name).stdout should not include (""""code"""")
+  }
+
+  behavior of "Wsk Trigger CLI"
+
+  it should "create, update, get, fire and list trigger" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "listTriggers"
+    val params = Map("a" -> "A".toJson)
+    assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+      trigger.create(name, parameters = params)
+      trigger.create(name, update = true)
+    }
+    val stdout = wsk.trigger.get(name).stdout
+    stdout should include regex (""""key": "a"""")
+    stdout should include regex (""""value": "A"""")
+    stdout should include regex (""""publish": false""")
+    stdout should include regex (""""version": "0.0.2"""")
+
+    val dynamicParams = Map("t" -> "T".toJson)
+    val run = wsk.trigger.fire(name, dynamicParams)
+    withActivation(wsk.activation, run) { activation =>
+      activation.response.result shouldBe Some(dynamicParams.toJson)
+      activation.duration shouldBe 0L // shouldn't exist but CLI generates it
+      activation.end shouldBe Instant.EPOCH // shouldn't exist but CLI generates it
     }
 
-    it should "reject unauthenticated access" in {
-        implicit val wskprops = WskProps("xxx") // shadow properties
-        val errormsg = "The supplied authentication is invalid"
-        wsk.namespace.list(expectedExitCode = UNAUTHORIZED).
-            stderr should include(errormsg)
-        wsk.namespace.get(expectedExitCode = UNAUTHORIZED).
-            stderr should include(errormsg)
+    val runWithNoParams = wsk.trigger.fire(name, Map())
+    withActivation(wsk.activation, runWithNoParams) { activation =>
+      activation.response.result shouldBe Some(JsObject())
+      activation.duration shouldBe 0L // shouldn't exist but CLI generates it
+      activation.end shouldBe Instant.EPOCH // shouldn't exist but CLI generates it
     }
 
-    behavior of "Wsk Package CLI"
-
-    it should "create, update, get and list a package" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "testPackage"
-            val params = Map("a" -> "A".toJson)
-            assetHelper.withCleaner(wsk.pkg, name) {
-                (pkg, _) =>
-                    pkg.create(name, parameters = params, shared = Some(true))
-                    pkg.create(name, update = true)
-            }
-            val stdout = wsk.pkg.get(name).stdout
-            stdout should include regex (""""key": "a"""")
-            stdout should include regex (""""value": "A"""")
-            stdout should include regex (""""publish": true""")
-            stdout should include regex (""""version": "0.0.2"""")
-            wsk.pkg.list().stdout should include(name)
+    wsk.trigger.list().stdout should include(name)
+  }
+
+  it should "create, and get a trigger summary" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "triggerName"
+    val annots = Map(
+      "description" -> JsString("Trigger description"),
+      "parameters" -> JsArray(
+        JsObject("name" -> JsString("paramName1"), "description" -> JsString("Parameter description 1")),
+        JsObject("name" -> JsString("paramName2"), "description" -> JsString("Parameter description 2"))))
+
+    assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+      trigger.create(name, annotations = annots)
     }
 
-    it should "create, and get a package summary" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val packageName = "packageName"
-            val actionName = "actionName"
-            val packageAnnots = Map(
-                "description" -> JsString("Package description"),
-                "parameters" -> JsArray(
-                    JsObject(
-                        "name" -> JsString("paramName1"),
-                        "description" -> JsString("Parameter description 1")),
-                    JsObject(
-                        "name" -> JsString("paramName2"),
-                        "description" -> JsString("Parameter description 2"))))
-            val actionAnnots = Map(
-                "description" -> JsString("Action description"),
-                "parameters" -> JsArray(
-                    JsObject(
-                        "name" -> JsString("paramName1"),
-                        "description" -> JsString("Parameter description 1")),
-                    JsObject(
-                        "name" -> JsString("paramName2"),
-                        "description" -> JsString("Parameter description 2"))))
-
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, _) => pkg.create(packageName, annotations = packageAnnots)
-            }
-
-            wsk.action.create(packageName + "/" + actionName, defaultAction, annotations = actionAnnots)
-            val stdout = wsk.pkg.get(packageName, summary = true).stdout
-            val ns = wsk.namespace.whois()
-            wsk.action.delete(packageName + "/" + actionName)
-
-            stdout should include regex (s"(?i)package /$ns/$packageName: Package description\\s*\\(parameters: paramName1, paramName2\\)")
-            stdout should include regex (s"(?i)action /$ns/$packageName/$actionName: Action description\\s*\\(parameters: paramName1, paramName2\\)")
-    }
-
-    it should "create a package with a name that contains spaces" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "package with spaces"
-
-            val res = assetHelper.withCleaner(wsk.pkg, name) {
-                (pkg, _) => pkg.create(name)
-            }
-
-            res.stdout should include(s"ok: created package $name")
-    }
-
-    it should "create a package, and get its individual fields" in withAssetCleaner(wskprops) {
-        val name = "packageFields"
-        val paramInput = Map("payload" -> "test".toJson)
-        val successMsg = s"ok: got package $name, displaying field"
-
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.pkg, name) {
-                (pkg, _) => pkg.create(name, parameters = paramInput)
-            }
-
-            val expectedParam = JsObject("payload" -> JsString("test"))
-            val ns = wsk.namespace.whois()
-
-            wsk.pkg.get(name, fieldFilter = Some("namespace")).stdout should include regex (s"""(?i)$successMsg namespace\n"$ns"""")
-            wsk.pkg.get(name, fieldFilter = Some("name")).stdout should include(s"""$successMsg name\n"$name"""")
-            wsk.pkg.get(name, fieldFilter = Some("version")).stdout should include(s"""$successMsg version\n"0.0.1"""")
-            wsk.pkg.get(name, fieldFilter = Some("publish")).stdout should include(s"""$successMsg publish\nfalse""")
-            wsk.pkg.get(name, fieldFilter = Some("binding")).stdout should include regex (s"""\\{\\}""")
-            wsk.pkg.get(name, fieldFilter = Some("invalid"), expectedExitCode = ERROR_EXIT).stderr should include("error: Invalid field filter 'invalid'.")
-    }
-
-    it should "reject creation of duplication packages" in withAssetCleaner(wskprops) {
-        val name = "dupePackage"
-
-        (wp, assetHelper) => assetHelper.withCleaner(wsk.pkg, name) {
-            (pkg, _) => pkg.create(name)
-        }
-
-        val stderr = wsk.pkg.create(name, expectedExitCode = CONFLICT).stderr
-        stderr should include regex (s"""Unable to create package '$name': resource already exists \\(code \\d+\\)""")
-    }
-
-    it should "reject delete of package that does not exist" in {
-        val name = "nonexistentPackage"
-        val stderr = wsk.pkg.delete(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to delete package '$name'. The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "reject get of package that does not exist" in {
-        val name = "nonexistentPackage"
-        val stderr = wsk.pkg.get(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to get package '$name': The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    behavior of "Wsk Action CLI"
-
-    it should "create the same action twice with different cases" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.action, "TWICE") { (action, name) => action.create(name, defaultAction) }
-            assetHelper.withCleaner(wsk.action, "twice") { (action, name) => action.create(name, defaultAction) }
-    }
-
-    it should "create, update, get and list an action" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "createAndUpdate"
-            val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-            val params = Map("a" -> "A".toJson)
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, parameters = params)
-                    action.create(name, None, parameters = Map("b" -> "B".toJson), update = true)
-            }
-
-            val stdout = wsk.action.get(name).stdout
-            stdout should not include regex(""""key": "a"""")
-            stdout should not include regex(""""value": "A"""")
-            stdout should include regex (""""key": "b""")
-            stdout should include regex (""""value": "B"""")
-            stdout should include regex (""""publish": false""")
-            stdout should include regex (""""version": "0.0.2"""")
-            wsk.action.list().stdout should include(name)
-    }
-
-    it should "reject create of an action that already exists" in withAssetCleaner(wskprops) {
-        val name = "dupeAction"
-        val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
-
-        (wp, assetHelper) => assetHelper.withCleaner(wsk.action, name) {
-            (action, _) => action.create(name, file)
-        }
-
-        val stderr = wsk.action.create(name, file, expectedExitCode = CONFLICT).stderr
-        stderr should include regex (s"""Unable to create action '$name': resource already exists \\(code \\d+\\)""")
-    }
-
-    it should "reject delete of action that does not exist" in {
-        val name = "nonexistentAction"
-        val stderr = wsk.action.delete(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to delete action '$name'. The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "reject invocation of action that does not exist" in {
-        val name = "nonexistentAction"
-        val stderr = wsk.action.invoke(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to invoke action '$name': The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "reject get of an action that does not exist" in {
-        val name = "nonexistentAction"
-        val stderr = wsk.action.get(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to get action '$name': The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "create, and invoke an action that utilizes a docker container" in withAssetCleaner(wskprops) {
-        val name = "dockerContainer"
-        (wp, assetHelper) => assetHelper.withCleaner(wsk.action, name) {
-            // this docker image will be need to be pulled from dockerhub and hence has to be published there first
-            (action, _) => action.create(name, None, docker = Some("openwhisk/example"))
-        }
-
-        val args = Map("payload" -> "test".toJson)
-        val run = wsk.action.invoke(name, args)
-        withActivation(wsk.activation, run) {
-            activation =>
-                activation.response.result shouldBe Some(JsObject(
-                    "args" -> args.toJson,
-                    "msg" -> "Hello from arbitrary C program!".toJson))
-        }
-    }
-
-    it should "create, and invoke an action that utilizes dockerskeleton with native zip" in withAssetCleaner(wskprops) {
-        val name = "dockerContainerWithZip"
-        (wp, assetHelper) => assetHelper.withCleaner(wsk.action, name) {
-            // this docker image will be need to be pulled from dockerhub and hence has to be published there first
-            (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("blackbox.zip")), kind = Some("native"))
-        }
-
-        val run = wsk.action.invoke(name, Map())
-        withActivation(wsk.activation, run) {
-            activation =>
-                activation.response.result shouldBe Some(JsObject(
-                    "msg" -> "hello zip".toJson))
-                activation.logs shouldBe defined
-                val logs = activation.logs.get.toString
-                logs should include("This is an example zip used with the docker skeleton action.")
-                logs should not include ("XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX")
-        }
-    }
-
-    it should "create, and invoke an action using a parameter file" in withAssetCleaner(wskprops) {
-        val name = "paramFileAction"
-        val file = Some(TestCLIUtils.getTestActionFilename("argCheck.js"))
-        val argInput = Some(TestCLIUtils.getTestActionFilename("validInput2.json"))
-
-        (wp, assetHelper) => assetHelper.withCleaner(wsk.action, name) {
-            (action, _) => action.create(name, file)
-        }
-
-        val expectedOutput = JsObject("payload" -> JsString("test"))
-        val run = wsk.action.invoke(name, parameterFile = argInput)
-        withActivation(wsk.activation, run) {
-            activation => activation.response.result shouldBe Some(expectedOutput)
-        }
-    }
-
-    it should "create an action, and get its individual fields" in withAssetCleaner(wskprops) {
-        val name = "actionFields"
-        val paramInput = Map("payload" -> "test".toJson)
-        val successMsg = s"ok: got action $name, displaying field"
-
-        (wp, assetHelper) => assetHelper.withCleaner(wsk.action, name) {
-            (action, _) => action.create(name, defaultAction, parameters = paramInput)
-        }
-
-        val expectedParam = JsObject("payload" -> JsString("test"))
-        val ns = wsk.namespace.whois()
-
-        wsk.action.get(name, fieldFilter = Some("name")).stdout should include(s"""$successMsg name\n"$name"""")
-        wsk.action.get(name, fieldFilter = Some("version")).stdout should include(s"""$successMsg version\n"0.0.1"""")
-        wsk.action.get(name, fieldFilter = Some("exec")).stdout should include(s"""$successMsg""")
-        wsk.action.get(name, fieldFilter = Some("exec")).stdout should include regex (s"""$successMsg exec\n\\{\\s+"kind":\\s+"nodejs:6",\\s+"code":\\s+"\\/\\*\\*[\\\\r]*\\\\n \\* Hello, world.[\\\\r]*\\\\n \\*\\/[\\\\r]*\\\\nfunction main\\(params\\) \\{[\\\\r]*\\\\n    greeting \\= 'hello, ' \\+ params.payload \\+ '!'[\\\\r]*\\\\n    console.log\\(greeting\\);[\\\\r]*\\\\n    return \\{payload: greeting\\}[\\\\r]*\\\\n\\}""")
-        wsk.action.get(name, fieldFilter = Some("parameters")).stdout should include regex (s"""$successMsg parameters\n\\[\\s+\\{\\s+"key":\\s+"payload",\\s+"value":\\s+"test"\\s+\\}\\s+\\]""")
-        wsk.action.get(name, fieldFilter = Some("annotations")).stdout should include regex (s"""$successMsg annotations\n\\[\\s+\\{\\s+"key":\\s+"exec",\\s+"value":\\s+"nodejs:6"\\s+\\}\\s+\\]""")
-        wsk.action.get(name, fieldFilter = Some("limits")).stdout should include regex (s"""$successMsg limits\n\\{\\s+"timeout":\\s+60000,\\s+"memory":\\s+256,\\s+"logs":\\s+10\\s+\\}""")
-        wsk.action.get(name, fieldFilter = Some("namespace")).stdout should include regex (s"""(?i)$successMsg namespace\n"$ns"""")
-        wsk.action.get(name, fieldFilter = Some("invalid"), expectedExitCode = MISUSE_EXIT).stderr should include("error: Invalid field filter 'invalid'.")
-        wsk.action.get(name, fieldFilter = Some("publish")).stdout should include(s"""$successMsg publish\nfalse""")
-    }
-
-    /**
-     * Tests creating an action from a malformed js file. This should fail in
-     * some way - preferably when trying to create the action. If not, then
-     * surely when it runs there should be some indication in the logs. Don't
-     * think this is true currently.
-     */
-    it should "create and invoke action with malformed js resulting in activation error" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "MALFORMED"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("malformed.js")))
-            }
-
-            val run = wsk.action.invoke(name, Map("payload" -> "whatever".toJson))
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.status shouldBe "action developer error"
-                    // representing nodejs giving an error when given malformed.js
-                    activation.response.result.get.toString should include("ReferenceError")
-            }
-    }
-
-    it should "create and invoke a blocking action resulting in an application error response" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "applicationError"
-            val strErrInput = Map("error" -> "Error message".toJson)
-            val numErrInput = Map("error" -> 502.toJson)
-            val boolErrInput = Map("error" -> true.toJson)
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("echo.js")))
-            }
-
-            Seq(strErrInput, numErrInput, boolErrInput) foreach { input =>
-                getJSONFromCLIResponse(wsk.action.invoke(name, parameters = input, blocking = true, expectedExitCode = 246).stderr).
-                    fields("response").asJsObject.fields("result").asJsObject shouldBe input.toJson.asJsObject
-
-                wsk.action.invoke(name, parameters = input, blocking = true, result = true, expectedExitCode = 246).
-                    stderr.parseJson.asJsObject shouldBe input.toJson.asJsObject
-            }
-    }
-
-    it should "create and invoke a blocking action resulting in an failed promise" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "errorResponseObject"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("asyncError.js")))
-            }
-
-            val stderr = wsk.action.invoke(name, blocking = true, expectedExitCode = 246).stderr
-            ActivationResult.serdes.read(removeCLIHeader(stderr).parseJson).response.result shouldBe Some {
-                JsObject("error" -> JsObject("msg" -> "failed activation on purpose".toJson))
-            }
-    }
-
-    it should "invoke a blocking action and get only the result" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "basicInvoke"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("wc.js")))
-            }
-
-            wsk.action.invoke(name, Map("payload" -> "one two three".toJson), result = true)
-                .stdout should include regex (""""count": 3""")
-    }
-
-    it should "create, and get an action summary" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "actionName"
-            val annots = Map(
-                "description" -> JsString("Action description"),
-                "parameters" -> JsArray(
-                    JsObject(
-                        "name" -> JsString("paramName1"),
-                        "description" -> JsString("Parameter description 1")),
-                    JsObject(
-                        "name" -> JsString("paramName2"),
-                        "description" -> JsString("Parameter description 2"))))
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, defaultAction, annotations = annots)
-            }
-
-            val stdout = wsk.action.get(name, summary = true).stdout
-            val ns = wsk.namespace.whois()
-
-            stdout should include regex (s"(?i)action /$ns/$name: Action description\\s*\\(parameters: paramName1, paramName2\\)")
-    }
-
-    it should "create an action with a name that contains spaces" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "action with spaces"
-
-            val res = assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, defaultAction)
-            }
-
-            res.stdout should include(s"ok: created action $name")
-    }
-
-    it should "create an action, and invoke an action that returns an empty JSON object" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "emptyJSONAction"
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, Some(TestCLIUtils.getTestActionFilename("emptyJSONResult.js")))
-            }
-
-            val stdout = wsk.action.invoke(name, result = true).stdout
-            stdout.parseJson.asJsObject shouldBe JsObject()
-    }
-
-    it should "create, and invoke an action that times out to ensure the proper response is received" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "sleepAction"
-            val params = Map("payload" -> "100000".toJson)
-            val allowedActionDuration = 120 seconds
-            val res = assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, Some(TestCLIUtils.getTestActionFilename("timeout.js")),
-                        timeout = Some(allowedActionDuration))
-                    action.invoke(name, parameters = params, result = true, expectedExitCode = ACCEPTED)
-            }
-
-            res.stderr should include("""but the request has not yet finished""")
-    }
-
-    it should "create, and get docker action get ensure exec code is omitted" in withAssetCleaner(wskprops) {
-        val name = "dockerContainer"
-        (wp, assetHelper) => assetHelper.withCleaner(wsk.action, name) {
-            (action, _) => action.create(name, None, docker = Some("fake-container"))
-        }
+    val stdout = wsk.trigger.get(name, summary = true).stdout
+    val ns = wsk.namespace.whois()
 
-        wsk.action.get(name).stdout should not include (""""code"""")
-    }
-
-    behavior of "Wsk Trigger CLI"
-
-    it should "create, update, get, fire and list trigger" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "listTriggers"
-            val params = Map("a" -> "A".toJson)
-            assetHelper.withCleaner(wsk.trigger, name) {
-                (trigger, _) =>
-                    trigger.create(name, parameters = params)
-                    trigger.create(name, update = true)
-            }
-            val stdout = wsk.trigger.get(name).stdout
-            stdout should include regex (""""key": "a"""")
-            stdout should include regex (""""value": "A"""")
-            stdout should include regex (""""publish": false""")
-            stdout should include regex (""""version": "0.0.2"""")
-
-            val dynamicParams = Map("t" -> "T".toJson)
-            val run = wsk.trigger.fire(name, dynamicParams)
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.result shouldBe Some(dynamicParams.toJson)
-                    activation.duration shouldBe 0L // shouldn't exist but CLI generates it
-                    activation.end shouldBe Instant.EPOCH // shouldn't exist but CLI generates it
-            }
-
-            val runWithNoParams = wsk.trigger.fire(name, Map())
-            withActivation(wsk.activation, runWithNoParams) {
-                activation =>
-                    activation.response.result shouldBe Some(JsObject())
-                    activation.duration shouldBe 0L // shouldn't exist but CLI generates it
-                    activation.end shouldBe Instant.EPOCH // shouldn't exist but CLI generates it
-            }
-
-            wsk.trigger.list().stdout should include(name)
-    }
-
-    it should "create, and get a trigger summary" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "triggerName"
-            val annots = Map(
-                "description" -> JsString("Trigger description"),
-                "parameters" -> JsArray(
-                    JsObject(
-                        "name" -> JsString("paramName1"),
-                        "description" -> JsString("Parameter description 1")),
-                    JsObject(
-                        "name" -> JsString("paramName2"),
-                        "description" -> JsString("Parameter description 2"))))
-
-            assetHelper.withCleaner(wsk.trigger, name) {
-                (trigger, _) =>
-                    trigger.create(name, annotations = annots)
-            }
-
-            val stdout = wsk.trigger.get(name, summary = true).stdout
-            val ns = wsk.namespace.whois()
-
-            stdout should include regex (s"trigger /$ns/$name: Trigger description\\s*\\(parameters: paramName1, paramName2\\)")
-    }
-
-    it should "create a trigger with a name that contains spaces" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "trigger with spaces"
-
-            val res = assetHelper.withCleaner(wsk.trigger, name) {
-                (trigger, _) => trigger.create(name)
-            }
-
-            res.stdout should include regex (s"ok: created trigger $name")
-    }
-
-    it should "create, and fire a trigger using a parameter file" in withAssetCleaner(wskprops) {
-        val name = "paramFileTrigger"
-        val file = Some(TestCLIUtils.getTestActionFilename("argCheck.js"))
-        val argInput = Some(TestCLIUtils.getTestActionFilename("validInput2.json"))
-
-        (wp, assetHelper) => assetHelper.withCleaner(wsk.trigger, name) {
-            (trigger, _) => trigger.create(name)
-        }
-
-        val expectedOutput = JsObject("payload" -> JsString("test"))
-        val run = wsk.trigger.fire(name, parameterFile = argInput)
-        withActivation(wsk.activation, run) {
-            activation => activation.response.result shouldBe Some(expectedOutput)
-        }
-    }
-
-    it should "create a trigger, and get its individual fields" in withAssetCleaner(wskprops) {
-        val name = "triggerFields"
-        val paramInput = Map("payload" -> "test".toJson)
-        val successMsg = s"ok: got trigger $name, displaying field"
-
-        (wp, assetHelper) => assetHelper.withCleaner(wsk.trigger, name) {
-            (trigger, _) => trigger.create(name, parameters = paramInput)
-        }
-
-        val expectedParam = JsObject("payload" -> JsString("test"))
-        val ns = wsk.namespace.whois()
-
-        wsk.trigger.get(name, fieldFilter = Some("namespace")).stdout should include regex (s"""(?i)$successMsg namespace\n"$ns"""")
-        wsk.trigger.get(name, fieldFilter = Some("name")).stdout should include(s"""$successMsg name\n"$name"""")
-        wsk.trigger.get(name, fieldFilter = Some("version")).stdout should include(s"""$successMsg version\n"0.0.1"""")
-        wsk.trigger.get(name, fieldFilter = Some("publish")).stdout should include(s"""$successMsg publish\nfalse""")
-        wsk.trigger.get(name, fieldFilter = Some("annotations")).stdout should include(s"""$successMsg annotations\n[]""")
-        wsk.trigger.get(name, fieldFilter = Some("parameters")).stdout should include regex (s"""$successMsg parameters\n\\[\\s+\\{\\s+"key":\\s+"payload",\\s+"value":\\s+"test"\\s+\\}\\s+\\]""")
-        wsk.trigger.get(name, fieldFilter = Some("limits")).stdout should include(s"""$successMsg limits\n{}""")
-        wsk.trigger.get(name, fieldFilter = Some("invalid"), expectedExitCode = ERROR_EXIT).stderr should include("error: Invalid field filter 'invalid'.")
-    }
-
-    it should "create, and fire a trigger to ensure result is empty" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "emptyResultTrigger"
-            assetHelper.withCleaner(wsk.trigger, name) {
-                (trigger, _) => trigger.create(name)
-            }
-
-            val run = wsk.trigger.fire(name)
-            withActivation(wsk.activation, run) {
-                activation => activation.response.result shouldBe Some(JsObject())
-            }
-    }
-
-    it should "reject creation of duplicate triggers" in withAssetCleaner(wskprops) {
-        val name = "dupeTrigger"
-
-        (wp, assetHelper) => assetHelper.withCleaner(wsk.trigger, name) {
-            (trigger, _) => trigger.create(name)
-        }
-
-        val stderr = wsk.trigger.create(name, expectedExitCode = CONFLICT).stderr
-        stderr should include regex (s"""Unable to create trigger '$name': resource already exists \\(code \\d+\\)""")
-    }
-
-    it should "reject delete of trigger that does not exist" in {
-        val name = "nonexistentTrigger"
-        val stderr = wsk.trigger.delete(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to get trigger '$name'. The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "reject get of trigger that does not exist" in {
-        val name = "nonexistentTrigger"
-        val stderr = wsk.trigger.get(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to get trigger '$name': The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "reject firing of a trigger that does not exist" in {
-        val name = "nonexistentTrigger"
-        val stderr = wsk.trigger.fire(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to fire trigger '$name': The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    behavior of "Wsk Rule CLI"
-
-    it should "create rule, get rule, update rule and list rule" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val ruleName = "listRules"
-            val triggerName = "listRulesTrigger"
-            val actionName = "listRulesAction"
-
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) => trigger.create(name)
-            }
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, name) => action.create(name, defaultAction)
-            }
-            assetHelper.withCleaner(wsk.rule, ruleName) {
-                (rule, name) =>
-                    rule.create(name, trigger = triggerName, action = actionName)
-            }
-
-            // finally, we perform the update, and expect success this time
-            wsk.rule.create(ruleName, trigger = triggerName, action = actionName, update = true)
-
-            val stdout = wsk.rule.get(ruleName).stdout
-            stdout should include(ruleName)
-            stdout should include(triggerName)
-            stdout should include(actionName)
-            stdout should include regex (""""version": "0.0.2"""")
-            wsk.rule.list().stdout should include(ruleName)
-    }
-
-    it should "create rule, get rule, ensure rule is enabled by default" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val ruleName = "enabledRule"
-            val triggerName = "enabledRuleTrigger"
-            val actionName = "enabledRuleAction"
-
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) => trigger.create(name)
-            }
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, name) => action.create(name, defaultAction)
-            }
-            assetHelper.withCleaner(wsk.rule, ruleName) {
-                (rule, name) => rule.create(name, trigger = triggerName, action = actionName)
-            }
-
-            val stdout = wsk.rule.get(ruleName).stdout
-            stdout should include regex (""""status":\s*"active"""")
-    }
-
-    it should "display a rule summary when --summary flag is used with 'wsk rule get'" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val ruleName = "mySummaryRule"
-            val triggerName = "summaryRuleTrigger"
-            val actionName = "summaryRuleAction"
-
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) => trigger.create(name)
-            }
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, name) => action.create(name, defaultAction)
-            }
-            assetHelper.withCleaner(wsk.rule, ruleName, confirmDelete = false) {
-                (rule, name) => rule.create(name, trigger = triggerName, action = actionName)
-            }
-
-            // Summary namespace should match one of the allowable namespaces (typically 'guest')
-            val ns = wsk.namespace.whois()
-            val stdout = wsk.rule.get(ruleName, summary = true).stdout
-
-            stdout should include regex (s"(?i)rule /$ns/$ruleName\\s*\\(status: active\\)")
-    }
-
-    it should "create a rule, and get its individual fields" in withAssetCleaner(wskprops) {
-        val ruleName = "ruleFields"
-        val triggerName = "ruleTriggerFields"
-        val actionName = "ruleActionFields"
-        val paramInput = Map("payload" -> "test".toJson)
-        val successMsg = s"ok: got rule $ruleName, displaying field"
-
-        (wp, assetHelper) => assetHelper.withCleaner(wsk.trigger, triggerName) {
-            (trigger, name) => trigger.create(name)
-        }
-        assetHelper.withCleaner(wsk.action, actionName) {
-            (action, name) => action.create(name, defaultAction)
-        }
-        assetHelper.withCleaner(wsk.rule, ruleName) {
-            (rule, name) => rule.create(name, trigger = triggerName, action = actionName)
-        }
-
-        val ns = wsk.namespace.whois()
-        wsk.rule.get(ruleName, fieldFilter = Some("namespace")).stdout should include regex (s"""(?i)$successMsg namespace\n"$ns"""")
-        wsk.rule.get(ruleName, fieldFilter = Some("name")).stdout should include(s"""$successMsg name\n"$ruleName"""")
-        wsk.rule.get(ruleName, fieldFilter = Some("version")).stdout should include(s"""$successMsg version\n"0.0.1"\n""")
-        wsk.rule.get(ruleName, fieldFilter = Some("status")).stdout should include(s"""$successMsg status\n"active"""")
-        val trigger = wsk.rule.get(ruleName, fieldFilter = Some("trigger")).stdout
-        trigger should include regex (s"""$successMsg trigger\n""")
-        trigger should include(triggerName)
-        trigger should not include (actionName)
-        val action = wsk.rule.get(ruleName, fieldFilter = Some("action")).stdout
-        action should include regex (s"""$successMsg action\n""")
-        action should include(actionName)
-        action should not include (triggerName)
-    }
-
-    it should "reject creation of duplicate rules" in withAssetCleaner(wskprops) {
-        val ruleName = "dupeRule"
-        val triggerName = "triggerName"
-        val actionName = "actionName"
-
-        (wp, assetHelper) => assetHelper.withCleaner(wsk.trigger, triggerName) {
-            (trigger, name) => trigger.create(name)
-        }
-        assetHelper.withCleaner(wsk.action, actionName) {
-            (action, name) => action.create(name, defaultAction)
-        }
-        assetHelper.withCleaner(wsk.rule, ruleName) {
-            (rule, name) => rule.create(name, trigger = triggerName, action = actionName)
-        }
-
-        val stderr = wsk.rule.create(ruleName, trigger = triggerName, action = actionName, expectedExitCode = CONFLICT).stderr
-        stderr should include regex (s"""Unable to create rule '$ruleName': resource already exists \\(code \\d+\\)""")
-    }
-
-    it should "reject delete of rule that does not exist" in {
-        val name = "nonexistentRule"
-        val stderr = wsk.rule.delete(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to delete rule '$name'. The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "reject enable of rule that does not exist" in {
-        val name = "nonexistentRule"
-        val stderr = wsk.rule.enable(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to enable rule '$name': The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "reject disable of rule that does not exist" in {
-        val name = "nonexistentRule"
-        val stderr = wsk.rule.disable(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to disable rule '$name': The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "reject status of rule that does not exist" in {
-        val name = "nonexistentRule"
-        val stderr = wsk.rule.state(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to get status of rule '$name': The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "reject get of rule that does not exist" in {
-        val name = "nonexistentRule"
-        val stderr = wsk.rule.get(name, expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to get rule '$name': The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    behavior of "Wsk Namespace CLI"
-
-    it should "return a list of exactly one namespace" in {
-        val lines = wsk.namespace.list().stdout.lines.toSeq
-        lines should have size 2
-        lines.head shouldBe "namespaces"
-        lines(1).trim should not be empty
-    }
-
-    it should "list entities in default namespace" in {
-        // use a fresh wsk props instance that is guaranteed to use
-        // the default namespace
-        wsk.namespace.get(expectedExitCode = SUCCESS_EXIT)(WskProps()).
-            stdout should include("default")
-    }
-
-    it should "not list entities with an invalid namespace" in {
-        val namespace = "fakeNamespace"
-        val stderr = wsk.namespace.get(Some(s"/${namespace}"), expectedExitCode = FORBIDDEN).stderr
-
-        stderr should include(s"Unable to obtain the list of entities for namespace '${namespace}'")
-    }
-
-    behavior of "Wsk Activation CLI"
-
-    it should "create a trigger, and fire a trigger to get its individual fields from an activation" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "activationFields"
-
-            assetHelper.withCleaner(wsk.trigger, name) {
-                (trigger, _) =>
-                    trigger.create(name)
-            }
-
-            val ns = s""""${wsk.namespace.whois()}""""
-            val run = wsk.trigger.fire(name)
-            withActivation(wsk.activation, run) {
-                activation =>
-                    val successMsg = s"ok: got activation ${activation.activationId}, displaying field"
-                    wsk.activation.get(Some(activation.activationId), fieldFilter = Some("namespace")).stdout should include regex (s"""(?i)$successMsg namespace\n$ns""")
-                    wsk.activation.get(Some(activation.activationId), fieldFilter = Some("name")).stdout should include(s"""$successMsg name\n"$name"""")
-                    wsk.activation.get(Some(activation.activationId), fieldFilter = Some("version")).stdout should include(s"""$successMsg version\n"0.0.1"""")
-                    wsk.activation.get(Some(activation.activationId), fieldFilter = Some("publish")).stdout should include(s"""$successMsg publish\nfalse""")
-                    wsk.activation.get(Some(activation.activationId), fieldFilter = Some("subject")).stdout should include regex (s"""(?i)$successMsg subject\n""")
-                    wsk.activation.get(Some(activation.activationId), fieldFilter = Some("activationid")).stdout should include(s"""$successMsg activationid\n"${activation.activationId}""")
-                    wsk.activation.get(Some(activation.activationId), fieldFilter = Some("start")).stdout should include regex (s"""$successMsg start\n\\d""")
-                    wsk.activation.get(Some(activation.activationId), fieldFilter = Some("end")).stdout should include regex (s"""$successMsg end\n\\d""")
-                    wsk.activation.get(Some(activation.activationId), fieldFilter = Some("duration")).stdout should include regex (s"""$successMsg duration\n\\d""")
-                    wsk.activation.get(Some(activation.activationId), fieldFilter = Some("annotations")).stdout should include(s"""$successMsg annotations\n[]""")
-            }
-    }
-
-    it should "reject get of activation that does not exist" in {
-        val name = "0" * 32
-        val stderr = wsk.activation.get(Some(name), expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to get activation '$name': The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "reject logs of activation that does not exist" in {
-        val name = "0" * 32
-        val stderr = wsk.activation.logs(Some(name), expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to get logs for activation '$name': The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "reject result of activation that does not exist" in {
-        val name = "0" * 32
-        val stderr = wsk.activation.result(Some(name), expectedExitCode = NOT_FOUND).stderr
-        stderr should include regex (s"""Unable to get result for activation '$name': The requested resource does not exist. \\(code \\d+\\)""")
-    }
-
-    it should "reject activation request when using activation ID with --last Flag" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val auth: Seq[String] = Seq("--auth", wskprops.authKey)
-
-            val lastId = "dummyActivationId"
-            val tooManyArgsMsg = s"${lastId}. An activation ID is required."
-            val invalidField = s"Invalid field filter '${lastId}'."
-
-            val invalidCmd = Seq(
-                (Seq("activation", "get", s"$lastId", "publish", "--last"), tooManyArgsMsg),
-                (Seq("activation", "get", s"$lastId", "--last"), invalidField),
-                (Seq("activation", "logs", s"$lastId", "--last"), tooManyArgsMsg),
-                (Seq("activation", "result", s"$lastId", "--last"), tooManyArgsMsg))
-
-            invalidCmd foreach {
-                case (cmd, err) =>
-                    val stderr = wsk.cli(cmd ++ wskprops.overrides ++ auth, expectedExitCode = ERROR_EXIT).stderr
-                    stderr should include(err)
-            }
-    }
+    stdout should include regex (s"trigger /$ns/$name: Trigger description\\s*\\(parameters: paramName1, paramName2\\)")
+  }
+
+  it should "create a trigger with a name that contains spaces" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "trigger with spaces"
+
+    val res = assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+      trigger.create(name)
+    }
+
+    res.stdout should include regex (s"ok: created trigger $name")
+  }
+
+  it should "create, and fire a trigger using a parameter file" in withAssetCleaner(wskprops) {
+    val name = "paramFileTrigger"
+    val file = Some(TestUtils.getTestActionFilename("argCheck.js"))
+    val argInput = Some(TestUtils.getTestActionFilename("validInput2.json"))
+
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+        trigger.create(name)
+      }
+
+      val expectedOutput = JsObject("payload" -> JsString("test"))
+      val run = wsk.trigger.fire(name, parameterFile = argInput)
+      withActivation(wsk.activation, run) { activation =>
+        activation.response.result shouldBe Some(expectedOutput)
+      }
+  }
+
+  it should "create a trigger, and get its individual fields" in withAssetCleaner(wskprops) {
+    val name = "triggerFields"
+    val paramInput = Map("payload" -> "test".toJson)
+    val successMsg = s"ok: got trigger $name, displaying field"
+
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+        trigger.create(name, parameters = paramInput)
+      }
+
+      val expectedParam = JsObject("payload" -> JsString("test"))
+      val ns = wsk.namespace.whois()
+
+      wsk.trigger
+        .get(name, fieldFilter = Some("namespace"))
+        .stdout should include regex (s"""(?i)$successMsg namespace\n"$ns"""")
+      wsk.trigger.get(name, fieldFilter = Some("name")).stdout should include(s"""$successMsg name\n"$name"""")
+      wsk.trigger.get(name, fieldFilter = Some("version")).stdout should include(s"""$successMsg version\n"0.0.1"""")
+      wsk.trigger.get(name, fieldFilter = Some("publish")).stdout should include(s"""$successMsg publish\nfalse""")
+      wsk.trigger.get(name, fieldFilter = Some("annotations")).stdout should include(s"""$successMsg annotations\n[]""")
+      wsk.trigger
+        .get(name, fieldFilter = Some("parameters"))
+        .stdout should include regex (s"""$successMsg parameters\n\\[\\s+\\{\\s+"key":\\s+"payload",\\s+"value":\\s+"test"\\s+\\}\\s+\\]""")
+      wsk.trigger.get(name, fieldFilter = Some("limits")).stdout should include(s"""$successMsg limits\n{}""")
+      wsk.trigger.get(name, fieldFilter = Some("invalid"), expectedExitCode = ERROR_EXIT).stderr should include(
+        "error: Invalid field filter 'invalid'.")
+  }
+
+  it should "create, and fire a trigger to ensure result is empty" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "emptyResultTrigger"
+    assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+      trigger.create(name)
+    }
+
+    val run = wsk.trigger.fire(name)
+    withActivation(wsk.activation, run) { activation =>
+      activation.response.result shouldBe Some(JsObject())
+    }
+  }
+
+  it should "reject creation of duplicate triggers" in withAssetCleaner(wskprops) {
+    val name = "dupeTrigger"
+
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+        trigger.create(name)
+      }
+
+      val stderr = wsk.trigger.create(name, expectedExitCode = CONFLICT).stderr
+      stderr should include regex (s"""Unable to create trigger '$name': resource already exists \\(code \\d+\\)""")
+  }
+
+  it should "reject delete of trigger that does not exist" in {
+    val name = "nonexistentTrigger"
+    val stderr = wsk.trigger.delete(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to get trigger '$name'. The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "reject get of trigger that does not exist" in {
+    val name = "nonexistentTrigger"
+    val stderr = wsk.trigger.get(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to get trigger '$name': The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "reject firing of a trigger that does not exist" in {
+    val name = "nonexistentTrigger"
+    val stderr = wsk.trigger.fire(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to fire trigger '$name': The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  behavior of "Wsk Rule CLI"
+
+  it should "create rule, get rule, update rule and list rule" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val ruleName = "listRules"
+    val triggerName = "listRulesTrigger"
+    val actionName = "listRulesAction"
+
+    assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
+      trigger.create(name)
+    }
+    assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+      action.create(name, defaultAction)
+    }
+    assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+      rule.create(name, trigger = triggerName, action = actionName)
+    }
+
+    // finally, we perform the update, and expect success this time
+    wsk.rule.create(ruleName, trigger = triggerName, action = actionName, update = true)
+
+    val stdout = wsk.rule.get(ruleName).stdout
+    stdout should include(ruleName)
+    stdout should include(triggerName)
+    stdout should include(actionName)
+    stdout should include regex (""""version": "0.0.2"""")
+    wsk.rule.list().stdout should include(ruleName)
+  }
+
+  it should "create rule, get rule, ensure rule is enabled by default" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val ruleName = "enabledRule"
+      val triggerName = "enabledRuleTrigger"
+      val actionName = "enabledRuleAction"
+
+      assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
+        trigger.create(name)
+      }
+      assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+        action.create(name, defaultAction)
+      }
+      assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+        rule.create(name, trigger = triggerName, action = actionName)
+      }
+
+      val stdout = wsk.rule.get(ruleName).stdout
+      stdout should include regex (""""status":\s*"active"""")
+  }
+
+  it should "display a rule summary when --summary flag is used with 'wsk rule get'" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val ruleName = "mySummaryRule"
+      val triggerName = "summaryRuleTrigger"
+      val actionName = "summaryRuleAction"
+
+      assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
+        trigger.create(name)
+      }
+      assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+        action.create(name, defaultAction)
+      }
+      assetHelper.withCleaner(wsk.rule, ruleName, confirmDelete = false) { (rule, name) =>
+        rule.create(name, trigger = triggerName, action = actionName)
+      }
+
+      // Summary namespace should match one of the allowable namespaces (typically 'guest')
+      val ns = wsk.namespace.whois()
+      val stdout = wsk.rule.get(ruleName, summary = true).stdout
+
+      stdout should include regex (s"(?i)rule /$ns/$ruleName\\s*\\(status: active\\)")
+  }
+
+  it should "create a rule, and get its individual fields" in withAssetCleaner(wskprops) {
+    val ruleName = "ruleFields"
+    val triggerName = "ruleTriggerFields"
+    val actionName = "ruleActionFields"
+    val paramInput = Map("payload" -> "test".toJson)
+    val successMsg = s"ok: got rule $ruleName, displaying field"
+
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
+        trigger.create(name)
+      }
+      assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+        action.create(name, defaultAction)
+      }
+      assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+        rule.create(name, trigger = triggerName, action = actionName)
+      }
+
+      val ns = wsk.namespace.whois()
+      wsk.rule
+        .get(ruleName, fieldFilter = Some("namespace"))
+        .stdout should include regex (s"""(?i)$successMsg namespace\n"$ns"""")
+      wsk.rule.get(ruleName, fieldFilter = Some("name")).stdout should include(s"""$successMsg name\n"$ruleName"""")
+      wsk.rule.get(ruleName, fieldFilter = Some("version")).stdout should include(s"""$successMsg version\n"0.0.1"\n""")
+      wsk.rule.get(ruleName, fieldFilter = Some("status")).stdout should include(s"""$successMsg status\n"active"""")
+      val trigger = wsk.rule.get(ruleName, fieldFilter = Some("trigger")).stdout
+      trigger should include regex (s"""$successMsg trigger\n""")
+      trigger should include(triggerName)
+      trigger should not include (actionName)
+      val action = wsk.rule.get(ruleName, fieldFilter = Some("action")).stdout
+      action should include regex (s"""$successMsg action\n""")
+      action should include(actionName)
+      action should not include (triggerName)
+  }
+
+  it should "reject creation of duplicate rules" in withAssetCleaner(wskprops) {
+    val ruleName = "dupeRule"
+    val triggerName = "triggerName"
+    val actionName = "actionName"
+
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
+        trigger.create(name)
+      }
+      assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+        action.create(name, defaultAction)
+      }
+      assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+        rule.create(name, trigger = triggerName, action = actionName)
+      }
+
+      val stderr =
+        wsk.rule.create(ruleName, trigger = triggerName, action = actionName, expectedExitCode = CONFLICT).stderr
+      stderr should include regex (s"""Unable to create rule '$ruleName': resource already exists \\(code \\d+\\)""")
+  }
+
+  it should "reject delete of rule that does not exist" in {
+    val name = "nonexistentRule"
+    val stderr = wsk.rule.delete(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to delete rule '$name'. The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "reject enable of rule that does not exist" in {
+    val name = "nonexistentRule"
+    val stderr = wsk.rule.enable(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to enable rule '$name': The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "reject disable of rule that does not exist" in {
+    val name = "nonexistentRule"
+    val stderr = wsk.rule.disable(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to disable rule '$name': The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "reject status of rule that does not exist" in {
+    val name = "nonexistentRule"
+    val stderr = wsk.rule.state(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to get status of rule '$name': The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "reject get of rule that does not exist" in {
+    val name = "nonexistentRule"
+    val stderr = wsk.rule.get(name, expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to get rule '$name': The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  behavior of "Wsk Namespace CLI"
+
+  it should "return a list of exactly one namespace" in {
+    val lines = wsk.namespace.list().stdout.lines.toSeq
+    lines should have size 2
+    lines.head shouldBe "namespaces"
+    lines(1).trim should not be empty
+  }
+
+  it should "list entities in default namespace" in {
+    // use a fresh wsk props instance that is guaranteed to use
+    // the default namespace
+    wsk.namespace.get(expectedExitCode = SUCCESS_EXIT)(WskProps()).stdout should include("default")
+  }
+
+  it should "not list entities with an invalid namespace" in {
+    val namespace = "fakeNamespace"
+    val stderr = wsk.namespace.get(Some(s"/${namespace}"), expectedExitCode = FORBIDDEN).stderr
+
+    stderr should include(s"Unable to obtain the list of entities for namespace '${namespace}'")
+  }
+
+  behavior of "Wsk Activation CLI"
+
+  it should "create a trigger, and fire a trigger to get its individual fields from an activation" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "activationFields"
+
+    assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+      trigger.create(name)
+    }
+
+    val ns = s""""${wsk.namespace.whois()}""""
+    val run = wsk.trigger.fire(name)
+    withActivation(wsk.activation, run) { activation =>
+      val successMsg = s"ok: got activation ${activation.activationId}, displaying field"
+      wsk.activation
+        .get(Some(activation.activationId), fieldFilter = Some("namespace"))
+        .stdout should include regex (s"""(?i)$successMsg namespace\n$ns""")
+      wsk.activation.get(Some(activation.activationId), fieldFilter = Some("name")).stdout should include(
+        s"""$successMsg name\n"$name"""")
+      wsk.activation.get(Some(activation.activationId), fieldFilter = Some("version")).stdout should include(
+        s"""$successMsg version\n"0.0.1"""")
+      wsk.activation.get(Some(activation.activationId), fieldFilter = Some("publish")).stdout should include(
+        s"""$successMsg publish\nfalse""")
+      wsk.activation
+        .get(Some(activation.activationId), fieldFilter = Some("subject"))
+        .stdout should include regex (s"""(?i)$successMsg subject\n""")
+      wsk.activation.get(Some(activation.activationId), fieldFilter = Some("activationid")).stdout should include(
+        s"""$successMsg activationid\n"${activation.activationId}""")
+      wsk.activation
+        .get(Some(activation.activationId), fieldFilter = Some("start"))
+        .stdout should include regex (s"""$successMsg start\n\\d""")
+      wsk.activation
+        .get(Some(activation.activationId), fieldFilter = Some("end"))
+        .stdout should include regex (s"""$successMsg end\n\\d""")
+      wsk.activation
+        .get(Some(activation.activationId), fieldFilter = Some("duration"))
+        .stdout should include regex (s"""$successMsg duration\n\\d""")
+      wsk.activation.get(Some(activation.activationId), fieldFilter = Some("annotations")).stdout should include(
+        s"""$successMsg annotations\n[]""")
+    }
+  }
+
+  it should "reject get of activation that does not exist" in {
+    val name = "0" * 32
+    val stderr = wsk.activation.get(Some(name), expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to get activation '$name': The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "reject logs of activation that does not exist" in {
+    val name = "0" * 32
+    val stderr = wsk.activation.logs(Some(name), expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to get logs for activation '$name': The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "reject result of activation that does not exist" in {
+    val name = "0" * 32
+    val stderr = wsk.activation.result(Some(name), expectedExitCode = NOT_FOUND).stderr
+    stderr should include regex (s"""Unable to get result for activation '$name': The requested resource does not exist. \\(code \\d+\\)""")
+  }
+
+  it should "reject activation request when using activation ID with --last Flag" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val auth: Seq[String] = Seq("--auth", wskprops.authKey)
+
+      val lastId = "dummyActivationId"
+      val tooManyArgsMsg = s"${lastId}. An activation ID is required."
+      val invalidField = s"Invalid field filter '${lastId}'."
+
+      val invalidCmd = Seq(
+        (Seq("activation", "get", s"$lastId", "publish", "--last"), tooManyArgsMsg),
+        (Seq("activation", "get", s"$lastId", "--last"), invalidField),
+        (Seq("activation", "logs", s"$lastId", "--last"), tooManyArgsMsg),
+        (Seq("activation", "result", s"$lastId", "--last"), tooManyArgsMsg))
+
+      invalidCmd foreach {
+        case (cmd, err) =>
+          val stderr = wsk.cli(cmd ++ wskprops.overrides ++ auth, expectedExitCode = ERROR_EXIT).stderr
+          stderr should include(err)
+      }
+  }
 }
diff --git a/tests/src/test/scala/system/basic/WskConsoleTests.scala b/tests/src/test/scala/system/basic/WskConsoleTests.scala
index 1848733..c2191fa 100644
--- a/tests/src/test/scala/system/basic/WskConsoleTests.scala
+++ b/tests/src/test/scala/system/basic/WskConsoleTests.scala
@@ -41,59 +41,53 @@ import spray.json.pimpAny
  * Tests of the text console
  */
 @RunWith(classOf[JUnitRunner])
-class WskConsoleTests
-    extends TestHelpers
-    with WskTestHelpers {
+class WskConsoleTests extends TestHelpers with WskTestHelpers {
 
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-    val guestNamespace = wskprops.namespace
+  implicit val wskprops = WskProps()
+  val wsk = new Wsk
+  val guestNamespace = wskprops.namespace
 
-    behavior of "Wsk Activation Console"
+  behavior of "Wsk Activation Console"
 
-    it should "show an activation log message for hello world" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val packageName = "samples"
-            val actionName = "helloWorld"
-            val fullActionName = s"/$guestNamespace/$packageName/$actionName"
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, _) => pkg.create(packageName, shared = Some(true))
-            }
+  it should "show an activation log message for hello world" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val packageName = "samples"
+    val actionName = "helloWorld"
+    val fullActionName = s"/$guestNamespace/$packageName/$actionName"
+    assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
+      pkg.create(packageName, shared = Some(true))
+    }
 
-            assetHelper.withCleaner(wsk.action, fullActionName) {
-                (action, _) => action.create(fullActionName, Some(TestCLIUtils.getTestActionFilename("hello.js")))
-            }
+    assetHelper.withCleaner(wsk.action, fullActionName) { (action, _) =>
+      action.create(fullActionName, Some(TestUtils.getTestActionFilename("hello.js")))
+    }
 
-            val duration = Some(30 seconds)
-            val payload = new String("from the console!".getBytes, "UTF-8")
-            val run = wsk.action.invoke(fullActionName, Map("payload" -> payload.toJson))
-            withActivation(wsk.activation, run, totalWait = duration.get) {
-                activation =>
-                    val console = wsk.activation.console(10 seconds, since = duration)
-                    println(console.stdout)
-                    console.stdout should include(payload)
-            }
+    val duration = Some(30 seconds)
+    val payload = new String("from the console!".getBytes, "UTF-8")
+    val run = wsk.action.invoke(fullActionName, Map("payload" -> payload.toJson))
+    withActivation(wsk.activation, run, totalWait = duration.get) { activation =>
+      val console = wsk.activation.console(10 seconds, since = duration)
+      println(console.stdout)
+      console.stdout should include(payload)
     }
+  }
 
-    it should "show repeated activations" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "countdown"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("countdown.js")))
-            }
+  it should "show repeated activations" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "countdown"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("countdown.js")))
+    }
 
-            val start = Instant.now(Clock.systemUTC())
-            val run = wsk.action.invoke(name, Map("n" -> 3.toJson))
-            withActivation(wsk.activation, run) {
-                activation =>
-                    val activations = wsk.activation.pollFor(N = 4, Some(name), since = Some(start), retries = 80).length
-                    withClue(s"expected activations:") {
-                        activations should be(4)
-                    }
-                    val duration = Duration(Instant.now(Clock.systemUTC()).toEpochMilli - start.toEpochMilli, MILLISECONDS)
-                    val console = wsk.activation.console(10 seconds, since = Some(duration))
-                    console.stdout should include("Happy New Year")
-            }
+    val start = Instant.now(Clock.systemUTC())
+    val run = wsk.action.invoke(name, Map("n" -> 3.toJson))
+    withActivation(wsk.activation, run) { activation =>
+      val activations = wsk.activation.pollFor(N = 4, Some(name), since = Some(start), retries = 80).length
+      withClue(s"expected activations:") {
+        activations should be(4)
+      }
+      val duration = Duration(Instant.now(Clock.systemUTC()).toEpochMilli - start.toEpochMilli, MILLISECONDS)
+      val console = wsk.activation.console(10 seconds, since = Some(duration))
+      console.stdout should include("Happy New Year")
     }
+  }
 
 }
diff --git a/tests/src/test/scala/system/basic/WskPackageTests.scala b/tests/src/test/scala/system/basic/WskPackageTests.scala
index 88618f0..1fae059 100644
--- a/tests/src/test/scala/system/basic/WskPackageTests.scala
+++ b/tests/src/test/scala/system/basic/WskPackageTests.scala
@@ -34,110 +34,103 @@ import common.TestHelpers
 import common.WskProps
 
 @RunWith(classOf[JUnitRunner])
-class WskPackageTests
-    extends TestHelpers
-    with WskTestHelpers {
+class WskPackageTests extends TestHelpers with WskTestHelpers {
 
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-    val LOG_DELAY = 80 seconds
+  implicit val wskprops = WskProps()
+  val wsk = new Wsk
+  val LOG_DELAY = 80 seconds
 
-    behavior of "Wsk Package"
+  behavior of "Wsk Package"
 
-    it should "allow creation and deletion of a package" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "simplepackage"
-            assetHelper.withCleaner(wsk.pkg, name) {
-                (pkg, _) => pkg.create(name, Map())
-            }
+  it should "allow creation and deletion of a package" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "simplepackage"
+    assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+      pkg.create(name, Map())
     }
+  }
 
-    val params1 = Map("p1" -> "v1".toJson, "p2" -> "".toJson)
-    val params2 = Map("p1" -> "v1".toJson, "p2" -> "v2".toJson, "p3" -> "v3".toJson)
+  val params1 = Map("p1" -> "v1".toJson, "p2" -> "".toJson)
+  val params2 = Map("p1" -> "v1".toJson, "p2" -> "v2".toJson, "p3" -> "v3".toJson)
 
-    it should "allow creation of a package with parameters" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "simplepackagewithparams"
-            assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
-                pkg.create(name, params1)
-            }
+  it should "allow creation of a package with parameters" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "simplepackagewithparams"
+    assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+      pkg.create(name, params1)
     }
+  }
 
-    it should "allow updating a package" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "simplepackagetoupdate"
-            assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
-                pkg.create(name, params1)
-                pkg.create(name, params2, update = true)
-            }
+  it should "allow updating a package" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "simplepackagetoupdate"
+    assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+      pkg.create(name, params1)
+      pkg.create(name, params2, update = true)
     }
+  }
 
-    it should "allow binding of a package" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "simplepackagetobind"
-            val bindName = "simplebind"
-            assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
-                pkg.create(name, params1)
-            }
-            assetHelper.withCleaner(wsk.pkg, bindName) { (pkg, _) =>
-                pkg.bind(name, bindName, params2)
-            }
+  it should "allow binding of a package" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "simplepackagetobind"
+    val bindName = "simplebind"
+    assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+      pkg.create(name, params1)
     }
+    assetHelper.withCleaner(wsk.pkg, bindName) { (pkg, _) =>
+      pkg.bind(name, bindName, params2)
+    }
+  }
 
-    it should "perform package binds so parameters are inherited" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val packageName = "package1"
-            val bindName = "package2"
-            val actionName = "print"
-            val packageActionName = packageName + "/" + actionName
-            val bindActionName = bindName + "/" + actionName
-            val packageParams = Map("key1a" -> "value1a".toJson, "key1b" -> "value1b".toJson)
-            val bindParams = Map("key2a" -> "value2a".toJson, "key1b" -> "value2b".toJson)
-            val actionParams = Map("key0" -> "value0".toJson)
-            val file = TestCLIUtils.getTestActionFilename("printParams.js")
-            assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
-                pkg.create(packageName, packageParams)
-            }
-            assetHelper.withCleaner(wsk.action, packageActionName) { (action, _) =>
-                action.create(packageActionName, Some(file), parameters = actionParams)
-            }
-            assetHelper.withCleaner(wsk.pkg, bindName) { (pkg, _) =>
-                pkg.bind(packageName, bindName, bindParams)
-            }
+  it should "perform package binds so parameters are inherited" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val packageName = "package1"
+    val bindName = "package2"
+    val actionName = "print"
+    val packageActionName = packageName + "/" + actionName
+    val bindActionName = bindName + "/" + actionName
+    val packageParams = Map("key1a" -> "value1a".toJson, "key1b" -> "value1b".toJson)
+    val bindParams = Map("key2a" -> "value2a".toJson, "key1b" -> "value2b".toJson)
+    val actionParams = Map("key0" -> "value0".toJson)
+    val file = TestUtils.getTestActionFilename("printParams.js")
+    assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
+      pkg.create(packageName, packageParams)
+    }
+    assetHelper.withCleaner(wsk.action, packageActionName) { (action, _) =>
+      action.create(packageActionName, Some(file), parameters = actionParams)
+    }
+    assetHelper.withCleaner(wsk.pkg, bindName) { (pkg, _) =>
+      pkg.bind(packageName, bindName, bindParams)
+    }
 
-            // Check that the description of packages and actions includes all the inherited parameters.
-            val packageDescription = wsk.pkg.get(packageName).stdout
-            val bindDescription = wsk.pkg.get(bindName).stdout
-            val packageActionDescription = wsk.action.get(packageActionName).stdout
-            val bindActionDescription = wsk.action.get(bindActionName).stdout
-            checkForParameters(packageDescription, packageParams)
-            checkForParameters(bindDescription, packageParams, bindParams)
-            checkForParameters(packageActionDescription, packageParams, actionParams)
-            checkForParameters(bindActionDescription, packageParams, bindParams, actionParams)
+    // Check that the description of packages and actions includes all the inherited parameters.
+    val packageDescription = wsk.pkg.get(packageName).stdout
+    val bindDescription = wsk.pkg.get(bindName).stdout
+    val packageActionDescription = wsk.action.get(packageActionName).stdout
+    val bindActionDescription = wsk.action.get(bindActionName).stdout
+    checkForParameters(packageDescription, packageParams)
+    checkForParameters(bindDescription, packageParams, bindParams)
+    checkForParameters(packageActionDescription, packageParams, actionParams)
+    checkForParameters(bindActionDescription, packageParams, bindParams, actionParams)
 
-            // Check that inherited parameters are passed to the action.
-            val now = new Date().toString()
-            val run = wsk.action.invoke(bindActionName, Map("payload" -> now.toJson))
-            withActivation(wsk.activation, run, totalWait = LOG_DELAY) {
-                _.logs.get.mkString(" ") should include regex (
-                    String.format(".*key0: value0.*key1a: value1a.*key1b: value2b.*key2a: value2a.*payload: %s", now))
-            }
+    // Check that inherited parameters are passed to the action.
+    val now = new Date().toString()
+    val run = wsk.action.invoke(bindActionName, Map("payload" -> now.toJson))
+    withActivation(wsk.activation, run, totalWait = LOG_DELAY) {
+      _.logs.get.mkString(" ") should include regex (String
+        .format(".*key0: value0.*key1a: value1a.*key1b: value2b.*key2a: value2a.*payload: %s", now))
     }
+  }
 
-    /**
-     * Check that a description of an item includes the specified parameters.
-     * Parameters keys in later parameter maps override earlier ones.
-     */
-    def checkForParameters(itemDescription: String, paramSets: Map[String, JsValue]*) {
-        // Merge and the parameters handling overrides.
-        val merged = HashMap.empty[String, JsValue]
-        paramSets.foreach { merged ++= _ }
-        val flatDescription = itemDescription.replace("\n", "").replace("\r", "")
-        merged.foreach {
-            case (key: String, value: JsValue) =>
-                val toFind = s""""key": "${key}",.*"value": ${value.toString}"""
-                flatDescription should include regex toFind
-        }
+  /**
+   * Check that a description of an item includes the specified parameters.
+   * Parameters keys in later parameter maps override earlier ones.
+   */
+  def checkForParameters(itemDescription: String, paramSets: Map[String, JsValue]*) {
+    // Merge and the parameters handling overrides.
+    val merged = HashMap.empty[String, JsValue]
+    paramSets.foreach { merged ++= _ }
+    val flatDescription = itemDescription.replace("\n", "").replace("\r", "")
+    merged.foreach {
+      case (key: String, value: JsValue) =>
+        val toFind = s""""key": "${key}",.*"value": ${value.toString}"""
+        flatDescription should include regex toFind
     }
+  }
 
 }
diff --git a/tests/src/test/scala/system/basic/WskRuleTests.scala b/tests/src/test/scala/system/basic/WskRuleTests.scala
index ae8768d..adc95a7 100644
--- a/tests/src/test/scala/system/basic/WskRuleTests.scala
+++ b/tests/src/test/scala/system/basic/WskRuleTests.scala
@@ -29,364 +29,394 @@ import spray.json.DefaultJsonProtocol._
 import java.time.Instant
 
 @RunWith(classOf[JUnitRunner])
-class WskRuleTests
-    extends TestHelpers
-    with WskTestHelpers {
-
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-    val defaultAction = TestCLIUtils.getTestActionFilename("wc.js")
-    val secondAction = TestCLIUtils.getTestActionFilename("hello.js")
-    val testString = "this is a test"
-    val testResult = JsObject("count" -> testString.split(" ").length.toJson)
-
-    /**
-     * Invoker clock skew can sometimes make it appear as if an action was invoked
-     * _before_ the trigger was fired. The "fudge factor" below allows the test to look
-     * for action activations that occur starting at most this amount of time before
-     * the trigger was fired.
-     */
-    val activationTimeSkewFactorMs = 500
-
-    /**
-     * Sets up trigger -> rule -> action triplets. Deduplicates triggers and rules
-     * and links it all up.
-     *
-     * @param rules Tuple3s containing
-     *   (rule, trigger, (action name for created action, action name for the rule binding, actionFile))
-     *   where the action name for the created action is allowed to differ from that used by the rule binding
-     *   for cases that reference actions in a package binding.
-     */
-    def ruleSetup(rules: Seq[(String, String, (String, String, String))], assetHelper: AssetCleaner) = {
-        val triggers = rules.map(_._2).distinct
-        val actions = rules.map(_._3).distinct
-
-        triggers.foreach { trigger =>
-            assetHelper.withCleaner(wsk.trigger, trigger) {
-                (trigger, name) => trigger.create(name)
-            }
-        }
+class WskRuleTests extends TestHelpers with WskTestHelpers {
+
+  implicit val wskprops = WskProps()
+  val wsk = new Wsk
+  val defaultAction = TestCLIUtils.getTestActionFilename("wc.js")
+  val secondAction = TestCLIUtils.getTestActionFilename("hello.js")
+  val testString = "this is a test"
+  val testResult = JsObject("count" -> testString.split(" ").length.toJson)
+
+  /**
+   * Invoker clock skew can sometimes make it appear as if an action was invoked
+   * _before_ the trigger was fired. The "fudge factor" below allows the test to look
+   * for action activations that occur starting at most this amount of time before
+   * the trigger was fired.
+   */
+  val activationTimeSkewFactorMs = 500
+
+  /**
+   * Sets up trigger -> rule -> action triplets. Deduplicates triggers and rules
+   * and links it all up.
+   *
+   * @param rules Tuple3s containing
+   *   (rule, trigger, (action name for created action, action name for the rule binding, actionFile))
+   *   where the action name for the created action is allowed to differ from that used by the rule binding
+   *   for cases that reference actions in a package binding.
+   */
+  def ruleSetup(rules: Seq[(String, String, (String, String, String))], assetHelper: AssetCleaner) = {
+    val triggers = rules.map(_._2).distinct
+    val actions = rules.map(_._3).distinct
+
+    triggers.foreach { trigger =>
+      assetHelper.withCleaner(wsk.trigger, trigger) { (trigger, name) =>
+        trigger.create(name)
+      }
+    }
 
-        actions.foreach {
-            case (actionName, _, file) =>
-                assetHelper.withCleaner(wsk.action, actionName) {
-                    (action, name) => action.create(name, Some(file))
-                }
+    actions.foreach {
+      case (actionName, _, file) =>
+        assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+          action.create(name, Some(file))
         }
+    }
 
-        rules.foreach {
-            case (ruleName, triggerName, action) =>
-                assetHelper.withCleaner(wsk.rule, ruleName) {
-                    (rule, name) => rule.create(name, triggerName, action._2)
-                }
+    rules.foreach {
+      case (ruleName, triggerName, action) =>
+        assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+          rule.create(name, triggerName, action._2)
         }
     }
+  }
+
+  /**
+   * Append the current timestamp in ms
+   */
+  def withTimestamp(text: String) = s"${text}-${System.currentTimeMillis}"
+
+  behavior of "Whisk rules"
+
+  it should "invoke the action attached on trigger fire, creating an activation for each entity including the cause" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val ruleName = withTimestamp("r1to1")
+    val triggerName = withTimestamp("t1to1")
+    val actionName = withTimestamp("a1 to 1") // spaces in name intended for greater test coverage
+
+    ruleSetup(Seq((ruleName, triggerName, (actionName, actionName, defaultAction))), assetHelper)
+
+    val run = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
+
+    withActivation(wsk.activation, run) { triggerActivation =>
+      triggerActivation.cause shouldBe None
+
+      withActivationsFromEntity(
+        wsk.activation,
+        ruleName,
+        since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
+        _.head.cause shouldBe Some(triggerActivation.activationId)
+      }
+
+      withActivationsFromEntity(
+        wsk.activation,
+        actionName,
+        since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) { activationList =>
+        activationList.head.response.result shouldBe Some(testResult)
+        activationList.head.cause shouldBe None
+      }
+    }
+  }
+
+  it should "invoke the action from a package attached on trigger fire, creating an activation for each entity including the cause" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val ruleName = withTimestamp("pr1to1")
+    val triggerName = withTimestamp("pt1to1")
+    val pkgName = withTimestamp("rule pkg") // spaces in name intended to test uri path encoding
+    val actionName = withTimestamp("a1 to 1")
+    val pkgActionName = s"$pkgName/$actionName"
+
+    assetHelper.withCleaner(wsk.pkg, pkgName) { (pkg, name) =>
+      pkg.create(name)
+    }
 
-    /**
-     * Append the current timestamp in ms
-     */
-    def withTimestamp(text: String) = s"${text}-${System.currentTimeMillis}"
-
-    behavior of "Whisk rules"
-
-    it should "invoke the action attached on trigger fire, creating an activation for each entity including the cause" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val ruleName = withTimestamp("r1to1")
-            val triggerName = withTimestamp("t1to1")
-            val actionName = withTimestamp("a1 to 1") // spaces in name intended for greater test coverage
-
-            ruleSetup(Seq(
-                (ruleName, triggerName, (actionName, actionName, defaultAction))),
-                assetHelper)
+    ruleSetup(Seq((ruleName, triggerName, (pkgActionName, pkgActionName, defaultAction))), assetHelper)
 
-            val run = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
+    val now = Instant.now
+    val run = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
 
-            withActivation(wsk.activation, run) {
-                triggerActivation =>
-                    triggerActivation.cause shouldBe None
+    withActivation(wsk.activation, run) { triggerActivation =>
+      triggerActivation.cause shouldBe None
 
-                    withActivationsFromEntity(wsk.activation, ruleName, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-                        _.head.cause shouldBe Some(triggerActivation.activationId)
-                    }
+      withActivationsFromEntity(
+        wsk.activation,
+        ruleName,
+        since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
+        _.head.cause shouldBe Some(triggerActivation.activationId)
+      }
 
-                    withActivationsFromEntity(wsk.activation, actionName, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) { activationList =>
-                        activationList.head.response.result shouldBe Some(testResult)
-                        activationList.head.cause shouldBe None
-                    }
-            }
+      withActivationsFromEntity(
+        wsk.activation,
+        actionName,
+        since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
+        _.head.response.result shouldBe Some(testResult)
+      }
     }
-
-    it should "invoke the action from a package attached on trigger fire, creating an activation for each entity including the cause" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val ruleName = withTimestamp("pr1to1")
-            val triggerName = withTimestamp("pt1to1")
-            val pkgName = withTimestamp("rule pkg") // spaces in name intended to test uri path encoding
-            val actionName = withTimestamp("a1 to 1")
-            val pkgActionName = s"$pkgName/$actionName"
-
-            assetHelper.withCleaner(wsk.pkg, pkgName) {
-                (pkg, name) => pkg.create(name)
-            }
-
-            ruleSetup(Seq(
-                (ruleName, triggerName, (pkgActionName, pkgActionName, defaultAction))),
-                assetHelper)
-
-            val now = Instant.now
-            val run = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
-
-            withActivation(wsk.activation, run) {
-                triggerActivation =>
-                    triggerActivation.cause shouldBe None
-
-                    withActivationsFromEntity(wsk.activation, ruleName, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-                        _.head.cause shouldBe Some(triggerActivation.activationId)
-                    }
-
-                    withActivationsFromEntity(wsk.activation, actionName, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-                        _.head.response.result shouldBe Some(testResult)
-                    }
-            }
-    }
-
-    it should "invoke the action from a package binding attached on trigger fire, creating an activation for each entity including the cause" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val ruleName = withTimestamp("pr1to1")
-            val triggerName = withTimestamp("pt1to1")
-            val pkgName = withTimestamp("rule pkg") // spaces in name intended to test uri path encoding
-            val pkgBindingName = withTimestamp("rule pkg binding")
-            val actionName = withTimestamp("a1 to 1")
-            val pkgActionName = s"$pkgName/$actionName"
-
-            assetHelper.withCleaner(wsk.pkg, pkgName) {
-                (pkg, name) => pkg.create(name)
-            }
-
-            assetHelper.withCleaner(wsk.pkg, pkgBindingName) {
-                (pkg, name) => pkg.bind(pkgName, pkgBindingName)
-            }
-
-            ruleSetup(Seq(
-                (ruleName, triggerName, (pkgActionName, s"$pkgBindingName/$actionName", defaultAction))),
-                assetHelper)
-
-            val run = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
-
-            withActivation(wsk.activation, run) {
-                triggerActivation =>
-                    triggerActivation.cause shouldBe None
-
-                    withActivationsFromEntity(wsk.activation, ruleName, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-                        _.head.cause shouldBe Some(triggerActivation.activationId)
-                    }
-
-                    withActivationsFromEntity(wsk.activation, actionName, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-                        _.head.response.result shouldBe Some(testResult)
-                    }
-            }
+  }
+
+  it should "invoke the action from a package binding attached on trigger fire, creating an activation for each entity including the cause" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val ruleName = withTimestamp("pr1to1")
+    val triggerName = withTimestamp("pt1to1")
+    val pkgName = withTimestamp("rule pkg") // spaces in name intended to test uri path encoding
+    val pkgBindingName = withTimestamp("rule pkg binding")
+    val actionName = withTimestamp("a1 to 1")
+    val pkgActionName = s"$pkgName/$actionName"
+
+    assetHelper.withCleaner(wsk.pkg, pkgName) { (pkg, name) =>
+      pkg.create(name)
     }
 
-    it should "not activate an action if the rule is deleted when the trigger is fired" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val ruleName = withTimestamp("ruleDelete")
-            val triggerName = withTimestamp("ruleDeleteTrigger")
-            val actionName = withTimestamp("ruleDeleteAction")
-
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) => trigger.create(name)
-            }
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, name) => action.create(name, Some(defaultAction))
-            }
-            assetHelper.withCleaner(wsk.rule, ruleName, false) {
-                (rule, name) => rule.create(name, triggerName, actionName)
-            }
-
-            val first = wsk.trigger.fire(triggerName, Map("payload" -> "bogus".toJson))
-            wsk.rule.delete(ruleName)
-            wsk.trigger.fire(triggerName, Map("payload" -> "bogus2".toJson))
-
-            withActivation(wsk.activation, first) {
-                activation =>
-                    // tries to find 2 activations for the action, should only find 1
-                    val activations = wsk.activation.pollFor(2, Some(actionName), since = Some(activation.start.minusMillis(activationTimeSkewFactorMs)), retries = 30)
-
-                    activations.length shouldBe 1
-            }
+    assetHelper.withCleaner(wsk.pkg, pkgBindingName) { (pkg, name) =>
+      pkg.bind(pkgName, pkgBindingName)
     }
 
-    it should "enable and disable a rule and check action is activated only when rule is enabled" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val ruleName = withTimestamp("ruleDisable")
-            val triggerName = withTimestamp("ruleDisableTrigger")
-            val actionName = withTimestamp("ruleDisableAction")
-
-            ruleSetup(Seq(
-                (ruleName, triggerName, (actionName, actionName, defaultAction))),
-                assetHelper)
-
-            val first = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
-            wsk.rule.disable(ruleName)
-            wsk.trigger.fire(triggerName, Map("payload" -> s"$testString with added words".toJson))
-            wsk.rule.enable(ruleName)
-            wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
-
-            withActivation(wsk.activation, first) {
-                triggerActivation =>
-                    withActivationsFromEntity(wsk.activation, actionName, N = 2, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-                        activations =>
-                            val results = activations.map(_.response.result)
-                            results should contain theSameElementsAs Seq(Some(testResult), Some(testResult))
-                    }
-            }
-    }
+    ruleSetup(Seq((ruleName, triggerName, (pkgActionName, s"$pkgBindingName/$actionName", defaultAction))), assetHelper)
 
-    it should "be able to recreate a rule with the same name and match it successfully" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val ruleName = withTimestamp("ruleRecreate")
-            val triggerName1 = withTimestamp("ruleRecreateTrigger1")
-            val triggerName2 = withTimestamp("ruleRecreateTrigger2")
-            val actionName = withTimestamp("ruleRecreateAction")
-
-            assetHelper.withCleaner(wsk.trigger, triggerName1) {
-                (trigger, name) => trigger.create(name)
-            }
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, name) => action.create(name, Some(defaultAction))
-            }
-            assetHelper.withCleaner(wsk.rule, ruleName, false) {
-                (rule, name) => rule.create(name, triggerName1, actionName)
-            }
-
-            wsk.rule.delete(ruleName)
-
-            assetHelper.withCleaner(wsk.trigger, triggerName2) {
-                (trigger, name) => trigger.create(name)
-            }
-            assetHelper.withCleaner(wsk.rule, ruleName) {
-                (rule, name) => rule.create(name, triggerName2, actionName)
-            }
-
-            val first = wsk.trigger.fire(triggerName2, Map("payload" -> testString.toJson))
-            withActivation(wsk.activation, first) {
-                triggerActivation =>
-                    withActivationsFromEntity(wsk.activation, actionName, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-                        _.head.response.result shouldBe Some(testResult)
-                    }
-            }
-    }
+    val run = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
 
-    it should "connect two triggers via rules to one action and activate it accordingly" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val triggerName1 = withTimestamp("t2to1a")
-            val triggerName2 = withTimestamp("t2to1b")
-            val actionName = withTimestamp("a2to1")
-
-            ruleSetup(Seq(
-                ("r2to1a", triggerName1, (actionName, actionName, defaultAction)),
-                ("r2to1b", triggerName2, (actionName, actionName, defaultAction))),
-                assetHelper)
-
-            val testPayloads = Seq("got three words", "got four words, period")
-
-            val run = wsk.trigger.fire(triggerName1, Map("payload" -> testPayloads(0).toJson))
-            wsk.trigger.fire(triggerName2, Map("payload" -> testPayloads(1).toJson))
-
-            withActivation(wsk.activation, run) {
-                triggerActivation =>
-                    withActivationsFromEntity(wsk.activation, actionName, N = 2, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-                        activations =>
-                            val results = activations.map(_.response.result)
-                            val expectedResults = testPayloads.map { payload =>
-                                Some(JsObject("count" -> payload.split(" ").length.toJson))
-                            }
-
-                            results should contain theSameElementsAs expectedResults
-                    }
-            }
-    }
+    withActivation(wsk.activation, run) { triggerActivation =>
+      triggerActivation.cause shouldBe None
 
-    it should "connect one trigger to two different actions, invoking them both eventually" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val triggerName = withTimestamp("t1to2")
-            val actionName1 = withTimestamp("a1to2a")
-            val actionName2 = withTimestamp("a1to2b")
-
-            ruleSetup(Seq(
-                ("r1to2a", triggerName, (actionName1, actionName1, defaultAction)),
-                ("r1to2b", triggerName, (actionName2, actionName2, secondAction))),
-                assetHelper)
-
-            val run = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
-
-            withActivation(wsk.activation, run) {
-                triggerActivation =>
-                    withActivationsFromEntity(wsk.activation, actionName1, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-                        _.head.response.result shouldBe Some(testResult)
-                    }
-                    withActivationsFromEntity(wsk.activation, actionName2, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-                        _.head.logs.get.mkString(" ") should include(s"hello, $testString")
-                    }
-            }
-    }
+      withActivationsFromEntity(
+        wsk.activation,
+        ruleName,
+        since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
+        _.head.cause shouldBe Some(triggerActivation.activationId)
+      }
 
-    it should "connect two triggers to two different actions, invoking them both eventually" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val triggerName1 = withTimestamp("t1to1a")
-            val triggerName2 = withTimestamp("t1to1b")
-            val actionName1 = withTimestamp("a1to1a")
-            val actionName2 = withTimestamp("a1to1b")
-
-            ruleSetup(Seq(
-                ("r2to2a", triggerName1, (actionName1, actionName1, defaultAction)),
-                ("r2to2b", triggerName1, (actionName2, actionName2, secondAction)),
-                ("r2to2c", triggerName2, (actionName1, actionName1, defaultAction)),
-                ("r2to2d", triggerName2, (actionName2, actionName2, secondAction))),
-                assetHelper)
-
-            val testPayloads = Seq("got three words", "got four words, period")
-            val run = wsk.trigger.fire(triggerName1, Map("payload" -> testPayloads(0).toJson))
-            wsk.trigger.fire(triggerName2, Map("payload" -> testPayloads(1).toJson))
-
-            withActivation(wsk.activation, run) {
-                triggerActivation =>
-                    withActivationsFromEntity(wsk.activation, actionName1, N = 2, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-                        activations =>
-                            val results = activations.map(_.response.result)
-                            val expectedResults = testPayloads.map { payload =>
-                                Some(JsObject("count" -> payload.split(" ").length.toJson))
-                            }
-
-                            results should contain theSameElementsAs expectedResults
-                    }
-                    withActivationsFromEntity(wsk.activation, actionName2, N = 2, since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-                        activations =>
-                            // drops the leftmost 39 characters (timestamp + streamname)
-                            val logs = activations.map(_.logs.get.map(_.drop(39))).flatten
-                            val expectedLogs = testPayloads.map { payload => s"hello, $payload!" }
-
-                            logs should contain theSameElementsAs expectedLogs
-                    }
-            }
+      withActivationsFromEntity(
+        wsk.activation,
+        actionName,
+        since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
+        _.head.response.result shouldBe Some(testResult)
+      }
     }
-
-    it should "disable a rule and check its status is displayed when listed" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val ruleName = withTimestamp("ruleDisable")
-            val ruleName2 = withTimestamp("ruleEnable")
-            val triggerName = withTimestamp("ruleDisableTrigger")
-            val actionName = withTimestamp("ruleDisableAction")
-
-            ruleSetup(Seq(
-                (ruleName, triggerName, (actionName, actionName, defaultAction)),
-                (ruleName2, triggerName, (actionName, actionName, defaultAction))),
-                assetHelper)
-
-            wsk.rule.disable(ruleName)
-            val listOutput = wsk.rule.list().stdout.lines
-            listOutput.find(_.contains(ruleName2)).get should (include(ruleName2) and include("active"))
-            listOutput.find(_.contains(ruleName)).get should (include(ruleName) and include("inactive"))
-            wsk.rule.list().stdout should not include ("Unknown")
+  }
+
+  it should "not activate an action if the rule is deleted when the trigger is fired" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val ruleName = withTimestamp("ruleDelete")
+      val triggerName = withTimestamp("ruleDeleteTrigger")
+      val actionName = withTimestamp("ruleDeleteAction")
+
+      assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
+        trigger.create(name)
+      }
+      assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+        action.create(name, Some(defaultAction))
+      }
+      assetHelper.withCleaner(wsk.rule, ruleName, false) { (rule, name) =>
+        rule.create(name, triggerName, actionName)
+      }
+
+      val first = wsk.trigger.fire(triggerName, Map("payload" -> "bogus".toJson))
+      wsk.rule.delete(ruleName)
+      wsk.trigger.fire(triggerName, Map("payload" -> "bogus2".toJson))
+
+      withActivation(wsk.activation, first) { activation =>
+        // tries to find 2 activations for the action, should only find 1
+        val activations = wsk.activation.pollFor(
+          2,
+          Some(actionName),
+          since = Some(activation.start.minusMillis(activationTimeSkewFactorMs)),
+          retries = 30)
+
+        activations.length shouldBe 1
+      }
+  }
+
+  it should "enable and disable a rule and check action is activated only when rule is enabled" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val ruleName = withTimestamp("ruleDisable")
+    val triggerName = withTimestamp("ruleDisableTrigger")
+    val actionName = withTimestamp("ruleDisableAction")
+
+    ruleSetup(Seq((ruleName, triggerName, (actionName, actionName, defaultAction))), assetHelper)
+
+    val first = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
+    wsk.rule.disable(ruleName)
+    wsk.trigger.fire(triggerName, Map("payload" -> s"$testString with added words".toJson))
+    wsk.rule.enable(ruleName)
+    wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
+
+    withActivation(wsk.activation, first) { triggerActivation =>
+      withActivationsFromEntity(
+        wsk.activation,
+        actionName,
+        N = 2,
+        since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) { activations =>
+        val results = activations.map(_.response.result)
+        results should contain theSameElementsAs Seq(Some(testResult), Some(testResult))
+      }
     }
+  }
+
+  it should "be able to recreate a rule with the same name and match it successfully" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val ruleName = withTimestamp("ruleRecreate")
+      val triggerName1 = withTimestamp("ruleRecreateTrigger1")
+      val triggerName2 = withTimestamp("ruleRecreateTrigger2")
+      val actionName = withTimestamp("ruleRecreateAction")
+
+      assetHelper.withCleaner(wsk.trigger, triggerName1) { (trigger, name) =>
+        trigger.create(name)
+      }
+      assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+        action.create(name, Some(defaultAction))
+      }
+      assetHelper.withCleaner(wsk.rule, ruleName, false) { (rule, name) =>
+        rule.create(name, triggerName1, actionName)
+      }
+
+      wsk.rule.delete(ruleName)
+
+      assetHelper.withCleaner(wsk.trigger, triggerName2) { (trigger, name) =>
+        trigger.create(name)
+      }
+      assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+        rule.create(name, triggerName2, actionName)
+      }
+
+      val first = wsk.trigger.fire(triggerName2, Map("payload" -> testString.toJson))
+      withActivation(wsk.activation, first) { triggerActivation =>
+        withActivationsFromEntity(
+          wsk.activation,
+          actionName,
+          since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
+          _.head.response.result shouldBe Some(testResult)
+        }
+      }
+  }
+
+  it should "connect two triggers via rules to one action and activate it accordingly" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val triggerName1 = withTimestamp("t2to1a")
+      val triggerName2 = withTimestamp("t2to1b")
+      val actionName = withTimestamp("a2to1")
+
+      ruleSetup(
+        Seq(
+          ("r2to1a", triggerName1, (actionName, actionName, defaultAction)),
+          ("r2to1b", triggerName2, (actionName, actionName, defaultAction))),
+        assetHelper)
+
+      val testPayloads = Seq("got three words", "got four words, period")
+
+      val run = wsk.trigger.fire(triggerName1, Map("payload" -> testPayloads(0).toJson))
+      wsk.trigger.fire(triggerName2, Map("payload" -> testPayloads(1).toJson))
+
+      withActivation(wsk.activation, run) { triggerActivation =>
+        withActivationsFromEntity(
+          wsk.activation,
+          actionName,
+          N = 2,
+          since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) { activations =>
+          val results = activations.map(_.response.result)
+          val expectedResults = testPayloads.map { payload =>
+            Some(JsObject("count" -> payload.split(" ").length.toJson))
+          }
+
+          results should contain theSameElementsAs expectedResults
+        }
+      }
+  }
+
+  it should "connect one trigger to two different actions, invoking them both eventually" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val triggerName = withTimestamp("t1to2")
+      val actionName1 = withTimestamp("a1to2a")
+      val actionName2 = withTimestamp("a1to2b")
+
+      ruleSetup(
+        Seq(
+          ("r1to2a", triggerName, (actionName1, actionName1, defaultAction)),
+          ("r1to2b", triggerName, (actionName2, actionName2, secondAction))),
+        assetHelper)
+
+      val run = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
+
+      withActivation(wsk.activation, run) { triggerActivation =>
+        withActivationsFromEntity(
+          wsk.activation,
+          actionName1,
+          since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
+          _.head.response.result shouldBe Some(testResult)
+        }
+        withActivationsFromEntity(
+          wsk.activation,
+          actionName2,
+          since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
+          _.head.logs.get.mkString(" ") should include(s"hello, $testString")
+        }
+      }
+  }
+
+  it should "connect two triggers to two different actions, invoking them both eventually" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val triggerName1 = withTimestamp("t1to1a")
+      val triggerName2 = withTimestamp("t1to1b")
+      val actionName1 = withTimestamp("a1to1a")
+      val actionName2 = withTimestamp("a1to1b")
+
+      ruleSetup(
+        Seq(
+          ("r2to2a", triggerName1, (actionName1, actionName1, defaultAction)),
+          ("r2to2b", triggerName1, (actionName2, actionName2, secondAction)),
+          ("r2to2c", triggerName2, (actionName1, actionName1, defaultAction)),
+          ("r2to2d", triggerName2, (actionName2, actionName2, secondAction))),
+        assetHelper)
+
+      val testPayloads = Seq("got three words", "got four words, period")
+      val run = wsk.trigger.fire(triggerName1, Map("payload" -> testPayloads(0).toJson))
+      wsk.trigger.fire(triggerName2, Map("payload" -> testPayloads(1).toJson))
+
+      withActivation(wsk.activation, run) { triggerActivation =>
+        withActivationsFromEntity(
+          wsk.activation,
+          actionName1,
+          N = 2,
+          since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) { activations =>
+          val results = activations.map(_.response.result)
+          val expectedResults = testPayloads.map { payload =>
+            Some(JsObject("count" -> payload.split(" ").length.toJson))
+          }
+
+          results should contain theSameElementsAs expectedResults
+        }
+        withActivationsFromEntity(
+          wsk.activation,
+          actionName2,
+          N = 2,
+          since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) { activations =>
+          // drops the leftmost 39 characters (timestamp + streamname)
+          val logs = activations.map(_.logs.get.map(_.drop(39))).flatten
+          val expectedLogs = testPayloads.map { payload =>
+            s"hello, $payload!"
+          }
+
+          logs should contain theSameElementsAs expectedLogs
+        }
+      }
+  }
+
+  it should "disable a rule and check its status is displayed when listed" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val ruleName = withTimestamp("ruleDisable")
+      val ruleName2 = withTimestamp("ruleEnable")
+      val triggerName = withTimestamp("ruleDisableTrigger")
+      val actionName = withTimestamp("ruleDisableAction")
+
+      ruleSetup(
+        Seq(
+          (ruleName, triggerName, (actionName, actionName, defaultAction)),
+          (ruleName2, triggerName, (actionName, actionName, defaultAction))),
+        assetHelper)
+
+      wsk.rule.disable(ruleName)
+      val listOutput = wsk.rule.list().stdout.lines
+      listOutput.find(_.contains(ruleName2)).get should (include(ruleName2) and include("active"))
+      listOutput.find(_.contains(ruleName)).get should (include(ruleName) and include("inactive"))
+      wsk.rule.list().stdout should not include ("Unknown")
+  }
 
 }
diff --git a/tests/src/test/scala/system/basic/WskSdkTests.scala b/tests/src/test/scala/system/basic/WskSdkTests.scala
index ac448b1..62c8d60 100644
--- a/tests/src/test/scala/system/basic/WskSdkTests.scala
+++ b/tests/src/test/scala/system/basic/WskSdkTests.scala
@@ -33,85 +33,83 @@ import common.WskProps
 import common.WskTestHelpers
 
 @RunWith(classOf[JUnitRunner])
-class WskSdkTests
-    extends TestHelpers
-    with WskTestHelpers {
-
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-
-    behavior of "Wsk SDK"
-
-    it should "download docker action sdk" in {
-        val dir = File.createTempFile("wskinstall", ".tmp")
-        dir.delete()
-        dir.mkdir() should be(true)
-        try {
-            wsk.cli(wskprops.overrides ++ Seq("sdk", "install", "docker"), workingDir = dir).
-                stdout should include("The docker skeleton is now installed at the current directory.")
-
-            val sdk = new File(dir, "dockerSkeleton")
-            sdk.exists() should be(true)
-            sdk.isDirectory() should be(true)
-
-            val dockerfile = new File(sdk, "Dockerfile")
-            dockerfile.exists() should be(true)
-            dockerfile.isFile() should be(true)
-            val lines = FileUtils.readLines(dockerfile)
-            // confirm that the image is correct
-            lines.get(1) shouldBe "FROM openwhisk/dockerskeleton"
-
-            val buildAndPushFile = new File(sdk, "buildAndPush.sh")
-            buildAndPushFile.canExecute() should be(true)
-
-            // confirm there is no other divergence from the base dockerfile
-            val originalDockerfile = WhiskProperties.getFileRelativeToWhiskHome("sdk/docker/Dockerfile")
-            val originalLines = FileUtils.readLines(originalDockerfile)
-            lines.get(0) shouldBe originalLines.get(0)
-            lines.drop(2).mkString("\n") shouldBe originalLines.drop(2).mkString("\n")
-        } finally {
-            FileUtils.deleteDirectory(dir)
-        }
+class WskSdkTests extends TestHelpers with WskTestHelpers {
+
+  implicit val wskprops = WskProps()
+  val wsk = new Wsk
+
+  behavior of "Wsk SDK"
+
+  it should "download docker action sdk" in {
+    val dir = File.createTempFile("wskinstall", ".tmp")
+    dir.delete()
+    dir.mkdir() should be(true)
+    try {
+      wsk.cli(wskprops.overrides ++ Seq("sdk", "install", "docker"), workingDir = dir).stdout should include(
+        "The docker skeleton is now installed at the current directory.")
+
+      val sdk = new File(dir, "dockerSkeleton")
+      sdk.exists() should be(true)
+      sdk.isDirectory() should be(true)
+
+      val dockerfile = new File(sdk, "Dockerfile")
+      dockerfile.exists() should be(true)
+      dockerfile.isFile() should be(true)
+      val lines = FileUtils.readLines(dockerfile)
+      // confirm that the image is correct
+      lines.get(1) shouldBe "FROM openwhisk/dockerskeleton"
+
+      val buildAndPushFile = new File(sdk, "buildAndPush.sh")
+      buildAndPushFile.canExecute() should be(true)
+
+      // confirm there is no other divergence from the base dockerfile
+      val originalDockerfile = WhiskProperties.getFileRelativeToWhiskHome("sdk/docker/Dockerfile")
+      val originalLines = FileUtils.readLines(originalDockerfile)
+      lines.get(0) shouldBe originalLines.get(0)
+      lines.drop(2).mkString("\n") shouldBe originalLines.drop(2).mkString("\n")
+    } finally {
+      FileUtils.deleteDirectory(dir)
     }
-
-    it should "download iOS sdk" in {
-        val dir = File.createTempFile("wskinstall", ".tmp")
-        dir.delete()
-        dir.mkdir() should be(true)
-
-        wsk.cli(wskprops.overrides ++ Seq("sdk", "install", "iOS"), workingDir = dir).
-            stdout should include("Downloaded OpenWhisk iOS starter app. Unzip OpenWhiskIOSStarterApp.zip and open the project in Xcode.")
-
-        val sdk = new File(dir, "OpenWhiskIOSStarterApp.zip")
-        sdk.exists() should be(true)
-        sdk.isFile() should be(true)
-        FileUtils.sizeOf(sdk) should be > 20000L
-        FileUtils.deleteDirectory(dir)
+  }
+
+  it should "download iOS sdk" in {
+    val dir = File.createTempFile("wskinstall", ".tmp")
+    dir.delete()
+    dir.mkdir() should be(true)
+
+    wsk.cli(wskprops.overrides ++ Seq("sdk", "install", "iOS"), workingDir = dir).stdout should include(
+      "Downloaded OpenWhisk iOS starter app. Unzip OpenWhiskIOSStarterApp.zip and open the project in Xcode.")
+
+    val sdk = new File(dir, "OpenWhiskIOSStarterApp.zip")
+    sdk.exists() should be(true)
+    sdk.isFile() should be(true)
+    FileUtils.sizeOf(sdk) should be > 20000L
+    FileUtils.deleteDirectory(dir)
+  }
+
+  it should "install the bash auto-completion bash script" in {
+    // Use a temp dir for testing to not disturb user's local folder
+    val dir = File.createTempFile("wskinstall", ".tmp")
+    dir.delete()
+    dir.mkdir() should be(true)
+
+    val scriptfilename = "wsk_cli_bash_completion.sh"
+    var scriptfile = new File(dir.getPath(), scriptfilename)
+    try {
+      val stdout = wsk.cli(Seq("sdk", "install", "bashauto"), workingDir = dir, expectedExitCode = SUCCESS_EXIT).stdout
+      stdout should include("is installed in the current directory")
+      val fileContent = FileUtils.readFileToString(scriptfile)
+      fileContent should include("bash completion for wsk")
+    } finally {
+      scriptfile.delete()
+      FileUtils.deleteDirectory(dir)
     }
+  }
 
-    it should "install the bash auto-completion bash script" in {
-        // Use a temp dir for testing to not disturb user's local folder
-        val dir = File.createTempFile("wskinstall", ".tmp")
-        dir.delete()
-        dir.mkdir() should be(true)
-
-        val scriptfilename = "wsk_cli_bash_completion.sh"
-        var scriptfile = new File(dir.getPath(), scriptfilename)
-        try {
-            val stdout = wsk.cli(Seq("sdk", "install", "bashauto"), workingDir = dir, expectedExitCode = SUCCESS_EXIT).stdout
-            stdout should include("is installed in the current directory")
-            val fileContent = FileUtils.readFileToString(scriptfile)
-            fileContent should include("bash completion for wsk")
-        } finally {
-            scriptfile.delete()
-            FileUtils.deleteDirectory(dir)
-        }
-    }
-
-    it should "print bash command completion script to STDOUT" in {
-        val msg = "bash completion for wsk"    // Subject to change, dependent on Cobra script
+  it should "print bash command completion script to STDOUT" in {
+    val msg = "bash completion for wsk" // Subject to change, dependent on Cobra script
 
-        val stdout = wsk.cli(Seq("sdk", "install", "bashauto", "--stdout")).stdout
-        stdout should include(msg)
-    }
+    val stdout = wsk.cli(Seq("sdk", "install", "bashauto", "--stdout")).stdout
+    stdout should include(msg)
+  }
 }
diff --git a/tests/src/test/scala/system/basic/WskSequenceTests.scala b/tests/src/test/scala/system/basic/WskSequenceTests.scala
index 3a1dbe3..bd5cdc0 100644
--- a/tests/src/test/scala/system/basic/WskSequenceTests.scala
+++ b/tests/src/test/scala/system/basic/WskSequenceTests.scala
@@ -49,481 +49,498 @@ import whisk.http.Messages.sequenceIsTooLong
  */
 
 @RunWith(classOf[JUnitRunner])
-class WskSequenceTests
-    extends TestHelpers
-    with ScalatestRouteTest
-    with WskTestHelpers
-    with StreamLogging {
-
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-    val allowedActionDuration = 120 seconds
-    val shortDuration = 10 seconds
-
-    behavior of "Wsk Sequence"
-
-    it should "invoke a sequence with normal payload and payload with error field" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "sequence"
-            val actions = Seq("split", "sort", "head", "cat")
-            for (actionName <- actions) {
-                val file = TestCLIUtils.getTestActionFilename(s"$actionName.js")
-                assetHelper.withCleaner(wsk.action, actionName) { (action, _) =>
-                    action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration))
-                }
-            }
-
-            println(s"Sequence $actions")
-            assetHelper.withCleaner(wsk.action, name) {
-                val sequence = actions.mkString(",")
-                (action, _) => action.create(name, Some(sequence), kind = Some("sequence"), timeout = Some(allowedActionDuration))
-            }
-
-            val now = "it is now " + new Date()
-            val args = Array("what time is it?", now)
-            val run = wsk.action.invoke(name, Map("payload" -> args.mkString("\n").toJson))
-            withActivation(wsk.activation, run, totalWait = 4 * allowedActionDuration) {
-                activation =>
-                    checkSequenceLogsAndAnnotations(activation, 4) // 4 activations in this sequence
-                    activation.cause shouldBe None // topmost sequence
-                    val result = activation.response.result.get
-                    result.fields.get("payload") shouldBe defined
-                    result.fields.get("length") should not be defined
-                    result.fields.get("lines") shouldBe Some(JsArray(Vector(now.toJson)))
-            }
-
-            // update action sequence and run it with normal payload
-            val newSequence = Seq("split", "sort").mkString(",")
-            println(s"Update sequence to $newSequence")
-            wsk.action.create(name, Some(newSequence), kind = Some("sequence"), timeout = Some(allowedActionDuration), update = true)
-            val secondrun = wsk.action.invoke(name, Map("payload" -> args.mkString("\n").toJson))
-            withActivation(wsk.activation, secondrun, totalWait = 2 * allowedActionDuration) {
-                activation =>
-                    checkSequenceLogsAndAnnotations(activation, 2) // 2 activations in this sequence
-                    val result = activation.response.result.get
-                    result.fields.get("length") shouldBe Some(2.toJson)
-                    result.fields.get("lines") shouldBe Some(args.sortWith(_.compareTo(_) < 0).toArray.toJson)
-            }
-
-            println("Run sequence with error in payload")
-            // run sequence with error in the payload
-            // sequence should run with no problems, error should be ignored in this test case
-            // result of sequence should be identical to previous invocation above
-            val payload = Map("error" -> JsString("irrelevant error string"), "payload" -> args.mkString("\n").toJson)
-            val thirdrun = wsk.action.invoke(name, payload)
-            withActivation(wsk.activation, thirdrun, totalWait = 2 * allowedActionDuration) {
-                activation =>
-                    checkSequenceLogsAndAnnotations(activation, 2) // 2 activations in this sequence
-                    val result = activation.response.result.get
-                    result.fields.get("length") shouldBe Some(2.toJson)
-                    result.fields.get("lines") shouldBe Some(args.sortWith(_.compareTo(_) < 0).toArray.toJson)
-            }
+class WskSequenceTests extends TestHelpers with ScalatestRouteTest with WskTestHelpers with StreamLogging {
+
+  implicit val wskprops = WskProps()
+  val wsk = new Wsk
+  val allowedActionDuration = 120 seconds
+  val shortDuration = 10 seconds
+
+  val whiskConfig = new WhiskConfig(Map(WhiskConfig.actionSequenceMaxLimit -> null))
+  assert(whiskConfig.isValid)
+
+  behavior of "Wsk Sequence"
+
+  it should "invoke a sequence with normal payload and payload with error field" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "sequence"
+      val actions = Seq("split", "sort", "head", "cat")
+      for (actionName <- actions) {
+        val file = TestUtils.getTestActionFilename(s"$actionName.js")
+        assetHelper.withCleaner(wsk.action, actionName) { (action, _) =>
+          action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration))
+        }
+      }
+
+      println(s"Sequence $actions")
+      assetHelper.withCleaner(wsk.action, name) {
+        val sequence = actions.mkString(",")
+        (action, _) =>
+          action.create(name, Some(sequence), kind = Some("sequence"), timeout = Some(allowedActionDuration))
+      }
+
+      val now = "it is now " + new Date()
+      val args = Array("what time is it?", now)
+      val run = wsk.action.invoke(name, Map("payload" -> args.mkString("\n").toJson))
+      withActivation(wsk.activation, run, totalWait = 4 * allowedActionDuration) { activation =>
+        checkSequenceLogsAndAnnotations(activation, 4) // 4 activations in this sequence
+        activation.cause shouldBe None // topmost sequence
+        val result = activation.response.result.get
+        result.fields.get("payload") shouldBe defined
+        result.fields.get("length") should not be defined
+        result.fields.get("lines") shouldBe Some(JsArray(Vector(now.toJson)))
+      }
+
+      // update action sequence and run it with normal payload
+      val newSequence = Seq("split", "sort").mkString(",")
+      println(s"Update sequence to $newSequence")
+      wsk.action.create(
+        name,
+        Some(newSequence),
+        kind = Some("sequence"),
+        timeout = Some(allowedActionDuration),
+        update = true)
+      val secondrun = wsk.action.invoke(name, Map("payload" -> args.mkString("\n").toJson))
+      withActivation(wsk.activation, secondrun, totalWait = 2 * allowedActionDuration) { activation =>
+        checkSequenceLogsAndAnnotations(activation, 2) // 2 activations in this sequence
+        val result = activation.response.result.get
+        result.fields.get("length") shouldBe Some(2.toJson)
+        result.fields.get("lines") shouldBe Some(args.sortWith(_.compareTo(_) < 0).toArray.toJson)
+      }
+
+      println("Run sequence with error in payload")
+      // run sequence with error in the payload
+      // sequence should run with no problems, error should be ignored in this test case
+      // result of sequence should be identical to previous invocation above
+      val payload = Map("error" -> JsString("irrelevant error string"), "payload" -> args.mkString("\n").toJson)
+      val thirdrun = wsk.action.invoke(name, payload)
+      withActivation(wsk.activation, thirdrun, totalWait = 2 * allowedActionDuration) { activation =>
+        checkSequenceLogsAndAnnotations(activation, 2) // 2 activations in this sequence
+        val result = activation.response.result.get
+        result.fields.get("length") shouldBe Some(2.toJson)
+        result.fields.get("lines") shouldBe Some(args.sortWith(_.compareTo(_) < 0).toArray.toJson)
+      }
+  }
+
+  it should "invoke a sequence with an enclosing sequence action" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val inner_name = "inner_sequence"
+    val outer_name = "outer_sequence"
+    val inner_actions = Seq("sort", "head")
+    val actions = Seq("split") ++ inner_actions ++ Seq("cat")
+    // create atomic actions
+    for (actionName <- actions) {
+      val file = TestUtils.getTestActionFilename(s"$actionName.js")
+      assetHelper.withCleaner(wsk.action, actionName) { (action, _) =>
+        action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration))
+      }
     }
 
-    it should "invoke a sequence with an enclosing sequence action" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val inner_name = "inner_sequence"
-            val outer_name = "outer_sequence"
-            val inner_actions = Seq("sort", "head")
-            val actions = Seq("split") ++ inner_actions ++ Seq("cat")
-            // create atomic actions
-            for (actionName <- actions) {
-                val file = TestCLIUtils.getTestActionFilename(s"$actionName.js")
-                assetHelper.withCleaner(wsk.action, actionName) { (action, _) =>
-                    action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration))
-                }
-            }
-
-            // create inner sequence
-            assetHelper.withCleaner(wsk.action, inner_name) {
-                val inner_sequence = inner_actions.mkString(",")
-                (action, _) => action.create(inner_name, Some(inner_sequence), kind = Some("sequence"))
-            }
-
-            // create outer sequence
-            assetHelper.withCleaner(wsk.action, outer_name) {
-                val outer_sequence = Seq("split", "inner_sequence", "cat").mkString(",")
-                (action, _) => action.create(outer_name, Some(outer_sequence), kind = Some("sequence"))
-            }
-
-            val now = "it is now " + new Date()
-            val args = Array("what time is it?", now)
-            val run = wsk.action.invoke(outer_name, Map("payload" -> args.mkString("\n").toJson))
-            withActivation(wsk.activation, run, totalWait = 4 * allowedActionDuration) {
-                activation =>
-                    checkSequenceLogsAndAnnotations(activation, 3) // 3 activations in this sequence
-                    activation.cause shouldBe None // topmost sequence
-                    val result = activation.response.result.get
-                    result.fields.get("payload") shouldBe defined
-                    result.fields.get("length") should not be defined
-                    result.fields.get("lines") shouldBe Some(JsArray(Vector(now.toJson)))
-            }
+    // create inner sequence
+    assetHelper.withCleaner(wsk.action, inner_name) {
+      val inner_sequence = inner_actions.mkString(",")
+      (action, _) =>
+        action.create(inner_name, Some(inner_sequence), kind = Some("sequence"))
     }
 
-    /**
-     * s -> echo, x, echo
-     * x -> echo
-     *
-     * update x -> <limit-1> echo -- should work
-     * run s -> should stop after <limit> echo
-     *
-     * This confirms that a dynamic check on the sequence length holds within the system limit.
-     * This is different from creating a long sequence up front which will report a length error at create time.
-     */
-    it should "replace atomic component in a sequence that is too long and report invoke error" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val xName = "xSequence"
-            val sName = "sSequence"
-            val echo = "echo"
-
-            // create echo action
-            val file = TestCLIUtils.getTestActionFilename(s"$echo.js")
-            assetHelper.withCleaner(wsk.action, echo) { (action, actionName) =>
-                action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration))
-            }
-            // create x
-            assetHelper.withCleaner(wsk.action, xName) {
-                (action, seqName) => action.create(seqName, Some(echo), kind = Some("sequence"))
-            }
-            // create s
-            assetHelper.withCleaner(wsk.action, sName) {
-                (action, seqName) => action.create(seqName, Some(s"$echo,$xName,$echo"), kind = Some("sequence"))
-            }
-
-            // invoke s
-            val now = "it is now " + new Date()
-            val args = Array("what time is it?", now)
-            val argsJson = args.mkString("\n").toJson
-            val run = wsk.action.invoke(sName, Map("payload" -> argsJson))
-            println(s"RUN: ${run.stdout}")
-            withActivation(wsk.activation, run, totalWait = 2 * allowedActionDuration) {
-                activation =>
-                    checkSequenceLogsAndAnnotations(activation, 3) // 3 activations in this sequence
-                    val result = activation.response.result.get
-                    result.fields.get("payload") shouldBe Some(argsJson)
-            }
-            // update x with limit echo
-            val limit = WhiskProperties.getProperty("defaultLimits.actions.sequence.maxLength").toInt
-            val manyEcho = for (i <- 1 to limit) yield echo
-
-            wsk.action.create(xName, Some(manyEcho.mkString(",")), kind = Some("sequence"), update = true)
-
-            val updateRun = wsk.action.invoke(sName, Map("payload" -> argsJson))
-            withActivation(wsk.activation, updateRun, totalWait = 2 * allowedActionDuration) {
-                activation =>
-                    activation.response.status shouldBe ("application error")
-                    checkSequenceLogsAndAnnotations(activation, 2)
-                    val result = activation.response.result.get
-                    result.fields.get("error") shouldBe Some(JsString(sequenceIsTooLong))
-                    // check that inner sequence had only (limit - 1) activations
-                    val innerSeq = activation.logs.get(1) // the id of the inner sequence activation
-                    val getInnerSeq = wsk.activation.get(Some(innerSeq))
-                    withActivation(wsk.activation, getInnerSeq, totalWait = allowedActionDuration) {
-                        innerSeqActivation =>
-                            innerSeqActivation.logs.get.size shouldBe (limit - 1)
-                            innerSeqActivation.cause shouldBe Some(activation.activationId)
-                    }
-            }
+    // create outer sequence
+    assetHelper.withCleaner(wsk.action, outer_name) {
+      val outer_sequence = Seq("split", "inner_sequence", "cat").mkString(",")
+      (action, _) =>
+        action.create(outer_name, Some(outer_sequence), kind = Some("sequence"))
     }
 
-    it should "create and run a sequence in a package with parameters" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val sName = "sSequence"
-
-            // create a package
-            val pkgName = "echopackage"
-            val pkgStr = "LonelyPackage"
-            assetHelper.withCleaner(wsk.pkg, pkgName) {
-                (pkg, name) => pkg.create(name, Map("payload" -> JsString(pkgStr)))
-            }
-            val helloName = "hello"
-            val helloWithPkg = s"$pkgName/$helloName"
-
-            // create hello action in package
-            val file = TestCLIUtils.getTestActionFilename(s"$helloName.js")
-            val actionStr = "AtomicAction"
-            assetHelper.withCleaner(wsk.action, helloWithPkg) { (action, actionName) =>
-                action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration), parameters = Map("payload" -> JsString(actionStr)))
-            }
-            // create s
-            assetHelper.withCleaner(wsk.action, sName) {
-                (action, seqName) => action.create(seqName, Some(helloWithPkg), kind = Some("sequence"))
-            }
-            val run = wsk.action.invoke(sName)
-            // action params trump package params
-            checkLogsAtomicAction(0, run, new Regex(actionStr))
-            // run with some parameters
-            val sequenceStr = "AlmightySequence"
-            val sequenceParamRun = wsk.action.invoke(sName, parameters = Map("payload" -> JsString(sequenceStr)))
-            // sequence param should be passed to the first atomic action and trump the action params
-            checkLogsAtomicAction(0, sequenceParamRun, new Regex(sequenceStr))
-            // update action and remove the params by sending an unused param that overrides previous params
-            wsk.action.create(name = helloWithPkg, artifact = Some(file), timeout = Some(allowedActionDuration), parameters = Map("param" -> JsString("irrelevant")), update = true)
-            val sequenceParamSecondRun = wsk.action.invoke(sName, parameters = Map("payload" -> JsString(sequenceStr)))
-            // sequence param should be passed to the first atomic action and trump the package params
-            checkLogsAtomicAction(0, sequenceParamSecondRun, new Regex(sequenceStr))
-            val pkgParamRun = wsk.action.invoke(sName)
-            // no sequence params, no atomic action params used, the pkg params should show up
-            checkLogsAtomicAction(0, pkgParamRun, new Regex(pkgStr))
+    val now = "it is now " + new Date()
+    val args = Array("what time is it?", now)
+    val run = wsk.action.invoke(outer_name, Map("payload" -> args.mkString("\n").toJson))
+    withActivation(wsk.activation, run, totalWait = 4 * allowedActionDuration) { activation =>
+      checkSequenceLogsAndAnnotations(activation, 3) // 3 activations in this sequence
+      activation.cause shouldBe None // topmost sequence
+      val result = activation.response.result.get
+      result.fields.get("payload") shouldBe defined
+      result.fields.get("length") should not be defined
+      result.fields.get("lines") shouldBe Some(JsArray(Vector(now.toJson)))
     }
-
-    it should "run a sequence with an action in a package binding with parameters" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val packageName = "package1"
-            val bindName = "package2"
-            val actionName = "print"
-            val packageActionName = packageName + "/" + actionName
-            val bindActionName = bindName + "/" + actionName
-            val packageParams = Map("key1a" -> "value1a".toJson, "key1b" -> "value1b".toJson)
-            val bindParams = Map("key2a" -> "value2a".toJson, "key1b" -> "value2b".toJson)
-            val actionParams = Map("key0" -> "value0".toJson)
-            val file = TestCLIUtils.getTestActionFilename("printParams.js")
-            assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
-                pkg.create(packageName, packageParams)
-            }
-            assetHelper.withCleaner(wsk.action, packageActionName) { (action, _) =>
-                action.create(packageActionName, Some(file), parameters = actionParams)
-            }
-            assetHelper.withCleaner(wsk.pkg, bindName) { (pkg, _) =>
-                pkg.bind(packageName, bindName, bindParams)
-            }
-            // sequence
-            val sName = "sequenceWithBindingParams"
-            assetHelper.withCleaner(wsk.action, sName) {
-                (action, seqName) => action.create(seqName, Some(bindActionName), kind = Some("sequence"))
-            }
-            // Check that inherited parameters are passed to the action.
-            val now = new Date().toString()
-            val run = wsk.action.invoke(sName, Map("payload" -> now.toJson))
-            // action params trump package params
-            checkLogsAtomicAction(0, run, new Regex(String.format(".*key0: value0.*key1a: value1a.*key1b: value2b.*key2a: value2a.*payload: %s", now)))
+  }
+
+  /**
+   * s -> echo, x, echo
+   * x -> echo
+   *
+   * update x -> <limit-1> echo -- should work
+   * run s -> should stop after <limit> echo
+   *
+   * This confirms that a dynamic check on the sequence length holds within the system limit.
+   * This is different from creating a long sequence up front which will report a length error at create time.
+   */
+  it should "replace atomic component in a sequence that is too long and report invoke error" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val xName = "xSequence"
+    val sName = "sSequence"
+    val echo = "echo"
+
+    // create echo action
+    val file = TestUtils.getTestActionFilename(s"$echo.js")
+    assetHelper.withCleaner(wsk.action, echo) { (action, actionName) =>
+      action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration))
     }
-
-    /**
-     * s -> apperror, echo
-     * only apperror should run
-     */
-    it should "stop execution of a sequence (with no payload) on error" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val sName = "sSequence"
-            val apperror = "applicationError"
-            val echo = "echo"
-
-            // create actions
-            val actions = Seq(apperror, echo)
-            for (actionName <- actions) {
-                val file = TestCLIUtils.getTestActionFilename(s"$actionName.js")
-                assetHelper.withCleaner(wsk.action, actionName) { (action, actionName) =>
-                    action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration))
-                }
-            }
-            // create sequence s
-            assetHelper.withCleaner(wsk.action, sName) {
-                (action, seqName) => action.create(seqName, artifact = Some(actions.mkString(",")), kind = Some("sequence"))
-            }
-            // run sequence s with no payload
-            val run = wsk.action.invoke(sName)
-            withActivation(wsk.activation, run, totalWait = 2 * allowedActionDuration) {
-                activation =>
-                    checkSequenceLogsAndAnnotations(activation, 1) // only the first action should have run
-                    activation.response.success shouldBe (false)
-                    // the status should be error
-                    activation.response.status shouldBe ("application error")
-                    val result = activation.response.result.get
-                    // the result of the activation should be the application error
-                    result shouldBe (JsObject("error" -> JsString("This error thrown on purpose by the action.")))
-            }
+    // create x
+    assetHelper.withCleaner(wsk.action, xName) { (action, seqName) =>
+      action.create(seqName, Some(echo), kind = Some("sequence"))
     }
-
-    /**
-     * s -> echo, initforever
-     * should run both, but error
-     */
-    it should "propagate execution error (timeout) from atomic action to sequence" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val sName = "sSequence"
-            val initforever = "initforever"
-            val echo = "echo"
-
-            // create actions
-            val actions = Seq(echo, initforever)
-            // timeouts for the action; make the one for initforever short
-            val timeout = Map(echo -> allowedActionDuration, initforever -> shortDuration)
-            for (actionName <- actions) {
-                val file = TestCLIUtils.getTestActionFilename(s"$actionName.js")
-                assetHelper.withCleaner(wsk.action, actionName) { (action, actionName) =>
-                    action.create(name = actionName, artifact = Some(file), timeout = Some(timeout(actionName)))
-                }
-            }
-            // create sequence s
-            assetHelper.withCleaner(wsk.action, sName) {
-                (action, seqName) => action.create(seqName, artifact = Some(actions.mkString(",")), kind = Some("sequence"))
-            }
-            // run sequence s with no payload
-            val run = wsk.action.invoke(sName)
-            withActivation(wsk.activation, run, totalWait = 2 * allowedActionDuration) {
-                activation =>
-                    checkSequenceLogsAndAnnotations(activation, 2) // 2 actions
-                    activation.response.success shouldBe (false)
-                    // the status should be error
-                    //activation.response.status shouldBe("application error")
-                    val result = activation.response.result.get
-                    // the result of the activation should be timeout
-                    result shouldBe (JsObject("error" -> JsString("The action exceeded its time limits of 10000 milliseconds during initialization.")))
-            }
+    // create s
+    assetHelper.withCleaner(wsk.action, sName) { (action, seqName) =>
+      action.create(seqName, Some(s"$echo,$xName,$echo"), kind = Some("sequence"))
     }
 
-    /**
-     * s -> echo, sleep
-     * sleep sleeps for 90s, timeout set at 120s
-     * should run both, the blocking call should be transformed into a non-blocking call, but finish executing
-     */
-    it should "execute a sequence in blocking fashion and finish execution even if longer than blocking response timeout" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val sName = "sSequence"
-            val sleep = "timeout"
-            val echo = "echo"
-
-            // create actions
-            val actions = Seq(echo, sleep)
-            for (actionName <- actions) {
-                val file = TestCLIUtils.getTestActionFilename(s"$actionName.js")
-                assetHelper.withCleaner(wsk.action, actionName) { (action, actionName) =>
-                    action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration))
-                }
-            }
-            // create sequence s
-            assetHelper.withCleaner(wsk.action, sName) {
-                (action, seqName) => action.create(seqName, artifact = Some(actions.mkString(",")), kind = Some("sequence"))
-            }
-            // run sequence s with sleep equal to payload
-            val payload = 65000
-            val run = wsk.action.invoke(sName, parameters = Map("payload" -> JsNumber(payload)), blocking = true, expectedExitCode = ACCEPTED)
-            withActivation(wsk.activation, run, initialWait = 5 seconds, totalWait = 3 * allowedActionDuration) {
-                activation =>
-                    checkSequenceLogsAndAnnotations(activation, 2) // 2 actions
-                    activation.response.success shouldBe (true)
-                    // the status should be error
-                    //activation.response.status shouldBe("application error")
-                    val result = activation.response.result.get
-                    // the result of the activation should be timeout
-                    result shouldBe (JsObject("msg" -> JsString(s"[OK] message terminated successfully after $payload milliseconds.")))
-            }
+    // invoke s
+    val now = "it is now " + new Date()
+    val args = Array("what time is it?", now)
+    val argsJson = args.mkString("\n").toJson
+    val run = wsk.action.invoke(sName, Map("payload" -> argsJson))
+    println(s"RUN: ${run.stdout}")
+    withActivation(wsk.activation, run, totalWait = 2 * allowedActionDuration) { activation =>
+      checkSequenceLogsAndAnnotations(activation, 3) // 3 activations in this sequence
+      val result = activation.response.result.get
+      result.fields.get("payload") shouldBe Some(argsJson)
     }
-
-    /**
-     * sequence s -> echo
-     * t trigger with payload
-     * rule r: t -> s
-     */
-    it should "execute a sequence that is part of a rule and pass the trigger parameters to the sequence" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val seqName = "seqRule"
-            val actionName = "echo"
-            val triggerName = "trigSeq"
-            val ruleName = "ruleSeq"
-
-            val itIsNow = "it is now " + new Date()
-            // set up all entities
-            // trigger
-            val triggerPayload: Map[String, JsValue] = Map("payload" -> JsString(itIsNow))
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) => trigger.create(name, parameters = triggerPayload)
-            }
-            // action
-            val file = TestCLIUtils.getTestActionFilename(s"$actionName.js")
-            assetHelper.withCleaner(wsk.action, actionName) { (action, actionName) =>
-                action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration))
-            }
-            // sequence
-            assetHelper.withCleaner(wsk.action, seqName) {
-                (action, seqName) => action.create(seqName, artifact = Some(actionName), kind = Some("sequence"))
-            }
-            // rule
-            assetHelper.withCleaner(wsk.rule, ruleName) {
-                (rule, name) => rule.create(name, triggerName, seqName)
-            }
-            // fire trigger
-            val run = wsk.trigger.fire(triggerName)
-            // check that the sequence was invoked and that the echo action produced the expected result
-            checkEchoSeqRuleResult(run, seqName, JsObject(triggerPayload))
-            // fire trigger with new payload
-            val now = "this is now: " + Instant.now
-            val newPayload = Map("payload" -> JsString(now))
-            val newRun = wsk.trigger.fire(triggerName, newPayload)
-            checkEchoSeqRuleResult(newRun, seqName, JsObject(newPayload))
+    // update x with limit echo
+    val limit = whiskConfig.actionSequenceLimit.toInt
+    val manyEcho = for (i <- 1 to limit) yield echo
+
+    wsk.action.create(xName, Some(manyEcho.mkString(",")), kind = Some("sequence"), update = true)
+
+    val updateRun = wsk.action.invoke(sName, Map("payload" -> argsJson))
+    withActivation(wsk.activation, updateRun, totalWait = 2 * allowedActionDuration) { activation =>
+      activation.response.status shouldBe ("application error")
+      checkSequenceLogsAndAnnotations(activation, 2)
+      val result = activation.response.result.get
+      result.fields.get("error") shouldBe Some(JsString(sequenceIsTooLong))
+      // check that inner sequence had only (limit - 1) activations
+      val innerSeq = activation.logs.get(1) // the id of the inner sequence activation
+      val getInnerSeq = wsk.activation.get(Some(innerSeq))
+      withActivation(wsk.activation, getInnerSeq, totalWait = allowedActionDuration) { innerSeqActivation =>
+        innerSeqActivation.logs.get.size shouldBe (limit - 1)
+        innerSeqActivation.cause shouldBe Some(activation.activationId)
+      }
     }
-
-    /**
-     * checks the result of an echo sequence connected to a trigger through a rule
-     * @param triggerFireRun the run result of firing the trigger
-     * @param seqName the sequence name
-     * @param triggerPayload the payload used for the trigger (that should be reflected in the sequence result)
-     */
-    private def checkEchoSeqRuleResult(triggerFireRun: RunResult, seqName: String, triggerPayload: JsObject) = {
-        withActivation(wsk.activation, triggerFireRun) {
-            triggerActivation =>
-                withActivationsFromEntity(wsk.activation, seqName, since = Some(triggerActivation.start)) { activationList =>
-                    activationList.head.response.result shouldBe Some(triggerPayload)
-                    activationList.head.cause shouldBe None
-                }
+  }
+
+  it should "create and run a sequence in a package with parameters" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val sName = "sSequence"
+
+      // create a package
+      val pkgName = "echopackage"
+      val pkgStr = "LonelyPackage"
+      assetHelper.withCleaner(wsk.pkg, pkgName) { (pkg, name) =>
+        pkg.create(name, Map("payload" -> JsString(pkgStr)))
+      }
+      val helloName = "hello"
+      val helloWithPkg = s"$pkgName/$helloName"
+
+      // create hello action in package
+      val file = TestUtils.getTestActionFilename(s"$helloName.js")
+      val actionStr = "AtomicAction"
+      assetHelper.withCleaner(wsk.action, helloWithPkg) { (action, actionName) =>
+        action.create(
+          name = actionName,
+          artifact = Some(file),
+          timeout = Some(allowedActionDuration),
+          parameters = Map("payload" -> JsString(actionStr)))
+      }
+      // create s
+      assetHelper.withCleaner(wsk.action, sName) { (action, seqName) =>
+        action.create(seqName, Some(helloWithPkg), kind = Some("sequence"))
+      }
+      val run = wsk.action.invoke(sName)
+      // action params trump package params
+      checkLogsAtomicAction(0, run, new Regex(actionStr))
+      // run with some parameters
+      val sequenceStr = "AlmightySequence"
+      val sequenceParamRun = wsk.action.invoke(sName, parameters = Map("payload" -> JsString(sequenceStr)))
+      // sequence param should be passed to the first atomic action and trump the action params
+      checkLogsAtomicAction(0, sequenceParamRun, new Regex(sequenceStr))
+      // update action and remove the params by sending an unused param that overrides previous params
+      wsk.action.create(
+        name = helloWithPkg,
+        artifact = Some(file),
+        timeout = Some(allowedActionDuration),
+        parameters = Map("param" -> JsString("irrelevant")),
+        update = true)
+      val sequenceParamSecondRun = wsk.action.invoke(sName, parameters = Map("payload" -> JsString(sequenceStr)))
+      // sequence param should be passed to the first atomic action and trump the package params
+      checkLogsAtomicAction(0, sequenceParamSecondRun, new Regex(sequenceStr))
+      val pkgParamRun = wsk.action.invoke(sName)
+      // no sequence params, no atomic action params used, the pkg params should show up
+      checkLogsAtomicAction(0, pkgParamRun, new Regex(pkgStr))
+  }
+
+  it should "run a sequence with an action in a package binding with parameters" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val packageName = "package1"
+      val bindName = "package2"
+      val actionName = "print"
+      val packageActionName = packageName + "/" + actionName
+      val bindActionName = bindName + "/" + actionName
+      val packageParams = Map("key1a" -> "value1a".toJson, "key1b" -> "value1b".toJson)
+      val bindParams = Map("key2a" -> "value2a".toJson, "key1b" -> "value2b".toJson)
+      val actionParams = Map("key0" -> "value0".toJson)
+      val file = TestUtils.getTestActionFilename("printParams.js")
+      assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
+        pkg.create(packageName, packageParams)
+      }
+      assetHelper.withCleaner(wsk.action, packageActionName) { (action, _) =>
+        action.create(packageActionName, Some(file), parameters = actionParams)
+      }
+      assetHelper.withCleaner(wsk.pkg, bindName) { (pkg, _) =>
+        pkg.bind(packageName, bindName, bindParams)
+      }
+      // sequence
+      val sName = "sequenceWithBindingParams"
+      assetHelper.withCleaner(wsk.action, sName) { (action, seqName) =>
+        action.create(seqName, Some(bindActionName), kind = Some("sequence"))
+      }
+      // Check that inherited parameters are passed to the action.
+      val now = new Date().toString()
+      val run = wsk.action.invoke(sName, Map("payload" -> now.toJson))
+      // action params trump package params
+      checkLogsAtomicAction(
+        0,
+        run,
+        new Regex(String.format(".*key0: value0.*key1a: value1a.*key1b: value2b.*key2a: value2a.*payload: %s", now)))
+  }
+
+  /**
+   * s -> apperror, echo
+   * only apperror should run
+   */
+  it should "stop execution of a sequence (with no payload) on error" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val sName = "sSequence"
+      val apperror = "applicationError"
+      val echo = "echo"
+
+      // create actions
+      val actions = Seq(apperror, echo)
+      for (actionName <- actions) {
+        val file = TestUtils.getTestActionFilename(s"$actionName.js")
+        assetHelper.withCleaner(wsk.action, actionName) { (action, actionName) =>
+          action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration))
         }
-    }
-
-    /**
-     * checks logs for the activation of a sequence (length/size and ids)
-     * checks that the cause field for composing atomic actions is set properly
-     * checks duration
-     * checks memory
-     */
-    private def checkSequenceLogsAndAnnotations(activation: ActivationResult, size: Int) = {
-        activation.logs shouldBe defined
-        // check that the logs are what they are supposed to be (activation ids)
-        // check that the cause field is properly set for these activations
-        activation.logs.get.size shouldBe (size) // the number of activations in this sequence
-        var totalTime: Long = 0
-        var maxMemory: Long = 0
-        for (id <- activation.logs.get) {
-            withActivation(wsk.activation, id, initialWait = 1 second, pollPeriod = 60 seconds, totalWait = allowedActionDuration) {
-                componentActivation =>
-                    componentActivation.cause shouldBe defined
-                    componentActivation.cause.get shouldBe (activation.activationId)
-                    // check causedBy
-                    val causedBy = componentActivation.getAnnotationValue("causedBy")
-                    causedBy shouldBe defined
-                    causedBy.get shouldBe (JsString("sequence"))
-                    totalTime += componentActivation.duration
-                    // extract memory
-                    val mem = extractMemoryAnnotation(componentActivation)
-                    maxMemory = maxMemory max mem
-            }
+      }
+      // create sequence s
+      assetHelper.withCleaner(wsk.action, sName) { (action, seqName) =>
+        action.create(seqName, artifact = Some(actions.mkString(",")), kind = Some("sequence"))
+      }
+      // run sequence s with no payload
+      val run = wsk.action.invoke(sName)
+      withActivation(wsk.activation, run, totalWait = 2 * allowedActionDuration) { activation =>
+        checkSequenceLogsAndAnnotations(activation, 1) // only the first action should have run
+        activation.response.success shouldBe (false)
+        // the status should be error
+        activation.response.status shouldBe ("application error")
+        val result = activation.response.result.get
+        // the result of the activation should be the application error
+        result shouldBe (JsObject("error" -> JsString("This error thrown on purpose by the action.")))
+      }
+  }
+
+  /**
+   * s -> echo, initforever
+   * should run both, but error
+   */
+  it should "propagate execution error (timeout) from atomic action to sequence" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val sName = "sSequence"
+      val initforever = "initforever"
+      val echo = "echo"
+
+      // create actions
+      val actions = Seq(echo, initforever)
+      // timeouts for the action; make the one for initforever short
+      val timeout = Map(echo -> allowedActionDuration, initforever -> shortDuration)
+      for (actionName <- actions) {
+        val file = TestUtils.getTestActionFilename(s"$actionName.js")
+        assetHelper.withCleaner(wsk.action, actionName) { (action, actionName) =>
+          action.create(name = actionName, artifact = Some(file), timeout = Some(timeout(actionName)))
         }
-        // extract duration
-        activation.duration shouldBe (totalTime)
+      }
+      // create sequence s
+      assetHelper.withCleaner(wsk.action, sName) { (action, seqName) =>
+        action.create(seqName, artifact = Some(actions.mkString(",")), kind = Some("sequence"))
+      }
+      // run sequence s with no payload
+      val run = wsk.action.invoke(sName)
+      withActivation(wsk.activation, run, totalWait = 2 * allowedActionDuration) { activation =>
+        checkSequenceLogsAndAnnotations(activation, 2) // 2 actions
+        activation.response.success shouldBe (false)
+        // the status should be error
+        //activation.response.status shouldBe("application error")
+        val result = activation.response.result.get
+        // the result of the activation should be timeout
+        result shouldBe (JsObject(
+          "error" -> JsString("The action exceeded its time limits of 10000 milliseconds during initialization.")))
+      }
+  }
+
+  /**
+   * s -> echo, sleep
+   * sleep sleeps for 90s, timeout set at 120s
+   * should run both, the blocking call should be transformed into a non-blocking call, but finish executing
+   */
+  it should "execute a sequence in blocking fashion and finish execution even if longer than blocking response timeout" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val sName = "sSequence"
+    val sleep = "timeout"
+    val echo = "echo"
+
+    // create actions
+    val actions = Seq(echo, sleep)
+    for (actionName <- actions) {
+      val file = TestUtils.getTestActionFilename(s"$actionName.js")
+      assetHelper.withCleaner(wsk.action, actionName) { (action, actionName) =>
+        action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration))
+      }
+    }
+    // create sequence s
+    assetHelper.withCleaner(wsk.action, sName) { (action, seqName) =>
+      action.create(seqName, artifact = Some(actions.mkString(",")), kind = Some("sequence"))
+    }
+    // run sequence s with sleep equal to payload
+    val payload = 65000
+    val run = wsk.action.invoke(
+      sName,
+      parameters = Map("payload" -> JsNumber(payload)),
+      blocking = true,
+      expectedExitCode = ACCEPTED)
+    withActivation(wsk.activation, run, initialWait = 5 seconds, totalWait = 3 * allowedActionDuration) { activation =>
+      checkSequenceLogsAndAnnotations(activation, 2) // 2 actions
+      activation.response.success shouldBe (true)
+      // the status should be error
+      //activation.response.status shouldBe("application error")
+      val result = activation.response.result.get
+      // the result of the activation should be timeout
+      result shouldBe (JsObject(
+        "msg" -> JsString(s"[OK] message terminated successfully after $payload milliseconds.")))
+    }
+  }
+
+  /**
+   * sequence s -> echo
+   * t trigger with payload
+   * rule r: t -> s
+   */
+  it should "execute a sequence that is part of a rule and pass the trigger parameters to the sequence" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val seqName = "seqRule"
+    val actionName = "echo"
+    val triggerName = "trigSeq"
+    val ruleName = "ruleSeq"
+
+    val itIsNow = "it is now " + new Date()
+    // set up all entities
+    // trigger
+    val triggerPayload: Map[String, JsValue] = Map("payload" -> JsString(itIsNow))
+    assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
+      trigger.create(name, parameters = triggerPayload)
+    }
+    // action
+    val file = TestUtils.getTestActionFilename(s"$actionName.js")
+    assetHelper.withCleaner(wsk.action, actionName) { (action, actionName) =>
+      action.create(name = actionName, artifact = Some(file), timeout = Some(allowedActionDuration))
+    }
+    // sequence
+    assetHelper.withCleaner(wsk.action, seqName) { (action, seqName) =>
+      action.create(seqName, artifact = Some(actionName), kind = Some("sequence"))
+    }
+    // rule
+    assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+      rule.create(name, triggerName, seqName)
+    }
+    // fire trigger
+    val run = wsk.trigger.fire(triggerName)
+    // check that the sequence was invoked and that the echo action produced the expected result
+    checkEchoSeqRuleResult(run, seqName, JsObject(triggerPayload))
+    // fire trigger with new payload
+    val now = "this is now: " + Instant.now
+    val newPayload = Map("payload" -> JsString(now))
+    val newRun = wsk.trigger.fire(triggerName, newPayload)
+    checkEchoSeqRuleResult(newRun, seqName, JsObject(newPayload))
+  }
+
+  /**
+   * checks the result of an echo sequence connected to a trigger through a rule
+   * @param triggerFireRun the run result of firing the trigger
+   * @param seqName the sequence name
+   * @param triggerPayload the payload used for the trigger (that should be reflected in the sequence result)
+   */
+  private def checkEchoSeqRuleResult(triggerFireRun: RunResult, seqName: String, triggerPayload: JsObject) = {
+    withActivation(wsk.activation, triggerFireRun) { triggerActivation =>
+      withActivationsFromEntity(wsk.activation, seqName, since = Some(triggerActivation.start)) { activationList =>
+        activationList.head.response.result shouldBe Some(triggerPayload)
+        activationList.head.cause shouldBe None
+      }
+    }
+  }
+
+  /**
+   * checks logs for the activation of a sequence (length/size and ids)
+   * checks that the cause field for composing atomic actions is set properly
+   * checks duration
+   * checks memory
+   */
+  private def checkSequenceLogsAndAnnotations(activation: ActivationResult, size: Int) = {
+    activation.logs shouldBe defined
+    // check that the logs are what they are supposed to be (activation ids)
+    // check that the cause field is properly set for these activations
+    activation.logs.get.size shouldBe (size) // the number of activations in this sequence
+    var totalTime: Long = 0
+    var maxMemory: Long = 0
+    for (id <- activation.logs.get) {
+      withActivation(
+        wsk.activation,
+        id,
+        initialWait = 1 second,
+        pollPeriod = 60 seconds,
+        totalWait = allowedActionDuration) { componentActivation =>
+        componentActivation.cause shouldBe defined
+        componentActivation.cause.get shouldBe (activation.activationId)
+        // check causedBy
+        val causedBy = componentActivation.getAnnotationValue("causedBy")
+        causedBy shouldBe defined
+        causedBy.get shouldBe (JsString("sequence"))
+        totalTime += componentActivation.duration
         // extract memory
-        activation.annotations shouldBe defined
-        val memory = extractMemoryAnnotation(activation)
-        memory shouldBe (maxMemory)
+        val mem = extractMemoryAnnotation(componentActivation)
+        maxMemory = maxMemory max mem
+      }
     }
-
-    /** checks that the logs of the idx-th atomic action from a sequence contains logsStr */
-    private def checkLogsAtomicAction(atomicActionIdx: Int, run: RunResult, regex: Regex) {
-        withActivation(wsk.activation, run, totalWait = 2 * allowedActionDuration) { activation =>
-            checkSequenceLogsAndAnnotations(activation, 1)
-            val componentId = activation.logs.get(atomicActionIdx)
-            val getComponentActivation = wsk.activation.get(Some(componentId))
-            withActivation(wsk.activation, getComponentActivation, totalWait = allowedActionDuration) { componentActivation =>
-                println(componentActivation)
-                componentActivation.logs shouldBe defined
-                val logs = componentActivation.logs.get.mkString(" ")
-                regex.findFirstIn(logs) shouldBe defined
-            }
-        }
+    // extract duration
+    activation.duration shouldBe (totalTime)
+    // extract memory
+    activation.annotations shouldBe defined
+    val memory = extractMemoryAnnotation(activation)
+    memory shouldBe (maxMemory)
+  }
+
+  /** checks that the logs of the idx-th atomic action from a sequence contains logsStr */
+  private def checkLogsAtomicAction(atomicActionIdx: Int, run: RunResult, regex: Regex) {
+    withActivation(wsk.activation, run, totalWait = 2 * allowedActionDuration) { activation =>
+      checkSequenceLogsAndAnnotations(activation, 1)
+      val componentId = activation.logs.get(atomicActionIdx)
+      val getComponentActivation = wsk.activation.get(Some(componentId))
+      withActivation(wsk.activation, getComponentActivation, totalWait = allowedActionDuration) { componentActivation =>
+        println(componentActivation)
+        componentActivation.logs shouldBe defined
+        val logs = componentActivation.logs.get.mkString(" ")
+        regex.findFirstIn(logs) shouldBe defined
+      }
     }
+  }
 
-    private def extractMemoryAnnotation(activation: ActivationResult): Long = {
-        val limits = activation.getAnnotationValue("limits")
-        limits shouldBe defined
-        limits.get.asJsObject.getFields("memory")(0).convertTo[Long]
-    }
+  private def extractMemoryAnnotation(activation: ActivationResult): Long = {
+    val limits = activation.getAnnotationValue("limits")
+    limits shouldBe defined
+    limits.get.asJsObject.getFields("memory")(0).convertTo[Long]
+  }
 }
diff --git a/tests/src/test/scala/whisk/core/admin/WskAdminTests.scala b/tests/src/test/scala/whisk/core/admin/WskAdminTests.scala
index 66ebd90..c42e2e8 100644
--- a/tests/src/test/scala/whisk/core/admin/WskAdminTests.scala
+++ b/tests/src/test/scala/whisk/core/admin/WskAdminTests.scala
@@ -33,141 +33,150 @@ import whisk.core.entity.Subject
 import common.TestUtils
 
 @RunWith(classOf[JUnitRunner])
-class WskAdminTests
-    extends TestHelpers
-    with Matchers {
-
-    behavior of "Wsk Admin CLI"
-
-    it should "confirm wskadmin exists" in {
-        WskAdmin.exists
+class WskAdminTests extends TestHelpers with Matchers {
+
+  behavior of "Wsk Admin CLI"
+
+  it should "confirm wskadmin exists" in {
+    WskAdmin.exists
+  }
+
+  it should "CRD a subject" in {
+    val wskadmin = new RunWskAdminCmd {}
+    val auth = AuthKey()
+    val subject = Subject().asString
+    try {
+      println(s"CRD subject: $subject")
+      val create = wskadmin.cli(Seq("user", "create", subject))
+      val get = wskadmin.cli(Seq("user", "get", subject))
+      create.stdout should be(get.stdout)
+
+      val authkey = get.stdout.trim
+      authkey should include(":")
+      authkey.split(":")(0).length should be(36)
+      authkey.split(":")(1).length should be >= 64
+
+      wskadmin.cli(Seq("user", "whois", authkey)).stdout.trim should be(
+        Seq(s"subject: $subject", s"namespace: $subject").mkString("\n"))
+
+      whisk.utils.retry({
+        // reverse lookup by namespace
+        wskadmin.cli(Seq("user", "list", "-k", subject)).stdout.trim should be(authkey)
+      }, 10, Some(1.second))
+
+      wskadmin.cli(Seq("user", "delete", subject)).stdout should include("Subject deleted")
+
+      // recreate with explicit
+      val newspace = s"${subject}.myspace"
+      wskadmin.cli(Seq("user", "create", subject, "-ns", newspace, "-u", auth.compact))
+
+      whisk.utils.retry({
+        // reverse lookup by namespace
+        wskadmin.cli(Seq("user", "list", "-k", newspace)).stdout.trim should be(auth.compact)
+      }, 10, Some(1.second))
+
+      wskadmin.cli(Seq("user", "get", subject, "-ns", newspace)).stdout.trim should be(auth.compact)
+
+      // delete namespace
+      wskadmin.cli(Seq("user", "delete", subject, "-ns", newspace)).stdout should include("Namespace deleted")
+    } finally {
+      wskadmin.cli(Seq("user", "delete", subject)).stdout should include("Subject deleted")
     }
-
-    it should "CRD a subject" in {
-        val wskadmin = new RunWskAdminCmd {}
-        val auth = AuthKey()
-        val subject = Subject().asString
-        try {
-            println(s"CRD subject: $subject")
-            val create = wskadmin.cli(Seq("user", "create", subject))
-            val get = wskadmin.cli(Seq("user", "get", subject))
-            create.stdout should be(get.stdout)
-
-            val authkey = get.stdout.trim
-            authkey should include(":")
-            authkey.split(":")(0).length should be(36)
-            authkey.split(":")(1).length should be >= 64
-
-            wskadmin.cli(Seq("user", "whois", authkey)).stdout.trim should be(Seq(s"subject: $subject", s"namespace: $subject").mkString("\n"))
-
-            whisk.utils.retry({
-                // reverse lookup by namespace
-                wskadmin.cli(Seq("user", "list", "-k", subject)).stdout.trim should be(authkey)
-            }, 10, Some(1.second))
-
-            wskadmin.cli(Seq("user", "delete", subject)).stdout should include("Subject deleted")
-
-            // recreate with explicit
-            val newspace = s"${subject}.myspace"
-            wskadmin.cli(Seq("user", "create", subject, "-ns", newspace, "-u", auth.compact))
-
-            whisk.utils.retry({
-                // reverse lookup by namespace
-                wskadmin.cli(Seq("user", "list", "-k", newspace)).stdout.trim should be(auth.compact)
-            }, 10, Some(1.second))
-
-            wskadmin.cli(Seq("user", "get", subject, "-ns", newspace)).stdout.trim should be(auth.compact)
-
-            // delete namespace
-            wskadmin.cli(Seq("user", "delete", subject, "-ns", newspace)).stdout should include("Namespace deleted")
-        } finally {
-            wskadmin.cli(Seq("user", "delete", subject)).stdout should include("Subject deleted")
-        }
+  }
+
+  it should "verify guest account installed correctly" in {
+    val wskadmin = new RunWskAdminCmd {}
+    implicit val wskprops = WskProps()
+    val wsk = new Wsk
+    val ns = wsk.namespace.whois()
+    wskadmin.cli(Seq("user", "get", ns)).stdout.trim should be(wskprops.authKey)
+  }
+
+  it should "block and unblock a user respectively" in {
+    val wskadmin = new RunWskAdminCmd {}
+    val auth = AuthKey()
+    val subject1 = Subject().asString
+    val subject2 = Subject().asString
+    val commonNamespace = "testspace"
+    try {
+      wskadmin.cli(Seq("user", "create", subject1, "-ns", commonNamespace, "-u", auth.compact))
+      wskadmin.cli(Seq("user", "create", subject2, "-ns", commonNamespace))
+
+      whisk.utils.retry({
+        // reverse lookup by namespace
+        val out = wskadmin.cli(Seq("user", "list", "-p", "2", "-k", commonNamespace)).stdout.trim
+        out should include(auth.compact)
+        out.lines should have size 2
+      }, 10, Some(1.second))
+
+      // block the user
+      wskadmin.cli(Seq("user", "block", subject1))
+
+      // wait until the user can no longer be found
+      whisk.utils.retry({
+        wskadmin.cli(Seq("user", "list", "-p", "2", "-k", commonNamespace)).stdout.trim.lines should have size 1
+      }, 10, Some(1.second))
+
+      // unblock the user
+      wskadmin.cli(Seq("user", "unblock", subject1))
+
+      // wait until the user can be found again
+      whisk.utils.retry({
+        val out = wskadmin.cli(Seq("user", "list", "-p", "2", "-k", commonNamespace)).stdout.trim
+        out should include(auth.compact)
+        out.lines should have size 2
+      }, 10, Some(1.second))
+    } finally {
+      wskadmin.cli(Seq("user", "delete", subject1)).stdout should include("Subject deleted")
+      wskadmin.cli(Seq("user", "delete", subject2)).stdout should include("Subject deleted")
     }
-
-    it should "verify guest account installed correctly" in {
-        val wskadmin = new RunWskAdminCmd {}
-        implicit val wskprops = WskProps()
-        val wsk = new Wsk
-        val ns = wsk.namespace.whois()
-        wskadmin.cli(Seq("user", "get", ns)).stdout.trim should be(wskprops.authKey)
+  }
+
+  it should "not allow edits on a blocked subject" in {
+    val wskadmin = new RunWskAdminCmd {}
+    val subject = Subject().asString
+    try {
+      // initially create the subject
+      wskadmin.cli(Seq("user", "create", subject))
+      // editing works
+      wskadmin.cli(Seq("user", "create", subject, "-ns", "testspace1"))
+      // block it
+      wskadmin.cli(Seq("user", "block", subject))
+      // Try to add a namespace, doesn't work
+      wskadmin.cli(Seq("user", "create", subject, "-ns", "testspace2"), expectedExitCode = TestUtils.ERROR_EXIT)
+      // Unblock the user
+      wskadmin.cli(Seq("user", "unblock", subject))
+      // Adding a namespace works
+      wskadmin.cli(Seq("user", "create", subject, "-ns", "testspace2"))
+    } finally {
+      wskadmin.cli(Seq("user", "delete", subject)).stdout should include("Subject deleted")
     }
-
-    it should "block and unblock a user respectively" in {
-        val wskadmin = new RunWskAdminCmd {}
-        val auth = AuthKey()
-        val subject1 = Subject().asString
-        val subject2 = Subject().asString
-        val commonNamespace = "testspace"
-        try {
-            wskadmin.cli(Seq("user", "create", subject1, "-ns", commonNamespace, "-u", auth.compact))
-            wskadmin.cli(Seq("user", "create", subject2, "-ns", commonNamespace))
-
-            whisk.utils.retry({
-                // reverse lookup by namespace
-                val out = wskadmin.cli(Seq("user", "list", "-p", "2", "-k", commonNamespace)).stdout.trim
-                out should include(auth.compact)
-                out.lines should have size 2
-            }, 10, Some(1.second))
-
-            // block the user
-            wskadmin.cli(Seq("user", "block", subject1))
-
-            // wait until the user can no longer be found
-            whisk.utils.retry({
-                wskadmin.cli(Seq("user", "list", "-p", "2", "-k", commonNamespace)).stdout.trim.lines should have size 1
-            }, 10, Some(1.second))
-
-            // unblock the user
-            wskadmin.cli(Seq("user", "unblock", subject1))
-
-            // wait until the user can be found again
-            whisk.utils.retry({
-                val out = wskadmin.cli(Seq("user", "list", "-p", "2", "-k", commonNamespace)).stdout.trim
-                out should include(auth.compact)
-                out.lines should have size 2
-            }, 10, Some(1.second))
-        } finally {
-            wskadmin.cli(Seq("user", "delete", subject1)).stdout should include("Subject deleted")
-            wskadmin.cli(Seq("user", "delete", subject2)).stdout should include("Subject deleted")
-        }
-    }
-
-    it should "not allow edits on a blocked subject" in {
-        val wskadmin = new RunWskAdminCmd {}
-        val subject = Subject().asString
-        try {
-            // initially create the subject
-            wskadmin.cli(Seq("user", "create", subject))
-            // editing works
-            wskadmin.cli(Seq("user", "create", subject, "-ns", "testspace1"))
-            // block it
-            wskadmin.cli(Seq("user", "block", subject))
-            // Try to add a namespace, doesn't work
-            wskadmin.cli(Seq("user", "create", subject, "-ns", "testspace2"), expectedExitCode = TestUtils.ERROR_EXIT)
-            // Unblock the user
-            wskadmin.cli(Seq("user", "unblock", subject))
-            // Adding a namespace works
-            wskadmin.cli(Seq("user", "create", subject, "-ns", "testspace2"))
-        } finally {
-            wskadmin.cli(Seq("user", "delete", subject)).stdout should include("Subject deleted")
-        }
-    }
-
-    it should "adjust throttles for namespace" in {
-        val wskadmin = new RunWskAdminCmd {}
-        val subject = Subject().asString
-        try {
-            // set some limits
-            wskadmin.cli(Seq("limits", "set", subject, "--invocationsPerMinute", "1", "--firesPerMinute", "2", "--concurrentInvocations", "3"))
-            // check correctly set
-            val lines = wskadmin.cli(Seq("limits", "get", subject)).stdout.lines.toSeq
-            lines should have size 3
-            lines(0) shouldBe "invocationsPerMinute = 1"
-            lines(1) shouldBe "firesPerMinute = 2"
-            lines(2) shouldBe "concurrentInvocations = 3"
-        } finally {
-            wskadmin.cli(Seq("limits", "delete", subject)).stdout should include("Limits deleted")
-        }
+  }
+
+  it should "adjust throttles for namespace" in {
+    val wskadmin = new RunWskAdminCmd {}
+    val subject = Subject().asString
+    try {
+      // set some limits
+      wskadmin.cli(
+        Seq(
+          "limits",
+          "set",
+          subject,
+          "--invocationsPerMinute",
+          "1",
+          "--firesPerMinute",
+          "2",
+          "--concurrentInvocations",
+          "3"))
+      // check correctly set
+      val lines = wskadmin.cli(Seq("limits", "get", subject)).stdout.lines.toSeq
+      lines should have size 3
+      lines(0) shouldBe "invocationsPerMinute = 1"
+      lines(1) shouldBe "firesPerMinute = 2"
+      lines(2) shouldBe "concurrentInvocations = 3"
+    } finally {
+      wskadmin.cli(Seq("limits", "delete", subject)).stdout should include("Limits deleted")
     }
+  }
 }
diff --git a/tests/src/test/scala/whisk/core/apigw/actions/test/ApiGwRoutemgmtActionTests.scala b/tests/src/test/scala/whisk/core/apigw/actions/test/ApiGwRoutemgmtActionTests.scala
index 28f9b0f..fa56de6 100644
--- a/tests/src/test/scala/whisk/core/apigw/actions/test/ApiGwRoutemgmtActionTests.scala
+++ b/tests/src/test/scala/whisk/core/apigw/actions/test/ApiGwRoutemgmtActionTests.scala
@@ -36,20 +36,19 @@ import common.WskTestHelpers
 import spray.json._
 import spray.json.DefaultJsonProtocol._
 
-case class ApiAction(
-    name: String,
-    namespace: String,
-    backendMethod: String = "POST",
-    backendUrl: String,
-    authkey: String) {
-    def toJson(): JsObject = {
-        return JsObject(
-            "name" -> name.toJson,
-            "namespace" -> namespace.toJson,
-            "backendMethod" -> backendMethod.toJson,
-            "backendUrl" -> backendUrl.toJson,
-            "authkey" -> authkey.toJson)
-    }
+case class ApiAction(name: String,
+                     namespace: String,
+                     backendMethod: String = "POST",
+                     backendUrl: String,
+                     authkey: String) {
+  def toJson(): JsObject = {
+    return JsObject(
+      "name" -> name.toJson,
+      "namespace" -> namespace.toJson,
+      "backendMethod" -> backendMethod.toJson,
+      "backendUrl" -> backendUrl.toJson,
+      "authkey" -> authkey.toJson)
+  }
 }
 
 /**
@@ -64,284 +63,532 @@ class ApiGwRoutemgmtActionTests
     with JsHelpers
     with StreamLogging {
 
-    val systemId = "whisk.system"
-    implicit val wskprops = WskProps(authKey = WskAdmin.listKeys(systemId)(0)._1, namespace = systemId)
-    val wsk = new Wsk
-
-    def getApis(
-        bpOrName: Option[String],
-        relpath: Option[String] = None,
-        operation: Option[String] = None,
-        docid: Option[String] = None,
-        accesstoken: Option[String] = Some("AnAccessToken"),
-        spaceguid: Option[String] = Some("ASpaceGuid") ): Vector[JsValue] = {
-        val parms = Map[String, JsValue]() ++
-            Map("__ow_user" -> wskprops.namespace.toJson) ++
-            { bpOrName map { b => Map("basepath" -> b.toJson) } getOrElse Map[String, JsValue]() } ++
-            { relpath map { r => Map("relpath" -> r.toJson) } getOrElse Map[String, JsValue]() } ++
-            { operation map { o => Map("operation" -> o.toJson) } getOrElse Map[String, JsValue]() } ++
-            { docid map { d => Map("docid" -> d.toJson) } getOrElse Map[String, JsValue]() } ++
-            { accesstoken map { t => Map("accesstoken" -> t.toJson) } getOrElse Map[String, JsValue]() } ++
-            { spaceguid map { s => Map("spaceguid" -> s.toJson) } getOrElse Map[String, JsValue]() }
+  val systemId = "whisk.system"
+  implicit val wskprops = WskProps(authKey = WskAdmin.listKeys(systemId)(0)._1, namespace = systemId)
+  val wsk = new Wsk
 
-        val rr = wsk.action.invoke(
-            name = "apimgmt/getApi",
-            parameters = parms,
-            blocking = true,
-            result = true,
-            expectedExitCode = SUCCESS_EXIT)(wskprops)
-        var apiJsArray: JsArray =
-            try {
-                var apisobj = rr.stdout.parseJson.asJsObject.fields("apis")
-                apisobj.convertTo[JsArray]
-            } catch {
-                case e: Exception =>
-                    JsArray.empty
-            }
-        return apiJsArray.elements
+  def getApis(bpOrName: Option[String],
+              relpath: Option[String] = None,
+              operation: Option[String] = None,
+              docid: Option[String] = None,
+              accesstoken: Option[String] = Some("AnAccessToken"),
+              spaceguid: Option[String] = Some("ASpaceGuid")): Vector[JsValue] = {
+    val parms = Map[String, JsValue]() ++
+      Map("__ow_user" -> wskprops.namespace.toJson) ++ {
+      bpOrName map { b =>
+        Map("basepath" -> b.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      relpath map { r =>
+        Map("relpath" -> r.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      operation map { o =>
+        Map("operation" -> o.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      docid map { d =>
+        Map("docid" -> d.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      accesstoken map { t =>
+        Map("accesstoken" -> t.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      spaceguid map { s =>
+        Map("spaceguid" -> s.toJson)
+      } getOrElse Map[String, JsValue]()
     }
 
-    def createApi(
-        namespace: Option[String] = Some("_"),
-        basepath: Option[String] = Some("/"),
-        relpath: Option[String],
-        operation: Option[String],
-        apiname: Option[String],
-        action: Option[ApiAction],
-        swagger: Option[String] = None,
-        accesstoken: Option[String] = Some("AnAccessToken"),
-        spaceguid: Option[String] = Some("ASpaceGuid"),
-        expectedExitCode: Int = SUCCESS_EXIT): RunResult = {
-        val parms = Map[String, JsValue]() ++
-            { namespace map { n => Map("namespace" -> n.toJson) } getOrElse Map[String, JsValue]() } ++
-            { basepath map { b => Map("gatewayBasePath" -> b.toJson) } getOrElse Map[String, JsValue]() } ++
-            { relpath map { r => Map("gatewayPath" -> r.toJson) } getOrElse Map[String, JsValue]() } ++
-            { operation map { o => Map("gatewayMethod" -> o.toJson) } getOrElse Map[String, JsValue]() } ++
-            { apiname map { an => Map("apiName" -> an.toJson) } getOrElse Map[String, JsValue]() } ++
-            { action map { a => Map("action" -> a.toJson) } getOrElse Map[String, JsValue]() } ++
-            { swagger map { s => Map("swagger" -> s.toJson) } getOrElse Map[String, JsValue]() }
-        val parm = Map[String, JsValue]("apidoc" -> JsObject(parms)) ++
-            { namespace map { n => Map("__ow_user" -> n.toJson) } getOrElse Map[String, JsValue]() } ++
-            { accesstoken map { t => Map("accesstoken" -> t.toJson) } getOrElse Map[String, JsValue]() } ++
-            { spaceguid map { s => Map("spaceguid" -> s.toJson) } getOrElse Map[String, JsValue]() }
+    val rr = wsk.action.invoke(
+      name = "apimgmt/getApi",
+      parameters = parms,
+      blocking = true,
+      result = true,
+      expectedExitCode = SUCCESS_EXIT)(wskprops)
+    var apiJsArray: JsArray =
+      try {
+        var apisobj = rr.stdout.parseJson.asJsObject.fields("apis")
+        apisobj.convertTo[JsArray]
+      } catch {
+        case e: Exception =>
+          JsArray.empty
+      }
+    return apiJsArray.elements
+  }
 
-        val rr = wsk.action.invoke(
-            name = "apimgmt/createApi",
-            parameters = parm,
-            blocking = true,
-            result = true,
-            expectedExitCode = expectedExitCode)(wskprops)
-        return rr
+  def createApi(namespace: Option[String] = Some("_"),
+                basepath: Option[String] = Some("/"),
+                relpath: Option[String],
+                operation: Option[String],
+                apiname: Option[String],
+                action: Option[ApiAction],
+                swagger: Option[String] = None,
+                accesstoken: Option[String] = Some("AnAccessToken"),
+                spaceguid: Option[String] = Some("ASpaceGuid"),
+                expectedExitCode: Int = SUCCESS_EXIT): RunResult = {
+    val parms = Map[String, JsValue]() ++ {
+      namespace map { n =>
+        Map("namespace" -> n.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      basepath map { b =>
+        Map("gatewayBasePath" -> b.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      relpath map { r =>
+        Map("gatewayPath" -> r.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      operation map { o =>
+        Map("gatewayMethod" -> o.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      apiname map { an =>
+        Map("apiName" -> an.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      action map { a =>
+        Map("action" -> a.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      swagger map { s =>
+        Map("swagger" -> s.toJson)
+      } getOrElse Map[String, JsValue]()
+    }
+    val parm = Map[String, JsValue]("apidoc" -> JsObject(parms)) ++ {
+      namespace map { n =>
+        Map("__ow_user" -> n.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      accesstoken map { t =>
+        Map("accesstoken" -> t.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      spaceguid map { s =>
+        Map("spaceguid" -> s.toJson)
+      } getOrElse Map[String, JsValue]()
     }
 
-    def deleteApi(
-        namespace: Option[String] = Some("_"),
-        basepath: Option[String] = Some("/"),
-        relpath: Option[String] = None,
-        operation: Option[String] = None,
-        apiname: Option[String] = None,
-        accesstoken: Option[String] = Some("AnAccessToken"),
-        spaceguid: Option[String] = Some("ASpaceGuid"),
-        expectedExitCode: Int = SUCCESS_EXIT): RunResult = {
-        val parms = Map[String, JsValue]() ++
-            { namespace map { n => Map("__ow_user" -> n.toJson) } getOrElse Map[String, JsValue]() } ++
-            { basepath map { b => Map("basepath" -> b.toJson) } getOrElse Map[String, JsValue]() } ++
-            { relpath map { r => Map("relpath" -> r.toJson) } getOrElse Map[String, JsValue]() } ++
-            { operation map { o => Map("operation" -> o.toJson) } getOrElse Map[String, JsValue]() } ++
-            { apiname map { an => Map("apiname" -> an.toJson) } getOrElse Map[String, JsValue]() } ++
-            { accesstoken map { t => Map("accesstoken" -> t.toJson) } getOrElse Map[String, JsValue]() } ++
-            { spaceguid map { s => Map("spaceguid" -> s.toJson) } getOrElse Map[String, JsValue]() }
+    val rr = wsk.action.invoke(
+      name = "apimgmt/createApi",
+      parameters = parm,
+      blocking = true,
+      result = true,
+      expectedExitCode = expectedExitCode)(wskprops)
+    return rr
+  }
 
-        val rr = wsk.action.invoke(
-            name = "apimgmt/deleteApi",
-            parameters = parms,
-            blocking = true,
-            result = true,
-            expectedExitCode = expectedExitCode)(wskprops)
-        return rr
+  def deleteApi(namespace: Option[String] = Some("_"),
+                basepath: Option[String] = Some("/"),
+                relpath: Option[String] = None,
+                operation: Option[String] = None,
+                apiname: Option[String] = None,
+                accesstoken: Option[String] = Some("AnAccessToken"),
+                spaceguid: Option[String] = Some("ASpaceGuid"),
+                expectedExitCode: Int = SUCCESS_EXIT): RunResult = {
+    val parms = Map[String, JsValue]() ++ {
+      namespace map { n =>
+        Map("__ow_user" -> n.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      basepath map { b =>
+        Map("basepath" -> b.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      relpath map { r =>
+        Map("relpath" -> r.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      operation map { o =>
+        Map("operation" -> o.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      apiname map { an =>
+        Map("apiname" -> an.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      accesstoken map { t =>
+        Map("accesstoken" -> t.toJson)
+      } getOrElse Map[String, JsValue]()
+    } ++ {
+      spaceguid map { s =>
+        Map("spaceguid" -> s.toJson)
+      } getOrElse Map[String, JsValue]()
     }
 
-    def apiMatch(
-        apiarr: Vector[JsValue],
-        basepath: String = "/",
-        relpath: String = "",
-        operation: String = "",
-        apiname: String = "",
-        action: ApiAction = null): Boolean = {
-        var matches: Boolean = false
-        for (api <- apiarr) {
-            val basepathExists = JsObjectHelper(api.asJsObject).fieldPathExists("value", "apidoc", "basePath")
-            if (basepathExists) {
-                System.out.println("basePath exists")
-                val basepathMatches = (JsObjectHelper(api.asJsObject).getFieldPath("value", "apidoc", "basePath").get.convertTo[String] == basepath)
-                if (basepathMatches) {
-                    System.out.println("basePath matches: " + basepath)
-                    val apinameExists = JsObjectHelper(api.asJsObject).fieldPathExists("value", "apidoc", "info", "title")
-                    if (apinameExists) {
-                        System.out.println("api name exists")
-                        val apinameMatches = (JsObjectHelper(api.asJsObject).getFieldPath("value", "apidoc", "info", "title").get.convertTo[String] == apiname)
-                        if (apinameMatches) {
-                            System.out.println("api name matches: " + apiname)
-                            val endpointMatches = JsObjectHelper(api.asJsObject).fieldPathExists("value", "apidoc", "paths", relpath, operation)
-                            if (endpointMatches) {
-                                System.out.println("endpoint exists/matches : " + relpath + "  " + operation)
-                                val actionConfig = JsObjectHelper(api.asJsObject).getFieldPath("value", "apidoc", "paths", relpath, operation, "x-openwhisk").get.asJsObject
-                                val actionMatches = actionMatch(actionConfig, action)
-                                if (actionMatches) {
-                                    System.out.println("endpoint action matches")
-                                    matches = true;
-                                }
-                            }
-                        }
-                    }
+    val rr = wsk.action.invoke(
+      name = "apimgmt/deleteApi",
+      parameters = parms,
+      blocking = true,
+      result = true,
+      expectedExitCode = expectedExitCode)(wskprops)
+    return rr
+  }
+
+  def apiMatch(apiarr: Vector[JsValue],
+               basepath: String = "/",
+               relpath: String = "",
+               operation: String = "",
+               apiname: String = "",
+               action: ApiAction = null): Boolean = {
+    var matches: Boolean = false
+    for (api <- apiarr) {
+      val basepathExists = JsObjectHelper(api.asJsObject).fieldPathExists("value", "apidoc", "basePath")
+      if (basepathExists) {
+        System.out.println("basePath exists")
+        val basepathMatches = (JsObjectHelper(api.asJsObject)
+          .getFieldPath("value", "apidoc", "basePath")
+          .get
+          .convertTo[String] == basepath)
+        if (basepathMatches) {
+          System.out.println("basePath matches: " + basepath)
+          val apinameExists = JsObjectHelper(api.asJsObject).fieldPathExists("value", "apidoc", "info", "title")
+          if (apinameExists) {
+            System.out.println("api name exists")
+            val apinameMatches = (JsObjectHelper(api.asJsObject)
+              .getFieldPath("value", "apidoc", "info", "title")
+              .get
+              .convertTo[String] == apiname)
+            if (apinameMatches) {
+              System.out.println("api name matches: " + apiname)
+              val endpointMatches =
+                JsObjectHelper(api.asJsObject).fieldPathExists("value", "apidoc", "paths", relpath, operation)
+              if (endpointMatches) {
+                System.out.println("endpoint exists/matches : " + relpath + "  " + operation)
+                val actionConfig = JsObjectHelper(api.asJsObject)
+                  .getFieldPath("value", "apidoc", "paths", relpath, operation, "x-openwhisk")
+                  .get
+                  .asJsObject
+                val actionMatches = actionMatch(actionConfig, action)
+                if (actionMatches) {
+                  System.out.println("endpoint action matches")
+                  matches = true;
                 }
+              }
             }
+          }
         }
-        return matches
+      }
     }
+    return matches
+  }
 
-    def actionMatch(
-        jsAction: JsObject,
-        action: ApiAction): Boolean = {
-        System.out.println("actionMatch: url " + jsAction.fields("url").convertTo[String] + "; backendUrl " + action.backendUrl)
-        System.out.println("actionMatch: namespace " + jsAction.fields("namespace").convertTo[String] + "; namespace " + action.namespace)
-        System.out.println("actionMatch: action " + jsAction.fields("action").convertTo[String] + "; action " + action.name)
-        val matches = jsAction.fields("url").convertTo[String] == action.backendUrl &&
-            jsAction.fields("namespace").convertTo[String] == action.namespace &&
-            jsAction.fields("action").convertTo[String] == action.name
-        return matches
-    }
+  def actionMatch(jsAction: JsObject, action: ApiAction): Boolean = {
+    System.out.println(
+      "actionMatch: url " + jsAction.fields("url").convertTo[String] + "; backendUrl " + action.backendUrl)
+    System.out.println(
+      "actionMatch: namespace " + jsAction.fields("namespace").convertTo[String] + "; namespace " + action.namespace)
+    System.out.println("actionMatch: action " + jsAction.fields("action").convertTo[String] + "; action " + action.name)
+    val matches = jsAction.fields("url").convertTo[String] == action.backendUrl &&
+      jsAction.fields("namespace").convertTo[String] == action.namespace &&
+      jsAction.fields("action").convertTo[String] == action.name
+    return matches
+  }
 
-    behavior of "API Gateway apimgmt action parameter validation"
+  behavior of "API Gateway apimgmt action parameter validation"
 
-    it should "verify successful creation of a new API" in {
-        val testName = "APIGWTEST1"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        val actionNamespace = wskprops.namespace
-        val actionUrl = "https://some.whisk.host/api/v1/web/" + actionNamespace + "/default/" + actionName + ".json"
-        val actionAuthKey = testName + "_authkey"
-        val testaction = ApiAction(name = actionName, namespace = actionNamespace, backendUrl = actionUrl, authkey = actionAuthKey)
+  it should "verify successful creation of a new API" in {
+    val testName = "APIGWTEST1"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    val actionNamespace = wskprops.namespace
+    val actionUrl = "https://some.whisk.host/api/v1/web/" + actionNamespace + "/default/" + actionName + ".json"
+    val actionAuthKey = testName + "_authkey"
+    val testaction =
+      ApiAction(name = actionName, namespace = actionNamespace, backendUrl = actionUrl, authkey = actionAuthKey)
 
-        try {
-            val createResult = createApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), relpath = Some(testrelpath),
-                operation = Some(testurlop), apiname = Some(testapiname), action = Some(testaction))
-            JsObjectHelper(createResult.stdout.parseJson.asJsObject).fieldPathExists("apidoc") should be(true)
-            val apiVector = getApis(bpOrName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
-            apiVector.size should be > 0
-            apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
-        } finally {
-            val deleteResult = deleteApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), expectedExitCode = DONTCARE_EXIT)
-        }
+    try {
+      val createResult = createApi(
+        namespace = Some(wskprops.namespace),
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        apiname = Some(testapiname),
+        action = Some(testaction))
+      JsObjectHelper(createResult.stdout.parseJson.asJsObject).fieldPathExists("apidoc") should be(true)
+      val apiVector = getApis(bpOrName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+      apiVector.size should be > 0
+      apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
+    } finally {
+      val deleteResult =
+        deleteApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), expectedExitCode = DONTCARE_EXIT)
     }
+  }
 
-    it should "verify successful API deletion using basepath" in {
-        val testName = "APIGWTEST2"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        val actionNamespace = wskprops.namespace
-        val actionUrl = "https://some.whisk.host/api/v1/web/" + actionNamespace + "/default/" + actionName + ".json"
-        val actionAuthKey = testName + "_authkey"
-        val testaction = ApiAction(name = actionName, namespace = actionNamespace, backendUrl = actionUrl, authkey = actionAuthKey)
+  it should "verify successful API deletion using basepath" in {
+    val testName = "APIGWTEST2"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    val actionNamespace = wskprops.namespace
+    val actionUrl = "https://some.whisk.host/api/v1/web/" + actionNamespace + "/default/" + actionName + ".json"
+    val actionAuthKey = testName + "_authkey"
+    val testaction =
+      ApiAction(name = actionName, namespace = actionNamespace, backendUrl = actionUrl, authkey = actionAuthKey)
 
-        try {
-            val createResult = createApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), relpath = Some(testrelpath),
-                operation = Some(testurlop), apiname = Some(testapiname), action = Some(testaction))
-            JsObjectHelper(createResult.stdout.parseJson.asJsObject).fieldPathExists("apidoc") should be(true)
-            var apiVector = getApis(bpOrName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
-            apiVector.size should be > 0
-            apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
-            val deleteResult = deleteApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath))
-            apiVector = getApis(bpOrName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
-            apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(false)
-        } finally {
-            val deleteResult = deleteApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), expectedExitCode = DONTCARE_EXIT)
-        }
+    try {
+      val createResult = createApi(
+        namespace = Some(wskprops.namespace),
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        apiname = Some(testapiname),
+        action = Some(testaction))
+      JsObjectHelper(createResult.stdout.parseJson.asJsObject).fieldPathExists("apidoc") should be(true)
+      var apiVector = getApis(bpOrName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+      apiVector.size should be > 0
+      apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
+      val deleteResult = deleteApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath))
+      apiVector = getApis(bpOrName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+      apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(false)
+    } finally {
+      val deleteResult =
+        deleteApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), expectedExitCode = DONTCARE_EXIT)
     }
+  }
 
-    it should "verify successful addition of new relative path to existing API" in {
-        val testName = "APIGWTEST3"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testnewurlop = "delete"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        val actionNamespace = wskprops.namespace
-        val actionUrl = "https://some.whisk.host/api/v1/web/" + actionNamespace + "/default/" + actionName + ".json"
-        val actionAuthKey = testName + "_authkey"
-        val testaction = ApiAction(name = actionName, namespace = actionNamespace, backendUrl = actionUrl, authkey = actionAuthKey)
+  it should "verify successful addition of new relative path to existing API" in {
+    val testName = "APIGWTEST3"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testnewurlop = "delete"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    val actionNamespace = wskprops.namespace
+    val actionUrl = "https://some.whisk.host/api/v1/web/" + actionNamespace + "/default/" + actionName + ".json"
+    val actionAuthKey = testName + "_authkey"
+    val testaction =
+      ApiAction(name = actionName, namespace = actionNamespace, backendUrl = actionUrl, authkey = actionAuthKey)
 
-        try {
-            var createResult = createApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), relpath = Some(testrelpath),
-                operation = Some(testurlop), apiname = Some(testapiname), action = Some(testaction))
-            createResult = createApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), relpath = Some(testnewrelpath),
-                operation = Some(testnewurlop), apiname = Some(testapiname), action = Some(testaction))
-            JsObjectHelper(createResult.stdout.parseJson.asJsObject).fieldPathExists("apidoc") should be(true)
-            var apiVector = getApis(bpOrName = Some(testbasepath))
-            apiVector.size should be > 0
-            apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
-            apiMatch(apiVector, testbasepath, testnewrelpath, testnewurlop, testapiname, testaction) should be(true)
-        } finally {
-            val deleteResult = deleteApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), expectedExitCode = DONTCARE_EXIT)
-        }
+    try {
+      var createResult = createApi(
+        namespace = Some(wskprops.namespace),
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        apiname = Some(testapiname),
+        action = Some(testaction))
+      createResult = createApi(
+        namespace = Some(wskprops.namespace),
+        basepath = Some(testbasepath),
+        relpath = Some(testnewrelpath),
+        operation = Some(testnewurlop),
+        apiname = Some(testapiname),
+        action = Some(testaction))
+      JsObjectHelper(createResult.stdout.parseJson.asJsObject).fieldPathExists("apidoc") should be(true)
+      var apiVector = getApis(bpOrName = Some(testbasepath))
+      apiVector.size should be > 0
+      apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
+      apiMatch(apiVector, testbasepath, testnewrelpath, testnewurlop, testapiname, testaction) should be(true)
+    } finally {
+      val deleteResult =
+        deleteApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), expectedExitCode = DONTCARE_EXIT)
     }
+  }
 
-    it should "reject apimgmt actions that are invoked with not enough parameters" in {
-        val invalidArgs = Seq(
-            //getApi
-            ("/whisk.system/apimgmt/getApi", ANY_ERROR_EXIT, "Invalid authentication.", Seq()),
+  it should "reject apimgmt actions that are invoked with not enough parameters" in {
+    val invalidArgs = Seq(
+      //getApi
+      ("/whisk.system/apimgmt/getApi", ANY_ERROR_EXIT, "Invalid authentication.", Seq()),
+      //deleteApi
+      (
+        "/whisk.system/apimgmt/deleteApi",
+        ANY_ERROR_EXIT,
+        "Invalid authentication.",
+        Seq("-p", "basepath", "/ApiGwRoutemgmtActionTests_bp")),
+      (
+        "/whisk.system/apimgmt/deleteApi",
+        ANY_ERROR_EXIT,
+        "basepath is required",
+        Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN")),
+      (
+        "/whisk.system/apimgmt/deleteApi",
+        ANY_ERROR_EXIT,
+        "When specifying an operation, the path is required",
+        Seq(
+          "-p",
+          "__ow_user",
+          "_",
+          "-p",
+          "accesstoken",
+          "TOKEN",
+          "-p",
+          "basepath",
+          "/ApiGwRoutemgmtActionTests_bp",
+          "-p",
+          "operation",
+          "get")),
+      //createApi
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "apidoc is required",
+        Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN")),
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "apidoc is missing the namespace field",
+        Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", "{}")),
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "apidoc is missing the gatewayBasePath field",
+        Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_"}""")),
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "apidoc is missing the gatewayPath field",
+        Seq(
+          "-p",
+          "__ow_user",
+          "_",
+          "-p",
+          "accesstoken",
+          "TOKEN",
+          "-p",
+          "apidoc",
+          """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp"}""")),
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "apidoc is missing the gatewayMethod field",
+        Seq(
+          "-p",
+          "__ow_user",
+          "_",
+          "-p",
+          "accesstoken",
+          "TOKEN",
+          "-p",
+          "apidoc",
+          """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp"}""")),
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "apidoc is missing the action field",
+        Seq(
+          "-p",
+          "__ow_user",
+          "_",
+          "-p",
+          "accesstoken",
+          "TOKEN",
+          "-p",
+          "apidoc",
+          """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get"}""")),
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "action is missing the backendMethod field",
+        Seq(
+          "-p",
+          "__ow_user",
+          "_",
+          "-p",
+          "accesstoken",
+          "TOKEN",
+          "-p",
+          "apidoc",
+          """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{}}""")),
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "action is missing the backendUrl field",
+        Seq(
+          "-p",
+          "__ow_user",
+          "_",
+          "-p",
+          "accesstoken",
+          "TOKEN",
+          "-p",
+          "apidoc",
+          """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post"}}""")),
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "action is missing the namespace field",
+        Seq(
+          "-p",
+          "__ow_user",
+          "_",
+          "-p",
+          "accesstoken",
+          "TOKEN",
+          "-p",
+          "apidoc",
+          """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post","backendUrl":"URL"}}""")),
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "action is missing the name field",
+        Seq(
+          "-p",
+          "__ow_user",
+          "_",
+          "-p",
+          "accesstoken",
+          "TOKEN",
+          "-p",
+          "apidoc",
+          """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post","backendUrl":"URL","namespace":"_"}}""")),
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "action is missing the authkey field",
+        Seq(
+          "-p",
+          "__ow_user",
+          "_",
+          "-p",
+          "accesstoken",
+          "TOKEN",
+          "-p",
+          "apidoc",
+          """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post","backendUrl":"URL","namespace":"_","name":"N"}}""")),
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "swagger and gatewayBasePath are mutually exclusive and cannot be specified together",
+        Seq(
+          "-p",
+          "__ow_user",
+          "_",
+          "-p",
+          "accesstoken",
+          "TOKEN",
+          "-p",
+          "apidoc",
+          """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post","backendUrl":"URL","namespace":"_","name":"N","authkey":"XXXX"},"swagger":{}}""")),
+      (
+        "/whisk.system/apimgmt/createApi",
+        ANY_ERROR_EXIT,
+        "apidoc field cannot be parsed. Ensure it is valid JSON",
+        Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", "{1:[}}}")))
 
-            //deleteApi
-            ("/whisk.system/apimgmt/deleteApi", ANY_ERROR_EXIT, "Invalid authentication.", Seq("-p", "basepath", "/ApiGwRoutemgmtActionTests_bp")),
-            ("/whisk.system/apimgmt/deleteApi", ANY_ERROR_EXIT, "basepath is required", Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN")),
-            ("/whisk.system/apimgmt/deleteApi", ANY_ERROR_EXIT, "When specifying an operation, the path is required",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "basepath", "/ApiGwRoutemgmtActionTests_bp", "-p", "operation", "get")),
-
-            //createApi
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc is required", Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN")),
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc is missing the namespace field",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", "{}")),
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc is missing the gatewayBasePath field",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_"}""")),
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc is missing the gatewayPath field",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp"}""")),
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc is missing the gatewayMethod field",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp"}""")),
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc is missing the action field",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get"}""")),
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "action is missing the backendMethod field",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{}}""")),
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "action is missing the backendUrl field",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post"}}""")),
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "action is missing the namespace field",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post","backendUrl":"URL"}}""")),
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "action is missing the name field",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post","backendUrl":"URL","namespace":"_"}}""")),
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "action is missing the authkey field",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post","backendUrl":"URL","namespace":"_","name":"N"}}""")),
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "swagger and gatewayBasePath are mutually exclusive and cannot be specified together",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post","backendUrl":"URL","namespace":"_","name":"N","authkey":"XXXX"},"swagger":{}}""")),
-            ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc field cannot be parsed. Ensure it is valid JSON",
-              Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", "{1:[}}}")))
-
-        invalidArgs foreach {
-            case (action: String, exitcode: Int, errmsg: String, params: Seq[String]) =>
-                val cmd: Seq[String] = Seq("action",
-                    "invoke",
-                    action,
-                    "-i", "-b", "-r",
-                    "--apihost", wskprops.apihost,
-                    "--auth", wskprops.authKey) ++ params
-                val rr = wsk.cli(cmd, expectedExitCode = exitcode)
-                rr.stderr should include regex (errmsg)
-        }
+    invalidArgs foreach {
+      case (action: String, exitcode: Int, errmsg: String, params: Seq[String]) =>
+        val cmd: Seq[String] = Seq(
+          "action",
+          "invoke",
+          action,
+          "-i",
+          "-b",
+          "-r",
+          "--apihost",
+          wskprops.apihost,
+          "--auth",
+          wskprops.authKey) ++ params
+        val rr = wsk.cli(cmd, expectedExitCode = exitcode)
+        rr.stderr should include regex (errmsg)
     }
+  }
 }
diff --git a/tests/src/test/scala/whisk/core/cli/test/ApiGwTests.scala b/tests/src/test/scala/whisk/core/cli/test/ApiGwTests.scala
index ac0f01c..5b7c304 100644
--- a/tests/src/test/scala/whisk/core/cli/test/ApiGwTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/ApiGwTests.scala
@@ -43,189 +43,209 @@ import common.WskTestHelpers
  * Tests for testing the CLI "api" subcommand.  Most of these tests require a deployed backend.
  */
 @RunWith(classOf[JUnitRunner])
-class ApiGwTests
-    extends TestHelpers
-    with WskTestHelpers
-    with BeforeAndAfterEach
-    with BeforeAndAfterAll {
-
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-    val clinamespace = wsk.namespace.whois()
-
-    // This test suite makes enough CLI invocations in 60 seconds to trigger the OpenWhisk
-    // throttling restriction.  To avoid CLI failures due to being throttled, track the
-    // CLI invocation calls and when at the throttle limit, pause the next CLI invocation
-    // with exactly enough time to relax the throttling.
-    val maxActionsPerMin = WhiskProperties.getMaxActionInvokesPerMinute()
-    val invocationTimes = new ArrayBuffer[Instant]()
-
-    // Custom CLI properties file
-    val cliWskPropsFile = File.createTempFile("wskprops", ".tmp")
-
-    /**
-     * Expected to be called before each test.
-     * Assumes that each test will not invoke more than 5 actions and
-     * settle the throttle when there isn't enough capacity to handle the test.
-     */
-    def checkThrottle(maxInvocationsBeforeThrottle: Int = maxActionsPerMin, expectedActivationsPerTest: Int = 5) = {
-        val t = Instant.now
-        val tminus60 = t.minusSeconds(60)
-        val invocationsLast60Seconds = invocationTimes.filter(_.isAfter(tminus60)).sorted
-        val invocationCount = invocationsLast60Seconds.length
-        println(s"Action invokes within last minute: ${invocationCount}")
-
-        if (invocationCount >= maxInvocationsBeforeThrottle) {
-            // Instead of waiting a fixed 60 seconds to settle the throttle,
-            // calculate a wait time that will clear out about half of the
-            // current invocations (assuming even distribution) from the
-            // next 60 second period.
-            val oldestInvocationInLast60Seconds = invocationsLast60Seconds.head
-
-            // Take the oldest invocation time in this 60 second period.  To clear
-            // this invocation from the next 60 second period, the wait time will be
-            // (60sec - oldest invocation's delta time away from the period end).
-            // This will clear all of the invocations from the next period at the
-            // expense of potentially waiting uncessarily long. Instead, this calculation
-            // halves the delta time as a compromise.
-            val throttleTime = 60.seconds.toMillis - ((t.toEpochMilli - oldestInvocationInLast60Seconds.toEpochMilli) / 2)
-            println(s"Waiting ${throttleTime} milliseconds to settle the throttle")
-            Thread.sleep(throttleTime)
-        }
-
-        invocationTimes += Instant.now
+class ApiGwTests extends TestHelpers with WskTestHelpers with BeforeAndAfterEach with BeforeAndAfterAll {
+
+  implicit val wskprops = WskProps()
+  val wsk = new Wsk
+  val clinamespace = wsk.namespace.whois()
+
+  // This test suite makes enough CLI invocations in 60 seconds to trigger the OpenWhisk
+  // throttling restriction.  To avoid CLI failures due to being throttled, track the
+  // CLI invocation calls and when at the throttle limit, pause the next CLI invocation
+  // with exactly enough time to relax the throttling.
+  val maxActionsPerMin = WhiskProperties.getMaxActionInvokesPerMinute()
+  val invocationTimes = new ArrayBuffer[Instant]()
+
+  // Custom CLI properties file
+  val cliWskPropsFile = File.createTempFile("wskprops", ".tmp")
+
+  /**
+   * Expected to be called before each test.
+   * Assumes that each test will not invoke more than 5 actions and
+   * settle the throttle when there isn't enough capacity to handle the test.
+   */
+  def checkThrottle(maxInvocationsBeforeThrottle: Int = maxActionsPerMin, expectedActivationsPerTest: Int = 5) = {
+    val t = Instant.now
+    val tminus60 = t.minusSeconds(60)
+    val invocationsLast60Seconds = invocationTimes.filter(_.isAfter(tminus60)).sorted
+    val invocationCount = invocationsLast60Seconds.length
+    println(s"Action invokes within last minute: ${invocationCount}")
+
+    if (invocationCount >= maxInvocationsBeforeThrottle) {
+      // Instead of waiting a fixed 60 seconds to settle the throttle,
+      // calculate a wait time that will clear out about half of the
+      // current invocations (assuming even distribution) from the
+      // next 60 second period.
+      val oldestInvocationInLast60Seconds = invocationsLast60Seconds.head
+
+      // Take the oldest invocation time in this 60 second period.  To clear
+      // this invocation from the next 60 second period, the wait time will be
+      // (60sec - oldest invocation's delta time away from the period end).
+      // This will clear all of the invocations from the next period at the
+      // expense of potentially waiting uncessarily long. Instead, this calculation
+      // halves the delta time as a compromise.
+      val throttleTime = 60.seconds.toMillis - ((t.toEpochMilli - oldestInvocationInLast60Seconds.toEpochMilli) / 2)
+      println(s"Waiting ${throttleTime} milliseconds to settle the throttle")
+      Thread.sleep(throttleTime)
     }
 
-    override def beforeEach() = {
-        //checkThrottle()
-    }
-
-    /*
-     * Create a CLI properties file for use by the tests
-     */
-    override def beforeAll() = {
-        cliWskPropsFile.deleteOnExit()
-        val wskprops = WskProps(token = "SOME TOKEN")
-        wskprops.writeFile(cliWskPropsFile)
-        println(s"wsk temporary props file created here: ${cliWskPropsFile.getCanonicalPath()}")
-    }
-
-    /*
-     * Forcibly clear the throttle so that downstream tests are not affected by
-     * this test suite
-     */
-    override def afterAll() = {
-        // Check and settle the throttle so that this test won't cause issues with and follow on tests
-        checkThrottle(30)
-    }
-
-    def apiCreate(
-        basepath: Option[String] = None,
-        relpath: Option[String] = None,
-        operation: Option[String] = None,
-        action: Option[String] = None,
-        apiname: Option[String] = None,
-        swagger: Option[String] = None,
-        responsetype: Option[String] = None,
-        expectedExitCode: Int = SUCCESS_EXIT,
-        cliCfgFile: Option[String] = Some(cliWskPropsFile.getCanonicalPath()))(implicit wskpropsOverride: WskProps): RunResult = {
-
-        checkThrottle()
-        wsk.api.create(basepath, relpath, operation, action, apiname, swagger, responsetype, expectedExitCode, cliCfgFile)(wskpropsOverride)
-    }
-
-    def apiList(
-        basepathOrApiName: Option[String] = None,
-        relpath: Option[String] = None,
-        operation: Option[String] = None,
-        limit: Option[Int] = None,
-        since: Option[Instant] = None,
-        full: Option[Boolean] = None,
-        nameSort: Option[Boolean] = None,
-        expectedExitCode: Int = SUCCESS_EXIT,
-        cliCfgFile: Option[String] = Some(cliWskPropsFile.getCanonicalPath())): RunResult = {
-
-        checkThrottle()
-        wsk.api.list(basepathOrApiName, relpath, operation, limit, since, full, nameSort, expectedExitCode, cliCfgFile)
-    }
-
-    def apiGet(
-        basepathOrApiName: Option[String] = None,
-        full: Option[Boolean] = None,
-        expectedExitCode: Int = SUCCESS_EXIT,
-        cliCfgFile: Option[String] = Some(cliWskPropsFile.getCanonicalPath()),
-        format: Option[String] = None): RunResult = {
-
-        checkThrottle()
-        wsk.api.get(basepathOrApiName, full, expectedExitCode, cliCfgFile, format)
-    }
-
-    def apiDelete(
-        basepathOrApiName: String,
-        relpath: Option[String] = None,
-        operation: Option[String] = None,
-        expectedExitCode: Int = SUCCESS_EXIT,
-        cliCfgFile: Option[String] = Some(cliWskPropsFile.getCanonicalPath())): RunResult = {
-
-        checkThrottle()
-        wsk.api.delete(basepathOrApiName, relpath, operation, expectedExitCode, cliCfgFile)
-    }
-
-    behavior of "Wsk api"
-
-    it should "reject an api commands with an invalid path parameter" in {
-        val badpath = "badpath"
-
-        var rr = apiCreate(basepath = Some("/basepath"), relpath = Some(badpath), operation = Some("GET"), action = Some("action"), expectedExitCode = ANY_ERROR_EXIT)
-        rr.stderr should include(s"'${badpath}' must begin with '/'")
-
-        rr = apiDelete(basepathOrApiName = "/basepath", relpath = Some(badpath), operation = Some("GET"), expectedExitCode = ANY_ERROR_EXIT)
-        rr.stderr should include(s"'${badpath}' must begin with '/'")
-
-        rr = apiList(basepathOrApiName = Some("/basepath"), relpath = Some(badpath), operation = Some("GET"), expectedExitCode = ANY_ERROR_EXIT)
-        rr.stderr should include(s"'${badpath}' must begin with '/'")
-    }
-
-    it should "reject an api commands with an invalid verb parameter" in {
-        val badverb = "badverb"
-
-        var rr = apiCreate(basepath = Some("/basepath"), relpath = Some("/path"), operation = Some(badverb), action = Some("action"), expectedExitCode = ANY_ERROR_EXIT)
-        rr.stderr should include(s"'${badverb}' is not a valid API verb.  Valid values are:")
-
-        rr = apiDelete(basepathOrApiName = "/basepath", relpath = Some("/path"), operation = Some(badverb), expectedExitCode = ANY_ERROR_EXIT)
-        rr.stderr should include(s"'${badverb}' is not a valid API verb.  Valid values are:")
-
-        rr = apiList(basepathOrApiName = Some("/basepath"), relpath = Some("/path"), operation = Some(badverb), expectedExitCode = ANY_ERROR_EXIT)
-        rr.stderr should include(s"'${badverb}' is not a valid API verb.  Valid values are:")
-    }
-
-    it should "reject an api create command that specifies a nonexistent configuration file" in {
-        val configfile = "/nonexistent/file"
-
-        val rr = apiCreate(swagger = Some(configfile), expectedExitCode = ANY_ERROR_EXIT)
-        rr.stderr should include(s"Error reading swagger file '${configfile}':")
-    }
-
-    it should "reject an api create command specifying a non-JSON configuration file" in {
-        val file = File.createTempFile("api.json", ".txt")
-        file.deleteOnExit()
-        val filename = file.getAbsolutePath()
-
-        val bw = new BufferedWriter(new FileWriter(file))
-        bw.write("a=A")
-        bw.close()
-
-        val rr = apiCreate(swagger = Some(filename), expectedExitCode = ANY_ERROR_EXIT)
-        rr.stderr should include(s"Error parsing swagger file '${filename}':")
-    }
-
-    it should "reject an api create command specifying a non-swagger JSON configuration file" in {
-        val file = File.createTempFile("api.json", ".txt")
-        file.deleteOnExit()
-        val filename = file.getAbsolutePath()
-
-        val bw = new BufferedWriter(new FileWriter(file))
-        bw.write("""|{
+    invocationTimes += Instant.now
+  }
+
+  override def beforeEach() = {
+    //checkThrottle()
+  }
+
+  /*
+   * Create a CLI properties file for use by the tests
+   */
+  override def beforeAll() = {
+    cliWskPropsFile.deleteOnExit()
+    val wskprops = WskProps(token = "SOME TOKEN")
+    wskprops.writeFile(cliWskPropsFile)
+    println(s"wsk temporary props file created here: ${cliWskPropsFile.getCanonicalPath()}")
+  }
+
+  /*
+   * Forcibly clear the throttle so that downstream tests are not affected by
+   * this test suite
+   */
+  override def afterAll() = {
+    // Check and settle the throttle so that this test won't cause issues with and follow on tests
+    checkThrottle(30)
+  }
+
+  def apiCreate(basepath: Option[String] = None,
+                relpath: Option[String] = None,
+                operation: Option[String] = None,
+                action: Option[String] = None,
+                apiname: Option[String] = None,
+                swagger: Option[String] = None,
+                responsetype: Option[String] = None,
+                expectedExitCode: Int = SUCCESS_EXIT,
+                cliCfgFile: Option[String] = Some(cliWskPropsFile.getCanonicalPath()))(
+    implicit wskpropsOverride: WskProps): RunResult = {
+
+    checkThrottle()
+    wsk.api.create(basepath, relpath, operation, action, apiname, swagger, responsetype, expectedExitCode, cliCfgFile)(
+      wskpropsOverride)
+  }
+
+  def apiList(basepathOrApiName: Option[String] = None,
+              relpath: Option[String] = None,
+              operation: Option[String] = None,
+              limit: Option[Int] = None,
+              since: Option[Instant] = None,
+              full: Option[Boolean] = None,
+              nameSort: Option[Boolean] = None,
+              expectedExitCode: Int = SUCCESS_EXIT,
+              cliCfgFile: Option[String] = Some(cliWskPropsFile.getCanonicalPath())): RunResult = {
+
+    checkThrottle()
+    wsk.api.list(basepathOrApiName, relpath, operation, limit, since, full, nameSort, expectedExitCode, cliCfgFile)
+  }
+
+  def apiGet(basepathOrApiName: Option[String] = None,
+             full: Option[Boolean] = None,
+             expectedExitCode: Int = SUCCESS_EXIT,
+             cliCfgFile: Option[String] = Some(cliWskPropsFile.getCanonicalPath()),
+             format: Option[String] = None): RunResult = {
+
+    checkThrottle()
+    wsk.api.get(basepathOrApiName, full, expectedExitCode, cliCfgFile, format)
+  }
+
+  def apiDelete(basepathOrApiName: String,
+                relpath: Option[String] = None,
+                operation: Option[String] = None,
+                expectedExitCode: Int = SUCCESS_EXIT,
+                cliCfgFile: Option[String] = Some(cliWskPropsFile.getCanonicalPath())): RunResult = {
+
+    checkThrottle()
+    wsk.api.delete(basepathOrApiName, relpath, operation, expectedExitCode, cliCfgFile)
+  }
+
+  behavior of "Wsk api"
+
+  it should "reject an api commands with an invalid path parameter" in {
+    val badpath = "badpath"
+
+    var rr = apiCreate(
+      basepath = Some("/basepath"),
+      relpath = Some(badpath),
+      operation = Some("GET"),
+      action = Some("action"),
+      expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(s"'${badpath}' must begin with '/'")
+
+    rr = apiDelete(
+      basepathOrApiName = "/basepath",
+      relpath = Some(badpath),
+      operation = Some("GET"),
+      expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(s"'${badpath}' must begin with '/'")
+
+    rr = apiList(
+      basepathOrApiName = Some("/basepath"),
+      relpath = Some(badpath),
+      operation = Some("GET"),
+      expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(s"'${badpath}' must begin with '/'")
+  }
+
+  it should "reject an api commands with an invalid verb parameter" in {
+    val badverb = "badverb"
+
+    var rr = apiCreate(
+      basepath = Some("/basepath"),
+      relpath = Some("/path"),
+      operation = Some(badverb),
+      action = Some("action"),
+      expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(s"'${badverb}' is not a valid API verb.  Valid values are:")
+
+    rr = apiDelete(
+      basepathOrApiName = "/basepath",
+      relpath = Some("/path"),
+      operation = Some(badverb),
+      expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(s"'${badverb}' is not a valid API verb.  Valid values are:")
+
+    rr = apiList(
+      basepathOrApiName = Some("/basepath"),
+      relpath = Some("/path"),
+      operation = Some(badverb),
+      expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(s"'${badverb}' is not a valid API verb.  Valid values are:")
+  }
+
+  it should "reject an api create command that specifies a nonexistent configuration file" in {
+    val configfile = "/nonexistent/file"
+
+    val rr = apiCreate(swagger = Some(configfile), expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(s"Error reading swagger file '${configfile}':")
+  }
+
+  it should "reject an api create command specifying a non-JSON configuration file" in {
+    val file = File.createTempFile("api.json", ".txt")
+    file.deleteOnExit()
+    val filename = file.getAbsolutePath()
+
+    val bw = new BufferedWriter(new FileWriter(file))
+    bw.write("a=A")
+    bw.close()
+
+    val rr = apiCreate(swagger = Some(filename), expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(s"Error parsing swagger file '${filename}':")
+  }
+
+  it should "reject an api create command specifying a non-swagger JSON configuration file" in {
+    val file = File.createTempFile("api.json", ".txt")
+    file.deleteOnExit()
+    val filename = file.getAbsolutePath()
+
+    val bw = new BufferedWriter(new FileWriter(file))
+    bw.write("""|{
                     |   "swagger": "2.0",
                     |   "info": {
                     |      "title": "My API",
@@ -238,706 +258,807 @@ class ApiGwTests
                     |     }
                     |   }
                     |}""".stripMargin)
-        bw.close()
-
-        val rr = apiCreate(swagger = Some(filename), expectedExitCode = ANY_ERROR_EXIT)
-        rr.stderr should include(s"Swagger file is invalid (missing basePath, info, paths, or swagger fields")
+    bw.close()
+
+    val rr = apiCreate(swagger = Some(filename), expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(s"Swagger file is invalid (missing basePath, info, paths, or swagger fields")
+  }
+
+  it should "verify full list output" in {
+    val testName = "CLI_APIGWTEST_RO1"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    try {
+      println("cli namespace: " + clinamespace)
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      var rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      println("api create: " + rr.stdout)
+      rr.stdout should include("ok: created API")
+      rr = apiList(
+        basepathOrApiName = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        full = Some(true))
+      println("api list: " + rr.stdout)
+      rr.stdout should include("ok: APIs")
+      rr.stdout should include regex (s"Action:\\s+/${clinamespace}/${actionName}\n")
+      rr.stdout should include regex (s"Verb:\\s+${testurlop}\n")
+      rr.stdout should include regex (s"Base path:\\s+${testbasepath}\n")
+      rr.stdout should include regex (s"Path:\\s+${testrelpath}\n")
+      rr.stdout should include regex (s"API Name:\\s+${testapiname}\n")
+      rr.stdout should include regex (s"URL:\\s+")
+      rr.stdout should include(testbasepath + testrelpath)
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath)
     }
-
-    it should "verify full list output" in {
-        val testName = "CLI_APIGWTEST_RO1"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        try {
-            println("cli namespace: " + clinamespace)
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            println("api create: " + rr.stdout)
-            rr.stdout should include("ok: created API")
-            rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), full = Some(true))
-            println("api list: " + rr.stdout)
-            rr.stdout should include("ok: APIs")
-            rr.stdout should include regex (s"Action:\\s+/${clinamespace}/${actionName}\n")
-            rr.stdout should include regex (s"Verb:\\s+${testurlop}\n")
-            rr.stdout should include regex (s"Base path:\\s+${testbasepath}\n")
-            rr.stdout should include regex (s"Path:\\s+${testrelpath}\n")
-            rr.stdout should include regex (s"API Name:\\s+${testapiname}\n")
-            rr.stdout should include regex (s"URL:\\s+")
-            rr.stdout should include(testbasepath + testrelpath)
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath)
-        }
+  }
+
+  it should "verify successful creation and deletion of a new API" in {
+    val testName = "CLI_APIGWTEST1"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path/with/sub_paths/in/it"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    try {
+      println("cli namespace: " + clinamespace)
+
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      var rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr.stdout should include("ok: created API")
+      rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+      rr.stdout should include("ok: APIs")
+      rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr.stdout should include(testbasepath + testrelpath)
+      rr = apiGet(basepathOrApiName = Some(testbasepath))
+      rr.stdout should include regex (s""""operationId":\\s+"getPathWithSub_pathsInIt"""")
+      val deleteresult = apiDelete(basepathOrApiName = testbasepath)
+      deleteresult.stdout should include("ok: deleted API")
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify successful creation and deletion of a new API" in {
-        val testName = "CLI_APIGWTEST1"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path/with/sub_paths/in/it"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        try {
-            println("cli namespace: " + clinamespace)
-
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            rr.stdout should include("ok: created API")
-            rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
-            rr.stdout should include("ok: APIs")
-            rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr.stdout should include(testbasepath + testrelpath)
-            rr = apiGet(basepathOrApiName = Some(testbasepath))
-            rr.stdout should include regex (s""""operationId":\\s+"getPathWithSub_pathsInIt"""")
-            val deleteresult = apiDelete(basepathOrApiName = testbasepath)
-            deleteresult.stdout should include("ok: deleted API")
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify get API name " in {
+    val testName = "CLI_APIGWTEST3"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    try {
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      var rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr.stdout should include("ok: created API")
+      rr = apiGet(basepathOrApiName = Some(testapiname))
+      rr.stdout should include(testbasepath)
+      rr.stdout should include(s"${actionName}")
+      rr.stdout should include regex (""""cors":\s*\{\s*\n\s*"enabled":\s*true""")
+      rr.stdout should include regex (s""""target-url":\\s+.*${actionName}.json""")
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify get API name " in {
-        val testName = "CLI_APIGWTEST3"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        try {
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            rr.stdout should include("ok: created API")
-            rr = apiGet(basepathOrApiName = Some(testapiname))
-            rr.stdout should include(testbasepath)
-            rr.stdout should include(s"${actionName}")
-            rr.stdout should include regex (""""cors":\s*\{\s*\n\s*"enabled":\s*true""")
-            rr.stdout should include regex (s""""target-url":\\s+.*${actionName}.json""")
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify delete API name " in {
+    val testName = "CLI_APIGWTEST4"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    try {
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      var rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr.stdout should include("ok: created API")
+      rr = apiDelete(basepathOrApiName = testapiname)
+      rr.stdout should include("ok: deleted API")
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify delete API name " in {
-        val testName = "CLI_APIGWTEST4"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        try {
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            rr.stdout should include("ok: created API")
-            rr = apiDelete(basepathOrApiName = testapiname)
-            rr.stdout should include("ok: deleted API")
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify delete API basepath " in {
+    val testName = "CLI_APIGWTEST5"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    try {
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      var rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr.stdout should include("ok: created API")
+      rr = apiDelete(basepathOrApiName = testbasepath)
+      rr.stdout should include("ok: deleted API")
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify delete API basepath " in {
-        val testName = "CLI_APIGWTEST5"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        try {
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            rr.stdout should include("ok: created API")
-            rr = apiDelete(basepathOrApiName = testbasepath)
-            rr.stdout should include("ok: deleted API")
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify adding endpoints to existing api" in {
+    val testName = "CLI_APIGWTEST6"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path2"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    val newEndpoint = "/newEndpoint"
+    try {
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      var rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr.stdout should include("ok: created API")
+      rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(newEndpoint),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr.stdout should include("ok: created API")
+      rr = apiList(basepathOrApiName = Some(testbasepath))
+      rr.stdout should include("ok: APIs")
+      rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr.stdout should include(testbasepath + testrelpath)
+      rr.stdout should include(testbasepath + newEndpoint)
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify adding endpoints to existing api" in {
-        val testName = "CLI_APIGWTEST6"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path2"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        val newEndpoint = "/newEndpoint"
-        try {
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            rr.stdout should include("ok: created API")
-            rr = apiCreate(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            rr.stdout should include("ok: created API")
-            rr = apiList(basepathOrApiName = Some(testbasepath))
-            rr.stdout should include("ok: APIs")
-            rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr.stdout should include(testbasepath + testrelpath)
-            rr.stdout should include(testbasepath + newEndpoint)
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify successful creation with swagger doc as input" in {
+    // NOTE: These values must match the swagger file contents
+    val testName = "CLI_APIGWTEST7"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    val swaggerPath = TestUtils.getTestApiGwFilename("testswaggerdoc1")
+    try {
+      var rr = apiCreate(swagger = Some(swaggerPath))
+      rr.stdout should include("ok: created API")
+      rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+      println("list stdout: " + rr.stdout)
+      println("list stderr: " + rr.stderr)
+      rr.stdout should include("ok: APIs")
+      // Actual CLI namespace will vary from local dev to automated test environments, so don't check
+      rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr.stdout should include(testbasepath + testrelpath)
+    } finally {
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify successful creation with swagger doc as input" in {
-        // NOTE: These values must match the swagger file contents
-        val testName = "CLI_APIGWTEST7"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        val swaggerPath = TestCLIUtils.getTestApiGwFilename("testswaggerdoc1")
-        try {
-            var rr = apiCreate(swagger = Some(swaggerPath))
-            rr.stdout should include("ok: created API")
-            rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
-            println("list stdout: " + rr.stdout)
-            println("list stderr: " + rr.stderr)
-            rr.stdout should include("ok: APIs")
-            // Actual CLI namespace will vary from local dev to automated test environments, so don't check
-            rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr.stdout should include(testbasepath + testrelpath)
-        } finally {
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify adding endpoints to two existing apis" in {
+    val testName = "CLI_APIGWTEST8"
+    val testbasepath = "/" + testName + "_bp"
+    val testbasepath2 = "/" + testName + "_bp2"
+    val testrelpath = "/path2"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val testapiname2 = testName + " API Name 2"
+    val actionName = testName + "_action"
+    val newEndpoint = "/newEndpoint"
+    try {
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      var rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr.stdout should include("ok: created API")
+      rr = apiCreate(
+        basepath = Some(testbasepath2),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname2))
+      rr.stdout should include("ok: created API")
+
+      // Update both APIs - each with a new endpoint
+      rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(newEndpoint),
+        operation = Some(testurlop),
+        action = Some(actionName))
+      rr.stdout should include("ok: created API")
+      rr = apiCreate(
+        basepath = Some(testbasepath2),
+        relpath = Some(newEndpoint),
+        operation = Some(testurlop),
+        action = Some(actionName))
+      rr.stdout should include("ok: created API")
+
+      rr = apiList(basepathOrApiName = Some(testbasepath))
+      rr.stdout should include("ok: APIs")
+      rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr.stdout should include(testbasepath + testrelpath)
+      rr.stdout should include(testbasepath + newEndpoint)
+
+      rr = apiList(basepathOrApiName = Some(testbasepath2))
+      rr.stdout should include("ok: APIs")
+      rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr.stdout should include(testbasepath2 + testrelpath)
+      rr.stdout should include(testbasepath2 + newEndpoint)
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify adding endpoints to two existing apis" in {
-        val testName = "CLI_APIGWTEST8"
-        val testbasepath = "/" + testName + "_bp"
-        val testbasepath2 = "/" + testName + "_bp2"
-        val testrelpath = "/path2"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val testapiname2 = testName + " API Name 2"
-        val actionName = testName + "_action"
-        val newEndpoint = "/newEndpoint"
-        try {
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            rr.stdout should include("ok: created API")
-            rr = apiCreate(basepath = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname2))
-            rr.stdout should include("ok: created API")
-
-            // Update both APIs - each with a new endpoint
-            rr = apiCreate(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName))
-            rr.stdout should include("ok: created API")
-            rr = apiCreate(basepath = Some(testbasepath2), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName))
-            rr.stdout should include("ok: created API")
-
-            rr = apiList(basepathOrApiName = Some(testbasepath))
-            rr.stdout should include("ok: APIs")
-            rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr.stdout should include(testbasepath + testrelpath)
-            rr.stdout should include(testbasepath + newEndpoint)
-
-            rr = apiList(basepathOrApiName = Some(testbasepath2))
-            rr.stdout should include("ok: APIs")
-            rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr.stdout should include(testbasepath2 + testrelpath)
-            rr.stdout should include(testbasepath2 + newEndpoint)
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify successful creation of a new API using an action name using all allowed characters" in {
+    // Be aware: full action name is close to being truncated by the 'list' command
+    // e.g. /lime@us.ibm.com/CLI_APIGWTEST9a-c@t ion  is currently at the 40 char 'list' display max
+    val testName = "CLI_APIGWTEST9"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "a-c@t ion"
+    try {
+      println("cli namespace: " + clinamespace)
+
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      var rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr.stdout should include("ok: created API")
+      rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+      rr.stdout should include("ok: APIs")
+      rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr.stdout should include(testbasepath + testrelpath)
+      val deleteresult = apiDelete(basepathOrApiName = testbasepath)
+      deleteresult.stdout should include("ok: deleted API")
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify successful creation of a new API using an action name using all allowed characters" in {
-        // Be aware: full action name is close to being truncated by the 'list' command
-        // e.g. /lime@us.ibm.com/CLI_APIGWTEST9a-c@t ion  is currently at the 40 char 'list' display max
-        val testName = "CLI_APIGWTEST9"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "a-c@t ion"
-        try {
-            println("cli namespace: " + clinamespace)
-
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            rr.stdout should include("ok: created API")
-            rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
-            rr.stdout should include("ok: APIs")
-            rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr.stdout should include(testbasepath + testrelpath)
-            val deleteresult = apiDelete(basepathOrApiName = testbasepath)
-            deleteresult.stdout should include("ok: deleted API")
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify failed creation with invalid swagger doc as input" in {
+    val testName = "CLI_APIGWTEST10"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    val swaggerPath = TestUtils.getTestApiGwFilename(s"testswaggerdocinvalid")
+    try {
+      val rr = apiCreate(swagger = Some(swaggerPath), expectedExitCode = ANY_ERROR_EXIT)
+      println("api create stdout: " + rr.stdout)
+      println("api create stderr: " + rr.stderr)
+      rr.stderr should include(s"Swagger file is invalid")
+    } finally {
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify failed creation with invalid swagger doc as input" in {
-        val testName = "CLI_APIGWTEST10"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        val swaggerPath = TestCLIUtils.getTestApiGwFilename(s"testswaggerdocinvalid")
-        try {
-            val rr = apiCreate(swagger = Some(swaggerPath), expectedExitCode = ANY_ERROR_EXIT)
-            println("api create stdout: " + rr.stdout)
-            println("api create stderr: " + rr.stderr)
-            rr.stderr should include(s"Swagger file is invalid")
-        } finally {
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify delete basepath/path " in {
+    val testName = "CLI_APIGWTEST11"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    try {
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      var rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr.stdout should include("ok: created API")
+      var rr2 = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testnewrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr2.stdout should include("ok: created API")
+      rr = apiDelete(basepathOrApiName = testbasepath, relpath = Some(testrelpath))
+      rr.stdout should include("ok: deleted " + testrelpath + " from " + testbasepath)
+      rr2 = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testnewrelpath))
+      rr2.stdout should include("ok: APIs")
+      rr2.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr2.stdout should include(testbasepath + testnewrelpath)
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify delete basepath/path " in {
-        val testName = "CLI_APIGWTEST11"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        try {
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            rr.stdout should include("ok: created API")
-            var rr2 = apiCreate(basepath = Some(testbasepath), relpath = Some(testnewrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            rr2.stdout should include("ok: created API")
-            rr = apiDelete(basepathOrApiName = testbasepath, relpath = Some(testrelpath))
-            rr.stdout should include("ok: deleted " + testrelpath + " from " + testbasepath)
-            rr2 = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testnewrelpath))
-            rr2.stdout should include("ok: APIs")
-            rr2.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr2.stdout should include(testbasepath + testnewrelpath)
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify delete single operation from existing API basepath/path/operation(s) " in {
+    val testName = "CLI_APIGWTEST12"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path2"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testurlop2 = "post"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    try {
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      var rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr.stdout should include("ok: created API")
+      rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop2),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr.stdout should include("ok: created API")
+      rr = apiList(basepathOrApiName = Some(testbasepath))
+      rr.stdout should include("ok: APIs")
+      rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr.stdout should include(testbasepath + testrelpath)
+      rr = apiDelete(basepathOrApiName = testbasepath, relpath = Some(testrelpath), operation = Some(testurlop2))
+      rr.stdout should include("ok: deleted " + testrelpath + " " + "POST" + " from " + testbasepath)
+      rr = apiList(basepathOrApiName = Some(testbasepath))
+      rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify delete single operation from existing API basepath/path/operation(s) " in {
-        val testName = "CLI_APIGWTEST12"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path2"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testurlop2 = "post"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        try {
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            rr.stdout should include("ok: created API")
-            rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop2), action = Some(actionName), apiname = Some(testapiname))
-            rr.stdout should include("ok: created API")
-            rr = apiList(basepathOrApiName = Some(testbasepath))
-            rr.stdout should include("ok: APIs")
-            rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr.stdout should include(testbasepath + testrelpath)
-            rr = apiDelete(basepathOrApiName = testbasepath, relpath = Some(testrelpath), operation = Some(testurlop2))
-            rr.stdout should include("ok: deleted " + testrelpath + " " + "POST" + " from " + testbasepath)
-            rr = apiList(basepathOrApiName = Some(testbasepath))
-            rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify successful creation with complex swagger doc as input" in {
+    val testName = "CLI_APIGWTEST13"
+    val testbasepath = "/test1/v1"
+    val testrelpath = "/whisk_system/utils/echo"
+    val testrelpath2 = "/whisk_system/utils/split"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = "test1a"
+    val swaggerPath = TestUtils.getTestApiGwFilename(s"testswaggerdoc2")
+    try {
+      var rr = apiCreate(swagger = Some(swaggerPath))
+      println("api create stdout: " + rr.stdout)
+      println("api create stderror: " + rr.stderr)
+      rr.stdout should include("ok: created API")
+      rr = apiList(basepathOrApiName = Some(testbasepath))
+      rr.stdout should include("ok: APIs")
+      // Actual CLI namespace will vary from local dev to automated test environments, so don't check
+      rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr.stdout should include(testbasepath + testrelpath)
+      rr.stdout should include(testbasepath + testrelpath2)
+    } finally {
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify successful creation with complex swagger doc as input" in {
-        val testName = "CLI_APIGWTEST13"
-        val testbasepath = "/test1/v1"
-        val testrelpath = "/whisk_system/utils/echo"
-        val testrelpath2 = "/whisk_system/utils/split"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = "test1a"
-        val swaggerPath = TestCLIUtils.getTestApiGwFilename(s"testswaggerdoc2")
-        try {
-            var rr = apiCreate(swagger = Some(swaggerPath))
-            println("api create stdout: " + rr.stdout)
-            println("api create stderror: " + rr.stderr)
-            rr.stdout should include("ok: created API")
-            rr = apiList(basepathOrApiName = Some(testbasepath))
-            rr.stdout should include("ok: APIs")
-            // Actual CLI namespace will vary from local dev to automated test environments, so don't check
-            rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr.stdout should include(testbasepath + testrelpath)
-            rr.stdout should include(testbasepath + testrelpath2)
-        } finally {
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify successful creation and deletion with multiple base paths" in {
+    val testName = "CLI_APIGWTEST14"
+    val testbasepath = "/" + testName + "_bp"
+    val testbasepath2 = "/" + testName + "_bp2"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val testapiname2 = testName + " API Name 2"
+    val actionName = testName + "_action"
+    try {
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      var rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname))
+      rr.stdout should include("ok: created API")
+      rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+      rr.stdout should include("ok: APIs")
+      rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr.stdout should include(testbasepath + testrelpath)
+      rr = apiCreate(
+        basepath = Some(testbasepath2),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname2))
+      rr.stdout should include("ok: created API")
+      rr = apiList(basepathOrApiName = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop))
+      rr.stdout should include("ok: APIs")
+      rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr.stdout should include(testbasepath2 + testrelpath)
+      rr = apiDelete(basepathOrApiName = testbasepath2)
+      rr.stdout should include("ok: deleted API")
+      rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+      rr.stdout should include("ok: APIs")
+      rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr.stdout should include(testbasepath + testrelpath)
+      rr = apiDelete(basepathOrApiName = testbasepath)
+      rr.stdout should include("ok: deleted API")
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "verify successful creation and deletion with multiple base paths" in {
-        val testName = "CLI_APIGWTEST14"
-        val testbasepath = "/" + testName + "_bp"
-        val testbasepath2 = "/" + testName + "_bp2"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val testapiname2 = testName + " API Name 2"
-        val actionName = testName + "_action"
-        try {
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
-            rr.stdout should include("ok: created API")
-            rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
-            rr.stdout should include("ok: APIs")
-            rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr.stdout should include(testbasepath + testrelpath)
-            rr = apiCreate(basepath = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname2))
-            rr.stdout should include("ok: created API")
-            rr = apiList(basepathOrApiName = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop))
-            rr.stdout should include("ok: APIs")
-            rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr.stdout should include(testbasepath2 + testrelpath)
-            rr = apiDelete(basepathOrApiName = testbasepath2)
-            rr.stdout should include("ok: deleted API")
-            rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
-            rr.stdout should include("ok: APIs")
-            rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr.stdout should include(testbasepath + testrelpath)
-            rr = apiDelete(basepathOrApiName = testbasepath)
-            rr.stdout should include("ok: deleted API")
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "reject an API created with a non-existent action" in {
+    val testName = "CLI_APIGWTEST15"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    try {
+      val rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname),
+        expectedExitCode = ANY_ERROR_EXIT)
+      rr.stderr should include("does not exist")
+    } finally {
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "reject an API created with a non-existent action" in {
-        val testName = "CLI_APIGWTEST15"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        try {
-            val rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname), expectedExitCode = ANY_ERROR_EXIT)
-            rr.stderr should include("does not exist")
-        } finally {
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "reject an API created with an action that is not a web action" in {
+    val testName = "CLI_APIGWTEST16"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    try {
+      // Create the action for the API.  It must NOT be a "web-action" action for this test
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT)
+
+      val rr = apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname),
+        expectedExitCode = ANY_ERROR_EXIT)
+      rr.stderr should include("is not a web action")
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "reject an API created with an action that is not a web action" in {
-        val testName = "CLI_APIGWTEST16"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        try {
-            // Create the action for the API.  It must NOT be a "web-action" action for this test
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT)
-
-            val rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname), expectedExitCode = ANY_ERROR_EXIT)
-            rr.stderr should include("is not a web action")
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
-    }
-
-    it should "verify API with http response type " in {
-        val testName = "CLI_APIGWTEST17"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        val responseType = "http"
-        try {
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            apiCreate(
-                basepath = Some(testbasepath),
-                relpath = Some(testrelpath),
-                operation = Some(testurlop),
-                action = Some(actionName),
-                apiname = Some(testapiname),
-                responsetype = Some(responseType))
-                .stdout should include("ok: created API")
-
-            val rr = apiGet(basepathOrApiName = Some(testapiname))
-            rr.stdout should include(testbasepath)
-            rr.stdout should include(s"${actionName}")
-            rr.stdout should include regex (s""""target-url":\\s+.*${actionName}.${responseType}""")
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
-    }
-
-    it should "reject API export when export type is invalid" in {
-        val testName = "CLI_APIGWTEST18"
-        val testbasepath = "/" + testName + "_bp"
-
-        val rr = apiGet(basepathOrApiName = Some(testbasepath), format = Some("BadType"), expectedExitCode = ANY_ERROR_EXIT)
-        rr.stderr should include("Invalid format type")
-    }
-
-    it should "successfully export an API in YAML format" in {
-        val testName = "CLI_APIGWTEST19"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        val responseType = "http"
-        try {
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            apiCreate(
-                basepath = Some(testbasepath),
-                relpath = Some(testrelpath),
-                operation = Some(testurlop),
-                action = Some(actionName),
-                apiname = Some(testapiname),
-                responsetype = Some(responseType))
-                .stdout should include("ok: created API")
-
-            val rr = apiGet(basepathOrApiName = Some(testapiname), format = Some("yaml"))
-            rr.stdout should include(s"basePath: ${testbasepath}")
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "verify API with http response type " in {
+    val testName = "CLI_APIGWTEST17"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    val responseType = "http"
+    try {
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname),
+        responsetype = Some(responseType)).stdout should include("ok: created API")
+
+      val rr = apiGet(basepathOrApiName = Some(testapiname))
+      rr.stdout should include(testbasepath)
+      rr.stdout should include(s"${actionName}")
+      rr.stdout should include regex (s""""target-url":\\s+.*${actionName}.${responseType}""")
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "successfully export an API when JSON format is explcitly specified" in {
-        val testName = "CLI_APIGWTEST20"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testnewrelpath = "/path_new"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-        val responseType = "http"
-        try {
-            // Create the action for the API.  It must be a "web-action" action.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            apiCreate(
-                basepath = Some(testbasepath),
-                relpath = Some(testrelpath),
-                operation = Some(testurlop),
-                action = Some(actionName),
-                apiname = Some(testapiname),
-                responsetype = Some(responseType))
-                .stdout should include("ok: created API")
-
-            val rr = apiGet(basepathOrApiName = Some(testapiname), format = Some("json"))
-            rr.stdout should include(testbasepath)
-            rr.stdout should include(s"${actionName}")
-            rr.stdout should include regex (s""""target-url":\\s+.*${actionName}.${responseType}""")
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "reject API export when export type is invalid" in {
+    val testName = "CLI_APIGWTEST18"
+    val testbasepath = "/" + testName + "_bp"
+
+    val rr = apiGet(basepathOrApiName = Some(testbasepath), format = Some("BadType"), expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include("Invalid format type")
+  }
+
+  it should "successfully export an API in YAML format" in {
+    val testName = "CLI_APIGWTEST19"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    val responseType = "http"
+    try {
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname),
+        responsetype = Some(responseType)).stdout should include("ok: created API")
+
+      val rr = apiGet(basepathOrApiName = Some(testapiname), format = Some("yaml"))
+      rr.stdout should include(s"basePath: ${testbasepath}")
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "successfully create an API from a YAML formatted API configuration file" in {
-        val testName = "CLI_APIGWTEST21"
-        val testbasepath = "/bp"
-        val testrelpath = "/rp"
-        val testurlop = "get"
-        val testapiname = testbasepath
-        val actionName = "webhttpecho"
-        val swaggerPath = TestCLIUtils.getTestApiGwFilename(s"local.api.yaml")
-        try {
-            var rr = apiCreate(swagger = Some(swaggerPath))
-            println("api create stdout: " + rr.stdout)
-            println("api create stderror: " + rr.stderr)
-            rr.stdout should include("ok: created API")
-            rr = apiList(basepathOrApiName = Some(testbasepath))
-            rr.stdout should include("ok: APIs")
-            // Actual CLI namespace will vary from local dev to automated test environments, so don't check
-            rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
-            rr.stdout should include(testbasepath + testrelpath)
-        } finally {
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "successfully export an API when JSON format is explcitly specified" in {
+    val testName = "CLI_APIGWTEST20"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testnewrelpath = "/path_new"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+    val responseType = "http"
+    try {
+      // Create the action for the API.  It must be a "web-action" action.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname),
+        responsetype = Some(responseType)).stdout should include("ok: created API")
+
+      val rr = apiGet(basepathOrApiName = Some(testapiname), format = Some("json"))
+      rr.stdout should include(testbasepath)
+      rr.stdout should include(s"${actionName}")
+      rr.stdout should include regex (s""""target-url":\\s+.*${actionName}.${responseType}""")
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "reject creation of an API from invalid YAML formatted API configuration file" in {
-        val testName = "CLI_APIGWTEST22"
-        val testbasepath = "/" + testName + "_bp"
-        val swaggerPath = TestCLIUtils.getTestApiGwFilename(s"local.api.bad.yaml")
-        try {
-            val rr = apiCreate(swagger = Some(swaggerPath), expectedExitCode = ANY_ERROR_EXIT)
-            println("api create stdout: " + rr.stdout)
-            println("api create stderror: " + rr.stderr)
-            rr.stderr should include("Unable to parse YAML configuration file")
-        } finally {
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "successfully create an API from a YAML formatted API configuration file" in {
+    val testName = "CLI_APIGWTEST21"
+    val testbasepath = "/bp"
+    val testrelpath = "/rp"
+    val testurlop = "get"
+    val testapiname = testbasepath
+    val actionName = "webhttpecho"
+    val swaggerPath = TestUtils.getTestApiGwFilename(s"local.api.yaml")
+    try {
+      var rr = apiCreate(swagger = Some(swaggerPath))
+      println("api create stdout: " + rr.stdout)
+      println("api create stderror: " + rr.stderr)
+      rr.stdout should include("ok: created API")
+      rr = apiList(basepathOrApiName = Some(testbasepath))
+      rr.stdout should include("ok: APIs")
+      // Actual CLI namespace will vary from local dev to automated test environments, so don't check
+      rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      rr.stdout should include(testbasepath + testrelpath)
+    } finally {
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "reject deletion of a non-existent api" in {
-        val nonexistentApi = "/not-there"
-
-        val rr = apiDelete(basepathOrApiName = nonexistentApi, expectedExitCode = ANY_ERROR_EXIT)
-        rr.stderr should include(s"API '${nonexistentApi}' does not exist")
+  }
+
+  it should "reject creation of an API from invalid YAML formatted API configuration file" in {
+    val testName = "CLI_APIGWTEST22"
+    val testbasepath = "/" + testName + "_bp"
+    val swaggerPath = TestUtils.getTestApiGwFilename(s"local.api.bad.yaml")
+    try {
+      val rr = apiCreate(swagger = Some(swaggerPath), expectedExitCode = ANY_ERROR_EXIT)
+      println("api create stdout: " + rr.stdout)
+      println("api create stderror: " + rr.stderr)
+      rr.stderr should include("Unable to parse YAML configuration file")
+    } finally {
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "successfully list an API whose endpoints are not mapped to actions" in {
-        val testName = "CLI_APIGWTEST23"
-        val testapiname = "A descriptive name"
-        val testbasepath = "/NoActions"
-        val testrelpath = "/"
-        val testops: Seq[String] = Seq("put", "delete", "get", "head", "options", "patch", "post")
-        val swaggerPath = TestCLIUtils.getTestApiGwFilename(s"endpoints.without.action.swagger.json")
-
-        try {
-            var rr = apiCreate(swagger = Some(swaggerPath))
-            println("api create stdout: " + rr.stdout)
-            println("api create stderror: " + rr.stderr)
-            rr.stdout should include("ok: created API")
-
-            rr = apiList(basepathOrApiName = Some(testbasepath))
-            println("api list:\n" + rr.stdout)
-            testops foreach { testurlop =>
-                rr.stdout should include regex (s"\\s+${testurlop}\\s+${testapiname}\\s+")
-            }
-            rr.stdout should include(testbasepath + testrelpath)
-
-            rr = apiList(basepathOrApiName = Some(testbasepath), full = Some(true))
-            println("api full list:\n" + rr.stdout)
-            testops foreach { testurlop =>
-                rr.stdout should include regex (s"Verb:\\s+${testurlop}")
-            }
-            rr.stdout should include(testbasepath + testrelpath)
-
-        } finally {
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "reject deletion of a non-existent api" in {
+    val nonexistentApi = "/not-there"
+
+    val rr = apiDelete(basepathOrApiName = nonexistentApi, expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(s"API '${nonexistentApi}' does not exist")
+  }
+
+  it should "successfully list an API whose endpoints are not mapped to actions" in {
+    val testName = "CLI_APIGWTEST23"
+    val testapiname = "A descriptive name"
+    val testbasepath = "/NoActions"
+    val testrelpath = "/"
+    val testops: Seq[String] = Seq("put", "delete", "get", "head", "options", "patch", "post")
+    val swaggerPath = TestUtils.getTestApiGwFilename(s"endpoints.without.action.swagger.json")
+
+    try {
+      var rr = apiCreate(swagger = Some(swaggerPath))
+      println("api create stdout: " + rr.stdout)
+      println("api create stderror: " + rr.stderr)
+      rr.stdout should include("ok: created API")
+
+      rr = apiList(basepathOrApiName = Some(testbasepath))
+      println("api list:\n" + rr.stdout)
+      testops foreach { testurlop =>
+        rr.stdout should include regex (s"\\s+${testurlop}\\s+${testapiname}\\s+")
+      }
+      rr.stdout should include(testbasepath + testrelpath)
+
+      rr = apiList(basepathOrApiName = Some(testbasepath), full = Some(true))
+      println("api full list:\n" + rr.stdout)
+      testops foreach { testurlop =>
+        rr.stdout should include regex (s"Verb:\\s+${testurlop}")
+      }
+      rr.stdout should include(testbasepath + testrelpath)
+
+    } finally {
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "reject creation of an API with invalid auth key" in {
-        val testName = "CLI_APIGWTEST24"
-        val testbasepath = "/" + testName + "_bp"
-        val testrelpath = "/path"
-        val testurlop = "get"
-        val testapiname = testName + " API Name"
-        val actionName = testName + "_action"
-
-        try {
-            // Create the action for the API.
-            val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-            wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-
-            // Set an invalid auth key
-            val badWskProps = WskProps(authKey = "bad-auth-key")
-
-            apiCreate(
-                basepath = Some(testbasepath),
-                relpath = Some(testrelpath),
-                operation = Some(testurlop),
-                action = Some(actionName),
-                apiname = Some(testapiname),
-                expectedExitCode = ANY_ERROR_EXIT)(badWskProps)
-                .stderr should include("The supplied authentication is invalid")
-        } finally {
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-            apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "reject creation of an API with invalid auth key" in {
+    val testName = "CLI_APIGWTEST24"
+    val testbasepath = "/" + testName + "_bp"
+    val testrelpath = "/path"
+    val testurlop = "get"
+    val testapiname = testName + " API Name"
+    val actionName = testName + "_action"
+
+    try {
+      // Create the action for the API.
+      val file = TestUtils.getTestActionFilename(s"echo.js")
+      wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+
+      // Set an invalid auth key
+      val badWskProps = WskProps(authKey = "bad-auth-key")
+
+      apiCreate(
+        basepath = Some(testbasepath),
+        relpath = Some(testrelpath),
+        operation = Some(testurlop),
+        action = Some(actionName),
+        apiname = Some(testapiname),
+        expectedExitCode = ANY_ERROR_EXIT)(badWskProps).stderr should include("The supplied authentication is invalid")
+    } finally {
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
+      apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
     }
-
-    it should "list api alphabetically by Base/Rel/Verb" in {
-        val baseName = "/BaseTestPathApiList"
-        val actionName = "actionName"
-        val file = TestCLIUtils.getTestActionFilename(s"echo-web-http.js")
-        try {
-            // Create Action for apis
-            var action = wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
-            println("action creation: " + action.stdout)
-            // Create apis
-            for (i <- 1 to 3) {
-                val base = s"$baseName$i"
-                var api = apiCreate(
-                    basepath = Some(base),
-                    relpath = Some("/relPath"),
-                    operation = Some("GET"),
-                    action = Some(actionName))
-                println("api creation: " + api.stdout)
-            }
-            val original = apiList(nameSort = Some(true)).stdout
-            val originalFull = apiList(full = Some(true), nameSort = Some(true)).stdout
-            val scalaSorted = List(s"${baseName}1" + "/", s"${baseName}2" + "/", s"${baseName}3" + "/")
-            val regex = s"${baseName}[1-3]/".r
-            val list = (regex.findAllMatchIn(original)).toList
-            val listFull = (regex.findAllMatchIn(originalFull)).toList
-
-            scalaSorted.toString shouldEqual list.toString
-            scalaSorted.toString shouldEqual listFull.toString
-        } finally {
-            // Clean up Apis
-            for (i <- 1 to 3) {
-                apiDelete(basepathOrApiName = s"${baseName}$i", expectedExitCode = DONTCARE_EXIT)
-            }
-            wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
-        }
+  }
+
+  it should "list api alphabetically by Base/Rel/Verb" in {
+    val baseName = "/BaseTestPathApiList"
+    val actionName = "actionName"
+    val file = TestUtils.getTestActionFilename(s"echo-web-http.js")
+    try {
+      // Create Action for apis
+      var action =
+        wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true"))
+      println("action creation: " + action.stdout)
+      // Create apis
+      for (i <- 1 to 3) {
+        val base = s"$baseName$i"
+        var api = apiCreate(
+          basepath = Some(base),
+          relpath = Some("/relPath"),
+          operation = Some("GET"),
+          action = Some(actionName))
+        println("api creation: " + api.stdout)
+      }
+      val original = apiList(nameSort = Some(true)).stdout
+      val originalFull = apiList(full = Some(true), nameSort = Some(true)).stdout
+      val scalaSorted = List(s"${baseName}1" + "/", s"${baseName}2" + "/", s"${baseName}3" + "/")
+      val regex = s"${baseName}[1-3]/".r
+      val list = (regex.findAllMatchIn(original)).toList
+      val listFull = (regex.findAllMatchIn(originalFull)).toList
+
+      scalaSorted.toString shouldEqual list.toString
+      scalaSorted.toString shouldEqual listFull.toString
+    } finally {
+      // Clean up Apis
+      for (i <- 1 to 3) {
+        apiDelete(basepathOrApiName = s"${baseName}$i", expectedExitCode = DONTCARE_EXIT)
+      }
+      wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT)
     }
+  }
 }
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskActionSequenceTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskActionSequenceTests.scala
index 84d4a82..f48d0ac 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskActionSequenceTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskActionSequenceTests.scala
@@ -32,55 +32,54 @@ import whisk.core.entity.EntityPath
  * Tests creation and retrieval of a sequence action
  */
 @RunWith(classOf[JUnitRunner])
-class WskActionSequenceTests
-    extends TestHelpers
-    with WskTestHelpers {
+class WskActionSequenceTests extends TestHelpers with WskTestHelpers {
 
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-    val defaultNamespace = EntityPath.DEFAULT.asString
-    val namespace = wsk.namespace.whois()
+  implicit val wskprops = WskProps()
+  val wsk = new Wsk
+  val defaultNamespace = EntityPath.DEFAULT.asString
+  val namespace = wsk.namespace.whois()
 
-    behavior of "Wsk Action Sequence"
+  behavior of "Wsk Action Sequence"
 
-    it should "create, and get an action sequence" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "actionSeq"
-            val packageName = "samples"
-            val helloName = "hello"
-            val catName = "cat"
-            val fullHelloActionName = s"/$defaultNamespace/$packageName/$helloName"
-            val fullCatActionName = s"/$defaultNamespace/$packageName/$catName"
+  it should "create, and get an action sequence" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "actionSeq"
+    val packageName = "samples"
+    val helloName = "hello"
+    val catName = "cat"
+    val fullHelloActionName = s"/$defaultNamespace/$packageName/$helloName"
+    val fullCatActionName = s"/$defaultNamespace/$packageName/$catName"
 
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, _) => pkg.create(packageName, shared = Some(true))(wp)
-            }
-
-            assetHelper.withCleaner(wsk.action, fullHelloActionName) {
-                val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-                (action, _) => action.create(fullHelloActionName, file)(wp)
-            }
+    assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
+      pkg.create(packageName, shared = Some(true))(wp)
+    }
 
-            assetHelper.withCleaner(wsk.action, fullCatActionName) {
-                val file = Some(TestCLIUtils.getTestActionFilename("cat.js"))
-                (action, _) => action.create(fullCatActionName, file)(wp)
-            }
+    assetHelper.withCleaner(wsk.action, fullHelloActionName) {
+      val file = Some(TestUtils.getTestActionFilename("hello.js"))
+      (action, _) =>
+        action.create(fullHelloActionName, file)(wp)
+    }
 
-            val artifacts = s"$fullHelloActionName,$fullCatActionName"
-            val kindValue = JsString("sequence")
-            val compValue = JsArray(
-                JsString(resolveDefaultNamespace(fullHelloActionName)),
-                JsString(resolveDefaultNamespace(fullCatActionName)))
+    assetHelper.withCleaner(wsk.action, fullCatActionName) {
+      val file = Some(TestUtils.getTestActionFilename("cat.js"))
+      (action, _) =>
+        action.create(fullCatActionName, file)(wp)
+    }
 
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(artifacts), kind = Some("sequence"))
-            }
+    val artifacts = s"$fullHelloActionName,$fullCatActionName"
+    val kindValue = JsString("sequence")
+    val compValue = JsArray(
+      JsString(resolveDefaultNamespace(fullHelloActionName)),
+      JsString(resolveDefaultNamespace(fullCatActionName)))
 
-            val stdout = wsk.action.get(name).stdout
-            assert(stdout.startsWith(s"ok: got action $name\n"))
-            wsk.parseJsonString(stdout).fields("exec").asJsObject.fields("components") shouldBe compValue
-            wsk.parseJsonString(stdout).fields("exec").asJsObject.fields("kind") shouldBe kindValue
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(artifacts), kind = Some("sequence"))
     }
 
-    private def resolveDefaultNamespace(actionName: String) = actionName.replace("/_/", s"/$namespace/")
+    val stdout = wsk.action.get(name).stdout
+    assert(stdout.startsWith(s"ok: got action $name\n"))
+    wsk.parseJsonString(stdout).fields("exec").asJsObject.fields("components") shouldBe compValue
+    wsk.parseJsonString(stdout).fields("exec").asJsObject.fields("kind") shouldBe kindValue
+  }
+
+  private def resolveDefaultNamespace(actionName: String) = actionName.replace("/_/", s"/$namespace/")
 }
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
index f14a092..03b4fc3 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
@@ -53,1375 +53,354 @@ import whisk.http.Messages
  * Tests for basic CLI usage. Some of these tests require a deployed backend.
  */
 @RunWith(classOf[JUnitRunner])
-class WskBasicUsageTests
-    extends TestHelpers
-    with WskTestHelpers {
-
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
-    val defaultAction = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-
-    behavior of "Wsk CLI usage"
-
-    it should "show help and usage info" in {
-        val stdout = wsk.cli(Seq()).stdout
-        stdout should include regex ("""(?i)Usage:""")
-        stdout should include regex ("""(?i)Flags""")
-        stdout should include regex ("""(?i)Available commands""")
-        stdout should include regex ("""(?i)--help""")
-    }
-
-    it should "show help and usage info using the default language" in {
-        val env = Map("LANG" -> "de_DE")
-        // Call will fail with exit code 2 if language not supported
-        wsk.cli(Seq("-h"), env = env)
-    }
-
-    it should "show cli build version" in {
-        val stdout = wsk.cli(Seq("property", "get", "--cliversion")).stdout
-        stdout should include regex ("""(?i)whisk CLI version\s+201.*""")
-    }
-
-    it should "show api version" in {
-        val stdout = wsk.cli(Seq("property", "get", "--apiversion")).stdout
-        stdout should include regex ("""(?i)whisk API version\s+v1""")
-    }
-
-    it should "reject bad command" in {
-        val result = wsk.cli(Seq("bogus"), expectedExitCode = ERROR_EXIT)
-        result.stderr should include regex ("""(?i)Run 'wsk --help' for usage""")
-    }
-
-    it should "allow a 3 part Fully Qualified Name (FQN) without a leading '/'" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val guestNamespace = wsk.namespace.whois()
-            val packageName = "packageName3ptFQN"
-            val actionName = "actionName3ptFQN"
-            val triggerName = "triggerName3ptFQN"
-            val ruleName = "ruleName3ptFQN"
-            val fullQualifiedName = s"${guestNamespace}/${packageName}/${actionName}"
-            // Used for action and rule creation below
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, _) => pkg.create(packageName)
-            }
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, _) => trigger.create(triggerName)
-            }
-            // Test action and rule creation where action name is 3 part FQN w/out leading slash
-            assetHelper.withCleaner(wsk.action, fullQualifiedName) {
-                (action, _) => action.create(fullQualifiedName, defaultAction)
-            }
-            assetHelper.withCleaner(wsk.rule, ruleName) {
-                (rule, _) =>
-                    rule.create(ruleName, trigger = triggerName, action = fullQualifiedName)
-            }
-
-            wsk.action.invoke(fullQualifiedName).stdout should include(s"ok: invoked /$fullQualifiedName")
-            wsk.action.get(fullQualifiedName).stdout should include(s"ok: got action ${packageName}/${actionName}")
-    }
-
-
-    behavior of "Wsk actions"
-
-    it should "reject creating entities with invalid names" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val names = Seq(
-                ("", ERROR_EXIT),
-                (" ", BAD_REQUEST),
-                ("hi+there", BAD_REQUEST),
-                ("$hola", BAD_REQUEST),
-                ("dora?", BAD_REQUEST),
-                ("|dora|dora?", BAD_REQUEST))
-
-            names foreach {
-                case (name, ec) =>
-                    assetHelper.withCleaner(wsk.action, name, confirmDelete = false) {
-                        (action, _) => action.create(name, defaultAction, expectedExitCode = ec)
-                    }
-            }
-    }
-
-    it should "reject create with missing file" in {
-        wsk.action.create("missingFile", Some("notfound"),
-            expectedExitCode = MISUSE_EXIT).
-            stderr should include("not a valid file")
-    }
-
-    it should "reject action update when specified file is missing" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            // Create dummy action to update
-            val name = "updateMissingFile"
-            val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-            assetHelper.withCleaner(wsk.action, name) { (action, name) => action.create(name, file) }
-            // Update it with a missing file
-            wsk.action.create(name, Some("notfound"), update = true, expectedExitCode = MISUSE_EXIT)
-    }
-
-    it should "reject action update for sequence with no components" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "updateMissingComponents"
-            val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-            assetHelper.withCleaner(wsk.action, name) { (action, name) => action.create(name, file) }
-            wsk.action.create(name, None, update = true, kind = Some("sequence"), expectedExitCode = MISUSE_EXIT)
-    }
-
-    it should "create, and get an action to verify parameter and annotation parsing" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "actionAnnotations"
-            val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, annotations = getValidJSONTestArgInput,
-                        parameters = getValidJSONTestArgInput)
-            }
-
-            val stdout = wsk.action.get(name).stdout
-            assert(stdout.startsWith(s"ok: got action $name\n"))
-
-            val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-            val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-            val escapedJSONArr = getValidJSONTestArgOutput.convertTo[JsArray].elements
-
-            for (expectedItem <- escapedJSONArr) {
-                receivedParams should contain(expectedItem)
-                receivedAnnots should contain(expectedItem)
-            }
-    }
-
-    it should "create, and get an action to verify file parameter and annotation parsing" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "actionAnnotAndParamParsing"
-            val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-            val argInput = Some(TestCLIUtils.getTestActionFilename("validInput1.json"))
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, annotationFile = argInput, parameterFile = argInput)
-            }
-
-            val stdout = wsk.action.get(name).stdout
-            assert(stdout.startsWith(s"ok: got action $name\n"))
-
-            val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-            val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-            val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
-
-            for (expectedItem <- escapedJSONArr) {
-                receivedParams should contain(expectedItem)
-                receivedAnnots should contain(expectedItem)
-            }
-    }
-
-    it should "create an action with the proper parameter and annotation escapes" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "actionEscapes"
-            val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, parameters = getEscapedJSONTestArgInput,
-                        annotations = getEscapedJSONTestArgInput)
-            }
-
-            val stdout = wsk.action.get(name).stdout
-            assert(stdout.startsWith(s"ok: got action $name\n"))
-
-            val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-            val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-            val escapedJSONArr = getEscapedJSONTestArgOutput.convertTo[JsArray].elements
-
-            for (expectedItem <- escapedJSONArr) {
-                receivedParams should contain(expectedItem)
-                receivedAnnots should contain(expectedItem)
-            }
-    }
-
-    it should "invoke an action that exits during initialization and get appropriate error" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "abort init"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("initexit.js")))
-            }
-
-            withActivation(wsk.activation, wsk.action.invoke(name)) {
-                activation =>
-                    val response = activation.response
-                    response.result.get.fields("error") shouldBe Messages.abnormalInitialization.toJson
-                    response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ContainerError)
-            }
-    }
-
-    it should "invoke an action that hangs during initialization and get appropriate error" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "hang init"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(
-                        name,
-                        Some(TestCLIUtils.getTestActionFilename("initforever.js")),
-                        timeout = Some(3 seconds))
-            }
-
-            withActivation(wsk.activation, wsk.action.invoke(name)) {
-                activation =>
-                    val response = activation.response
-                    response.result.get.fields("error") shouldBe Messages.timedoutActivation(3 seconds, true).toJson
-                    response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
-            }
-    }
-
-    it should "invoke an action that exits during run and get appropriate error" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "abort run"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("runexit.js")))
-            }
-
-            withActivation(wsk.activation, wsk.action.invoke(name)) {
-                activation =>
-                    val response = activation.response
-                    response.result.get.fields("error") shouldBe Messages.abnormalRun.toJson
-                    response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ContainerError)
-            }
-    }
-
-    it should "retrieve the last activation using --last flag" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val auth: Seq[String] = Seq("--auth", wskprops.authKey)
-            val includeStr = "hello, undefined!"
-
-            assetHelper.withCleaner(wsk.action, "lastName") {
-                (action, _) => wsk.action.create("lastName", defaultAction)
-            }
-            retry({
-                val lastInvoke = wsk.action.invoke("lastName")
-                withActivation(wsk.activation, lastInvoke) { activation =>
-                    val lastFlag = Seq(
-                        (Seq("activation", "get", "publish", "--last"), activation.activationId),
-                        (Seq("activation", "get", "--last"), activation.activationId),
-                        (Seq("activation", "logs", "--last"), includeStr),
-                        (Seq("activation", "result", "--last"), includeStr))
-
-                    retry({
-                        lastFlag foreach {
-                            case (cmd, output) =>
-                                val stdout = wsk.cli(cmd ++ wskprops.overrides ++ auth, expectedExitCode = SUCCESS_EXIT).stdout
-                                stdout should include(output)
-                        }
-                    }, waitBeforeRetry = Some(500.milliseconds))
-
-                }
-            }, waitBeforeRetry = Some(1.second), N = 5)
-    }
-
-    it should "ensure keys are not omitted from activation record" in withAssetCleaner(wskprops) {
-        val name = "activationRecordTest"
-
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("argCheck.js")))
-            }
-
-            val run = wsk.action.invoke(name)
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.start should be > Instant.EPOCH
-                    activation.end should be > Instant.EPOCH
-                    activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.Success)
-                    activation.response.success shouldBe true
-                    activation.response.result shouldBe Some(JsObject())
-                    activation.logs shouldBe Some(List())
-                    activation.annotations shouldBe defined
-            }
-    }
-
-    it should "write the action-path and the limits to the annotations" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "annotations"
-            val memoryLimit = 512 MB
-            val logLimit = 1 MB
-            val timeLimit = 60 seconds
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("helloAsync.js")), memory = Some(memoryLimit), timeout = Some(timeLimit), logsize = Some(logLimit))
-            }
-
-            val run = wsk.action.invoke(name, Map("payload" -> "this is a test".toJson))
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.status shouldBe "success"
-                    val annotations = activation.annotations.get
-
-                    val limitsObj = JsObject(
-                        "key" -> JsString("limits"),
-                        "value" -> ActionLimits(TimeLimit(timeLimit), MemoryLimit(memoryLimit), LogLimit(logLimit)).toJson)
-
-                    val path = annotations.find { _.fields("key").convertTo[String] == "path" }.get
-
-                    path.fields("value").convertTo[String] should fullyMatch regex (s""".*/$name""")
-                    annotations should contain(limitsObj)
-            }
-    }
-
-    it should "report error when creating an action with unknown kind" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val rr = assetHelper.withCleaner(wsk.action, "invalid kind", confirmDelete = false) {
-                (action, name) => action.create(name, Some(TestCLIUtils.getTestActionFilename("echo.js")), kind = Some("foobar"), expectedExitCode = BAD_REQUEST)
-            }
-            rr.stderr should include regex "kind 'foobar' not in Set"
-    }
-
-    it should "report error when creating an action with zip but without kind" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "zipWithNoKind"
-            val zippedPythonAction = Some(TestCLIUtils.getTestActionFilename("python.zip"))
-            val createResult = assetHelper.withCleaner(wsk.action, name, confirmDelete = false) {
-                (action, _) =>
-                    action.create(name, zippedPythonAction, expectedExitCode = ANY_ERROR_EXIT)
-            }
-
-            createResult.stderr should include regex "requires specifying the action kind"
-    }
-
-    it should "create, and invoke an action that utilizes an invalid docker container with appropriate error" in withAssetCleaner(wskprops) {
-        val name = "invalidDockerContainer"
-        val containerName = s"bogus${Random.alphanumeric.take(16).mkString.toLowerCase}"
-
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.action, name) {
-                // docker name is a randomly generate string
-                (action, _) => action.create(name, None, docker = Some(containerName))
-            }
-
-            val run = wsk.action.invoke(name)
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
-                    activation.response.result.get.fields("error") shouldBe s"Failed to pull container image '$containerName'.".toJson
-                    activation.annotations shouldBe defined
-                    val limits = activation.annotations.get.filter(_.fields("key").convertTo[String] == "limits")
-                    withClue(limits) {
-                        limits.length should be > 0
-                        limits(0).fields("value") should not be JsNull
-                    }
-            }
-    }
-
-    it should "invoke an action using npm openwhisk" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "hello npm openwhisk"
-            assetHelper.withCleaner(wsk.action, name, confirmDelete = false) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("helloOpenwhiskPackage.js")))
-            }
-
-            val run = wsk.action.invoke(name, Map("ignore_certs" -> true.toJson, "name" -> name.toJson))
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.status shouldBe "success"
-                    activation.response.result shouldBe Some(JsObject("delete" -> true.toJson))
-                    activation.logs.get.mkString(" ") should include("action list has this many actions")
-            }
-
-            wsk.action.delete(name, expectedExitCode = TestUtils.NOT_FOUND)
-    }
-
-    it should "invoke an action receiving context properties" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val namespace = wsk.namespace.whois()
-            val name = "context"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("helloContext.js")))
-            }
-
-            val start = Instant.now(Clock.systemUTC()).toEpochMilli
-            val run = wsk.action.invoke(name)
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.status shouldBe "success"
-                    val fields = activation.response.result.get.convertTo[Map[String, String]]
-                    fields("api_host") shouldBe WhiskProperties.getApiHostForAction
-                    fields("api_key") shouldBe wskprops.authKey
-                    fields("namespace") shouldBe namespace
-                    fields("action_name") shouldBe s"/$namespace/$name"
-                    fields("activation_id") shouldBe activation.activationId
-                    fields("deadline").toLong should be >= start
-            }
-    }
-
-    it should "invoke an action successfully with options --blocking and --result" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "invokeResult"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("echo.js")))
-            }
-            val args = Map("hello" -> "Robert".toJson)
-            val run = wsk.action.invoke(name, args, blocking = true, result = true)
-            run.stdout.parseJson shouldBe args.toJson
-    }
-
-    it should "invoke an action that returns a result by the deadline" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "deadline"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("helloDeadline.js")), timeout = Some(3 seconds))
-            }
-
-            val run = wsk.action.invoke(name)
-            withActivation(wsk.activation, run) {
-                activation =>
-                    activation.response.status shouldBe "success"
-                    activation.response.result shouldBe Some(JsObject("timedout" -> true.toJson))
-            }
-    }
-
-    it should "invoke an action twice, where the first times out but the second does not and should succeed" in withAssetCleaner(wskprops) {
-        // this test issues two activations: the first is forced to time out and not return a result by its deadline (ie it does not resolve
-        // its promise). The invoker should reclaim its container so that a second activation of the same action (which must happen within a
-        // short period of time (seconds, not minutes) is allocated a fresh container and hence runs as expected (vs. hitting in the container
-        // cache and reusing a bad container).
-        (wp, assetHelper) =>
-            val name = "timeout"
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("helloDeadline.js")), timeout = Some(3 seconds))
-            }
-
-            val start = Instant.now(Clock.systemUTC()).toEpochMilli
-            val hungRun = wsk.action.invoke(name, Map("forceHang" -> true.toJson))
-            withActivation(wsk.activation, hungRun) {
-                activation =>
-                    // the first action must fail with a timeout error
-                    activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
-                    activation.response.result shouldBe Some(JsObject("error" -> Messages.timedoutActivation(3 seconds, false).toJson))
-            }
-
-            // run the action again, this time without forcing it to timeout
-            // it should succeed because it ran in a fresh container
-            val goodRun = wsk.action.invoke(name, Map("forceHang" -> false.toJson))
-            withActivation(wsk.activation, goodRun) {
-                activation =>
-                    // the first action must fail with a timeout error
-                    activation.response.status shouldBe "success"
-                    activation.response.result shouldBe Some(JsObject("timedout" -> true.toJson))
-            }
-    }
-
-    it should "ensure --web flags set the proper annotations" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "webaction"
-            val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, file)
-            }
-
-            Seq("true", "faLse", "tRue", "nO", "yEs", "no", "raw", "NO", "Raw").
-                foreach { flag =>
-                    val webEnabled = flag.toLowerCase == "true" || flag.toLowerCase == "yes"
-                    val rawEnabled = flag.toLowerCase == "raw"
-
-                    wsk.action.create(name, file, web = Some(flag), update = true)
-
-                    val stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
-                    assert(stdout.startsWith(s"ok: got action $name, displaying field annotations\n"))
-                    removeCLIHeader(stdout).parseJson shouldBe JsArray(
-                        JsObject(
-                            "key" -> JsString("exec"),
-                            "value" -> JsString("nodejs:6")),
-                        JsObject(
-                            "key" -> JsString("web-export"),
-                            "value" -> JsBoolean(webEnabled || rawEnabled)),
-                        JsObject(
-                            "key" -> JsString("raw-http"),
-                            "value" -> JsBoolean(rawEnabled)),
-                        JsObject(
-                            "key" -> JsString("final"),
-                            "value" -> JsBoolean(webEnabled || rawEnabled)))
-                }
-    }
-
-    it should "ensure action update with --web flag only copies existing annotations when new annotations are not provided" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "webaction"
-            val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
-            val createKey = "createKey"
-            val createValue = JsString("createValue")
-            val updateKey = "updateKey"
-            val updateValue = JsString("updateValue")
-            val origKey = "origKey"
-            val origValue = JsString("origValue")
-            val overwrittenValue = JsString("overwrittenValue")
-            val createAnnots = Map(createKey -> createValue, origKey -> origValue)
-            val updateAnnots = Map(updateKey -> updateValue, origKey -> overwrittenValue)
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, file, annotations = createAnnots)
-            }
-
-            wsk.action.create(name, file, web = Some("true"), update = true)
-
-            val existinAnnots = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
-            assert(existinAnnots.startsWith(s"ok: got action $name, displaying field annotations\n"))
-            removeCLIHeader(existinAnnots).parseJson shouldBe JsArray(
-                JsObject(
-                    "key" -> JsString("web-export"),
-                    "value" -> JsBoolean(true)),
-                JsObject(
-                    "key" -> JsString(origKey),
-                    "value" -> origValue),
-                JsObject(
-                    "key" -> JsString("raw-http"),
-                    "value" -> JsBoolean(false)),
-                JsObject(
-                    "key" -> JsString("final"),
-                    "value" -> JsBoolean(true)),
-                JsObject(
-                    "key" -> JsString(createKey),
-                    "value" -> createValue),
-                JsObject(
-                    "key" -> JsString("exec"),
-                    "value" -> JsString("nodejs:6")))
-
-            wsk.action.create(name, file, web = Some("true"), update = true, annotations = updateAnnots)
-
-            val updatedAnnots = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
-            assert(updatedAnnots.startsWith(s"ok: got action $name, displaying field annotations\n"))
-            removeCLIHeader(updatedAnnots).parseJson shouldBe JsArray(
-                JsObject(
-                    "key" -> JsString("web-export"),
-                    "value" -> JsBoolean(true)),
-                JsObject(
-                    "key" -> JsString(origKey),
-                    "value" -> overwrittenValue),
-                JsObject(
-                    "key" -> JsString(updateKey),
-                    "value" -> updateValue),
-                JsObject(
-                    "key" -> JsString("raw-http"),
-                    "value" -> JsBoolean(false)),
-                JsObject(
-                    "key" -> JsString("final"),
-                    "value" -> JsBoolean(true)),
-                JsObject(
-                    "key" -> JsString("exec"),
-                    "value" -> JsString("nodejs:6")))
-    }
-
-    it should "ensure action update creates an action with --web flag" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "webaction"
-            val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, file, web = Some("true"), update = true)
-            }
-
-            val stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
-            assert(stdout.startsWith(s"ok: got action $name, displaying field annotations\n"))
-            removeCLIHeader(stdout).parseJson shouldBe JsArray(
-                JsObject(
-                    "key" -> JsString("web-export"),
-                    "value" -> JsBoolean(true)),
-                JsObject(
-                    "key" -> JsString("raw-http"),
-                    "value" -> JsBoolean(false)),
-                JsObject(
-                    "key" -> JsString("final"),
-                    "value" -> JsBoolean(true)),
-                JsObject(
-                    "key" -> JsString("exec"),
-                    "value" -> JsString("nodejs:6")))
-    }
-
-    it should "reject action create and update with invalid web flag input" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "webaction"
-            val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
-            val invalidInput = "bogus"
-            val errorMsg = s"Invalid argument '$invalidInput' for --web flag. Valid input consist of 'yes', 'true', 'raw', 'false', or 'no'."
-            wsk.action.create(name, file, web = Some(invalidInput), expectedExitCode = MISUSE_EXIT).stderr should include(errorMsg)
-            wsk.action.create(name, file, web = Some(invalidInput), update = true, expectedExitCode = MISUSE_EXIT).stderr should include(errorMsg)
-    }
-
-    it should "invoke action while not encoding &, <, > characters" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "nonescape"
-            val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-            val nonescape = "&<>"
-            val input = Map("payload" -> nonescape.toJson)
-            val output = JsObject("payload" -> JsString(s"hello, $nonescape!"))
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, file)
-            }
-
-            withActivation(wsk.activation, wsk.action.invoke(name, parameters = input)) {
-                activation =>
-                    activation.response.success shouldBe true
-                    activation.response.result shouldBe Some(output)
-                    activation.logs.toList.flatten.filter(_.contains(nonescape)).length shouldBe 1
-            }
-    }
-
-    it should "get an action URL" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val actionName = "action name@_-."
-            val packageName = "package name@_-."
-            val defaultPackageName = "default"
-            val webActionName = "web action name@_-."
-            val nonExistentActionName = "non-existence action"
-            val packagedAction = s"$packageName/$actionName"
-            val packagedWebAction = s"$packageName/$webActionName"
-            val namespace = wsk.namespace.whois()
-            val encodedActionName = URLEncoder.encode(actionName, StandardCharsets.UTF_8.name).replace("+", "%20")
-            val encodedPackageName = URLEncoder.encode(packageName, StandardCharsets.UTF_8.name).replace("+", "%20")
-            val encodedWebActionName = URLEncoder.encode(webActionName, StandardCharsets.UTF_8.name).replace("+", "%20")
-            val encodedNamespace = URLEncoder.encode(namespace, StandardCharsets.UTF_8.name).replace("+", "%20")
-            val actionPath = "https://%s/api/%s/namespaces/%s/actions/%s"
-            val packagedActionPath = s"$actionPath/%s"
-            val webActionPath = "https://%s/api/%s/web/%s/%s/%s"
-
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, _) => action.create(actionName, defaultAction)
-            }
-
-            assetHelper.withCleaner(wsk.action, webActionName) {
-                (action, _) => action.create(webActionName, defaultAction, web = Some("true"))
-            }
-
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, _) => pkg.create(packageName)
-            }
-
-            assetHelper.withCleaner(wsk.action, packagedAction) {
-                (action, _) => action.create(packagedAction, defaultAction)
-            }
-
-            assetHelper.withCleaner(wsk.action, packagedWebAction) {
-                (action, _) => action.create(packagedWebAction, defaultAction, web = Some("true"))
-            }
-
-            wsk.action.get(actionName, url = Some(true)).
-                stdout should include(actionPath.format(wskprops.apihost, wskprops.apiversion, encodedNamespace, encodedActionName))
-
-            // Ensure url flag works when a field filter and summary flag are specified
-            wsk.action.get(actionName, url = Some(true), fieldFilter = Some("field"), summary = true).
-                stdout should include(actionPath.format(wskprops.apihost, wskprops.apiversion, encodedNamespace, encodedActionName))
-
-            wsk.action.get(webActionName, url = Some(true)).
-                stdout should include(webActionPath.format(wskprops.apihost, wskprops.apiversion, encodedNamespace, defaultPackageName, encodedWebActionName))
-
-            wsk.action.get(packagedAction, url = Some(true)).
-                stdout should include(packagedActionPath.format(wskprops.apihost, wskprops.apiversion, encodedNamespace, encodedPackageName, encodedActionName))
-
-            wsk.action.get(packagedWebAction, url = Some(true)).
-                stdout should include(webActionPath.format(wskprops.apihost, wskprops.apiversion, encodedNamespace, encodedPackageName, encodedWebActionName))
-
-            wsk.action.get(nonExistentActionName, url = Some(true), expectedExitCode = NOT_FOUND)
-    }
-    it should "limit length of HTTP request and response bodies for --verbose" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "limitVerbose"
-            val msg = "will be truncated"
-            val params = Seq("-p", "bigValue", "a" * 1000)
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some(TestCLIUtils.getTestActionFilename("echo.js")))
-            }
-
-            val truncated = wsk.cli(Seq("action", "invoke", name, "-b", "-v", "--auth", wskprops.authKey) ++ params ++ wskprops.overrides).stdout
-            msg.r.findAllIn(truncated).length shouldBe 2
-
-            val notTruncated = wsk.cli(Seq("action", "invoke", name, "-b", "-d", "--auth", wskprops.authKey) ++ params ++ wskprops.overrides).stdout
-            msg.r.findAllIn(notTruncated).length shouldBe 0
-    }
-
-    it should "denote bound and finalized action parameters for action summaries" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val nameBoundParams = "actionBoundParams"
-            val nameFinalParams = "actionFinalParams"
-            val paramAnnot = "paramAnnot"
-            val paramOverlap = "paramOverlap"
-            val paramBound = "paramBound"
-            val annots = Map(
-                "parameters" -> JsArray(
-                    JsObject(
-                        "name" -> JsString(paramAnnot),
-                        "description" -> JsString("Annotated")),
-                    JsObject(
-                        "name" -> JsString(paramOverlap),
-                        "description" -> JsString("Annotated And Bound"))))
-            val annotsFinal = Map(
-                "final" -> JsBoolean(true),
-                "parameters" -> JsArray(
-                    JsObject(
-                        "name" -> JsString(paramAnnot),
-                        "description" -> JsString("Annotated Parameter description")),
-                    JsObject(
-                        "name" -> JsString(paramOverlap),
-                        "description" -> JsString("Annotated And Bound"))))
-            val paramsBound = Map(
-                paramBound -> JsString("Bound"),
-                paramOverlap -> JsString("Bound And Annotated"))
-
-            assetHelper.withCleaner(wsk.action, nameBoundParams) {
-                (action, _) =>
-                    action.create(nameBoundParams, defaultAction, annotations = annots, parameters = paramsBound)
-            }
-            assetHelper.withCleaner(wsk.action, nameFinalParams) {
-                (action, _) =>
-                    action.create(nameFinalParams, defaultAction, annotations = annotsFinal, parameters = paramsBound)
-            }
-
-            val stdoutBound = wsk.action.get(nameBoundParams, summary = true).stdout
-            val stdoutFinal = wsk.action.get(nameFinalParams, summary = true).stdout
-
-            stdoutBound should include (
-                s"(parameters: $paramAnnot, *$paramBound, *$paramOverlap)")
-            stdoutFinal should include (
-                s"(parameters: $paramAnnot, **$paramBound, **$paramOverlap)")
-    }
-
-    it should "create, and get an action summary without a description and/or defined parameters" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val actNameNoParams = "actionNoParams"
-            val actNameNoDesc = "actionNoDesc"
-            val actNameNoDescOrParams = "actionNoDescOrParams"
-            val desc = "Action description"
-            val descFromParamsResp = "Returns a result based on parameters"
-            val annotsNoParams = Map(
-                "description" -> JsString(desc)
-            )
-            val annotsNoDesc = Map(
-                "parameters" -> JsArray(
-                    JsObject(
-                        "name" -> JsString("paramName1"),
-                        "description" -> JsString("Parameter description 1")),
-                    JsObject(
-                        "name" -> JsString("paramName2"),
-                        "description" -> JsString("Parameter description 2"))))
-
-            assetHelper.withCleaner(wsk.action, actNameNoDesc) {
-                (action, _) =>
-                    action.create(actNameNoDesc, defaultAction, annotations = annotsNoDesc)
-            }
-            assetHelper.withCleaner(wsk.action, actNameNoParams) {
-                (action, _) =>
-                    action.create(actNameNoParams, defaultAction, annotations = annotsNoParams)
-            }
-            assetHelper.withCleaner(wsk.action, actNameNoDescOrParams) {
-                (action, _) =>
-                    action.create(actNameNoDescOrParams, defaultAction)
-            }
-
-            val stdoutNoDesc = wsk.action.get(actNameNoDesc, summary = true).stdout
-            val stdoutNoParams = wsk.action.get(actNameNoParams, summary = true).stdout
-            val stdoutNoDescOrParams = wsk.action.get(actNameNoDescOrParams, summary = true).stdout
-            val namespace = wsk.namespace.whois()
-
-            stdoutNoDesc should include regex (
-                s"(?i)action /${namespace}/${actNameNoDesc}: ${descFromParamsResp} paramName1 and paramName2\\s*\\(parameters: paramName1, paramName2\\)")
-            stdoutNoParams should include regex (
-                s"(?i)action /${namespace}/${actNameNoParams}: ${desc}\\s*\\(parameters: none defined\\)")
-            stdoutNoDescOrParams should include regex (
-                s"(?i)action /${namespace}/${actNameNoDescOrParams}\\s*\\(parameters: none defined\\)")
-    }
-
-    behavior of "Wsk packages"
-
-    it should "create, and delete a package" in {
-        val name = "createDeletePackage"
-        wsk.pkg.create(name).stdout should include(s"ok: created package $name")
-        wsk.pkg.delete(name).stdout should include(s"ok: deleted package $name")
-    }
-
-    it should "create, and get a package to verify parameter and annotation parsing" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "packageAnnotAndParamParsing"
-
-            assetHelper.withCleaner(wsk.pkg, name) {
-                (pkg, _) =>
-                    pkg.create(name, annotations = getValidJSONTestArgInput, parameters = getValidJSONTestArgInput)
-            }
-
-            val stdout = wsk.pkg.get(name).stdout
-            assert(stdout.startsWith(s"ok: got package $name\n"))
-
-            val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-            val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-            val escapedJSONArr = getValidJSONTestArgOutput.convertTo[JsArray].elements
-
-            for (expectedItem <- escapedJSONArr) {
-                receivedParams should contain(expectedItem)
-                receivedAnnots should contain(expectedItem)
-            }
-    }
-
-    it should "create, and get a package to verify file parameter and annotation parsing" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "packageAnnotAndParamFileParsing"
-            val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-            val argInput = Some(TestCLIUtils.getTestActionFilename("validInput1.json"))
-
-            assetHelper.withCleaner(wsk.pkg, name) {
-                (pkg, _) =>
-                    pkg.create(name, annotationFile = argInput, parameterFile = argInput)
-            }
-
-            val stdout = wsk.pkg.get(name).stdout
-            assert(stdout.startsWith(s"ok: got package $name\n"))
-
-            val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-            val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-            val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
-
-            for (expectedItem <- escapedJSONArr) {
-                receivedParams should contain(expectedItem)
-                receivedAnnots should contain(expectedItem)
-            }
-    }
-
-    it should "create a package with the proper parameter and annotation escapes" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "packageEscapses"
-
-            assetHelper.withCleaner(wsk.pkg, name) {
-                (pkg, _) =>
-                    pkg.create(name, parameters = getEscapedJSONTestArgInput,
-                        annotations = getEscapedJSONTestArgInput)
-            }
-
-            val stdout = wsk.pkg.get(name).stdout
-            assert(stdout.startsWith(s"ok: got package $name\n"))
-
-            val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-            val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-            val escapedJSONArr = getEscapedJSONTestArgOutput.convertTo[JsArray].elements
-
-            for (expectedItem <- escapedJSONArr) {
-                receivedParams should contain(expectedItem)
-                receivedAnnots should contain(expectedItem)
-            }
-    }
-
-    it should "report conformance error accessing action as package" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "aAsP"
-            val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, file)
-            }
-
-            wsk.pkg.get(name, expectedExitCode = CONFLICT).
-                stderr should include(Messages.conformanceMessage)
-
-            wsk.pkg.bind(name, "bogus", expectedExitCode = CONFLICT).
-                stderr should include(Messages.requestedBindingIsNotValid)
-
-            wsk.pkg.bind("bogus", "alsobogus", expectedExitCode = BAD_REQUEST).
-                stderr should include(Messages.bindingDoesNotExist)
-
-    }
-
-    it should "create, and get a package summary without a description and/or parameters" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val pkgNoDesc = "pkgNoDesc"
-            val pkgNoParams = "pkgNoParams"
-            val pkgNoDescOrParams = "pkgNoDescOrParams"
-            val pkgDesc = "Package description"
-            val descFromParams = "Returns a result based on parameters"
-            val namespace = wsk.namespace.whois()
-            val qualpkgNoDesc = s"/${namespace}/${pkgNoDesc}"
-            val qualpkgNoParams = s"/${namespace}/${pkgNoParams}"
-            val qualpkgNoDescOrParams = s"/${namespace}/${pkgNoDescOrParams}"
-
-            val pkgAnnotsNoParams = Map(
-                "description" -> JsString(pkgDesc)
-            )
-            val pkgAnnotsNoDesc = Map(
-                "parameters" -> JsArray(
-                    JsObject(
-                        "name" -> JsString("paramName1"),
-                        "description" -> JsString("Parameter description 1")),
-                    JsObject(
-                        "name" -> JsString("paramName2"),
-                        "description" -> JsString("Parameter description 2"))))
-
-            assetHelper.withCleaner(wsk.pkg, pkgNoDesc) {
-                (pkg, _) =>
-                    pkg.create(pkgNoDesc, annotations = pkgAnnotsNoDesc)
-            }
-            assetHelper.withCleaner(wsk.pkg, pkgNoParams) {
-                (pkg, _) =>
-                    pkg.create(pkgNoParams, annotations = pkgAnnotsNoParams)
-            }
-            assetHelper.withCleaner(wsk.pkg, pkgNoDescOrParams) {
-                (pkg, _) =>
-                    pkg.create(pkgNoDescOrParams)
-            }
-
-            val stdoutNoDescPkg = wsk.pkg.get(pkgNoDesc, summary = true).stdout
-            val stdoutNoParamsPkg = wsk.pkg.get(pkgNoParams, summary = true).stdout
-            val stdoutNoDescOrParams = wsk.pkg.get(pkgNoDescOrParams, summary = true).stdout
-
-            stdoutNoDescPkg should include regex (
-                s"(?i)package ${qualpkgNoDesc}: ${descFromParams} paramName1 and paramName2\\s*\\(parameters: paramName1, paramName2\\)")
-            stdoutNoParamsPkg should include regex (
-                s"(?i)package ${qualpkgNoParams}: ${pkgDesc}\\s*\\(parameters: none defined\\)")
-            stdoutNoDescOrParams should include regex (
-                s"(?i)package ${qualpkgNoDescOrParams}\\s*\\(parameters: none defined\\)")
-    }
-
-    it should "denote bound package parameters for package summaries" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val pkgBoundParams = "pkgBoundParams"
-            val pkgParamAnnot = "pkgParamAnnot"
-            val pkgParamOverlap = "pkgParamOverlap"
-            val pkgParamBound = "pkgParamBound"
-            val pkgAnnots = Map(
-                "parameters" -> JsArray(
-                    JsObject(
-                        "name" -> JsString(pkgParamAnnot),
-                        "description" -> JsString("Annotated")),
-                    JsObject(
-                        "name" -> JsString(pkgParamOverlap),
-                        "description" -> JsString("Annotated And Bound"))))
-            val pkgParamsBound = Map(
-                pkgParamBound -> JsString("Bound"),
-                pkgParamOverlap -> JsString("Bound And Annotated"))
-
-            assetHelper.withCleaner(wsk.pkg, pkgBoundParams) {
-                (pkg, _) =>
-                    pkg.create(pkgBoundParams, annotations = pkgAnnots, parameters = pkgParamsBound)
-            }
-
-            val pkgStdoutBound = wsk.pkg.get(pkgBoundParams, summary = true).stdout
-
-            pkgStdoutBound should include (s"(parameters: $pkgParamAnnot, *$pkgParamBound, *$pkgParamOverlap)")
-    }
-
-    behavior of "Wsk triggers"
-
-    it should "create, and get a trigger to verify parameter and annotation parsing" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "triggerAnnotAndParamParsing"
-
-            assetHelper.withCleaner(wsk.trigger, name) {
-                (trigger, _) =>
-                    trigger.create(name, annotations = getValidJSONTestArgInput, parameters = getValidJSONTestArgInput)
-            }
-
-            val stdout = wsk.trigger.get(name).stdout
-            assert(stdout.startsWith(s"ok: got trigger $name\n"))
-
-            val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-            val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-            val escapedJSONArr = getValidJSONTestArgOutput.convertTo[JsArray].elements
-
-            for (expectedItem <- escapedJSONArr) {
-                receivedParams should contain(expectedItem)
-                receivedAnnots should contain(expectedItem)
-            }
-    }
-
-    it should "create, and get a trigger to verify file parameter and annotation parsing" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "triggerAnnotAndParamFileParsing"
-            val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-            val argInput = Some(TestCLIUtils.getTestActionFilename("validInput1.json"))
-
-            assetHelper.withCleaner(wsk.trigger, name) {
-                (trigger, _) =>
-                    trigger.create(name, annotationFile = argInput, parameterFile = argInput)
-            }
-
-            val stdout = wsk.trigger.get(name).stdout
-            assert(stdout.startsWith(s"ok: got trigger $name\n"))
-
-            val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-            val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-            val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
-
-            for (expectedItem <- escapedJSONArr) {
-                receivedParams should contain(expectedItem)
-                receivedAnnots should contain(expectedItem)
-            }
-    }
-
-    it should "display a trigger summary when --summary flag is used with 'wsk trigger get'" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val triggerName = "mySummaryTrigger"
-            assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) {
-                (trigger, name) => trigger.create(name)
-            }
-
-            // Summary namespace should match one of the allowable namespaces (typically 'guest')
-            val ns = wsk.namespace.whois()
-            val stdout = wsk.trigger.get(triggerName, summary = true).stdout
-            stdout should include regex (s"(?i)trigger\\s+/$ns/$triggerName")
-    }
-
-    it should "create a trigger with the proper parameter and annotation escapes" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "triggerEscapes"
-
-            assetHelper.withCleaner(wsk.trigger, name) {
-                (trigger, _) =>
-                    trigger.create(name, parameters = getEscapedJSONTestArgInput,
-                        annotations = getEscapedJSONTestArgInput)
-            }
-
-            val stdout = wsk.trigger.get(name).stdout
-            assert(stdout.startsWith(s"ok: got trigger $name\n"))
-
-            val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
-            val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
-            val escapedJSONArr = getEscapedJSONTestArgOutput.convertTo[JsArray].elements
-
-            for (expectedItem <- escapedJSONArr) {
-                receivedParams should contain(expectedItem)
-                receivedAnnots should contain(expectedItem)
-            }
-    }
-
-    it should "not create a trigger when feed fails to initialize" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.trigger, "badfeed", confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"bogus"), expectedExitCode = ANY_ERROR_EXIT).
-                        exitCode should equal(NOT_FOUND)
-                    trigger.get(name, expectedExitCode = NOT_FOUND)
-
-                    trigger.create(name, feed = Some(s"bogus/feed"), expectedExitCode = ANY_ERROR_EXIT).
-                        exitCode should equal(NOT_FOUND)
-                    trigger.get(name, expectedExitCode = NOT_FOUND)
-            }
-    }
-
-    it should "denote bound trigger parameters for trigger summaries" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val trgBoundParams = "trgBoundParams"
-            val trgParamAnnot = "trgParamAnnot"
-            val trgParamOverlap = "trgParamOverlap"
-            val trgParamBound = "trgParamBound"
-            val trgAnnots = Map(
-                "parameters" -> JsArray(
-                    JsObject(
-                        "name" -> JsString(trgParamAnnot),
-                        "description" -> JsString("Annotated")),
-                    JsObject(
-                        "name" -> JsString(trgParamOverlap),
-                        "description" -> JsString("Annotated And Bound"))))
-            val trgParamsBound = Map(
-                trgParamBound -> JsString("Bound"),
-                trgParamOverlap -> JsString("Bound And Annotated"))
-
-            assetHelper.withCleaner(wsk.trigger, trgBoundParams) {
-                (trigger, _) =>
-                    trigger.create(trgBoundParams, annotations = trgAnnots, parameters = trgParamsBound)
-            }
-
-            val trgStdoutBound = wsk.trigger.get(trgBoundParams, summary = true).stdout
-
-            trgStdoutBound should include (s"(parameters: $trgParamAnnot, *$trgParamBound, *$trgParamOverlap)")
-    }
-
-    it should "create, and get a trigger summary without a description and/or parameters" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val trgNoDesc = "trgNoDesc"
-            val trgNoParams = "trgNoParams"
-            val trgNoDescOrParams = "trgNoDescOrParams"
-            val trgDesc = "Package description"
-            val descFromParams = "Returns a result based on parameters"
-            val namespace = wsk.namespace.whois()
-            val qualtrgNoDesc = s"/${namespace}/${trgNoDesc}"
-            val qualtrgNoParams = s"/${namespace}/${trgNoParams}"
-            val qualtrgNoDescOrParams = s"/${namespace}/${trgNoDescOrParams}"
-
-            val trgAnnotsNoParams = Map(
-                "description" -> JsString(trgDesc)
-            )
-            val trgAnnotsNoDesc = Map(
-                "parameters" -> JsArray(
-                    JsObject(
-                        "name" -> JsString("paramName1"),
-                        "description" -> JsString("Parameter description 1")),
-                    JsObject(
-                        "name" -> JsString("paramName2"),
-                        "description" -> JsString("Parameter description 2"))))
-
-            assetHelper.withCleaner(wsk.trigger, trgNoDesc) {
-                (trigger, _) =>
-                    trigger.create(trgNoDesc, annotations = trgAnnotsNoDesc)
-            }
-            assetHelper.withCleaner(wsk.trigger, trgNoParams) {
-                (trigger, _) =>
-                    trigger.create(trgNoParams, annotations = trgAnnotsNoParams)
-            }
-            assetHelper.withCleaner(wsk.trigger, trgNoDescOrParams) {
-                (trigger, _) =>
-                    trigger.create(trgNoDescOrParams)
-            }
-
-            val stdoutNoDescPkg = wsk.trigger.get(trgNoDesc, summary = true).stdout
-            val stdoutNoParamsPkg = wsk.trigger.get(trgNoParams, summary = true).stdout
-            val stdoutNoDescOrParams = wsk.trigger.get(trgNoDescOrParams, summary = true).stdout
-
-            stdoutNoDescPkg should include regex (
-                s"(?i)trigger ${qualtrgNoDesc}: ${descFromParams} paramName1 and paramName2\\s*\\(parameters: paramName1, paramName2\\)")
-            stdoutNoParamsPkg should include regex (
-                s"(?i)trigger ${qualtrgNoParams}: ${trgDesc}\\s*\\(parameters: none defined\\)")
-            stdoutNoDescOrParams should include regex (
-                s"(?i)trigger ${qualtrgNoDescOrParams}\\s*\\(parameters: none defined\\)")
-    }
-
-    behavior of "Wsk entity list formatting"
-
-    it should "create, and list a package with a long name" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "x" * 70
-            assetHelper.withCleaner(wsk.pkg, name) {
-                (pkg, _) =>
-                    pkg.create(name)
-            }
-            retry({
-                wsk.pkg.list().stdout should include(s"$name private")
-            }, 5, Some(1 second))
-    }
-
-    it should "create, and list an action with a long name" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "x" * 70
-            val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file)
-            }
-            retry({
-                wsk.action.list().stdout should include(s"$name private nodejs")
-            }, 5, Some(1 second))
-    }
-
-    it should "create, and list a trigger with a long name" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "x" * 70
-            assetHelper.withCleaner(wsk.trigger, name) {
-                (trigger, _) =>
-                    trigger.create(name)
-            }
-            retry({
-                wsk.trigger.list().stdout should include(s"$name private")
-            }, 5, Some(1 second))
-    }
-
-    it should "create, and list a rule with a long name" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val ruleName = "x" * 70
-            val triggerName = "listRulesTrigger"
-            val actionName = "listRulesAction";
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) => trigger.create(name)
-            }
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, name) => action.create(name, defaultAction)
-            }
-            assetHelper.withCleaner(wsk.rule, ruleName) {
-                (rule, name) =>
-                    rule.create(name, trigger = triggerName, action = actionName)
-            }
-            retry({
-                wsk.rule.list().stdout should include(s"$ruleName private")
-            }, 5, Some(1 second))
-    }
-
-    it should "return a list of alphabetized actions" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            // Declare 4 actions, create them out of alphabetical order
-            val actionName = "actionAlphaTest"
-            for (i <- 1 to 3) {
-                val name = s"$actionName$i"
-                assetHelper.withCleaner(wsk.action, name) {
-                    (action, name) =>
-                        action.create(name, defaultAction)
-                }
-            }
-            retry({
-                val original = wsk.action.list(nameSort = Some(true)).stdout
-                // Create list with action names in correct order
-                val scalaSorted = List(s"${actionName}1", s"${actionName}2", s"${actionName}3")
-                // Filter out everything not previously created
-                val regex = s"${actionName}[1-3]".r
-                // Retrieve action names into list as found in original
-                val list  = (regex.findAllMatchIn(original)).toList
-                scalaSorted.toString shouldEqual list.toString
-            }, 5, Some(1 second))
-    }
-
-    it should "return an alphabetized list with default package actions on top" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            // Declare 4 actions, create them out of alphabetical order
-            val actionName = "actionPackageAlphaTest"
-            val packageName = "packageAlphaTest"
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, actionName) =>
-                    action.create(actionName, defaultAction)
-            }
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, packageName) =>
-                    pkg.create(packageName)
-            }
-            for (i <- 1 to 3) {
-                val name = s"${packageName}/${actionName}$i"
-                assetHelper.withCleaner(wsk.action, name) {
-                    (action, name) =>
-                        action.create(name, defaultAction)
-                }
-            }
-            retry({
-                val original = wsk.action.list(nameSort = Some(true)).stdout
-                // Create list with action names in correct order
-                val scalaSorted = List(s"$actionName", s"${packageName}/${actionName}1", s"${packageName}/${actionName}2", s"${packageName}/${actionName}3")
-                // Filter out everything not previously created
-                val regexNoPackage = s"$actionName".r
-                val regexWithPackage = s"${packageName}/${actionName}[1-3]".r
-                // Retrieve action names into list as found in original
-                val list = regexNoPackage.findFirstIn(original).get :: (regexWithPackage.findAllMatchIn(original)).toList
-                scalaSorted.toString shouldEqual list.toString
-            }, 5, Some(1 second))
-    }
-
-    it should "return a list of alphabetized packages" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            // Declare 3 packages, create them out of alphabetical order
-            val packageName = "pkgAlphaTest"
-            for (i <- 1 to 3) {
-                val name = s"$packageName$i"
-                assetHelper.withCleaner(wsk.pkg, name) {
-                    (pkg, name) =>
-                        pkg.create(name)
-                }
-            }
-            retry({
-                val original = wsk.pkg.list(nameSort = Some(true)).stdout
-                // Create list with package names in correct order
-                val scalaSorted = List(s"${packageName}1", s"${packageName}2", s"${packageName}3")
-                // Filter out everything not previously created
-                val regex = s"${packageName}[1-3]".r
-                // Retrieve package names into list as found in original
-                val list  = (regex.findAllMatchIn(original)).toList
-                scalaSorted.toString shouldEqual list.toString
-            }, 5, Some(1 second))
+class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
+
+  implicit val wskprops = WskProps()
+  val wsk = new Wsk
+  val defaultAction = Some(TestUtils.getTestActionFilename("hello.js"))
+
+  behavior of "Wsk CLI usage"
+
+  it should "show help and usage info" in {
+    val stdout = wsk.cli(Seq()).stdout
+    stdout should include regex ("""(?i)Usage:""")
+    stdout should include regex ("""(?i)Flags""")
+    stdout should include regex ("""(?i)Available commands""")
+    stdout should include regex ("""(?i)--help""")
+  }
+
+  it should "show help and usage info using the default language" in {
+    val env = Map("LANG" -> "de_DE")
+    // Call will fail with exit code 2 if language not supported
+    wsk.cli(Seq("-h"), env = env)
+  }
+
+  it should "show cli build version" in {
+    val stdout = wsk.cli(Seq("property", "get", "--cliversion")).stdout
+    stdout should include regex ("""(?i)whisk CLI version\s+201.*""")
+  }
+
+  it should "show api version" in {
+    val stdout = wsk.cli(Seq("property", "get", "--apiversion")).stdout
+    stdout should include regex ("""(?i)whisk API version\s+v1""")
+  }
+
+  it should "reject bad command" in {
+    val result = wsk.cli(Seq("bogus"), expectedExitCode = ERROR_EXIT)
+    result.stderr should include regex ("""(?i)Run 'wsk --help' for usage""")
+  }
+
+  it should "allow a 3 part Fully Qualified Name (FQN) without a leading '/'" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val guestNamespace = wsk.namespace.whois()
+      val packageName = "packageName3ptFQN"
+      val actionName = "actionName3ptFQN"
+      val triggerName = "triggerName3ptFQN"
+      val ruleName = "ruleName3ptFQN"
+      val fullQualifiedName = s"${guestNamespace}/${packageName}/${actionName}"
+      // Used for action and rule creation below
+      assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
+        pkg.create(packageName)
+      }
+      assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, _) =>
+        trigger.create(triggerName)
+      }
+      // Test action and rule creation where action name is 3 part FQN w/out leading slash
+      assetHelper.withCleaner(wsk.action, fullQualifiedName) { (action, _) =>
+        action.create(fullQualifiedName, defaultAction)
+      }
+      assetHelper.withCleaner(wsk.rule, ruleName) { (rule, _) =>
+        rule.create(ruleName, trigger = triggerName, action = fullQualifiedName)
+      }
+
+      wsk.action.invoke(fullQualifiedName).stdout should include(s"ok: invoked /$fullQualifiedName")
+      wsk.action.get(fullQualifiedName).stdout should include(s"ok: got action ${packageName}/${actionName}")
+  }
+
+  behavior of "Wsk actions"
+
+  it should "reject creating entities with invalid names" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val names = Seq(
+      ("", ERROR_EXIT),
+      (" ", BAD_REQUEST),
+      ("hi+there", BAD_REQUEST),
+      ("$hola", BAD_REQUEST),
+      ("dora?", BAD_REQUEST),
+      ("|dora|dora?", BAD_REQUEST))
+
+    names foreach {
+      case (name, ec) =>
+        assetHelper.withCleaner(wsk.action, name, confirmDelete = false) { (action, _) =>
+          action.create(name, defaultAction, expectedExitCode = ec)
+        }
     }
+  }
+
+  it should "reject create with missing file" in {
+    wsk.action.create("missingFile", Some("notfound"), expectedExitCode = MISUSE_EXIT).stderr should include(
+      "not a valid file")
+  }
+
+  it should "reject action update when specified file is missing" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    // Create dummy action to update
+    val name = "updateMissingFile"
+    val file = Some(TestUtils.getTestActionFilename("hello.js"))
+    assetHelper.withCleaner(wsk.action, name) { (action, name) =>
+      action.create(name, file)
+    }
+    // Update it with a missing file
+    wsk.action.create(name, Some("notfound"), update = true, expectedExitCode = MISUSE_EXIT)
+  }
+
+  it should "reject action update for sequence with no components" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "updateMissingComponents"
+    val file = Some(TestUtils.getTestActionFilename("hello.js"))
+    assetHelper.withCleaner(wsk.action, name) { (action, name) =>
+      action.create(name, file)
+    }
+    wsk.action.create(name, None, update = true, kind = Some("sequence"), expectedExitCode = MISUSE_EXIT)
+  }
+
+  it should "create, and get an action to verify parameter and annotation parsing" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "actionAnnotations"
+      val file = Some(TestUtils.getTestActionFilename("hello.js"))
+
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, file, annotations = getValidJSONTestArgInput, parameters = getValidJSONTestArgInput)
+      }
+
+      val stdout = wsk.action.get(name).stdout
+      assert(stdout.startsWith(s"ok: got action $name\n"))
+
+      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
+      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+      val escapedJSONArr = getValidJSONTestArgOutput.convertTo[JsArray].elements
+
+      for (expectedItem <- escapedJSONArr) {
+        receivedParams should contain(expectedItem)
+        receivedAnnots should contain(expectedItem)
+      }
+  }
+
+  it should "create, and get an action to verify file parameter and annotation parsing" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "actionAnnotAndParamParsing"
+      val file = Some(TestUtils.getTestActionFilename("hello.js"))
+      val argInput = Some(TestUtils.getTestActionFilename("validInput1.json"))
+
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, file, annotationFile = argInput, parameterFile = argInput)
+      }
+
+      val stdout = wsk.action.get(name).stdout
+      assert(stdout.startsWith(s"ok: got action $name\n"))
+
+      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
+      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+      val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
+
+      for (expectedItem <- escapedJSONArr) {
+        receivedParams should contain(expectedItem)
+        receivedAnnots should contain(expectedItem)
+      }
+  }
+
+  it should "create an action with the proper parameter and annotation escapes" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "actionEscapes"
+      val file = Some(TestUtils.getTestActionFilename("hello.js"))
+
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, file, parameters = getEscapedJSONTestArgInput, annotations = getEscapedJSONTestArgInput)
+      }
+
+      val stdout = wsk.action.get(name).stdout
+      assert(stdout.startsWith(s"ok: got action $name\n"))
+
+      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
+      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+      val escapedJSONArr = getEscapedJSONTestArgOutput.convertTo[JsArray].elements
+
+      for (expectedItem <- escapedJSONArr) {
+        receivedParams should contain(expectedItem)
+        receivedAnnots should contain(expectedItem)
+      }
+  }
+
+  it should "invoke an action that exits during initialization and get appropriate error" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "abort init"
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, Some(TestUtils.getTestActionFilename("initexit.js")))
+      }
+
+      withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
+        val response = activation.response
+        response.result.get.fields("error") shouldBe Messages.abnormalInitialization.toJson
+        response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ContainerError)
+      }
+  }
+
+  it should "invoke an action that hangs during initialization and get appropriate error" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "hang init"
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, Some(TestUtils.getTestActionFilename("initforever.js")), timeout = Some(3 seconds))
+      }
+
+      withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
+        val response = activation.response
+        response.result.get.fields("error") shouldBe Messages.timedoutActivation(3 seconds, true).toJson
+        response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
+      }
+  }
+
+  it should "invoke an action that exits during run and get appropriate error" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "abort run"
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, Some(TestUtils.getTestActionFilename("runexit.js")))
+      }
+
+      withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
+        val response = activation.response
+        response.result.get.fields("error") shouldBe Messages.abnormalRun.toJson
+        response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ContainerError)
+      }
+  }
+
+  it should "retrieve the last activation using --last flag" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val auth: Seq[String] = Seq("--auth", wskprops.authKey)
+    val includeStr = "hello, undefined!"
+
+    assetHelper.withCleaner(wsk.action, "lastName") { (action, _) =>
+      wsk.action.create("lastName", defaultAction)
+    }
+    retry(
+      {
+        val lastInvoke = wsk.action.invoke("lastName")
+        withActivation(wsk.activation, lastInvoke) {
+          activation =>
+            val lastFlag = Seq(
+              (Seq("activation", "get", "publish", "--last"), activation.activationId),
+              (Seq("activation", "get", "--last"), activation.activationId),
+              (Seq("activation", "logs", "--last"), includeStr),
+              (Seq("activation", "result", "--last"), includeStr))
 
-    it should "return a list of alphabetized triggers" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            // Declare 4 triggers, create them out of alphabetical order
-            val triggerName = "triggerAlphaTest"
-            for (i <- 1 to 3) {
-                val name = s"$triggerName$i"
-                assetHelper.withCleaner(wsk.trigger, name) {
-                    (trigger, name) =>
-                        trigger.create(name)
-                }
-            }
             retry({
-                val original = wsk.trigger.list(nameSort = Some(true)).stdout
-                // Create list with trigger names in correct order
-                val scalaSorted = List(s"${triggerName}1", s"${triggerName}2", s"${triggerName}3")
-                // Filter out everything not previously created
-                val regex = s"${triggerName}[1-3]".r
-                // Retrieve trigger names into list as found in original
-                val list  = (regex.findAllMatchIn(original)).toList
-                scalaSorted.toString shouldEqual list.toString
-            }, 5, Some(1 second))
-    }
+              lastFlag foreach {
+                case (cmd, output) =>
+                  val stdout = wsk.cli(cmd ++ wskprops.overrides ++ auth, expectedExitCode = SUCCESS_EXIT).stdout
+                  stdout should include(output)
+              }
+            }, waitBeforeRetry = Some(500.milliseconds))
 
-    it should "return a list of alphabetized rules" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            // Declare a trigger and an action for the purposes of creating rules
-            val triggerName = "listRulesTrigger"
-            val actionName = "listRulesAction"
-
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) => trigger.create(name)
-            }
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, name) => action.create(name, defaultAction)
-            }
-            // Declare 3 rules, create them out of alphabetical order
-            val ruleName = "ruleAlphaTest"
-            for (i <- 1 to 3) {
-                val name = s"$ruleName$i"
-                assetHelper.withCleaner(wsk.rule, name) {
-                    (rule, name) =>
-                        rule.create(name, trigger = triggerName, action = actionName)
-                }
-            }
-            retry({
-                val original = wsk.rule.list(nameSort = Some(true)).stdout
-                // Create list with rule names in correct order
-                val scalaSorted = List(s"${ruleName}1", s"${ruleName}2", s"${ruleName}3")
-                // Filter out everything not previously created
-                val regex = s"${ruleName}[1-3]".r
-                // Retrieve rule names into list as found in original
-                val list  = (regex.findAllMatchIn(original)).toList
-                scalaSorted.toString shouldEqual list.toString
-            })
-    }
-
-    behavior of "Wsk params and annotations"
-
-    it should "reject commands that are executed with invalid JSON for annotations and parameters" in {
-        val invalidJSONInputs = getInvalidJSONInput
-        val invalidJSONFiles = Seq(
-            TestCLIUtils.getTestActionFilename("malformed.js"),
-            TestCLIUtils.getTestActionFilename("invalidInput1.json"),
-            TestCLIUtils.getTestActionFilename("invalidInput2.json"),
-            TestCLIUtils.getTestActionFilename("invalidInput3.json"),
-            TestCLIUtils.getTestActionFilename("invalidInput4.json"))
-        val paramCmds = Seq(
-            Seq("action", "create", "actionName", TestCLIUtils.getTestActionFilename("hello.js")),
-            Seq("action", "update", "actionName", TestCLIUtils.getTestActionFilename("hello.js")),
-            Seq("action", "invoke", "actionName"),
-            Seq("package", "create", "packageName"),
-            Seq("package", "update", "packageName"),
-            Seq("package", "bind", "packageName", "boundPackageName"),
-            Seq("trigger", "create", "triggerName"),
-            Seq("trigger", "update", "triggerName"),
-            Seq("trigger", "fire", "triggerName"))
-        val annotCmds = Seq(
-            Seq("action", "create", "actionName", TestCLIUtils.getTestActionFilename("hello.js")),
-            Seq("action", "update", "actionName", TestCLIUtils.getTestActionFilename("hello.js")),
-            Seq("package", "create", "packageName"),
-            Seq("package", "update", "packageName"),
-            Seq("package", "bind", "packageName", "boundPackageName"),
-            Seq("trigger", "create", "triggerName"),
-            Seq("trigger", "update", "triggerName"))
-
-        for (cmd <- paramCmds) {
-            for (invalid <- invalidJSONInputs) {
-                wsk.cli(cmd ++ Seq("-p", "key", invalid) ++ wskprops.overrides, expectedExitCode = ERROR_EXIT)
-                    .stderr should include("Invalid parameter argument")
-            }
-
-            for (invalid <- invalidJSONFiles) {
-                wsk.cli(cmd ++ Seq("-P", invalid) ++ wskprops.overrides, expectedExitCode = ERROR_EXIT)
-                    .stderr should include("Invalid parameter argument")
-
-            }
         }
-
-        for (cmd <- annotCmds) {
-            for (invalid <- invalidJSONInputs) {
-                wsk.cli(cmd ++ Seq("-a", "key", invalid) ++ wskprops.overrides, expectedExitCode = ERROR_EXIT)
-                    .stderr should include("Invalid annotation argument")
-            }
-
-            for (invalid <- invalidJSONFiles) {
-                wsk.cli(cmd ++ Seq("-A", invalid) ++ wskprops.overrides, expectedExitCode = ERROR_EXIT)
-                    .stderr should include("Invalid annotation argument")
-            }
+      },
+      waitBeforeRetry = Some(1.second),
+      N = 5)
+  }
+
+  it should "ensure keys are not omitted from activation record" in withAssetCleaner(wskprops) {
+    val name = "activationRecordTest"
+
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, Some(TestUtils.getTestActionFilename("argCheck.js")))
+      }
+
+      val run = wsk.action.invoke(name)
+      withActivation(wsk.activation, run) { activation =>
+        activation.start should be > Instant.EPOCH
+        activation.end should be > Instant.EPOCH
+        activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.Success)
+        activation.response.success shouldBe true
+        activation.response.result shouldBe Some(JsObject())
+        activation.logs shouldBe Some(List())
+        activation.annotations shouldBe defined
+      }
+  }
+
+  it should "write the action-path and the limits to the annotations" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "annotations"
+      val memoryLimit = 512 MB
+      val logLimit = 1 MB
+      val timeLimit = 60 seconds
+
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(
+          name,
+          Some(TestUtils.getTestActionFilename("helloAsync.js")),
+          memory = Some(memoryLimit),
+          timeout = Some(timeLimit),
+          logsize = Some(logLimit))
+      }
+
+      val run = wsk.action.invoke(name, Map("payload" -> "this is a test".toJson))
+      withActivation(wsk.activation, run) { activation =>
+        activation.response.status shouldBe "success"
+        val annotations = activation.annotations.get
+
+        val limitsObj = JsObject(
+          "key" -> JsString("limits"),
+          "value" -> ActionLimits(TimeLimit(timeLimit), MemoryLimit(memoryLimit), LogLimit(logLimit)).toJson)
+
+        val path = annotations.find { _.fields("key").convertTo[String] == "path" }.get
+
+        path.fields("value").convertTo[String] should fullyMatch regex (s""".*/$name""")
+        annotations should contain(limitsObj)
+      }
+  }
+
+  it should "report error when creating an action with unknown kind" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val rr = assetHelper.withCleaner(wsk.action, "invalid kind", confirmDelete = false) { (action, name) =>
+        action.create(
+          name,
+          Some(TestUtils.getTestActionFilename("echo.js")),
+          kind = Some("foobar"),
+          expectedExitCode = BAD_REQUEST)
+      }
+      rr.stderr should include regex "kind 'foobar' not in Set"
+  }
+
+  it should "report error when creating an action with zip but without kind" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "zipWithNoKind"
+      val zippedPythonAction = Some(TestUtils.getTestActionFilename("python.zip"))
+      val createResult = assetHelper.withCleaner(wsk.action, name, confirmDelete = false) { (action, _) =>
+        action.create(name, zippedPythonAction, expectedExitCode = ANY_ERROR_EXIT)
+      }
+
+      createResult.stderr should include regex "requires specifying the action kind"
+  }
+
+  it should "create, and invoke an action that utilizes an invalid docker container with appropriate error" in withAssetCleaner(
+    wskprops) {
+    val name = "invalidDockerContainer"
+    val containerName = s"bogus${Random.alphanumeric.take(16).mkString.toLowerCase}"
+
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.action, name) {
+        // docker name is a randomly generate string
+        (action, _) =>
+          action.create(name, None, docker = Some(containerName))
+      }
+
+      val run = wsk.action.invoke(name)
+      withActivation(wsk.activation, run) { activation =>
+        activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
+        activation.response.result.get
+          .fields("error") shouldBe s"Failed to pull container image '$containerName'.".toJson
+        activation.annotations shouldBe defined
+        val limits = activation.annotations.get.filter(_.fields("key").convertTo[String] == "limits")
+        withClue(limits) {
+          limits.length should be > 0
+          limits(0).fields("value") should not be JsNull
         }
+<<<<<<< HEAD
     }
 
     it should "reject commands that are executed with a missing or invalid parameter or annotation file" in {
@@ -1476,246 +455,1207 @@ class WskBasicUsageTests
                 val stderr = wsk.cli(cmd, expectedExitCode = MISUSE_EXIT).stderr
                 stderr should include(err)
                 stderr should include("Run 'wsk --help' for usage.")
+=======
+      }
+  }
+
+  it should "invoke an action using npm openwhisk" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "hello npm openwhisk"
+    assetHelper.withCleaner(wsk.action, name, confirmDelete = false) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("helloOpenwhiskPackage.js")))
+    }
+
+    val run = wsk.action.invoke(name, Map("ignore_certs" -> true.toJson, "name" -> name.toJson))
+    withActivation(wsk.activation, run) { activation =>
+      activation.response.status shouldBe "success"
+      activation.response.result shouldBe Some(JsObject("delete" -> true.toJson))
+      activation.logs.get.mkString(" ") should include("action list has this many actions")
+    }
+
+    wsk.action.delete(name, expectedExitCode = TestUtils.NOT_FOUND)
+  }
+
+  it should "invoke an action receiving context properties" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val namespace = wsk.namespace.whois()
+    val name = "context"
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, Some(TestUtils.getTestActionFilename("helloContext.js")))
+    }
+
+    val start = Instant.now(Clock.systemUTC()).toEpochMilli
+    val run = wsk.action.invoke(name)
+    withActivation(wsk.activation, run) { activation =>
+      activation.response.status shouldBe "success"
+      val fields = activation.response.result.get.convertTo[Map[String, String]]
+      fields("api_host") shouldBe WhiskProperties.getApiHostForAction
+      fields("api_key") shouldBe wskprops.authKey
+      fields("namespace") shouldBe namespace
+      fields("action_name") shouldBe s"/$namespace/$name"
+      fields("activation_id") shouldBe activation.activationId
+      fields("deadline").toLong should be >= start
+    }
+  }
+
+  it should "invoke an action successfully with options --blocking and --result" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "invokeResult"
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, Some(TestUtils.getTestActionFilename("echo.js")))
+      }
+      val args = Map("hello" -> "Robert".toJson)
+      val run = wsk.action.invoke(name, args, blocking = true, result = true)
+      run.stdout.parseJson shouldBe args.toJson
+  }
+
+  it should "invoke an action that returns a result by the deadline" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "deadline"
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, Some(TestUtils.getTestActionFilename("helloDeadline.js")), timeout = Some(3 seconds))
+      }
+
+      val run = wsk.action.invoke(name)
+      withActivation(wsk.activation, run) { activation =>
+        activation.response.status shouldBe "success"
+        activation.response.result shouldBe Some(JsObject("timedout" -> true.toJson))
+      }
+  }
+
+  it should "invoke an action twice, where the first times out but the second does not and should succeed" in withAssetCleaner(
+    wskprops) {
+    // this test issues two activations: the first is forced to time out and not return a result by its deadline (ie it does not resolve
+    // its promise). The invoker should reclaim its container so that a second activation of the same action (which must happen within a
+    // short period of time (seconds, not minutes) is allocated a fresh container and hence runs as expected (vs. hitting in the container
+    // cache and reusing a bad container).
+    (wp, assetHelper) =>
+      val name = "timeout"
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, Some(TestUtils.getTestActionFilename("helloDeadline.js")), timeout = Some(3 seconds))
+      }
+
+      val start = Instant.now(Clock.systemUTC()).toEpochMilli
+      val hungRun = wsk.action.invoke(name, Map("forceHang" -> true.toJson))
+      withActivation(wsk.activation, hungRun) { activation =>
+        // the first action must fail with a timeout error
+        activation.response.status shouldBe ActivationResponse.messageForCode(ActivationResponse.ApplicationError)
+        activation.response.result shouldBe Some(
+          JsObject("error" -> Messages.timedoutActivation(3 seconds, false).toJson))
+      }
+
+      // run the action again, this time without forcing it to timeout
+      // it should succeed because it ran in a fresh container
+      val goodRun = wsk.action.invoke(name, Map("forceHang" -> false.toJson))
+      withActivation(wsk.activation, goodRun) { activation =>
+        // the first action must fail with a timeout error
+        activation.response.status shouldBe "success"
+        activation.response.result shouldBe Some(JsObject("timedout" -> true.toJson))
+      }
+  }
+
+  it should "ensure --web flags set the proper annotations" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "webaction"
+    val file = Some(TestUtils.getTestActionFilename("echo.js"))
+
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file)
+    }
+
+    Seq("true", "faLse", "tRue", "nO", "yEs", "no", "raw", "NO", "Raw").foreach { flag =>
+      val webEnabled = flag.toLowerCase == "true" || flag.toLowerCase == "yes"
+      val rawEnabled = flag.toLowerCase == "raw"
+
+      wsk.action.create(name, file, web = Some(flag), update = true)
+
+      val stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+      assert(stdout.startsWith(s"ok: got action $name, displaying field annotations\n"))
+      removeCLIHeader(stdout).parseJson shouldBe JsArray(
+        JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6")),
+        JsObject("key" -> JsString("web-export"), "value" -> JsBoolean(webEnabled || rawEnabled)),
+        JsObject("key" -> JsString("raw-http"), "value" -> JsBoolean(rawEnabled)),
+        JsObject("key" -> JsString("final"), "value" -> JsBoolean(webEnabled || rawEnabled)))
+    }
+  }
+
+  it should "ensure action update with --web flag only copies existing annotations when new annotations are not provided" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val name = "webaction"
+    val file = Some(TestUtils.getTestActionFilename("echo.js"))
+    val createKey = "createKey"
+    val createValue = JsString("createValue")
+    val updateKey = "updateKey"
+    val updateValue = JsString("updateValue")
+    val origKey = "origKey"
+    val origValue = JsString("origValue")
+    val overwrittenValue = JsString("overwrittenValue")
+    val createAnnots = Map(createKey -> createValue, origKey -> origValue)
+    val updateAnnots = Map(updateKey -> updateValue, origKey -> overwrittenValue)
+
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file, annotations = createAnnots)
+    }
+
+    wsk.action.create(name, file, web = Some("true"), update = true)
+
+    val existinAnnots = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+    assert(existinAnnots.startsWith(s"ok: got action $name, displaying field annotations\n"))
+    removeCLIHeader(existinAnnots).parseJson shouldBe JsArray(
+      JsObject("key" -> JsString("web-export"), "value" -> JsBoolean(true)),
+      JsObject("key" -> JsString(origKey), "value" -> origValue),
+      JsObject("key" -> JsString("raw-http"), "value" -> JsBoolean(false)),
+      JsObject("key" -> JsString("final"), "value" -> JsBoolean(true)),
+      JsObject("key" -> JsString(createKey), "value" -> createValue),
+      JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6")))
+
+    wsk.action.create(name, file, web = Some("true"), update = true, annotations = updateAnnots)
+
+    val updatedAnnots = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+    assert(updatedAnnots.startsWith(s"ok: got action $name, displaying field annotations\n"))
+    removeCLIHeader(updatedAnnots).parseJson shouldBe JsArray(
+      JsObject("key" -> JsString("web-export"), "value" -> JsBoolean(true)),
+      JsObject("key" -> JsString(origKey), "value" -> overwrittenValue),
+      JsObject("key" -> JsString(updateKey), "value" -> updateValue),
+      JsObject("key" -> JsString("raw-http"), "value" -> JsBoolean(false)),
+      JsObject("key" -> JsString("final"), "value" -> JsBoolean(true)),
+      JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6")))
+  }
+
+  it should "ensure action update creates an action with --web flag" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "webaction"
+      val file = Some(TestUtils.getTestActionFilename("echo.js"))
+
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, file, web = Some("true"), update = true)
+      }
+
+      val stdout = wsk.action.get(name, fieldFilter = Some("annotations")).stdout
+      assert(stdout.startsWith(s"ok: got action $name, displaying field annotations\n"))
+      removeCLIHeader(stdout).parseJson shouldBe JsArray(
+        JsObject("key" -> JsString("web-export"), "value" -> JsBoolean(true)),
+        JsObject("key" -> JsString("raw-http"), "value" -> JsBoolean(false)),
+        JsObject("key" -> JsString("final"), "value" -> JsBoolean(true)),
+        JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6")))
+  }
+
+  it should "reject action create and update with invalid web flag input" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "webaction"
+      val file = Some(TestUtils.getTestActionFilename("echo.js"))
+      val invalidInput = "bogus"
+      val errorMsg =
+        s"Invalid argument '$invalidInput' for --web flag. Valid input consist of 'yes', 'true', 'raw', 'false', or 'no'."
+      wsk.action.create(name, file, web = Some(invalidInput), expectedExitCode = MISUSE_EXIT).stderr should include(
+        errorMsg)
+      wsk.action
+        .create(name, file, web = Some(invalidInput), update = true, expectedExitCode = MISUSE_EXIT)
+        .stderr should include(errorMsg)
+  }
+
+  it should "invoke action while not encoding &, <, > characters" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "nonescape"
+    val file = Some(TestUtils.getTestActionFilename("hello.js"))
+    val nonescape = "&<>"
+    val input = Map("payload" -> nonescape.toJson)
+    val output = JsObject("payload" -> JsString(s"hello, $nonescape!"))
+
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file)
+    }
+
+    withActivation(wsk.activation, wsk.action.invoke(name, parameters = input)) { activation =>
+      activation.response.success shouldBe true
+      activation.response.result shouldBe Some(output)
+      activation.logs.toList.flatten.filter(_.contains(nonescape)).length shouldBe 1
+    }
+  }
+
+  it should "get an action URL" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val actionName = "action name@_-."
+    val packageName = "package name@_-."
+    val defaultPackageName = "default"
+    val webActionName = "web action name@_-."
+    val nonExistentActionName = "non-existence action"
+    val packagedAction = s"$packageName/$actionName"
+    val packagedWebAction = s"$packageName/$webActionName"
+    val namespace = wsk.namespace.whois()
+    val encodedActionName = URLEncoder.encode(actionName, StandardCharsets.UTF_8.name).replace("+", "%20")
+    val encodedPackageName = URLEncoder.encode(packageName, StandardCharsets.UTF_8.name).replace("+", "%20")
+    val encodedWebActionName = URLEncoder.encode(webActionName, StandardCharsets.UTF_8.name).replace("+", "%20")
+    val encodedNamespace = URLEncoder.encode(namespace, StandardCharsets.UTF_8.name).replace("+", "%20")
+    val actionPath = "https://%s/api/%s/namespaces/%s/actions/%s"
+    val packagedActionPath = s"$actionPath/%s"
+    val webActionPath = "https://%s/api/%s/web/%s/%s/%s"
+
+    assetHelper.withCleaner(wsk.action, actionName) { (action, _) =>
+      action.create(actionName, defaultAction)
+    }
+
+    assetHelper.withCleaner(wsk.action, webActionName) { (action, _) =>
+      action.create(webActionName, defaultAction, web = Some("true"))
+    }
+
+    assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
+      pkg.create(packageName)
+    }
+
+    assetHelper.withCleaner(wsk.action, packagedAction) { (action, _) =>
+      action.create(packagedAction, defaultAction)
+    }
+
+    assetHelper.withCleaner(wsk.action, packagedWebAction) { (action, _) =>
+      action.create(packagedWebAction, defaultAction, web = Some("true"))
+    }
+
+    wsk.action.get(actionName, url = Some(true)).stdout should include(
+      actionPath.format(wskprops.apihost, wskprops.apiversion, encodedNamespace, encodedActionName))
+
+    // Ensure url flag works when a field filter and summary flag are specified
+    wsk.action.get(actionName, url = Some(true), fieldFilter = Some("field"), summary = true).stdout should include(
+      actionPath.format(wskprops.apihost, wskprops.apiversion, encodedNamespace, encodedActionName))
+
+    wsk.action.get(webActionName, url = Some(true)).stdout should include(
+      webActionPath
+        .format(wskprops.apihost, wskprops.apiversion, encodedNamespace, defaultPackageName, encodedWebActionName))
+
+    wsk.action.get(packagedAction, url = Some(true)).stdout should include(
+      packagedActionPath
+        .format(wskprops.apihost, wskprops.apiversion, encodedNamespace, encodedPackageName, encodedActionName))
+
+    wsk.action.get(packagedWebAction, url = Some(true)).stdout should include(
+      webActionPath
+        .format(wskprops.apihost, wskprops.apiversion, encodedNamespace, encodedPackageName, encodedWebActionName))
+
+    wsk.action.get(nonExistentActionName, url = Some(true), expectedExitCode = NOT_FOUND)
+  }
+  it should "limit length of HTTP request and response bodies for --verbose" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "limitVerbose"
+      val msg = "will be truncated"
+      val params = Seq("-p", "bigValue", "a" * 1000)
+
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, Some(TestUtils.getTestActionFilename("echo.js")))
+      }
+
+      val truncated = wsk
+        .cli(Seq("action", "invoke", name, "-b", "-v", "--auth", wskprops.authKey) ++ params ++ wskprops.overrides)
+        .stdout
+      msg.r.findAllIn(truncated).length shouldBe 2
+
+      val notTruncated = wsk
+        .cli(Seq("action", "invoke", name, "-b", "-d", "--auth", wskprops.authKey) ++ params ++ wskprops.overrides)
+        .stdout
+      msg.r.findAllIn(notTruncated).length shouldBe 0
+  }
+
+  it should "denote bound and finalized action parameters for action summaries" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val nameBoundParams = "actionBoundParams"
+      val nameFinalParams = "actionFinalParams"
+      val paramAnnot = "paramAnnot"
+      val paramOverlap = "paramOverlap"
+      val paramBound = "paramBound"
+      val annots = Map(
+        "parameters" -> JsArray(
+          JsObject("name" -> JsString(paramAnnot), "description" -> JsString("Annotated")),
+          JsObject("name" -> JsString(paramOverlap), "description" -> JsString("Annotated And Bound"))))
+      val annotsFinal = Map(
+        "final" -> JsBoolean(true),
+        "parameters" -> JsArray(
+          JsObject("name" -> JsString(paramAnnot), "description" -> JsString("Annotated Parameter description")),
+          JsObject("name" -> JsString(paramOverlap), "description" -> JsString("Annotated And Bound"))))
+      val paramsBound = Map(paramBound -> JsString("Bound"), paramOverlap -> JsString("Bound And Annotated"))
+
+      assetHelper.withCleaner(wsk.action, nameBoundParams) { (action, _) =>
+        action.create(nameBoundParams, defaultAction, annotations = annots, parameters = paramsBound)
+      }
+      assetHelper.withCleaner(wsk.action, nameFinalParams) { (action, _) =>
+        action.create(nameFinalParams, defaultAction, annotations = annotsFinal, parameters = paramsBound)
+      }
+
+      val stdoutBound = wsk.action.get(nameBoundParams, summary = true).stdout
+      val stdoutFinal = wsk.action.get(nameFinalParams, summary = true).stdout
+
+      stdoutBound should include(s"(parameters: $paramAnnot, *$paramBound, *$paramOverlap)")
+      stdoutFinal should include(s"(parameters: $paramAnnot, **$paramBound, **$paramOverlap)")
+  }
+
+  it should "create, and get an action summary without a description and/or defined parameters" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val actNameNoParams = "actionNoParams"
+    val actNameNoDesc = "actionNoDesc"
+    val actNameNoDescOrParams = "actionNoDescOrParams"
+    val desc = "Action description"
+    val descFromParamsResp = "Returns a result based on parameters"
+    val annotsNoParams = Map("description" -> JsString(desc))
+    val annotsNoDesc = Map(
+      "parameters" -> JsArray(
+        JsObject("name" -> JsString("paramName1"), "description" -> JsString("Parameter description 1")),
+        JsObject("name" -> JsString("paramName2"), "description" -> JsString("Parameter description 2"))))
+
+    assetHelper.withCleaner(wsk.action, actNameNoDesc) { (action, _) =>
+      action.create(actNameNoDesc, defaultAction, annotations = annotsNoDesc)
+    }
+    assetHelper.withCleaner(wsk.action, actNameNoParams) { (action, _) =>
+      action.create(actNameNoParams, defaultAction, annotations = annotsNoParams)
+    }
+    assetHelper.withCleaner(wsk.action, actNameNoDescOrParams) { (action, _) =>
+      action.create(actNameNoDescOrParams, defaultAction)
+    }
+
+    val stdoutNoDesc = wsk.action.get(actNameNoDesc, summary = true).stdout
+    val stdoutNoParams = wsk.action.get(actNameNoParams, summary = true).stdout
+    val stdoutNoDescOrParams = wsk.action.get(actNameNoDescOrParams, summary = true).stdout
+    val namespace = wsk.namespace.whois()
+
+    stdoutNoDesc should include regex (s"(?i)action /${namespace}/${actNameNoDesc}: ${descFromParamsResp} paramName1 and paramName2\\s*\\(parameters: paramName1, paramName2\\)")
+    stdoutNoParams should include regex (s"(?i)action /${namespace}/${actNameNoParams}: ${desc}\\s*\\(parameters: none defined\\)")
+    stdoutNoDescOrParams should include regex (s"(?i)action /${namespace}/${actNameNoDescOrParams}\\s*\\(parameters: none defined\\)")
+  }
+
+  behavior of "Wsk packages"
+
+  it should "create, and delete a package" in {
+    val name = "createDeletePackage"
+    wsk.pkg.create(name).stdout should include(s"ok: created package $name")
+    wsk.pkg.delete(name).stdout should include(s"ok: deleted package $name")
+  }
+
+  it should "create, and get a package to verify parameter and annotation parsing" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "packageAnnotAndParamParsing"
+
+      assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+        pkg.create(name, annotations = getValidJSONTestArgInput, parameters = getValidJSONTestArgInput)
+      }
+
+      val stdout = wsk.pkg.get(name).stdout
+      assert(stdout.startsWith(s"ok: got package $name\n"))
+
+      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
+      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+      val escapedJSONArr = getValidJSONTestArgOutput.convertTo[JsArray].elements
+
+      for (expectedItem <- escapedJSONArr) {
+        receivedParams should contain(expectedItem)
+        receivedAnnots should contain(expectedItem)
+      }
+  }
+
+  it should "create, and get a package to verify file parameter and annotation parsing" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "packageAnnotAndParamFileParsing"
+      val file = Some(TestUtils.getTestActionFilename("hello.js"))
+      val argInput = Some(TestUtils.getTestActionFilename("validInput1.json"))
+
+      assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+        pkg.create(name, annotationFile = argInput, parameterFile = argInput)
+      }
+
+      val stdout = wsk.pkg.get(name).stdout
+      assert(stdout.startsWith(s"ok: got package $name\n"))
+
+      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
+      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+      val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
+
+      for (expectedItem <- escapedJSONArr) {
+        receivedParams should contain(expectedItem)
+        receivedAnnots should contain(expectedItem)
+      }
+  }
+
+  it should "create a package with the proper parameter and annotation escapes" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "packageEscapses"
+
+      assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+        pkg.create(name, parameters = getEscapedJSONTestArgInput, annotations = getEscapedJSONTestArgInput)
+      }
+
+      val stdout = wsk.pkg.get(name).stdout
+      assert(stdout.startsWith(s"ok: got package $name\n"))
+
+      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
+      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+      val escapedJSONArr = getEscapedJSONTestArgOutput.convertTo[JsArray].elements
+
+      for (expectedItem <- escapedJSONArr) {
+        receivedParams should contain(expectedItem)
+        receivedAnnots should contain(expectedItem)
+      }
+  }
+
+  it should "report conformance error accessing action as package" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "aAsP"
+    val file = Some(TestUtils.getTestActionFilename("hello.js"))
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file)
+    }
+
+    wsk.pkg.get(name, expectedExitCode = CONFLICT).stderr should include(Messages.conformanceMessage)
+
+    wsk.pkg.bind(name, "bogus", expectedExitCode = CONFLICT).stderr should include(Messages.requestedBindingIsNotValid)
+
+    wsk.pkg.bind("bogus", "alsobogus", expectedExitCode = BAD_REQUEST).stderr should include(
+      Messages.bindingDoesNotExist)
+
+  }
+
+  it should "create, and get a package summary without a description and/or parameters" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val pkgNoDesc = "pkgNoDesc"
+      val pkgNoParams = "pkgNoParams"
+      val pkgNoDescOrParams = "pkgNoDescOrParams"
+      val pkgDesc = "Package description"
+      val descFromParams = "Returns a result based on parameters"
+      val namespace = wsk.namespace.whois()
+      val qualpkgNoDesc = s"/${namespace}/${pkgNoDesc}"
+      val qualpkgNoParams = s"/${namespace}/${pkgNoParams}"
+      val qualpkgNoDescOrParams = s"/${namespace}/${pkgNoDescOrParams}"
+
+      val pkgAnnotsNoParams = Map("description" -> JsString(pkgDesc))
+      val pkgAnnotsNoDesc = Map(
+        "parameters" -> JsArray(
+          JsObject("name" -> JsString("paramName1"), "description" -> JsString("Parameter description 1")),
+          JsObject("name" -> JsString("paramName2"), "description" -> JsString("Parameter description 2"))))
+
+      assetHelper.withCleaner(wsk.pkg, pkgNoDesc) { (pkg, _) =>
+        pkg.create(pkgNoDesc, annotations = pkgAnnotsNoDesc)
+      }
+      assetHelper.withCleaner(wsk.pkg, pkgNoParams) { (pkg, _) =>
+        pkg.create(pkgNoParams, annotations = pkgAnnotsNoParams)
+      }
+      assetHelper.withCleaner(wsk.pkg, pkgNoDescOrParams) { (pkg, _) =>
+        pkg.create(pkgNoDescOrParams)
+      }
+
+      val stdoutNoDescPkg = wsk.pkg.get(pkgNoDesc, summary = true).stdout
+      val stdoutNoParamsPkg = wsk.pkg.get(pkgNoParams, summary = true).stdout
+      val stdoutNoDescOrParams = wsk.pkg.get(pkgNoDescOrParams, summary = true).stdout
+
+      stdoutNoDescPkg should include regex (s"(?i)package ${qualpkgNoDesc}: ${descFromParams} paramName1 and paramName2\\s*\\(parameters: paramName1, paramName2\\)")
+      stdoutNoParamsPkg should include regex (s"(?i)package ${qualpkgNoParams}: ${pkgDesc}\\s*\\(parameters: none defined\\)")
+      stdoutNoDescOrParams should include regex (s"(?i)package ${qualpkgNoDescOrParams}\\s*\\(parameters: none defined\\)")
+  }
+
+  it should "denote bound package parameters for package summaries" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val pkgBoundParams = "pkgBoundParams"
+    val pkgParamAnnot = "pkgParamAnnot"
+    val pkgParamOverlap = "pkgParamOverlap"
+    val pkgParamBound = "pkgParamBound"
+    val pkgAnnots = Map(
+      "parameters" -> JsArray(
+        JsObject("name" -> JsString(pkgParamAnnot), "description" -> JsString("Annotated")),
+        JsObject("name" -> JsString(pkgParamOverlap), "description" -> JsString("Annotated And Bound"))))
+    val pkgParamsBound = Map(pkgParamBound -> JsString("Bound"), pkgParamOverlap -> JsString("Bound And Annotated"))
+
+    assetHelper.withCleaner(wsk.pkg, pkgBoundParams) { (pkg, _) =>
+      pkg.create(pkgBoundParams, annotations = pkgAnnots, parameters = pkgParamsBound)
+    }
+
+    val pkgStdoutBound = wsk.pkg.get(pkgBoundParams, summary = true).stdout
+
+    pkgStdoutBound should include(s"(parameters: $pkgParamAnnot, *$pkgParamBound, *$pkgParamOverlap)")
+  }
+
+  behavior of "Wsk triggers"
+
+  it should "create, and get a trigger to verify parameter and annotation parsing" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "triggerAnnotAndParamParsing"
+
+      assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+        trigger.create(name, annotations = getValidJSONTestArgInput, parameters = getValidJSONTestArgInput)
+      }
+
+      val stdout = wsk.trigger.get(name).stdout
+      assert(stdout.startsWith(s"ok: got trigger $name\n"))
+
+      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
+      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+      val escapedJSONArr = getValidJSONTestArgOutput.convertTo[JsArray].elements
+
+      for (expectedItem <- escapedJSONArr) {
+        receivedParams should contain(expectedItem)
+        receivedAnnots should contain(expectedItem)
+      }
+  }
+
+  it should "create, and get a trigger to verify file parameter and annotation parsing" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "triggerAnnotAndParamFileParsing"
+      val file = Some(TestUtils.getTestActionFilename("hello.js"))
+      val argInput = Some(TestUtils.getTestActionFilename("validInput1.json"))
+
+      assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+        trigger.create(name, annotationFile = argInput, parameterFile = argInput)
+      }
+
+      val stdout = wsk.trigger.get(name).stdout
+      assert(stdout.startsWith(s"ok: got trigger $name\n"))
+
+      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
+      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+      val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
+
+      for (expectedItem <- escapedJSONArr) {
+        receivedParams should contain(expectedItem)
+        receivedAnnots should contain(expectedItem)
+      }
+  }
+
+  it should "display a trigger summary when --summary flag is used with 'wsk trigger get'" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val triggerName = "mySummaryTrigger"
+      assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false) { (trigger, name) =>
+        trigger.create(name)
+      }
+
+      // Summary namespace should match one of the allowable namespaces (typically 'guest')
+      val ns = wsk.namespace.whois()
+      val stdout = wsk.trigger.get(triggerName, summary = true).stdout
+      stdout should include regex (s"(?i)trigger\\s+/$ns/$triggerName")
+  }
+
+  it should "create a trigger with the proper parameter and annotation escapes" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "triggerEscapes"
+
+      assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+        trigger.create(name, parameters = getEscapedJSONTestArgInput, annotations = getEscapedJSONTestArgInput)
+      }
+
+      val stdout = wsk.trigger.get(name).stdout
+      assert(stdout.startsWith(s"ok: got trigger $name\n"))
+
+      val receivedParams = wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
+      val receivedAnnots = wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+      val escapedJSONArr = getEscapedJSONTestArgOutput.convertTo[JsArray].elements
+
+      for (expectedItem <- escapedJSONArr) {
+        receivedParams should contain(expectedItem)
+        receivedAnnots should contain(expectedItem)
+      }
+  }
+
+  it should "not create a trigger when feed fails to initialize" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    assetHelper.withCleaner(wsk.trigger, "badfeed", confirmDelete = false) { (trigger, name) =>
+      trigger.create(name, feed = Some(s"bogus"), expectedExitCode = ANY_ERROR_EXIT).exitCode should equal(NOT_FOUND)
+      trigger.get(name, expectedExitCode = NOT_FOUND)
+
+      trigger.create(name, feed = Some(s"bogus/feed"), expectedExitCode = ANY_ERROR_EXIT).exitCode should equal(
+        NOT_FOUND)
+      trigger.get(name, expectedExitCode = NOT_FOUND)
+    }
+  }
+
+  it should "denote bound trigger parameters for trigger summaries" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val trgBoundParams = "trgBoundParams"
+    val trgParamAnnot = "trgParamAnnot"
+    val trgParamOverlap = "trgParamOverlap"
+    val trgParamBound = "trgParamBound"
+    val trgAnnots = Map(
+      "parameters" -> JsArray(
+        JsObject("name" -> JsString(trgParamAnnot), "description" -> JsString("Annotated")),
+        JsObject("name" -> JsString(trgParamOverlap), "description" -> JsString("Annotated And Bound"))))
+    val trgParamsBound = Map(trgParamBound -> JsString("Bound"), trgParamOverlap -> JsString("Bound And Annotated"))
+
+    assetHelper.withCleaner(wsk.trigger, trgBoundParams) { (trigger, _) =>
+      trigger.create(trgBoundParams, annotations = trgAnnots, parameters = trgParamsBound)
+    }
+
+    val trgStdoutBound = wsk.trigger.get(trgBoundParams, summary = true).stdout
+
+    trgStdoutBound should include(s"(parameters: $trgParamAnnot, *$trgParamBound, *$trgParamOverlap)")
+  }
+
+  it should "create, and get a trigger summary without a description and/or parameters" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val trgNoDesc = "trgNoDesc"
+      val trgNoParams = "trgNoParams"
+      val trgNoDescOrParams = "trgNoDescOrParams"
+      val trgDesc = "Package description"
+      val descFromParams = "Returns a result based on parameters"
+      val namespace = wsk.namespace.whois()
+      val qualtrgNoDesc = s"/${namespace}/${trgNoDesc}"
+      val qualtrgNoParams = s"/${namespace}/${trgNoParams}"
+      val qualtrgNoDescOrParams = s"/${namespace}/${trgNoDescOrParams}"
+
+      val trgAnnotsNoParams = Map("description" -> JsString(trgDesc))
+      val trgAnnotsNoDesc = Map(
+        "parameters" -> JsArray(
+          JsObject("name" -> JsString("paramName1"), "description" -> JsString("Parameter description 1")),
+          JsObject("name" -> JsString("paramName2"), "description" -> JsString("Parameter description 2"))))
+
+      assetHelper.withCleaner(wsk.trigger, trgNoDesc) { (trigger, _) =>
+        trigger.create(trgNoDesc, annotations = trgAnnotsNoDesc)
+      }
+      assetHelper.withCleaner(wsk.trigger, trgNoParams) { (trigger, _) =>
+        trigger.create(trgNoParams, annotations = trgAnnotsNoParams)
+      }
+      assetHelper.withCleaner(wsk.trigger, trgNoDescOrParams) { (trigger, _) =>
+        trigger.create(trgNoDescOrParams)
+      }
+
+      val stdoutNoDescPkg = wsk.trigger.get(trgNoDesc, summary = true).stdout
+      val stdoutNoParamsPkg = wsk.trigger.get(trgNoParams, summary = true).stdout
+      val stdoutNoDescOrParams = wsk.trigger.get(trgNoDescOrParams, summary = true).stdout
+
+      stdoutNoDescPkg should include regex (s"(?i)trigger ${qualtrgNoDesc}: ${descFromParams} paramName1 and paramName2\\s*\\(parameters: paramName1, paramName2\\)")
+      stdoutNoParamsPkg should include regex (s"(?i)trigger ${qualtrgNoParams}: ${trgDesc}\\s*\\(parameters: none defined\\)")
+      stdoutNoDescOrParams should include regex (s"(?i)trigger ${qualtrgNoDescOrParams}\\s*\\(parameters: none defined\\)")
+  }
+
+  behavior of "Wsk entity list formatting"
+
+  it should "create, and list a package with a long name" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "x" * 70
+    assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+      pkg.create(name)
+    }
+    retry({
+      wsk.pkg.list().stdout should include(s"$name private")
+    }, 5, Some(1 second))
+  }
+
+  it should "create, and list an action with a long name" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "x" * 70
+    val file = Some(TestUtils.getTestActionFilename("hello.js"))
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file)
+    }
+    retry({
+      wsk.action.list().stdout should include(s"$name private nodejs")
+    }, 5, Some(1 second))
+  }
+
+  it should "create, and list a trigger with a long name" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "x" * 70
+    assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+      trigger.create(name)
+    }
+    retry({
+      wsk.trigger.list().stdout should include(s"$name private")
+    }, 5, Some(1 second))
+  }
+
+  it should "create, and list a rule with a long name" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val ruleName = "x" * 70
+    val triggerName = "listRulesTrigger"
+    val actionName = "listRulesAction";
+    assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
+      trigger.create(name)
+    }
+    assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+      action.create(name, defaultAction)
+    }
+    assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
+      rule.create(name, trigger = triggerName, action = actionName)
+    }
+    retry({
+      wsk.rule.list().stdout should include(s"$ruleName private")
+    }, 5, Some(1 second))
+  }
+
+  it should "return a list of alphabetized actions" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    // Declare 4 actions, create them out of alphabetical order
+    val actionName = "actionAlphaTest"
+    for (i <- 1 to 3) {
+      val name = s"$actionName$i"
+      assetHelper.withCleaner(wsk.action, name) { (action, name) =>
+        action.create(name, defaultAction)
+      }
+    }
+    retry({
+      val original = wsk.action.list(nameSort = Some(true)).stdout
+      // Create list with action names in correct order
+      val scalaSorted = List(s"${actionName}1", s"${actionName}2", s"${actionName}3")
+      // Filter out everything not previously created
+      val regex = s"${actionName}[1-3]".r
+      // Retrieve action names into list as found in original
+      val list = (regex.findAllMatchIn(original)).toList
+      scalaSorted.toString shouldEqual list.toString
+    }, 5, Some(1 second))
+  }
+
+  it should "return an alphabetized list with default package actions on top" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      // Declare 4 actions, create them out of alphabetical order
+      val actionName = "actionPackageAlphaTest"
+      val packageName = "packageAlphaTest"
+      assetHelper.withCleaner(wsk.action, actionName) { (action, actionName) =>
+        action.create(actionName, defaultAction)
+      }
+      assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, packageName) =>
+        pkg.create(packageName)
+      }
+      for (i <- 1 to 3) {
+        val name = s"${packageName}/${actionName}$i"
+        assetHelper.withCleaner(wsk.action, name) { (action, name) =>
+          action.create(name, defaultAction)
+>>>>>>> c10e681... Apply standard scala formatting. (#2650)
         }
-    }
-
-    it should "reject commands that are executed with not enough param or annot arguments" in {
-        val invalidParamMsg = "Arguments for '-p' must be a key/value pair"
-        val invalidAnnotMsg = "Arguments for '-a' must be a key/value pair"
-        val invalidParamFileMsg = "An argument must be provided for '-P'"
-        val invalidAnnotFileMsg = "An argument must be provided for '-A'"
-        val invalidArgs = Seq(
-            (Seq("action", "create", "actionName", "-p"), invalidParamMsg),
-            (Seq("action", "create", "actionName", "-p", "key"), invalidParamMsg),
-            (Seq("action", "create", "actionName", "-P"), invalidParamFileMsg),
-            (Seq("action", "update", "actionName", "-p"), invalidParamMsg),
-            (Seq("action", "update", "actionName", "-p", "key"), invalidParamMsg),
-            (Seq("action", "update", "actionName", "-P"), invalidParamFileMsg),
-            (Seq("action", "invoke", "actionName", "-p"), invalidParamMsg),
-            (Seq("action", "invoke", "actionName", "-p", "key"), invalidParamMsg),
-            (Seq("action", "invoke", "actionName", "-P"), invalidParamFileMsg),
-            (Seq("action", "create", "actionName", "-a"), invalidAnnotMsg),
-            (Seq("action", "create", "actionName", "-a", "key"), invalidAnnotMsg),
-            (Seq("action", "create", "actionName", "-A"), invalidAnnotFileMsg),
-            (Seq("action", "update", "actionName", "-a"), invalidAnnotMsg),
-            (Seq("action", "update", "actionName", "-a", "key"), invalidAnnotMsg),
-            (Seq("action", "update", "actionName", "-A"), invalidAnnotFileMsg),
-            (Seq("action", "invoke", "actionName", "-a"), invalidAnnotMsg),
-            (Seq("action", "invoke", "actionName", "-a", "key"), invalidAnnotMsg),
-            (Seq("action", "invoke", "actionName", "-A"), invalidAnnotFileMsg),
-            (Seq("package", "create", "packageName", "-p"), invalidParamMsg),
-            (Seq("package", "create", "packageName", "-p", "key"), invalidParamMsg),
-            (Seq("package", "create", "packageName", "-P"), invalidParamFileMsg),
-            (Seq("package", "update", "packageName", "-p"), invalidParamMsg),
-            (Seq("package", "update", "packageName", "-p", "key"), invalidParamMsg),
-            (Seq("package", "update", "packageName", "-P"), invalidParamFileMsg),
-            (Seq("package", "bind", "packageName", "boundPackageName", "-p"), invalidParamMsg),
-            (Seq("package", "bind", "packageName", "boundPackageName", "-p", "key"), invalidParamMsg),
-            (Seq("package", "bind", "packageName", "boundPackageName", "-P"), invalidParamFileMsg),
-            (Seq("package", "create", "packageName", "-a"), invalidAnnotMsg),
-            (Seq("package", "create", "packageName", "-a", "key"), invalidAnnotMsg),
-            (Seq("package", "create", "packageName", "-A"), invalidAnnotFileMsg),
-            (Seq("package", "update", "packageName", "-a"), invalidAnnotMsg),
-            (Seq("package", "update", "packageName", "-a", "key"), invalidAnnotMsg),
-            (Seq("package", "update", "packageName", "-A"), invalidAnnotFileMsg),
-            (Seq("package", "bind", "packageName", "boundPackageName", "-a"), invalidAnnotMsg),
-            (Seq("package", "bind", "packageName", "boundPackageName", "-a", "key"), invalidAnnotMsg),
-            (Seq("package", "bind", "packageName", "boundPackageName", "-A"), invalidAnnotFileMsg),
-            (Seq("trigger", "create", "triggerName", "-p"), invalidParamMsg),
-            (Seq("trigger", "create", "triggerName", "-p", "key"), invalidParamMsg),
-            (Seq("trigger", "create", "triggerName", "-P"), invalidParamFileMsg),
-            (Seq("trigger", "update", "triggerName", "-p"), invalidParamMsg),
-            (Seq("trigger", "update", "triggerName", "-p", "key"), invalidParamMsg),
-            (Seq("trigger", "update", "triggerName", "-P"), invalidParamFileMsg),
-            (Seq("trigger", "fire", "triggerName", "-p"), invalidParamMsg),
-            (Seq("trigger", "fire", "triggerName", "-p", "key"), invalidParamMsg),
-            (Seq("trigger", "fire", "triggerName", "-P"), invalidParamFileMsg),
-            (Seq("trigger", "create", "triggerName", "-a"), invalidAnnotMsg),
-            (Seq("trigger", "create", "triggerName", "-a", "key"), invalidAnnotMsg),
-            (Seq("trigger", "create", "triggerName", "-A"), invalidAnnotFileMsg),
-            (Seq("trigger", "update", "triggerName", "-a"), invalidAnnotMsg),
-            (Seq("trigger", "update", "triggerName", "-a", "key"), invalidAnnotMsg),
-            (Seq("trigger", "update", "triggerName", "-A"), invalidAnnotFileMsg),
-            (Seq("trigger", "fire", "triggerName", "-a"), invalidAnnotMsg),
-            (Seq("trigger", "fire", "triggerName", "-a", "key"), invalidAnnotMsg),
-            (Seq("trigger", "fire", "triggerName", "-A"), invalidAnnotFileMsg))
-
-        invalidArgs foreach {
-            case (cmd, err) =>
-                val stderr = wsk.cli(cmd, expectedExitCode = ERROR_EXIT).stderr
-                stderr should include(err)
-                stderr should include("Run 'wsk --help' for usage.")
+      }
+      retry(
+        {
+          val original = wsk.action.list(nameSort = Some(true)).stdout
+          // Create list with action names in correct order
+          val scalaSorted = List(
+            s"$actionName",
+            s"${packageName}/${actionName}1",
+            s"${packageName}/${actionName}2",
+            s"${packageName}/${actionName}3")
+          // Filter out everything not previously created
+          val regexNoPackage = s"$actionName".r
+          val regexWithPackage = s"${packageName}/${actionName}[1-3]".r
+          // Retrieve action names into list as found in original
+          val list = regexNoPackage.findFirstIn(original).get :: (regexWithPackage.findAllMatchIn(original)).toList
+          scalaSorted.toString shouldEqual list.toString
+        },
+        5,
+        Some(1 second))
+  }
+
+  it should "return a list of alphabetized packages" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    // Declare 3 packages, create them out of alphabetical order
+    val packageName = "pkgAlphaTest"
+    for (i <- 1 to 3) {
+      val name = s"$packageName$i"
+      assetHelper.withCleaner(wsk.pkg, name) { (pkg, name) =>
+        pkg.create(name)
+      }
+    }
+    retry({
+      val original = wsk.pkg.list(nameSort = Some(true)).stdout
+      // Create list with package names in correct order
+      val scalaSorted = List(s"${packageName}1", s"${packageName}2", s"${packageName}3")
+      // Filter out everything not previously created
+      val regex = s"${packageName}[1-3]".r
+      // Retrieve package names into list as found in original
+      val list = (regex.findAllMatchIn(original)).toList
+      scalaSorted.toString shouldEqual list.toString
+    }, 5, Some(1 second))
+  }
+
+  it should "return a list of alphabetized triggers" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    // Declare 4 triggers, create them out of alphabetical order
+    val triggerName = "triggerAlphaTest"
+    for (i <- 1 to 3) {
+      val name = s"$triggerName$i"
+      assetHelper.withCleaner(wsk.trigger, name) { (trigger, name) =>
+        trigger.create(name)
+      }
+    }
+    retry({
+      val original = wsk.trigger.list(nameSort = Some(true)).stdout
+      // Create list with trigger names in correct order
+      val scalaSorted = List(s"${triggerName}1", s"${triggerName}2", s"${triggerName}3")
+      // Filter out everything not previously created
+      val regex = s"${triggerName}[1-3]".r
+      // Retrieve trigger names into list as found in original
+      val list = (regex.findAllMatchIn(original)).toList
+      scalaSorted.toString shouldEqual list.toString
+    }, 5, Some(1 second))
+  }
+
+  it should "return a list of alphabetized rules" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    // Declare a trigger and an action for the purposes of creating rules
+    val triggerName = "listRulesTrigger"
+    val actionName = "listRulesAction"
+
+    assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
+      trigger.create(name)
+    }
+    assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
+      action.create(name, defaultAction)
+    }
+    // Declare 3 rules, create them out of alphabetical order
+    val ruleName = "ruleAlphaTest"
+    for (i <- 1 to 3) {
+      val name = s"$ruleName$i"
+      assetHelper.withCleaner(wsk.rule, name) { (rule, name) =>
+        rule.create(name, trigger = triggerName, action = actionName)
+      }
+    }
+    retry({
+      val original = wsk.rule.list(nameSort = Some(true)).stdout
+      // Create list with rule names in correct order
+      val scalaSorted = List(s"${ruleName}1", s"${ruleName}2", s"${ruleName}3")
+      // Filter out everything not previously created
+      val regex = s"${ruleName}[1-3]".r
+      // Retrieve rule names into list as found in original
+      val list = (regex.findAllMatchIn(original)).toList
+      scalaSorted.toString shouldEqual list.toString
+    })
+  }
+
+  behavior of "Wsk params and annotations"
+
+  it should "reject commands that are executed with invalid JSON for annotations and parameters" in {
+    val invalidJSONInputs = getInvalidJSONInput
+    val invalidJSONFiles = Seq(
+      TestUtils.getTestActionFilename("malformed.js"),
+      TestUtils.getTestActionFilename("invalidInput1.json"),
+      TestUtils.getTestActionFilename("invalidInput2.json"),
+      TestUtils.getTestActionFilename("invalidInput3.json"),
+      TestUtils.getTestActionFilename("invalidInput4.json"))
+    val paramCmds = Seq(
+      Seq("action", "create", "actionName", TestUtils.getTestActionFilename("hello.js")),
+      Seq("action", "update", "actionName", TestUtils.getTestActionFilename("hello.js")),
+      Seq("action", "invoke", "actionName"),
+      Seq("package", "create", "packageName"),
+      Seq("package", "update", "packageName"),
+      Seq("package", "bind", "packageName", "boundPackageName"),
+      Seq("trigger", "create", "triggerName"),
+      Seq("trigger", "update", "triggerName"),
+      Seq("trigger", "fire", "triggerName"))
+    val annotCmds = Seq(
+      Seq("action", "create", "actionName", TestUtils.getTestActionFilename("hello.js")),
+      Seq("action", "update", "actionName", TestUtils.getTestActionFilename("hello.js")),
+      Seq("package", "create", "packageName"),
+      Seq("package", "update", "packageName"),
+      Seq("package", "bind", "packageName", "boundPackageName"),
+      Seq("trigger", "create", "triggerName"),
+      Seq("trigger", "update", "triggerName"))
+
+    for (cmd <- paramCmds) {
+      for (invalid <- invalidJSONInputs) {
+        wsk
+          .cli(cmd ++ Seq("-p", "key", invalid) ++ wskprops.overrides, expectedExitCode = ERROR_EXIT)
+          .stderr should include("Invalid parameter argument")
+      }
+
+      for (invalid <- invalidJSONFiles) {
+        wsk.cli(cmd ++ Seq("-P", invalid) ++ wskprops.overrides, expectedExitCode = ERROR_EXIT).stderr should include(
+          "Invalid parameter argument")
+
+      }
+    }
+
+    for (cmd <- annotCmds) {
+      for (invalid <- invalidJSONInputs) {
+        wsk
+          .cli(cmd ++ Seq("-a", "key", invalid) ++ wskprops.overrides, expectedExitCode = ERROR_EXIT)
+          .stderr should include("Invalid annotation argument")
+      }
+
+      for (invalid <- invalidJSONFiles) {
+        wsk.cli(cmd ++ Seq("-A", invalid) ++ wskprops.overrides, expectedExitCode = ERROR_EXIT).stderr should include(
+          "Invalid annotation argument")
+      }
+    }
+  }
+
+  it should "reject commands that are executed with a missing or invalid parameter or annotation file" in {
+    val emptyFile = TestUtils.getTestActionFilename("emtpy.js")
+    val missingFile = "notafile"
+    val emptyFileMsg = s"File '$emptyFile' is not a valid file or it does not exist"
+    val missingFileMsg = s"File '$missingFile' is not a valid file or it does not exist"
+    val invalidArgs = Seq(
+      (
+        Seq("action", "create", "actionName", TestUtils.getTestActionFilename("hello.js"), "-P", emptyFile),
+        emptyFileMsg),
+      (
+        Seq("action", "update", "actionName", TestUtils.getTestActionFilename("hello.js"), "-P", emptyFile),
+        emptyFileMsg),
+      (Seq("action", "invoke", "actionName", "-P", emptyFile), emptyFileMsg),
+      (Seq("action", "create", "actionName", "-P", emptyFile), emptyFileMsg),
+      (Seq("action", "update", "actionName", "-P", emptyFile), emptyFileMsg),
+      (Seq("action", "invoke", "actionName", "-P", emptyFile), emptyFileMsg),
+      (Seq("package", "create", "packageName", "-P", emptyFile), emptyFileMsg),
+      (Seq("package", "update", "packageName", "-P", emptyFile), emptyFileMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-P", emptyFile), emptyFileMsg),
+      (Seq("package", "create", "packageName", "-P", emptyFile), emptyFileMsg),
+      (Seq("package", "update", "packageName", "-P", emptyFile), emptyFileMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-P", emptyFile), emptyFileMsg),
+      (Seq("trigger", "create", "triggerName", "-P", emptyFile), emptyFileMsg),
+      (Seq("trigger", "update", "triggerName", "-P", emptyFile), emptyFileMsg),
+      (Seq("trigger", "fire", "triggerName", "-P", emptyFile), emptyFileMsg),
+      (Seq("trigger", "create", "triggerName", "-P", emptyFile), emptyFileMsg),
+      (Seq("trigger", "update", "triggerName", "-P", emptyFile), emptyFileMsg),
+      (Seq("trigger", "fire", "triggerName", "-P", emptyFile), emptyFileMsg),
+      (
+        Seq("action", "create", "actionName", TestUtils.getTestActionFilename("hello.js"), "-A", missingFile),
+        missingFileMsg),
+      (
+        Seq("action", "update", "actionName", TestUtils.getTestActionFilename("hello.js"), "-A", missingFile),
+        missingFileMsg),
+      (Seq("action", "invoke", "actionName", "-A", missingFile), missingFileMsg),
+      (Seq("action", "create", "actionName", "-A", missingFile), missingFileMsg),
+      (Seq("action", "update", "actionName", "-A", missingFile), missingFileMsg),
+      (Seq("action", "invoke", "actionName", "-A", missingFile), missingFileMsg),
+      (Seq("package", "create", "packageName", "-A", missingFile), missingFileMsg),
+      (Seq("package", "update", "packageName", "-A", missingFile), missingFileMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-A", missingFile), missingFileMsg),
+      (Seq("package", "create", "packageName", "-A", missingFile), missingFileMsg),
+      (Seq("package", "update", "packageName", "-A", missingFile), missingFileMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-A", missingFile), missingFileMsg),
+      (Seq("trigger", "create", "triggerName", "-A", missingFile), missingFileMsg),
+      (Seq("trigger", "update", "triggerName", "-A", missingFile), missingFileMsg),
+      (Seq("trigger", "fire", "triggerName", "-A", missingFile), missingFileMsg),
+      (Seq("trigger", "create", "triggerName", "-A", missingFile), missingFileMsg),
+      (Seq("trigger", "update", "triggerName", "-A", missingFile), missingFileMsg),
+      (Seq("trigger", "fire", "triggerName", "-A", missingFile), missingFileMsg))
+
+    invalidArgs foreach {
+      case (cmd, err) =>
+        val stderr = wsk.cli(cmd, expectedExitCode = MISUSE_EXIT).stderr
+        stderr should include(err)
+        stderr should include("Run 'wsk --help' for usage.")
+    }
+  }
+
+  it should "reject commands that are executed with not enough param or annot arguments" in {
+    val invalidParamMsg = "Arguments for '-p' must be a key/value pair"
+    val invalidAnnotMsg = "Arguments for '-a' must be a key/value pair"
+    val invalidParamFileMsg = "An argument must be provided for '-P'"
+    val invalidAnnotFileMsg = "An argument must be provided for '-A'"
+    val invalidArgs = Seq(
+      (Seq("action", "create", "actionName", "-p"), invalidParamMsg),
+      (Seq("action", "create", "actionName", "-p", "key"), invalidParamMsg),
+      (Seq("action", "create", "actionName", "-P"), invalidParamFileMsg),
+      (Seq("action", "update", "actionName", "-p"), invalidParamMsg),
+      (Seq("action", "update", "actionName", "-p", "key"), invalidParamMsg),
+      (Seq("action", "update", "actionName", "-P"), invalidParamFileMsg),
+      (Seq("action", "invoke", "actionName", "-p"), invalidParamMsg),
+      (Seq("action", "invoke", "actionName", "-p", "key"), invalidParamMsg),
+      (Seq("action", "invoke", "actionName", "-P"), invalidParamFileMsg),
+      (Seq("action", "create", "actionName", "-a"), invalidAnnotMsg),
+      (Seq("action", "create", "actionName", "-a", "key"), invalidAnnotMsg),
+      (Seq("action", "create", "actionName", "-A"), invalidAnnotFileMsg),
+      (Seq("action", "update", "actionName", "-a"), invalidAnnotMsg),
+      (Seq("action", "update", "actionName", "-a", "key"), invalidAnnotMsg),
+      (Seq("action", "update", "actionName", "-A"), invalidAnnotFileMsg),
+      (Seq("action", "invoke", "actionName", "-a"), invalidAnnotMsg),
+      (Seq("action", "invoke", "actionName", "-a", "key"), invalidAnnotMsg),
+      (Seq("action", "invoke", "actionName", "-A"), invalidAnnotFileMsg),
+      (Seq("package", "create", "packageName", "-p"), invalidParamMsg),
+      (Seq("package", "create", "packageName", "-p", "key"), invalidParamMsg),
+      (Seq("package", "create", "packageName", "-P"), invalidParamFileMsg),
+      (Seq("package", "update", "packageName", "-p"), invalidParamMsg),
+      (Seq("package", "update", "packageName", "-p", "key"), invalidParamMsg),
+      (Seq("package", "update", "packageName", "-P"), invalidParamFileMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-p"), invalidParamMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-p", "key"), invalidParamMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-P"), invalidParamFileMsg),
+      (Seq("package", "create", "packageName", "-a"), invalidAnnotMsg),
+      (Seq("package", "create", "packageName", "-a", "key"), invalidAnnotMsg),
+      (Seq("package", "create", "packageName", "-A"), invalidAnnotFileMsg),
+      (Seq("package", "update", "packageName", "-a"), invalidAnnotMsg),
+      (Seq("package", "update", "packageName", "-a", "key"), invalidAnnotMsg),
+      (Seq("package", "update", "packageName", "-A"), invalidAnnotFileMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-a"), invalidAnnotMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-a", "key"), invalidAnnotMsg),
+      (Seq("package", "bind", "packageName", "boundPackageName", "-A"), invalidAnnotFileMsg),
+      (Seq("trigger", "create", "triggerName", "-p"), invalidParamMsg),
+      (Seq("trigger", "create", "triggerName", "-p", "key"), invalidParamMsg),
+      (Seq("trigger", "create", "triggerName", "-P"), invalidParamFileMsg),
+      (Seq("trigger", "update", "triggerName", "-p"), invalidParamMsg),
+      (Seq("trigger", "update", "triggerName", "-p", "key"), invalidParamMsg),
+      (Seq("trigger", "update", "triggerName", "-P"), invalidParamFileMsg),
+      (Seq("trigger", "fire", "triggerName", "-p"), invalidParamMsg),
+      (Seq("trigger", "fire", "triggerName", "-p", "key"), invalidParamMsg),
+      (Seq("trigger", "fire", "triggerName", "-P"), invalidParamFileMsg),
+      (Seq("trigger", "create", "triggerName", "-a"), invalidAnnotMsg),
+      (Seq("trigger", "create", "triggerName", "-a", "key"), invalidAnnotMsg),
+      (Seq("trigger", "create", "triggerName", "-A"), invalidAnnotFileMsg),
+      (Seq("trigger", "update", "triggerName", "-a"), invalidAnnotMsg),
+      (Seq("trigger", "update", "triggerName", "-a", "key"), invalidAnnotMsg),
+      (Seq("trigger", "update", "triggerName", "-A"), invalidAnnotFileMsg),
+      (Seq("trigger", "fire", "triggerName", "-a"), invalidAnnotMsg),
+      (Seq("trigger", "fire", "triggerName", "-a", "key"), invalidAnnotMsg),
+      (Seq("trigger", "fire", "triggerName", "-A"), invalidAnnotFileMsg))
+
+    invalidArgs foreach {
+      case (cmd, err) =>
+        val stderr = wsk.cli(cmd, expectedExitCode = ERROR_EXIT).stderr
+        stderr should include(err)
+        stderr should include("Run 'wsk --help' for usage.")
+    }
+  }
+
+  behavior of "Wsk invalid argument handling"
+
+  it should "reject commands that are executed with invalid arguments" in {
+    val invalidArgsMsg = "error: Invalid argument(s)"
+    val tooFewArgsMsg = invalidArgsMsg + "."
+    val tooManyArgsMsg = invalidArgsMsg + ": "
+    val actionNameActionReqMsg = "An action name and code artifact are required."
+    val actionNameReqMsg = "An action name is required."
+    val actionOptMsg = "A code artifact is optional."
+    val packageNameReqMsg = "A package name is required."
+    val packageNameBindingReqMsg = "A package name and binding name are required."
+    val ruleNameReqMsg = "A rule name is required."
+    val ruleTriggerActionReqMsg = "A rule, trigger and action name are required."
+    val activationIdReq = "An activation ID is required."
+    val triggerNameReqMsg = "A trigger name is required."
+    val optNamespaceMsg = "An optional namespace is the only valid argument."
+    val optPayloadMsg = "A payload is optional."
+    val noArgsReqMsg = "No arguments are required."
+    val invalidArg = "invalidArg"
+    val apiCreateReqMsg =
+      "Specify a swagger file or specify an API base path with an API path, an API verb, and an action name."
+    val apiGetReqMsg = "An API base path or API name is required."
+    val apiDeleteReqMsg =
+      "An API base path or API name is required.  An optional API relative path and operation may also be provided."
+    val apiListReqMsg = "Optional parameters are: API base path (or API name), API relative path and operation."
+    val invalidShared = s"Cannot use value '$invalidArg' for shared"
+    val entityNameMsg =
+      s"An entity name, '$invalidArg', was provided instead of a namespace. Valid namespaces are of the following format: /NAMESPACE."
+    val invalidArgs = Seq(
+      (Seq("api", "create"), s"${tooFewArgsMsg} ${apiCreateReqMsg}"),
+      (
+        Seq("api", "create", "/basepath", "/path", "GET", "action", invalidArg),
+        s"${tooManyArgsMsg}${invalidArg}. ${apiCreateReqMsg}"),
+      (Seq("api", "get"), s"${tooFewArgsMsg} ${apiGetReqMsg}"),
+      (Seq("api", "get", "/basepath", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${apiGetReqMsg}"),
+      (Seq("api", "delete"), s"${tooFewArgsMsg} ${apiDeleteReqMsg}"),
+      (
+        Seq("api", "delete", "/basepath", "/path", "GET", invalidArg),
+        s"${tooManyArgsMsg}${invalidArg}. ${apiDeleteReqMsg}"),
+      (
+        Seq("api", "list", "/basepath", "/path", "GET", invalidArg),
+        s"${tooManyArgsMsg}${invalidArg}. ${apiListReqMsg}"),
+      (Seq("action", "create"), s"${tooFewArgsMsg} ${actionNameActionReqMsg}"),
+      (Seq("action", "create", "someAction"), s"${tooFewArgsMsg} ${actionNameActionReqMsg}"),
+      (Seq("action", "create", "actionName", "artifactName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("action", "update"), s"${tooFewArgsMsg} ${actionNameReqMsg} ${actionOptMsg}"),
+      (
+        Seq("action", "update", "actionName", "artifactName", invalidArg),
+        s"${tooManyArgsMsg}${invalidArg}. ${actionNameReqMsg} ${actionOptMsg}"),
+      (Seq("action", "delete"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
+      (Seq("action", "delete", "actionName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("action", "get"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
+      (Seq("action", "get", "actionName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("action", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("action", "invoke"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
+      (Seq("action", "invoke", "actionName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("activation", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("activation", "get"), s"${tooFewArgsMsg} ${activationIdReq}"),
+      (Seq("activation", "get", "activationID", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("activation", "logs"), s"${tooFewArgsMsg} ${activationIdReq}"),
+      (Seq("activation", "logs", "activationID", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("activation", "result"), s"${tooFewArgsMsg} ${activationIdReq}"),
+      (Seq("activation", "result", "activationID", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("activation", "poll", "activationID", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("namespace", "list", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${noArgsReqMsg}"),
+      (Seq("namespace", "get", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("package", "create"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
+      (Seq("package", "create", "packageName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("package", "create", "packageName", "--shared", invalidArg), invalidShared),
+      (Seq("package", "update"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
+      (Seq("package", "update", "packageName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("package", "update", "packageName", "--shared", invalidArg), invalidShared),
+      (Seq("package", "get"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
+      (Seq("package", "get", "packageName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("package", "bind"), s"${tooFewArgsMsg} ${packageNameBindingReqMsg}"),
+      (Seq("package", "bind", "packageName"), s"${tooFewArgsMsg} ${packageNameBindingReqMsg}"),
+      (Seq("package", "bind", "packageName", "bindingName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("package", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("package", "list", invalidArg), entityNameMsg),
+      (Seq("package", "delete"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
+      (Seq("package", "delete", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("package", "refresh", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("package", "refresh", invalidArg), entityNameMsg),
+      (Seq("rule", "enable"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
+      (Seq("rule", "enable", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "disable"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
+      (Seq("rule", "disable", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "status"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
+      (Seq("rule", "status", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "create"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
+      (Seq("rule", "create", "ruleName"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
+      (Seq("rule", "create", "ruleName", "triggerName"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
+      (Seq("rule", "create", "ruleName", "triggerName", "actionName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "update"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
+      (Seq("rule", "update", "ruleName"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
+      (Seq("rule", "update", "ruleName", "triggerName"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
+      (Seq("rule", "update", "ruleName", "triggerName", "actionName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "get"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
+      (Seq("rule", "get", "ruleName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "delete"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
+      (Seq("rule", "delete", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("rule", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("rule", "list", invalidArg), entityNameMsg),
+      (Seq("trigger", "fire"), s"${tooFewArgsMsg} ${triggerNameReqMsg} ${optPayloadMsg}"),
+      (
+        Seq("trigger", "fire", "triggerName", "triggerPayload", invalidArg),
+        s"${tooManyArgsMsg}${invalidArg}. ${triggerNameReqMsg} ${optPayloadMsg}"),
+      (Seq("trigger", "create"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
+      (Seq("trigger", "create", "triggerName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("trigger", "update"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
+      (Seq("trigger", "update", "triggerName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("trigger", "get"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
+      (Seq("trigger", "get", "triggerName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("trigger", "delete"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
+      (Seq("trigger", "delete", "triggerName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+      (Seq("trigger", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
+      (Seq("trigger", "list", invalidArg), entityNameMsg))
+
+    invalidArgs foreach {
+      case (cmd, err) =>
+        withClue(cmd) {
+          val rr = wsk.cli(cmd ++ wskprops.overrides, expectedExitCode = ANY_ERROR_EXIT)
+          rr.exitCode should (be(ERROR_EXIT) or be(MISUSE_EXIT))
+          rr.stderr should include(err)
+          rr.stderr should include("Run 'wsk --help' for usage.")
         }
     }
-
-    behavior of "Wsk invalid argument handling"
-
-    it should "reject commands that are executed with invalid arguments" in {
-        val invalidArgsMsg = "error: Invalid argument(s)"
-        val tooFewArgsMsg = invalidArgsMsg + "."
-        val tooManyArgsMsg = invalidArgsMsg + ": "
-        val actionNameActionReqMsg = "An action name and code artifact are required."
-        val actionNameReqMsg = "An action name is required."
-        val actionOptMsg = "A code artifact is optional."
-        val packageNameReqMsg = "A package name is required."
-        val packageNameBindingReqMsg = "A package name and binding name are required."
-        val ruleNameReqMsg = "A rule name is required."
-        val ruleTriggerActionReqMsg = "A rule, trigger and action name are required."
-        val activationIdReq = "An activation ID is required."
-        val triggerNameReqMsg = "A trigger name is required."
-        val optNamespaceMsg = "An optional namespace is the only valid argument."
-        val optPayloadMsg = "A payload is optional."
-        val noArgsReqMsg = "No arguments are required."
-        val invalidArg = "invalidArg"
-        val apiCreateReqMsg = "Specify a swagger file or specify an API base path with an API path, an API verb, and an action name."
-        val apiGetReqMsg = "An API base path or API name is required."
-        val apiDeleteReqMsg = "An API base path or API name is required.  An optional API relative path and operation may also be provided."
-        val apiListReqMsg = "Optional parameters are: API base path (or API name), API relative path and operation."
-        val invalidShared = s"Cannot use value '$invalidArg' for shared"
-        val entityNameMsg = s"An entity name, '$invalidArg', was provided instead of a namespace. Valid namespaces are of the following format: /NAMESPACE."
-        val invalidArgs = Seq(
-            (Seq("api", "create"), s"${tooFewArgsMsg} ${apiCreateReqMsg}"),
-            (Seq("api", "create", "/basepath", "/path", "GET", "action", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${apiCreateReqMsg}"),
-            (Seq("api", "get"), s"${tooFewArgsMsg} ${apiGetReqMsg}"),
-            (Seq("api", "get", "/basepath", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${apiGetReqMsg}"),
-            (Seq("api", "delete"), s"${tooFewArgsMsg} ${apiDeleteReqMsg}"),
-            (Seq("api", "delete", "/basepath", "/path", "GET", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${apiDeleteReqMsg}"),
-            (Seq("api", "list", "/basepath", "/path", "GET", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${apiListReqMsg}"),
-            (Seq("action", "create"), s"${tooFewArgsMsg} ${actionNameActionReqMsg}"),
-            (Seq("action", "create", "someAction"), s"${tooFewArgsMsg} ${actionNameActionReqMsg}"),
-            (Seq("action", "create", "actionName", "artifactName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("action", "update"), s"${tooFewArgsMsg} ${actionNameReqMsg} ${actionOptMsg}"),
-            (Seq("action", "update", "actionName", "artifactName", invalidArg),
-                s"${tooManyArgsMsg}${invalidArg}. ${actionNameReqMsg} ${actionOptMsg}"),
-            (Seq("action", "delete"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
-            (Seq("action", "delete", "actionName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("action", "get"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
-            (Seq("action", "get", "actionName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("action", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
-            (Seq("action", "invoke"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
-            (Seq("action", "invoke", "actionName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("activation", "list", "namespace", invalidArg),
-                s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
-            (Seq("activation", "get"), s"${tooFewArgsMsg} ${activationIdReq}"),
-            (Seq("activation", "get", "activationID", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("activation", "logs"), s"${tooFewArgsMsg} ${activationIdReq}"),
-            (Seq("activation", "logs", "activationID", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("activation", "result"), s"${tooFewArgsMsg} ${activationIdReq}"),
-            (Seq("activation", "result", "activationID", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("activation", "poll", "activationID", invalidArg),
-                s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
-            (Seq("namespace", "list", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${noArgsReqMsg}"),
-            (Seq("namespace", "get", "namespace", invalidArg),
-                s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
-            (Seq("package", "create"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
-            (Seq("package", "create", "packageName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("package", "create", "packageName", "--shared", invalidArg), invalidShared),
-            (Seq("package", "update"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
-            (Seq("package", "update", "packageName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("package", "update", "packageName", "--shared", invalidArg), invalidShared),
-            (Seq("package", "get"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
-            (Seq("package", "get", "packageName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("package", "bind"), s"${tooFewArgsMsg} ${packageNameBindingReqMsg}"),
-            (Seq("package", "bind", "packageName"), s"${tooFewArgsMsg} ${packageNameBindingReqMsg}"),
-            (Seq("package", "bind", "packageName", "bindingName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("package", "list", "namespace", invalidArg),
-                s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
-            (Seq("package", "list", invalidArg), entityNameMsg),
-            (Seq("package", "delete"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
-            (Seq("package", "delete", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("package", "refresh", "namespace", invalidArg),
-                s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
-            (Seq("package", "refresh", invalidArg), entityNameMsg),
-            (Seq("rule", "enable"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
-            (Seq("rule", "enable", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("rule", "disable"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
-            (Seq("rule", "disable", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("rule", "status"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
-            (Seq("rule", "status", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("rule", "create"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
-            (Seq("rule", "create", "ruleName"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
-            (Seq("rule", "create", "ruleName", "triggerName"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
-            (Seq("rule", "create", "ruleName", "triggerName", "actionName", invalidArg),
-                s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("rule", "update"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
-            (Seq("rule", "update", "ruleName"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
-            (Seq("rule", "update", "ruleName", "triggerName"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
-            (Seq("rule", "update", "ruleName", "triggerName", "actionName", invalidArg),
-                s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("rule", "get"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
-            (Seq("rule", "get", "ruleName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("rule", "delete"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
-            (Seq("rule", "delete", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("rule", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
-            (Seq("rule", "list", invalidArg), entityNameMsg),
-            (Seq("trigger", "fire"), s"${tooFewArgsMsg} ${triggerNameReqMsg} ${optPayloadMsg}"),
-            (Seq("trigger", "fire", "triggerName", "triggerPayload", invalidArg),
-                s"${tooManyArgsMsg}${invalidArg}. ${triggerNameReqMsg} ${optPayloadMsg}"),
-            (Seq("trigger", "create"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
-            (Seq("trigger", "create", "triggerName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("trigger", "update"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
-            (Seq("trigger", "update", "triggerName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("trigger", "get"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
-            (Seq("trigger", "get", "triggerName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("trigger", "delete"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
-            (Seq("trigger", "delete", "triggerName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
-            (Seq("trigger", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
-            (Seq("trigger", "list", invalidArg), entityNameMsg))
-
-        invalidArgs foreach {
-            case (cmd, err) =>
-                withClue(cmd) {
-                    val rr = wsk.cli(cmd ++ wskprops.overrides, expectedExitCode = ANY_ERROR_EXIT)
-                    rr.exitCode should (be(ERROR_EXIT) or be(MISUSE_EXIT))
-                    rr.stderr should include(err)
-                    rr.stderr should include("Run 'wsk --help' for usage.")
-                }
+  }
+
+  behavior of "Wsk action parameters"
+
+  it should "create an action with different permutations of limits" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val file = Some(TestUtils.getTestActionFilename("hello.js"))
+
+      def testLimit(timeout: Option[Duration] = None,
+                    memory: Option[ByteSize] = None,
+                    logs: Option[ByteSize] = None,
+                    ec: Int = SUCCESS_EXIT) = {
+        // Limits to assert, standard values if CLI omits certain values
+        val limits = JsObject(
+          "timeout" -> timeout.getOrElse(STD_DURATION).toMillis.toJson,
+          "memory" -> memory.getOrElse(STD_MEMORY).toMB.toInt.toJson,
+          "logs" -> logs.getOrElse(STD_LOGSIZE).toMB.toInt.toJson)
+
+        val name = "ActionLimitTests" + Instant.now.toEpochMilli
+        val createResult = assetHelper.withCleaner(wsk.action, name, confirmDelete = (ec == SUCCESS_EXIT)) {
+          (action, _) =>
+            val result = action.create(
+              name,
+              file,
+              logsize = logs,
+              memory = memory,
+              timeout = timeout,
+              expectedExitCode = DONTCARE_EXIT)
+            withClue(s"create failed for parameters: timeout = $timeout, memory = $memory, logsize = $logs:") {
+              result.exitCode should be(ec)
+            }
+            result
         }
-    }
-
-    behavior of "Wsk action parameters"
-
-    it should "create an action with different permutations of limits" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-
-            def testLimit(timeout: Option[Duration] = None, memory: Option[ByteSize] = None, logs: Option[ByteSize] = None, ec: Int = SUCCESS_EXIT) = {
-                // Limits to assert, standard values if CLI omits certain values
-                val limits = JsObject(
-                    "timeout" -> timeout.getOrElse(STD_DURATION).toMillis.toJson,
-                    "memory" -> memory.getOrElse(STD_MEMORY).toMB.toInt.toJson,
-                    "logs" -> logs.getOrElse(STD_LOGSIZE).toMB.toInt.toJson)
-
-                val name = "ActionLimitTests" + Instant.now.toEpochMilli
-                val createResult = assetHelper.withCleaner(wsk.action, name, confirmDelete = (ec == SUCCESS_EXIT)) {
-                    (action, _) =>
-                        val result = action.create(name, file, logsize = logs, memory = memory, timeout = timeout, expectedExitCode = DONTCARE_EXIT)
-                        withClue(s"create failed for parameters: timeout = $timeout, memory = $memory, logsize = $logs:") {
-                            result.exitCode should be(ec)
-                        }
-                        result
-                }
-
-                if (ec == SUCCESS_EXIT) {
-                    val JsObject(parsedAction) = wsk.action.get(name).stdout.split("\n").tail.mkString.parseJson.asJsObject
-                    parsedAction("limits") shouldBe limits
-                } else {
-                    createResult.stderr should include("allowed threshold")
-                }
-            }
 
-            // Assert for valid permutations that the values are set correctly
-            for {
-                time <- Seq(None, Some(MIN_DURATION), Some(MAX_DURATION))
-                mem <- Seq(None, Some(MIN_MEMORY), Some(MAX_MEMORY))
-                log <- Seq(None, Some(MIN_LOGSIZE), Some(MAX_LOGSIZE))
-            } testLimit(time, mem, log)
-
-            // Assert that invalid permutation are rejected
-            testLimit(Some(0.milliseconds), None, None, BAD_REQUEST)
-            testLimit(Some(100.minutes), None, None, BAD_REQUEST)
-            testLimit(None, Some(0.MB), None, BAD_REQUEST)
-            testLimit(None, Some(32768.MB), None, BAD_REQUEST)
-            testLimit(None, None, Some(32768.MB), BAD_REQUEST)
-    }
+        if (ec == SUCCESS_EXIT) {
+          val JsObject(parsedAction) = wsk.action.get(name).stdout.split("\n").tail.mkString.parseJson.asJsObject
+          parsedAction("limits") shouldBe limits
+        } else {
+          createResult.stderr should include("allowed threshold")
+        }
+      }
+
+      // Assert for valid permutations that the values are set correctly
+      for {
+        time <- Seq(None, Some(MIN_DURATION), Some(MAX_DURATION))
+        mem <- Seq(None, Some(MIN_MEMORY), Some(MAX_MEMORY))
+        log <- Seq(None, Some(MIN_LOGSIZE), Some(MAX_LOGSIZE))
+      } testLimit(time, mem, log)
+
+      // Assert that invalid permutation are rejected
+      testLimit(Some(0.milliseconds), None, None, BAD_REQUEST)
+      testLimit(Some(100.minutes), None, None, BAD_REQUEST)
+      testLimit(None, Some(0.MB), None, BAD_REQUEST)
+      testLimit(None, Some(32768.MB), None, BAD_REQUEST)
+      testLimit(None, None, Some(32768.MB), BAD_REQUEST)
+  }
 }
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskConfigTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskConfigTests.scala
index fbe1631..90b014d 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskConfigTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskConfigTests.scala
@@ -33,229 +33,287 @@ import common.WskProps
 import common.WskTestHelpers
 
 @RunWith(classOf[JUnitRunner])
-class WskConfigTests
-    extends TestHelpers
-    with WskTestHelpers {
+class WskConfigTests extends TestHelpers with WskTestHelpers {
 
-    implicit val wskprops = WskProps()
-    val wsk = new Wsk
+  implicit val wskprops = WskProps()
+  val wsk = new Wsk
 
-    behavior of "Wsk CLI config"
+  behavior of "Wsk CLI config"
 
-    it should "fail to show api build when setting apihost to bogus value" in {
-        val tmpwskprops = File.createTempFile("wskprops", ".tmp")
-        try {
-            val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
-            wsk.cli(Seq("property", "set", "-i", "--apihost", "xxxx.yyyy"), env = env)
-            val rr = wsk.cli(Seq("property", "get", "--apibuild", "-i"), env = env, expectedExitCode = ANY_ERROR_EXIT)
-            rr.stdout should include regex ("""whisk API build\s*Unknown""")
-            rr.stderr should include regex ("Unable to obtain API build information")
-        } finally {
-            tmpwskprops.delete()
-        }
+  it should "fail to show api build when setting apihost to bogus value" in {
+    val tmpwskprops = File.createTempFile("wskprops", ".tmp")
+    try {
+      val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
+      wsk.cli(Seq("property", "set", "-i", "--apihost", "xxxx.yyyy"), env = env)
+      val rr = wsk.cli(Seq("property", "get", "--apibuild", "-i"), env = env, expectedExitCode = ANY_ERROR_EXIT)
+      rr.stdout should include regex ("""whisk API build\s*Unknown""")
+      rr.stderr should include regex ("Unable to obtain API build information")
+    } finally {
+      tmpwskprops.delete()
     }
+  }
 
-    it should "validate default property values" in {
-        val tmpwskprops = File.createTempFile("wskprops", ".tmp")
-        val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
-        val stdout = wsk.cli(Seq("property", "unset", "--auth", "--cert", "--key", "--apihost", "--apiversion", "--namespace"), env = env).stdout
-        try {
-            stdout should include regex ("ok: whisk auth unset")
-            stdout should include regex ("ok: client cert unset")
-            stdout should include regex ("ok: client key unset")
-            stdout should include regex ("ok: whisk API host unset")
-            stdout should include regex ("ok: whisk API version unset")
-            stdout should include regex ("ok: whisk namespace unset")
+  it should "validate default property values" in {
+    val tmpwskprops = File.createTempFile("wskprops", ".tmp")
+    val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
+    val stdout = wsk
+      .cli(Seq("property", "unset", "--auth", "--cert", "--key", "--apihost", "--apiversion", "--namespace"), env = env)
+      .stdout
+    try {
+      stdout should include regex ("ok: whisk auth unset")
+      stdout should include regex ("ok: client cert unset")
+      stdout should include regex ("ok: client key unset")
+      stdout should include regex ("ok: whisk API host unset")
+      stdout should include regex ("ok: whisk API version unset")
+      stdout should include regex ("ok: whisk namespace unset")
 
-            wsk.cli(Seq("property", "get", "--auth"), env = env).
-                    stdout should include regex ("""(?i)whisk auth\s*$""") // default = empty string
-            wsk.cli(Seq("property", "get", "--cert"), env = env).
-                    stdout should include regex ("""(?i)client cert\s*$""") // default = empty string
-            wsk.cli(Seq("property", "get", "--key"), env = env).
-                    stdout should include regex ("""(?i)client key\s*$""") // default = empty string
-            wsk.cli(Seq("property", "get", "--apihost"), env = env).
-                    stdout should include regex ("""(?i)whisk API host\s*$""") // default = empty string
-            wsk.cli(Seq("property", "get", "--namespace"), env = env).
-                    stdout should include regex ("""(?i)whisk namespace\s*_$""") // default = _
-        } finally {
-            tmpwskprops.delete()
-        }
+      wsk
+        .cli(Seq("property", "get", "--auth"), env = env)
+        .stdout should include regex ("""(?i)whisk auth\s*$""") // default = empty string
+      wsk
+        .cli(Seq("property", "get", "--cert"), env = env)
+        .stdout should include regex ("""(?i)client cert\s*$""") // default = empty string
+      wsk
+        .cli(Seq("property", "get", "--key"), env = env)
+        .stdout should include regex ("""(?i)client key\s*$""") // default = empty string
+      wsk
+        .cli(Seq("property", "get", "--apihost"), env = env)
+        .stdout should include regex ("""(?i)whisk API host\s*$""") // default = empty string
+      wsk
+        .cli(Seq("property", "get", "--namespace"), env = env)
+        .stdout should include regex ("""(?i)whisk namespace\s*_$""") // default = _
+    } finally {
+      tmpwskprops.delete()
     }
+  }
 
-    it should "reject authenticated command when no auth key is given" in {
-        // override wsk props file in case it exists
-        val tmpwskprops = File.createTempFile("wskprops", ".tmp")
-        val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
-        val stderr = wsk.cli(Seq("list") ++ wskprops.overrides, env = env, expectedExitCode = MISUSE_EXIT).stderr
-        try {
-            stderr should include regex (s"usage[:.]")
-            stderr should include("--auth is required")
-        } finally {
-            tmpwskprops.delete()
-        }
+  it should "reject authenticated command when no auth key is given" in {
+    // override wsk props file in case it exists
+    val tmpwskprops = File.createTempFile("wskprops", ".tmp")
+    val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
+    val stderr = wsk.cli(Seq("list") ++ wskprops.overrides, env = env, expectedExitCode = MISUSE_EXIT).stderr
+    try {
+      stderr should include regex (s"usage[:.]")
+      stderr should include("--auth is required")
+    } finally {
+      tmpwskprops.delete()
     }
+  }
 
-    it should "reject a command when the API host is not set" in {
-        val tmpwskprops = File.createTempFile("wskprops", ".tmp")
-        try {
-            val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
-            val stderr = wsk.cli(Seq("property", "get", "-i"), env = env, expectedExitCode = ERROR_EXIT).stderr
-            stderr should include("The API host is not valid: An API host must be provided.")
-        } finally {
-            tmpwskprops.delete()
-        }
+  it should "reject a command when the API host is not set" in {
+    val tmpwskprops = File.createTempFile("wskprops", ".tmp")
+    try {
+      val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
+      val stderr = wsk.cli(Seq("property", "get", "-i"), env = env, expectedExitCode = ERROR_EXIT).stderr
+      stderr should include("The API host is not valid: An API host must be provided.")
+    } finally {
+      tmpwskprops.delete()
     }
+  }
 
-    it should "show api build details" in {
-        val tmpProps = File.createTempFile("wskprops", ".tmp")
-        try {
-            val env = Map("WSK_CONFIG_FILE" -> tmpProps.getAbsolutePath())
-            wsk.cli(Seq("property", "set", "-i") ++ wskprops.overrides, env = env)
-            val rr = wsk.cli(Seq("property", "get", "--apibuild", "--apibuildno", "-i"), env = env)
-            rr.stderr should not include ("https:///api/v1: http: no Host in request URL")
-            rr.stdout should not include regex("Cannot determine API build")
-            rr.stdout should include regex ("""(?i)whisk API build\s+201.*""")
-            rr.stdout should include regex ("""(?i)whisk API build number\s+.*""")
-        } finally {
-            tmpProps.delete()
-        }
+  it should "show api build details" in {
+    val tmpProps = File.createTempFile("wskprops", ".tmp")
+    try {
+      val env = Map("WSK_CONFIG_FILE" -> tmpProps.getAbsolutePath())
+      wsk.cli(Seq("property", "set", "-i") ++ wskprops.overrides, env = env)
+      val rr = wsk.cli(Seq("property", "get", "--apibuild", "--apibuildno", "-i"), env = env)
+      rr.stderr should not include ("https:///api/v1: http: no Host in request URL")
+      rr.stdout should not include regex("Cannot determine API build")
+      rr.stdout should include regex ("""(?i)whisk API build\s+201.*""")
+      rr.stdout should include regex ("""(?i)whisk API build number\s+.*""")
+    } finally {
+      tmpProps.delete()
     }
+  }
 
-    it should "set apihost, auth, and namespace" in {
-        val tmpwskprops = File.createTempFile("wskprops", ".tmp")
-        try {
-            val namespace = wsk.namespace.whois()
-            val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
-            val stdout = wsk.cli(Seq("property", "set", "-i",
-                "--apihost", wskprops.apihost,
-                "--auth", wskprops.authKey,
-                "--namespace", namespace),
-                env = env).stdout
-            stdout should include(s"ok: whisk auth set")
-            stdout should include(s"ok: whisk API host set to ${wskprops.apihost}")
-            stdout should include(s"ok: whisk namespace set to ${namespace}")
-        } finally {
-            tmpwskprops.delete()
-        }
+  it should "set apihost, auth, and namespace" in {
+    val tmpwskprops = File.createTempFile("wskprops", ".tmp")
+    try {
+      val namespace = wsk.namespace.whois()
+      val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
+      val stdout = wsk
+        .cli(
+          Seq(
+            "property",
+            "set",
+            "-i",
+            "--apihost",
+            wskprops.apihost,
+            "--auth",
+            wskprops.authKey,
+            "--namespace",
+            namespace),
+          env = env)
+        .stdout
+      stdout should include(s"ok: whisk auth set")
+      stdout should include(s"ok: whisk API host set to ${wskprops.apihost}")
+      stdout should include(s"ok: whisk namespace set to ${namespace}")
+    } finally {
+      tmpwskprops.delete()
     }
+  }
 
-    // If client certificate verification is off, should ingore run below tests.
-    if (!WhiskProperties.getProperty("whisk.ssl.client.verification").equals("off")) {
-        it should "set valid cert key to get expected success result for client certificate verification" in {
-            val tmpwskprops = File.createTempFile("wskprops", ".tmp")
-            try {
-                val namespace = wsk.namespace.list().stdout.trim.split("\n").last
-                val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
-                // Send request to https://<apihost>/api/v1/namespaces, wsk client passes client certificate to nginx, nginx will
-                // verify it by client ca's openwhisk-client-ca-cert.pem
-                val stdout = wsk.cli(Seq("property", "set", "-i", "--apihost", wskprops.apihost, "--auth", wskprops.authKey,
-                    "--cert", wskprops.cert, "--key", wskprops.key, "--namespace", namespace), env = env).stdout
-                stdout should include(s"ok: client cert set")
-                stdout should include(s"ok: client key set")
-                stdout should include(s"ok: whisk auth set")
-                stdout should include(s"ok: whisk API host set to ${wskprops.apihost}")
-                stdout should include(s"ok: whisk namespace set to ${namespace}")
-            } finally {
-                tmpwskprops.delete()
-            }
-        }
+  // If client certificate verification is off, should ingore run below tests.
+  if (!WhiskProperties.getProperty("whisk.ssl.client.verification").equals("off")) {
+    it should "set valid cert key to get expected success result for client certificate verification" in {
+      val tmpwskprops = File.createTempFile("wskprops", ".tmp")
+      try {
+        val namespace = wsk.namespace.list().stdout.trim.split("\n").last
+        val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
+        // Send request to https://<apihost>/api/v1/namespaces, wsk client passes client certificate to nginx, nginx will
+        // verify it by client ca's openwhisk-client-ca-cert.pem
+        val stdout = wsk
+          .cli(
+            Seq(
+              "property",
+              "set",
+              "-i",
+              "--apihost",
+              wskprops.apihost,
+              "--auth",
+              wskprops.authKey,
+              "--cert",
+              wskprops.cert,
+              "--key",
+              wskprops.key,
+              "--namespace",
+              namespace),
+            env = env)
+          .stdout
+        stdout should include(s"ok: client cert set")
+        stdout should include(s"ok: client key set")
+        stdout should include(s"ok: whisk auth set")
+        stdout should include(s"ok: whisk API host set to ${wskprops.apihost}")
+        stdout should include(s"ok: whisk namespace set to ${namespace}")
+      } finally {
+        tmpwskprops.delete()
+      }
+    }
 
-        it should "set invalid cert key to get expected exception result for client certificate verification" in {
-            val tmpwskprops = File.createTempFile("wskprops", ".tmp")
-            try {
-                val namespace = wsk.namespace.list().stdout.trim.split("\n").last
-                val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
-                val thrown = the[Exception] thrownBy wsk.cli(Seq("property", "set", "-i", "--apihost", wskprops.apihost, "--auth", wskprops.authKey,
-                    "--cert", "invalid-cert.pem", "--key", "invalid-key.pem", "--namespace", namespace), env = env)
-                thrown.getMessage should include("cannot validate certificate")
-            } finally {
-                tmpwskprops.delete()
-            }
-        }
+    it should "set invalid cert key to get expected exception result for client certificate verification" in {
+      val tmpwskprops = File.createTempFile("wskprops", ".tmp")
+      try {
+        val namespace = wsk.namespace.list().stdout.trim.split("\n").last
+        val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
+        val thrown = the[Exception] thrownBy wsk.cli(
+          Seq(
+            "property",
+            "set",
+            "-i",
+            "--apihost",
+            wskprops.apihost,
+            "--auth",
+            wskprops.authKey,
+            "--cert",
+            "invalid-cert.pem",
+            "--key",
+            "invalid-key.pem",
+            "--namespace",
+            namespace),
+          env = env)
+        thrown.getMessage should include("cannot validate certificate")
+      } finally {
+        tmpwskprops.delete()
+      }
     }
+  }
 
-    it should "ensure default namespace is used when a blank namespace is set" in {
-        val tmpwskprops = File.createTempFile("wskprops", ".tmp")
-        try {
-            val writer = new BufferedWriter(new FileWriter(tmpwskprops))
-            writer.write(s"NAMESPACE=")
-            writer.close()
-            val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
-            val stdout = wsk.cli(Seq("property", "get", "-i", "--namespace"), env = env).stdout
-            stdout should include regex ("whisk namespace\\s+_")
-        } finally {
-            tmpwskprops.delete()
-        }
+  it should "ensure default namespace is used when a blank namespace is set" in {
+    val tmpwskprops = File.createTempFile("wskprops", ".tmp")
+    try {
+      val writer = new BufferedWriter(new FileWriter(tmpwskprops))
+      writer.write(s"NAMESPACE=")
+      writer.close()
+      val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
+      val stdout = wsk.cli(Seq("property", "get", "-i", "--namespace"), env = env).stdout
+      stdout should include regex ("whisk namespace\\s+_")
+    } finally {
+      tmpwskprops.delete()
     }
+  }
 
-    it should "show api build version using property file" in {
-        val tmpwskprops = File.createTempFile("wskprops", ".tmp")
-        try {
-            val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
-            wsk.cli(Seq("property", "set", "-i") ++ wskprops.overrides, env = env)
-            val stdout = wsk.cli(Seq("property", "get", "--apibuild", "-i"), env = env).stdout
-            stdout should include regex ("""(?i)whisk API build\s+201.*""")
-        } finally {
-            tmpwskprops.delete()
-        }
+  it should "show api build version using property file" in {
+    val tmpwskprops = File.createTempFile("wskprops", ".tmp")
+    try {
+      val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
+      wsk.cli(Seq("property", "set", "-i") ++ wskprops.overrides, env = env)
+      val stdout = wsk.cli(Seq("property", "get", "--apibuild", "-i"), env = env).stdout
+      stdout should include regex ("""(?i)whisk API build\s+201.*""")
+    } finally {
+      tmpwskprops.delete()
     }
+  }
 
-    it should "show api build using http apihost" in {
-        val tmpwskprops = File.createTempFile("wskprops", ".tmp")
-        try {
-            val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
-            val apihost = s"http://${WhiskProperties.getBaseControllerAddress()}"
-            wsk.cli(Seq("property", "set", "--apihost", apihost), env = env)
-            val rr = wsk.cli(Seq("property", "get", "--apibuild", "-i"), env = env)
-            rr.stdout should not include regex("""whisk API build\s*Unknown""")
-            rr.stderr should not include regex("Unable to obtain API build information")
-            rr.stdout should include regex ("""(?i)whisk API build\s+201.*""")
-        } finally {
-            tmpwskprops.delete()
-        }
+  it should "show api build using http apihost" in {
+    val tmpwskprops = File.createTempFile("wskprops", ".tmp")
+    try {
+      val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
+      val apihost = s"http://${WhiskProperties.getBaseControllerAddress()}"
+      wsk.cli(Seq("property", "set", "--apihost", apihost), env = env)
+      val rr = wsk.cli(Seq("property", "get", "--apibuild", "-i"), env = env)
+      rr.stdout should not include regex("""whisk API build\s*Unknown""")
+      rr.stderr should not include regex("Unable to obtain API build information")
+      rr.stdout should include regex ("""(?i)whisk API build\s+201.*""")
+    } finally {
+      tmpwskprops.delete()
     }
+  }
 
-    it should "set auth in property file" in {
-        val tmpwskprops = File.createTempFile("wskprops", ".tmp")
-        val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
-        wsk.cli(Seq("property", "set", "--auth", "testKey"), env = env)
-        try {
-            val fileContent = FileUtils.readFileToString(tmpwskprops)
-            fileContent should include("AUTH=testKey")
-        } finally {
-            tmpwskprops.delete()
-        }
+  it should "set auth in property file" in {
+    val tmpwskprops = File.createTempFile("wskprops", ".tmp")
+    val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
+    wsk.cli(Seq("property", "set", "--auth", "testKey"), env = env)
+    try {
+      val fileContent = FileUtils.readFileToString(tmpwskprops)
+      fileContent should include("AUTH=testKey")
+    } finally {
+      tmpwskprops.delete()
     }
+  }
 
-    it should "set multiple property values with single command" in {
-        val tmpwskprops = File.createTempFile("wskprops", ".tmp")
-        val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
-        val stdout = wsk.cli(Seq("property", "set", "--auth", "testKey", "--cert", "cert.pem", "--key", "key.pem", "--apihost", "openwhisk.ng.bluemix.net", "--apiversion", "v1"), env = env).stdout
-        try {
-            stdout should include regex ("ok: whisk auth set")
-            stdout should include regex ("ok: client cert set")
-            stdout should include regex ("ok: client key set")
-            stdout should include regex ("ok: whisk API host set")
-            stdout should include regex ("ok: whisk API version set")
-            val fileContent = FileUtils.readFileToString(tmpwskprops)
-            fileContent should include("AUTH=testKey")
-            fileContent should include("APIHOST=openwhisk.ng.bluemix.net")
-            fileContent should include("APIVERSION=v1")
-        } finally {
-            tmpwskprops.delete()
-        }
+  it should "set multiple property values with single command" in {
+    val tmpwskprops = File.createTempFile("wskprops", ".tmp")
+    val env = Map("WSK_CONFIG_FILE" -> tmpwskprops.getAbsolutePath())
+    val stdout = wsk
+      .cli(
+        Seq(
+          "property",
+          "set",
+          "--auth",
+          "testKey",
+          "--cert",
+          "cert.pem",
+          "--key",
+          "key.pem",
+          "--apihost",
+          "openwhisk.ng.bluemix.net",
+          "--apiversion",
+          "v1"),
+        env = env)
+      .stdout
+    try {
+      stdout should include regex ("ok: whisk auth set")
+      stdout should include regex ("ok: client cert set")
+      stdout should include regex ("ok: client key set")
+      stdout should include regex ("ok: whisk API host set")
+      stdout should include regex ("ok: whisk API version set")
+      val fileContent = FileUtils.readFileToString(tmpwskprops)
+      fileContent should include("AUTH=testKey")
+      fileContent should include("APIHOST=openwhisk.ng.bluemix.net")
+      fileContent should include("APIVERSION=v1")
+    } finally {
+      tmpwskprops.delete()
     }
+  }
 
-    it should "create a trigger using property file" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "listTriggers"
-            val tmpProps = File.createTempFile("wskprops", ".tmp")
-            val env = Map("WSK_CONFIG_FILE" -> tmpProps.getAbsolutePath())
-            wsk.cli(Seq("property", "set", "--auth", wp.authKey) ++ wskprops.overrides, env = env)
-            assetHelper.withCleaner(wsk.trigger, name) {
-                (trigger, _) =>
-                    wsk.cli(Seq("-i", "trigger", "create", name), env = env)
-            }
-            tmpProps.delete()
+  it should "create a trigger using property file" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "listTriggers"
+    val tmpProps = File.createTempFile("wskprops", ".tmp")
+    val env = Map("WSK_CONFIG_FILE" -> tmpProps.getAbsolutePath())
+    wsk.cli(Seq("property", "set", "--auth", wp.authKey) ++ wskprops.overrides, env = env)
+    assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
+      wsk.cli(Seq("-i", "trigger", "create", name), env = env)
     }
+    tmpProps.delete()
+  }
 }
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala
index 7f83762..8140cb4 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala
@@ -35,326 +35,315 @@ import whisk.core.entity.Subject
 import whisk.core.entity.WhiskPackage
 
 @RunWith(classOf[JUnitRunner])
-class WskEntitlementTests
-    extends TestHelpers
-    with WskTestHelpers
-    with BeforeAndAfterAll {
-
-    val wsk = new Wsk
-    lazy val defaultWskProps = WskProps()
-    lazy val guestWskProps = getAdditionalTestSubject(Subject().asString)
-
-    override def afterAll() = {
-        disposeAdditionalTestSubject(guestWskProps.namespace)
+class WskEntitlementTests extends TestHelpers with WskTestHelpers with BeforeAndAfterAll {
+
+  val wsk = new Wsk
+  lazy val defaultWskProps = WskProps()
+  lazy val guestWskProps = getAdditionalTestSubject(Subject().asString)
+
+  override def afterAll() = {
+    disposeAdditionalTestSubject(guestWskProps.namespace)
+  }
+
+  val samplePackage = "samplePackage"
+  val sampleAction = "sampleAction"
+  val fullSampleActionName = s"$samplePackage/$sampleAction"
+  val guestNamespace = guestWskProps.namespace
+
+  behavior of "Wsk Package Entitlement"
+
+  it should "not allow unauthorized subject to operate on private action" in withAssetCleaner(guestWskProps) {
+    (wp, assetHelper) =>
+      val privateAction = "privateAction"
+
+      assetHelper.withCleaner(wsk.action, privateAction) { (action, name) =>
+        action.create(name, Some(TestUtils.getTestActionFilename("hello.js")))(wp)
+      }
+
+      val fullyQualifiedActionName = s"/$guestNamespace/$privateAction"
+      wsk.action.get(fullyQualifiedActionName, expectedExitCode = FORBIDDEN)(defaultWskProps).stderr should include(
+        "not authorized")
+
+      withAssetCleaner(defaultWskProps) { (wp, assetHelper) =>
+        assetHelper.withCleaner(wsk.action, fullyQualifiedActionName, confirmDelete = false) { (action, name) =>
+          val rr = action.create(name, None, update = true, expectedExitCode = FORBIDDEN)(wp)
+          rr.stderr should include("not authorized")
+          rr
+        }
+        assetHelper.withCleaner(wsk.action, "unauthorized sequence", confirmDelete = false) { (action, name) =>
+          val rr = action.create(
+            name,
+            Some(fullyQualifiedActionName),
+            kind = Some("sequence"),
+            update = true,
+            expectedExitCode = FORBIDDEN)(wp)
+          rr.stderr should include("not authorized")
+          rr
+        }
+      }
+
+      wsk.action.delete(fullyQualifiedActionName, expectedExitCode = FORBIDDEN)(defaultWskProps).stderr should include(
+        "not authorized")
+
+      wsk.action.invoke(fullyQualifiedActionName, expectedExitCode = FORBIDDEN)(defaultWskProps).stderr should include(
+        "not authorized")
+  }
+
+  it should "reject deleting action in shared package not owned by authkey" in withAssetCleaner(guestWskProps) {
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
+        pkg.create(samplePackage, shared = Some(true))(wp)
+      }
+
+      assetHelper.withCleaner(wsk.action, fullSampleActionName) {
+        val file = Some(TestUtils.getTestActionFilename("empty.js"))
+        (action, _) =>
+          action.create(fullSampleActionName, file)(wp)
+      }
+
+      val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
+      wsk.action.get(fullyQualifiedActionName)(defaultWskProps)
+      wsk.action.delete(fullyQualifiedActionName, expectedExitCode = FORBIDDEN)(defaultWskProps)
+  }
+
+  it should "reject create action in shared package not owned by authkey" in withAssetCleaner(guestWskProps) {
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, name) =>
+        pkg.create(name, shared = Some(true))(wp)
+      }
+
+      val fullyQualifiedActionName = s"/$guestNamespace/notallowed"
+      val file = Some(TestUtils.getTestActionFilename("empty.js"))
+
+      withAssetCleaner(defaultWskProps) { (wp, assetHelper) =>
+        assetHelper.withCleaner(wsk.action, fullyQualifiedActionName, confirmDelete = false) { (action, name) =>
+          action.create(name, file, expectedExitCode = FORBIDDEN)(wp)
+        }
+      }
+  }
+
+  it should "reject update action in shared package not owned by authkey" in withAssetCleaner(guestWskProps) {
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
+        pkg.create(samplePackage, shared = Some(true))(wp)
+      }
+
+      assetHelper.withCleaner(wsk.action, fullSampleActionName) {
+        val file = Some(TestUtils.getTestActionFilename("empty.js"))
+        (action, _) =>
+          action.create(fullSampleActionName, file)(wp)
+      }
+
+      val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
+      wsk.action.create(fullyQualifiedActionName, None, update = true, expectedExitCode = FORBIDDEN)(defaultWskProps)
+  }
+
+  behavior of "Wsk Package Listing"
+
+  it should "list shared packages" in withAssetCleaner(guestWskProps) { (wp, assetHelper) =>
+    assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
+      pkg.create(samplePackage, shared = Some(true))(wp)
     }
 
-    val samplePackage = "samplePackage"
-    val sampleAction = "sampleAction"
-    val fullSampleActionName = s"$samplePackage/$sampleAction"
-    val guestNamespace = guestWskProps.namespace
-
-    behavior of "Wsk Package Entitlement"
-
-    it should "not allow unauthorized subject to operate on private action" in withAssetCleaner(guestWskProps) {
-        (wp, assetHelper) =>
-            val privateAction = "privateAction"
-
-            assetHelper.withCleaner(wsk.action, privateAction) {
-                (action, name) => action.create(name, Some(TestCLIUtils.getTestActionFilename("hello.js")))(wp)
-            }
-
-            val fullyQualifiedActionName = s"/$guestNamespace/$privateAction"
-            wsk.action.get(fullyQualifiedActionName, expectedExitCode = FORBIDDEN)(defaultWskProps).
-                stderr should include("not authorized")
-
-            withAssetCleaner(defaultWskProps) {
-                (wp, assetHelper) =>
-                    assetHelper.withCleaner(wsk.action, fullyQualifiedActionName, confirmDelete = false) {
-                        (action, name) =>
-                            val rr = action.create(name, None, update = true, expectedExitCode = FORBIDDEN)(wp)
-                            rr.stderr should include("not authorized")
-                            rr
-                    }
-                    assetHelper.withCleaner(wsk.action, "unauthorized sequence", confirmDelete = false) {
-                        (action, name) =>
-                            val rr = action.create(name, Some(fullyQualifiedActionName), kind = Some("sequence"), update = true, expectedExitCode = FORBIDDEN)(wp)
-                            rr.stderr should include("not authorized")
-                            rr
-                    }
-            }
-
-            wsk.action.delete(fullyQualifiedActionName, expectedExitCode = FORBIDDEN)(defaultWskProps).
-                stderr should include("not authorized")
-
-            wsk.action.invoke(fullyQualifiedActionName, expectedExitCode = FORBIDDEN)(defaultWskProps).
-                stderr should include("not authorized")
-    }
+    val fullyQualifiedPackageName = s"/$guestNamespace/$samplePackage"
+    val result = wsk.pkg.list(Some(s"/$guestNamespace"))(defaultWskProps).stdout
+    result should include regex (fullyQualifiedPackageName + """\s+shared""")
+  }
 
-    it should "reject deleting action in shared package not owned by authkey" in withAssetCleaner(guestWskProps) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.pkg, samplePackage) {
-                (pkg, _) => pkg.create(samplePackage, shared = Some(true))(wp)
-            }
+  it should "not list private packages" in withAssetCleaner(guestWskProps) { (wp, assetHelper) =>
+    assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
+      pkg.create(samplePackage)(wp)
+    }
 
-            assetHelper.withCleaner(wsk.action, fullSampleActionName) {
-                val file = Some(TestCLIUtils.getTestActionFilename("empty.js"))
-                (action, _) => action.create(fullSampleActionName, file)(wp)
-            }
+    val fullyQualifiedPackageName = s"/$guestNamespace/$samplePackage"
+    val result = wsk.pkg.list(Some(s"/$guestNamespace"))(defaultWskProps).stdout
+    result should not include regex(fullyQualifiedPackageName)
+  }
 
-            val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
-            wsk.action.get(fullyQualifiedActionName)(defaultWskProps)
-            wsk.action.delete(fullyQualifiedActionName, expectedExitCode = FORBIDDEN)(defaultWskProps)
+  it should "list shared package actions" in withAssetCleaner(guestWskProps) { (wp, assetHelper) =>
+    assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
+      pkg.create(samplePackage, shared = Some(true))(wp)
     }
 
-    it should "reject create action in shared package not owned by authkey" in withAssetCleaner(guestWskProps) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.pkg, samplePackage) {
-                (pkg, name) => pkg.create(name, shared = Some(true))(wp)
-            }
-
-            val fullyQualifiedActionName = s"/$guestNamespace/notallowed"
-            val file = Some(TestCLIUtils.getTestActionFilename("empty.js"))
-
-            withAssetCleaner(defaultWskProps) {
-                (wp, assetHelper) =>
-                    assetHelper.withCleaner(wsk.action, fullyQualifiedActionName, confirmDelete = false) {
-                        (action, name) => action.create(name, file, expectedExitCode = FORBIDDEN)(wp)
-                    }
-            }
+    assetHelper.withCleaner(wsk.action, fullSampleActionName) {
+      val file = Some(TestUtils.getTestActionFilename("empty.js"))
+      (action, _) =>
+        action.create(fullSampleActionName, file, kind = Some("nodejs:default"))(wp)
     }
 
-    it should "reject update action in shared package not owned by authkey" in withAssetCleaner(guestWskProps) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.pkg, samplePackage) {
-                (pkg, _) => pkg.create(samplePackage, shared = Some(true))(wp)
-            }
+    val fullyQualifiedPackageName = s"/$guestNamespace/$samplePackage"
+    val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
+    val result = wsk.action.list(Some(fullyQualifiedPackageName))(defaultWskProps).stdout
+    result should include regex (fullyQualifiedActionName)
+  }
 
-            assetHelper.withCleaner(wsk.action, fullSampleActionName) {
-                val file = Some(TestCLIUtils.getTestActionFilename("empty.js"))
-                (action, _) => action.create(fullSampleActionName, file)(wp)
-            }
+  behavior of "Wsk Package Binding"
 
-            val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
-            wsk.action.create(fullyQualifiedActionName, None, update = true, expectedExitCode = FORBIDDEN)(defaultWskProps)
+  it should "create a package binding" in withAssetCleaner(guestWskProps) { (wp, assetHelper) =>
+    assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
+      pkg.create(samplePackage, shared = Some(true))(wp)
     }
 
-    behavior of "Wsk Package Listing"
-
-    it should "list shared packages" in withAssetCleaner(guestWskProps) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.pkg, samplePackage) {
-                (pkg, _) => pkg.create(samplePackage, shared = Some(true))(wp)
-            }
-
-            val fullyQualifiedPackageName = s"/$guestNamespace/$samplePackage"
-            val result = wsk.pkg.list(Some(s"/$guestNamespace"))(defaultWskProps).stdout
-            result should include regex (fullyQualifiedPackageName + """\s+shared""")
+    val name = "bindPackage"
+    val annotations = Map("a" -> "A".toJson, WhiskPackage.bindingFieldName -> "xxx".toJson)
+    val provider = s"/$guestNamespace/$samplePackage"
+    withAssetCleaner(defaultWskProps) { (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
+        pkg.bind(provider, name, annotations = annotations)(wp)
+      }
+
+      val stdout = wsk.pkg.get(name)(defaultWskProps).stdout
+      val annotationString = wsk.parseJsonString(stdout).fields("annotations").toString
+      annotationString should include regex (""""key":"a"""")
+      annotationString should include regex (""""value":"A"""")
+      annotationString should include regex (s""""key":"${WhiskPackage.bindingFieldName}"""")
+      annotationString should not include regex(""""key":"xxx"""")
+      annotationString should include regex (s""""name":"${samplePackage}"""")
     }
+  }
 
-    it should "not list private packages" in withAssetCleaner(guestWskProps) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.pkg, samplePackage) {
-                (pkg, _) => pkg.create(samplePackage)(wp)
-            }
-
-            val fullyQualifiedPackageName = s"/$guestNamespace/$samplePackage"
-            val result = wsk.pkg.list(Some(s"/$guestNamespace"))(defaultWskProps).stdout
-            result should not include regex(fullyQualifiedPackageName)
+  it should "not create a package binding for private package" in withAssetCleaner(guestWskProps) { (wp, assetHelper) =>
+    assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
+      pkg.create(samplePackage, shared = Some(false))(wp)
     }
 
-    it should "list shared package actions" in withAssetCleaner(guestWskProps) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.pkg, samplePackage) {
-                (pkg, _) => pkg.create(samplePackage, shared = Some(true))(wp)
-            }
-
-            assetHelper.withCleaner(wsk.action, fullSampleActionName) {
-                val file = Some(TestCLIUtils.getTestActionFilename("empty.js"))
-                (action, _) => action.create(fullSampleActionName, file, kind = Some("nodejs:default"))(wp)
-            }
-
-            val fullyQualifiedPackageName = s"/$guestNamespace/$samplePackage"
-            val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
-            val result = wsk.action.list(Some(fullyQualifiedPackageName))(defaultWskProps).stdout
-            result should include regex (fullyQualifiedActionName)
+    val name = "bindPackage"
+    val provider = s"/$guestNamespace/$samplePackage"
+    withAssetCleaner(defaultWskProps) { (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.pkg, name, confirmDelete = false) { (pkg, _) =>
+        pkg.bind(provider, name, expectedExitCode = FORBIDDEN)(wp)
+      }
     }
+  }
+
+  behavior of "Wsk Package Action"
 
-    behavior of "Wsk Package Binding"
-
-    it should "create a package binding" in withAssetCleaner(guestWskProps) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.pkg, samplePackage) {
-                (pkg, _) => pkg.create(samplePackage, shared = Some(true))(wp)
-            }
-
-            val name = "bindPackage"
-            val annotations = Map("a" -> "A".toJson, WhiskPackage.bindingFieldName -> "xxx".toJson)
-            val provider = s"/$guestNamespace/$samplePackage"
-            withAssetCleaner(defaultWskProps) {
-                (wp, assetHelper) =>
-                    assetHelper.withCleaner(wsk.pkg, name) {
-                        (pkg, _) => pkg.bind(provider, name, annotations = annotations)(wp)
-                    }
-
-                    val stdout = wsk.pkg.get(name)(defaultWskProps).stdout
-                    val annotationString = wsk.parseJsonString(stdout).fields("annotations").toString
-                    annotationString should include regex (""""key":"a"""")
-                    annotationString should include regex (""""value":"A"""")
-                    annotationString should include regex (s""""key":"${WhiskPackage.bindingFieldName}"""")
-                    annotationString should not include regex(""""key":"xxx"""")
-                    annotationString should include regex (s""""name":"${samplePackage}"""")
-            }
+  it should "get and invoke an action from package" in withAssetCleaner(guestWskProps) { (wp, assetHelper) =>
+    assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
+      pkg.create(samplePackage, parameters = Map("a" -> "A".toJson), shared = Some(true))(wp)
     }
 
-    it should "not create a package binding for private package" in withAssetCleaner(guestWskProps) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.pkg, samplePackage) {
-                (pkg, _) => pkg.create(samplePackage, shared = Some(false))(wp)
-            }
-
-            val name = "bindPackage"
-            val provider = s"/$guestNamespace/$samplePackage"
-            withAssetCleaner(defaultWskProps) {
-                (wp, assetHelper) =>
-                    assetHelper.withCleaner(wsk.pkg, name, confirmDelete = false) {
-                        (pkg, _) => pkg.bind(provider, name, expectedExitCode = FORBIDDEN)(wp)
-                    }
-            }
+    assetHelper.withCleaner(wsk.action, fullSampleActionName) {
+      val file = Some(TestUtils.getTestActionFilename("hello.js"))
+      (action, _) =>
+        action.create(fullSampleActionName, file)(wp)
     }
 
-    behavior of "Wsk Package Action"
+    val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
+    val stdout = wsk.action.get(fullyQualifiedActionName)(defaultWskProps).stdout
+    stdout should include("name")
+    stdout should include("parameters")
+    stdout should include("limits")
+    stdout should include regex (""""key": "a"""")
+    stdout should include regex (""""value": "A"""")
 
-    it should "get and invoke an action from package" in withAssetCleaner(guestWskProps) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.pkg, samplePackage) {
-                (pkg, _) => pkg.create(samplePackage, parameters = Map("a" -> "A".toJson), shared = Some(true))(wp)
-            }
+    val run = wsk.action.invoke(fullyQualifiedActionName)(defaultWskProps)
 
-            assetHelper.withCleaner(wsk.action, fullSampleActionName) {
-                val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-                (action, _) => action.create(fullSampleActionName, file)(wp)
-            }
+    withActivation(wsk.activation, run)({
+      _.response.success shouldBe true
+    })(defaultWskProps)
+  }
 
-            val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
-            val stdout = wsk.action.get(fullyQualifiedActionName)(defaultWskProps).stdout
-            stdout should include("name")
-            stdout should include("parameters")
-            stdout should include("limits")
-            stdout should include regex (""""key": "a"""")
-            stdout should include regex (""""value": "A"""")
+  it should "invoke an action sequence from package" in withAssetCleaner(guestWskProps) { (wp, assetHelper) =>
+    assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
+      pkg.create(samplePackage, parameters = Map("a" -> "A".toJson), shared = Some(true))(wp)
+    }
+
+    assetHelper.withCleaner(wsk.action, fullSampleActionName) {
+      val file = Some(TestUtils.getTestActionFilename("hello.js"))
+      (action, _) =>
+        action.create(fullSampleActionName, file)(wp)
+    }
 
-            val run = wsk.action.invoke(fullyQualifiedActionName)(defaultWskProps)
+    withAssetCleaner(defaultWskProps) { (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.action, "sequence") { (action, name) =>
+        val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
+        action.create(name, Some(fullyQualifiedActionName), kind = Some("sequence"), update = true)(wp)
+      }
 
-            withActivation(wsk.activation, run)({
-                _.response.success shouldBe true
-            })(defaultWskProps)
+      val run = wsk.action.invoke("sequence")(defaultWskProps)
+      withActivation(wsk.activation, run)({
+        _.response.success shouldBe true
+      })(defaultWskProps)
+    }
+  }
+
+  it should "not allow invoke an action sequence with more than one component from package after entitlement change" in withAssetCleaner(
+    guestWskProps) { (guestwp, assetHelper) =>
+    val privateSamplePackage = samplePackage + "prv"
+    assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
+      pkg.create(samplePackage, parameters = Map("a" -> "A".toJson), shared = Some(true))(guestwp)
+      pkg.create(privateSamplePackage, parameters = Map("a" -> "A".toJson), shared = Some(true))(guestwp)
     }
 
-    it should "invoke an action sequence from package" in withAssetCleaner(guestWskProps) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.pkg, samplePackage) {
-                (pkg, _) => pkg.create(samplePackage, parameters = Map("a" -> "A".toJson), shared = Some(true))(wp)
-            }
-
-            assetHelper.withCleaner(wsk.action, fullSampleActionName) {
-                val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-                (action, _) => action.create(fullSampleActionName, file)(wp)
-            }
-
-            withAssetCleaner(defaultWskProps) {
-                (wp, assetHelper) =>
-                    assetHelper.withCleaner(wsk.action, "sequence") {
-                        (action, name) =>
-                            val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
-                            action.create(name, Some(fullyQualifiedActionName), kind = Some("sequence"), update = true)(wp)
-                    }
-
-                    val run = wsk.action.invoke("sequence")(defaultWskProps)
-                    withActivation(wsk.activation, run)({
-                        _.response.success shouldBe true
-                    })(defaultWskProps)
-            }
+    assetHelper.withCleaner(wsk.action, fullSampleActionName) {
+      val file = Some(TestUtils.getTestActionFilename("hello.js"))
+      (action, _) =>
+        action.create(fullSampleActionName, file)(guestwp)
+        action.create(s"$privateSamplePackage/$sampleAction", file)(guestwp)
     }
 
-    it should "not allow invoke an action sequence with more than one component from package after entitlement change" in withAssetCleaner(guestWskProps) {
-        (guestwp, assetHelper) =>
-            val privateSamplePackage = samplePackage + "prv"
-            assetHelper.withCleaner(wsk.pkg, samplePackage) {
-                (pkg, _) =>
-                    pkg.create(samplePackage, parameters = Map("a" -> "A".toJson), shared = Some(true))(guestwp)
-                    pkg.create(privateSamplePackage, parameters = Map("a" -> "A".toJson), shared = Some(true))(guestwp)
-            }
-
-            assetHelper.withCleaner(wsk.action, fullSampleActionName) {
-                val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-                (action, _) =>
-                    action.create(fullSampleActionName, file)(guestwp)
-                    action.create(s"$privateSamplePackage/$sampleAction", file)(guestwp)
-            }
-
-            withAssetCleaner(defaultWskProps) {
-                (dwp, assetHelper) =>
-                    assetHelper.withCleaner(wsk.action, "sequence") {
-                        (action, name) =>
-                            val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
-                            val fullyQualifiedActionName2 = s"/$guestNamespace/$privateSamplePackage/$sampleAction"
-                            action.create(name, Some(s"$fullyQualifiedActionName,$fullyQualifiedActionName2"),
-                                kind = Some("sequence"))(dwp)
-                    }
-
-                    // change package visibility
-                    wsk.pkg.create(privateSamplePackage, update = true, shared = Some(false))(guestwp)
-                    wsk.action.invoke("sequence", expectedExitCode = FORBIDDEN)(defaultWskProps)
-            }
+    withAssetCleaner(defaultWskProps) { (dwp, assetHelper) =>
+      assetHelper.withCleaner(wsk.action, "sequence") { (action, name) =>
+        val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
+        val fullyQualifiedActionName2 = s"/$guestNamespace/$privateSamplePackage/$sampleAction"
+        action.create(name, Some(s"$fullyQualifiedActionName,$fullyQualifiedActionName2"), kind = Some("sequence"))(dwp)
+      }
+
+      // change package visibility
+      wsk.pkg.create(privateSamplePackage, update = true, shared = Some(false))(guestwp)
+      wsk.action.invoke("sequence", expectedExitCode = FORBIDDEN)(defaultWskProps)
     }
+  }
+
+  it should "invoke a packaged action not owned by the subject to get the subject's namespace" in withAssetCleaner(
+    guestWskProps) { (_, assetHelper) =>
+    val packageName = "namespacePackage"
+    val actionName = "namespaceAction"
+    val packagedActionName = s"$packageName/$actionName"
 
-    it should "invoke a packaged action not owned by the subject to get the subject's namespace" in withAssetCleaner(guestWskProps) {
-        (_, assetHelper) =>
-            val packageName = "namespacePackage"
-            val actionName = "namespaceAction"
-            val packagedActionName = s"$packageName/$actionName"
-
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, _) => pkg.create(packageName, shared = Some(true))(guestWskProps)
-            }
-
-            assetHelper.withCleaner(wsk.action, packagedActionName) {
-                val file = Some(TestCLIUtils.getTestActionFilename("helloContext.js"))
-                (action, _) => action.create(packagedActionName, file)(guestWskProps)
-            }
-
-            val fullyQualifiedActionName = s"/$guestNamespace/$packagedActionName"
-            val run = wsk.action.invoke(fullyQualifiedActionName)(defaultWskProps)
-
-            withActivation(wsk.activation, run)({ activation =>
-                val namespace = wsk.namespace.whois()(defaultWskProps)
-                activation.response.success shouldBe true
-                activation.response.result.get.toString should include regex (s""""namespace":\\s*"$namespace"""")
-            })(defaultWskProps)
+    assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
+      pkg.create(packageName, shared = Some(true))(guestWskProps)
     }
 
-    behavior of "Wsk Trigger Feed"
-
-    it should "not create a trigger with timeout error when feed fails to initialize" in withAssetCleaner(guestWskProps) {
-        (wp, assetHelper) =>
-            assetHelper.withCleaner(wsk.pkg, samplePackage) {
-                (pkg, _) => pkg.create(samplePackage, shared = Some(true))(wp)
-            }
-
-            val sampleFeed = s"$samplePackage/sampleFeed"
-            assetHelper.withCleaner(wsk.action, sampleFeed) {
-                val file = Some(TestCLIUtils.getTestActionFilename("empty.js"))
-                (action, _) => action.create(sampleFeed, file, kind = Some("nodejs:default"))(wp)
-            }
-
-            val fullyQualifiedFeedName = s"/$guestNamespace/$sampleFeed"
-            withAssetCleaner(defaultWskProps) {
-                (wp, assetHelper) =>
-                    assetHelper.withCleaner(wsk.trigger, "badfeed", confirmDelete = false) {
-                        (trigger, name) => trigger.create(name, feed = Some(fullyQualifiedFeedName), expectedExitCode = TIMEOUT)(wp)
-                    }
-                    wsk.trigger.get("badfeed", expectedExitCode = NOT_FOUND)(wp)
-            }
+    assetHelper.withCleaner(wsk.action, packagedActionName) {
+      val file = Some(TestUtils.getTestActionFilename("helloContext.js"))
+      (action, _) =>
+        action.create(packagedActionName, file)(guestWskProps)
     }
 
+    val fullyQualifiedActionName = s"/$guestNamespace/$packagedActionName"
+    val run = wsk.action.invoke(fullyQualifiedActionName)(defaultWskProps)
+
+    withActivation(wsk.activation, run)({ activation =>
+      val namespace = wsk.namespace.whois()(defaultWskProps)
+      activation.response.success shouldBe true
+      activation.response.result.get.toString should include regex (s""""namespace":\\s*"$namespace"""")
+    })(defaultWskProps)
+  }
+
+  behavior of "Wsk Trigger Feed"
+
+  it should "not create a trigger with timeout error when feed fails to initialize" in withAssetCleaner(guestWskProps) {
+    (wp, assetHelper) =>
+      assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
+        pkg.create(samplePackage, shared = Some(true))(wp)
+      }
+
+      val sampleFeed = s"$samplePackage/sampleFeed"
+      assetHelper.withCleaner(wsk.action, sampleFeed) {
+        val file = Some(TestUtils.getTestActionFilename("empty.js"))
+        (action, _) =>
+          action.create(sampleFeed, file, kind = Some("nodejs:default"))(wp)
+      }
+
+      val fullyQualifiedFeedName = s"/$guestNamespace/$sampleFeed"
+      withAssetCleaner(defaultWskProps) { (wp, assetHelper) =>
+        assetHelper.withCleaner(wsk.trigger, "badfeed", confirmDelete = false) { (trigger, name) =>
+          trigger.create(name, feed = Some(fullyQualifiedFeedName), expectedExitCode = TIMEOUT)(wp)
+        }
+        wsk.trigger.get("badfeed", expectedExitCode = NOT_FOUND)(wp)
+      }
+  }
+
 }
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala
index 8097ce9..c94c36e 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala
@@ -49,295 +49,289 @@ import whisk.core.entity.Subject
  */
 @RunWith(classOf[JUnitRunner])
 class WskWebActionsTests extends TestHelpers with WskTestHelpers with RestUtil with BeforeAndAfterAll {
-    val MAX_URL_LENGTH = 8192 // 8K matching nginx default
+  val MAX_URL_LENGTH = 8192 // 8K matching nginx default
 
-    val wsk = new Wsk
-    private implicit val wskprops = WskProps()
-    val namespace = wsk.namespace.whois()
+  val wsk = new Wsk
+  private implicit val wskprops = WskProps()
+  val namespace = wsk.namespace.whois()
 
-    protected val testRoutePath: String = "/api/v1/web"
+  protected val testRoutePath: String = "/api/v1/web"
 
-    behavior of "Wsk Web Actions"
+  behavior of "Wsk Web Actions"
 
-    /**
-     * Tests web actions, plus max url limit.
-     */
-    it should "create a web action accessible via HTTPS" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "webaction"
-            val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
-            val host = getServiceURL()
-            val requestPath = host + s"$testRoutePath/$namespace/default/$name.text/a?a="
-            val padAmount = MAX_URL_LENGTH - requestPath.length
+  /**
+   * Tests web actions, plus max url limit.
+   */
+  it should "create a web action accessible via HTTPS" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "webaction"
+    val file = Some(TestUtils.getTestActionFilename("echo.js"))
+    val host = getServiceURL()
+    val requestPath = host + s"$testRoutePath/$namespace/default/$name.text/a?a="
+    val padAmount = MAX_URL_LENGTH - requestPath.length
 
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, file, web = Some("true"))
-            }
-
-            Seq(("A", 200),
-                ("A" * padAmount, 200),
-                // ideally the bad case is just +1 but there's some differences
-                // in how characters are counted i.e., whether these count "https://:443"
-                // or not; it seems sufficient to test right around the boundary
-                ("A" * (padAmount + 100), 414))
-                .foreach {
-                    case (pad, code) =>
-                        val url = (requestPath + pad)
-                        val response = RestAssured.given().config(sslconfig).get(url)
-                        val responseCode = response.statusCode
-
-                        withClue(s"response code: $responseCode, url length: ${url.length}, pad amount: ${pad.length}, url: $url") {
-                            responseCode shouldBe code
-                            if (code == 200) {
-                                response.body.asString shouldBe pad
-                            } else {
-                                response.body.asString should include("414 Request-URI Too Large") // from nginx
-                            }
-                        }
-                }
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file, web = Some("true"))
     }
 
-    /**
-     * Tests web action requiring authentication.
-     */
-    it should "create a web action requiring authentication accessible via HTTPS" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "webaction"
-            val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
-            val host = getServiceURL()
-            val url = s"$host$testRoutePath/$namespace/default/$name.text/__ow_user"
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, web = Some("true"), annotations = Map("require-whisk-auth" -> true.toJson))
+    Seq(
+      ("A", 200),
+      ("A" * padAmount, 200),
+      // ideally the bad case is just +1 but there's some differences
+      // in how characters are counted i.e., whether these count "https://:443"
+      // or not; it seems sufficient to test right around the boundary
+      ("A" * (padAmount + 100), 414))
+      .foreach {
+        case (pad, code) =>
+          val url = (requestPath + pad)
+          val response = RestAssured.given().config(sslconfig).get(url)
+          val responseCode = response.statusCode
+
+          withClue(s"response code: $responseCode, url length: ${url.length}, pad amount: ${pad.length}, url: $url") {
+            responseCode shouldBe code
+            if (code == 200) {
+              response.body.asString shouldBe pad
+            } else {
+              response.body.asString should include("414 Request-URI Too Large") // from nginx
             }
-
-            val unauthorizedResponse = RestAssured.given().config(sslconfig).get(url)
-            unauthorizedResponse.statusCode shouldBe 401
-
-            val authorizedResponse = RestAssured
-                .given()
-                .config(sslconfig)
-                .auth().preemptive().basic(wskprops.authKey.split(":")(0), wskprops.authKey.split(":")(1))
-                .get(url)
-
-            authorizedResponse.statusCode shouldBe 200
-            authorizedResponse.body.asString shouldBe namespace
+          }
+      }
+  }
+
+  /**
+   * Tests web action requiring authentication.
+   */
+  it should "create a web action requiring authentication accessible via HTTPS" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "webaction"
+      val file = Some(TestUtils.getTestActionFilename("echo.js"))
+      val host = getServiceURL()
+      val url = s"$host$testRoutePath/$namespace/default/$name.text/__ow_user"
+
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, file, web = Some("true"), annotations = Map("require-whisk-auth" -> true.toJson))
+      }
+
+      val unauthorizedResponse = RestAssured.given().config(sslconfig).get(url)
+      unauthorizedResponse.statusCode shouldBe 401
+
+      val authorizedResponse = RestAssured
+        .given()
+        .config(sslconfig)
+        .auth()
+        .preemptive()
+        .basic(wskprops.authKey.split(":")(0), wskprops.authKey.split(":")(1))
+        .get(url)
+
+      authorizedResponse.statusCode shouldBe 200
+      authorizedResponse.body.asString shouldBe namespace
+  }
+
+  it should "ensure that CORS header is preserved for custom options" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "webaction"
+      val file = Some(TestUtils.getTestActionFilename("corsHeaderMod.js"))
+      val host = getServiceURL()
+      val url = host + s"$testRoutePath/$namespace/default/$name.http"
+
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, file, web = Some("true"), annotations = Map("web-custom-options" -> true.toJson))
+      }
+
+      val response = RestAssured.given().config(sslconfig).options(url)
+
+      response.statusCode shouldBe 200
+      response.header("Access-Control-Allow-Origin") shouldBe "Origin set from Web Action"
+      response.header("Access-Control-Allow-Methods") shouldBe "Methods set from Web Action"
+      response.header("Access-Control-Allow-Headers") shouldBe "Headers set from Web Action"
+      response.header("Location") shouldBe "openwhisk.org"
+      response.header("Set-Cookie") shouldBe "cookie-cookie-cookie"
+  }
+
+  it should "ensure that default CORS header is preserved" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "webaction"
+    val file = Some(TestUtils.getTestActionFilename("corsHeaderMod.js"))
+    val host = getServiceURL()
+    val url = host + s"$testRoutePath/$namespace/default/$name"
+
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file, web = Some("true"))
     }
 
-    it should "ensure that CORS header is preserved for custom options" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "webaction"
-            val file = Some(TestCLIUtils.getTestActionFilename("corsHeaderMod.js"))
-            val host = getServiceURL()
-            val url = host + s"$testRoutePath/$namespace/default/$name.http"
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, web = Some("true"), annotations = Map("web-custom-options" -> true.toJson))
-            }
-
-            val response = RestAssured.given().config(sslconfig).options(url)
-
-            response.statusCode shouldBe 200
-            response.header("Access-Control-Allow-Origin") shouldBe "Origin set from Web Action"
-            response.header("Access-Control-Allow-Methods") shouldBe "Methods set from Web Action"
-            response.header("Access-Control-Allow-Headers") shouldBe "Headers set from Web Action"
-            response.header("Location") shouldBe "openwhisk.org"
-            response.header("Set-Cookie") shouldBe "cookie-cookie-cookie"
+    val responses = Seq(
+      RestAssured.given().config(sslconfig).options(s"$url.http"),
+      RestAssured.given().config(sslconfig).get(s"$url.json"))
+
+    responses.foreach { response =>
+      response.statusCode shouldBe 200
+      response.header("Access-Control-Allow-Origin") shouldBe "*"
+      response.header("Access-Control-Allow-Methods") shouldBe "OPTIONS, GET, DELETE, POST, PUT, HEAD, PATCH"
+      response.header("Access-Control-Allow-Headers") shouldBe "Authorization, Content-Type"
+      response.header("Location") shouldBe null
+      response.header("Set-Cookie") shouldBe null
     }
-
-    it should "ensure that default CORS header is preserved" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "webaction"
-            val file = Some(TestCLIUtils.getTestActionFilename("corsHeaderMod.js"))
-            val host = getServiceURL()
-            val url = host + s"$testRoutePath/$namespace/default/$name"
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, file, web = Some("true"))
-            }
-
-            val responses = Seq(
-                RestAssured.given().config(sslconfig).options(s"$url.http"),
-                RestAssured.given().config(sslconfig).get(s"$url.json"))
-
-            responses.foreach { response =>
-                response.statusCode shouldBe 200
-                response.header("Access-Control-Allow-Origin") shouldBe "*"
-                response.header("Access-Control-Allow-Methods") shouldBe "OPTIONS, GET, DELETE, POST, PUT, HEAD, PATCH"
-                response.header("Access-Control-Allow-Headers") shouldBe "Authorization, Content-Type"
-                response.header("Location") shouldBe null
-                response.header("Set-Cookie") shouldBe null
-            }
+  }
+
+  it should "invoke web action to ensure the returned body argument is correct" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "webaction"
+      val file = Some(TestUtils.getTestActionFilename("echo.js"))
+      val bodyContent = "This is the body"
+      val host = getServiceURL()
+      val url = s"$host$testRoutePath/$namespace/default/webaction.text/__ow_body"
+
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, file, web = Some("true"))
+      }
+
+      val paramRes = RestAssured.given().contentType("text/html").param("key", "value").config(sslconfig).post(url)
+      paramRes.statusCode shouldBe 200
+      new String(paramRes.body.asByteArray, StandardCharsets.UTF_8) shouldBe "key=value"
+
+      val bodyRes = RestAssured.given().contentType("text/html").body(bodyContent).config(sslconfig).post(url)
+      bodyRes.statusCode shouldBe 200
+      new String(bodyRes.body.asByteArray, StandardCharsets.UTF_8) shouldBe bodyContent
+  }
+
+  it should "reject invocation of web action with invalid accept header" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "webaction"
+      val file = Some(TestUtils.getTestActionFilename("textBody.js"))
+      val host = getServiceURL()
+      val url = host + s"$testRoutePath/$namespace/default/$name.http"
+
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, file, web = Some("true"))
+      }
+
+      val response = RestAssured.given().header("accept", "application/json").config(sslconfig).get(url)
+      response.statusCode shouldBe 406
+      response.body.asString should include("Resource representation is only available with these types:\\ntext/html")
+  }
+
+  it should "support multiple response header values" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "webaction"
+    val file = Some(TestUtils.getTestActionFilename("multipleHeaders.js"))
+    val host = getServiceURL()
+    val url = host + s"$testRoutePath/$namespace/default/$name.http"
+
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file, web = Some("true"), annotations = Map("web-custom-options" -> true.toJson))
     }
 
-    it should "invoke web action to ensure the returned body argument is correct" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "webaction"
-            val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
-            val bodyContent = "This is the body"
-            val host = getServiceURL()
-            val url = s"$host$testRoutePath/$namespace/default/webaction.text/__ow_body"
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, file, web = Some("true"))
-            }
-
-            val paramRes = RestAssured.given().contentType("text/html").param("key", "value").config(sslconfig).post(url)
-            paramRes.statusCode shouldBe 200
-            new String(paramRes.body.asByteArray, StandardCharsets.UTF_8) shouldBe "key=value"
-
-            val bodyRes = RestAssured.given().contentType("text/html").body(bodyContent).config(sslconfig).post(url)
-            bodyRes.statusCode shouldBe 200
-            new String(bodyRes.body.asByteArray, StandardCharsets.UTF_8) shouldBe bodyContent
-    }
+    val response = RestAssured.given().config(sslconfig).options(url)
 
-    it should "reject invocation of web action with invalid accept header" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "webaction"
-            val file = Some(TestCLIUtils.getTestActionFilename("textBody.js"))
-            val host = getServiceURL()
-            val url = host + s"$testRoutePath/$namespace/default/$name.http"
+    response.statusCode shouldBe 200
+    val cookieHeaders = response.headers.getList("Set-Cookie")
+    cookieHeaders should contain allOf (
+      new Header("Set-Cookie", "a=b"),
+      new Header("Set-Cookie", "c=d")
+    )
+  }
 
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, file, web = Some("true"))
-            }
+  it should "handle http web action with base64 encoded response" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "base64Web"
+    val file = Some(TestUtils.getTestActionFilename("base64Web.js"))
+    val host = getServiceURL
+    val url = host + s"$testRoutePath/$namespace/default/$name.http"
 
-            val response = RestAssured.given().header("accept", "application/json").config(sslconfig).get(url)
-            response.statusCode shouldBe 406
-            response.body.asString should include("Resource representation is only available with these types:\\ntext/html")
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, file, web = Some("raw"))
     }
 
-    it should "support multiple response header values" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "webaction"
-            val file = Some(TestCLIUtils.getTestActionFilename("multipleHeaders.js"))
-            val host = getServiceURL()
-            val url = host + s"$testRoutePath/$namespace/default/$name.http"
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, web = Some("true"), annotations = Map("web-custom-options" -> true.toJson))
-            }
-
-            val response = RestAssured.given().config(sslconfig).options(url)
-
-            response.statusCode shouldBe 200
-            val cookieHeaders = response.headers.getList("Set-Cookie")
-            cookieHeaders should contain allOf (
-                new Header("Set-Cookie", "a=b"),
-                new Header("Set-Cookie", "c=d")
-            )
-    }
-
-    it should "handle http web action with base64 encoded response" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "base64Web"
-            val file = Some(TestCLIUtils.getTestActionFilename("base64Web.js"))
-            val host = getServiceURL
-            val url = host + s"$testRoutePath/$namespace/default/$name.http"
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, web = Some("raw"))
-            }
-
-            val response = RestAssured.given().config(sslconfig).get(url)
-
-            response.statusCode shouldBe 200
-            response.header("Content-type") shouldBe "application/json"
-            response.body.asString.parseJson.asJsObject shouldBe JsObject("status" -> "success".toJson)
-    }
-
-    it should "handle http web action with base64 encoded binary response" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            val name = "binaryWeb"
-            val file = Some(TestUtils.getTestActionFilename("pngWeb.js"))
-            val host = getServiceURL
-            val url = host + s"$testRoutePath/$namespace/default/$name.http"
-            val png = "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAGCAYAAAD68A/GAAAA/klEQVQYGWNgAAEHBxaG//+ZQMyyn581Pfas+cRQnf1LfF" +
-                "Ljf+62smUgcUbt0FA2Zh7drf/ffMy9vLn3RurrW9e5hCU11i2azfD4zu1/DHz8TAy/foUxsXBrFzHzC7r8+M9S1vn1qxQT07dDjL" +
-                "9fdemrqKxlYGT6z8AIMo6hgeUfA0PUvy9fGFh5GWK3z7vNxSWt++jX99+8SoyiGQwsW38w8PJEM7x5v5SJ8f+/xv8MDAzffv9hev" +
-                "fkWjiXBGMpMx+j2awovjcMjFztDO8+7GF49LkbZDCDeXLTWnZO7qDfn1/+5jbw/8pjYWS4wZLztXnuEuYTk2M+MzIw/AcA36Vewa" +
-                "D6fzsAAAAASUVORK5CYII="
-
-            assetHelper.withCleaner(wsk.action, name) {
-                (action, _) =>
-                    action.create(name, file, web = Some("true"))
-            }
-
-            val response = RestAssured.given().config(sslconfig).get(url)
-
-            response.statusCode shouldBe 200
-            response.header("Content-type") shouldBe "image/png"
-            response.body.asByteArray shouldBe Base64.getDecoder().decode(png)
-    }
-
-    private val subdomainRegex = Seq.fill(WhiskProperties.getPartsInVanitySubdomain)("[a-zA-Z0-9]+").mkString("-")
-
-    private val (vanitySubdomain, vanityNamespace, makeTestSubject) = {
-        if (namespace.matches(subdomainRegex)) {
-            (namespace, namespace, false)
-        } else {
-            val s = Subject().asString.toLowerCase // this will generate two confirming parts
-            (s, s.replace("-", "_"), true)
-        }
-    }
-
-    private val wskPropsForSubdomainTest = if (makeTestSubject) {
-        getAdditionalTestSubject(vanityNamespace) // create new subject for the test
+    val response = RestAssured.given().config(sslconfig).get(url)
+
+    response.statusCode shouldBe 200
+    response.header("Content-type") shouldBe "application/json"
+    response.body.asString.parseJson.asJsObject shouldBe JsObject("status" -> "success".toJson)
+  }
+
+  it should "handle http web action with base64 encoded binary response" in withAssetCleaner(wskprops) {
+    (wp, assetHelper) =>
+      val name = "binaryWeb"
+      val file = Some(TestUtils.getTestActionFilename("pngWeb.js"))
+      val host = getServiceURL
+      val url = host + s"$testRoutePath/$namespace/default/$name.http"
+      val png = "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAGCAYAAAD68A/GAAAA/klEQVQYGWNgAAEHBxaG//+ZQMyyn581Pfas+cRQnf1LfF" +
+        "Ljf+62smUgcUbt0FA2Zh7drf/ffMy9vLn3RurrW9e5hCU11i2azfD4zu1/DHz8TAy/foUxsXBrFzHzC7r8+M9S1vn1qxQT07dDjL" +
+        "9fdemrqKxlYGT6z8AIMo6hgeUfA0PUvy9fGFh5GWK3z7vNxSWt++jX99+8SoyiGQwsW38w8PJEM7x5v5SJ8f+/xv8MDAzffv9hev" +
+        "fkWjiXBGMpMx+j2awovjcMjFztDO8+7GF49LkbZDCDeXLTWnZO7qDfn1/+5jbw/8pjYWS4wZLztXnuEuYTk2M+MzIw/AcA36Vewa" +
+        "D6fzsAAAAASUVORK5CYII="
+
+      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+        action.create(name, file, web = Some("true"))
+      }
+
+      val response = RestAssured.given().config(sslconfig).get(url)
+
+      response.statusCode shouldBe 200
+      response.header("Content-type") shouldBe "image/png"
+      response.body.asByteArray shouldBe Base64.getDecoder().decode(png)
+  }
+
+  private val subdomainRegex = Seq.fill(WhiskProperties.getPartsInVanitySubdomain)("[a-zA-Z0-9]+").mkString("-")
+
+  private val (vanitySubdomain, vanityNamespace, makeTestSubject) = {
+    if (namespace.matches(subdomainRegex)) {
+      (namespace, namespace, false)
     } else {
-        WskProps()
+      val s = Subject().asString.toLowerCase // this will generate two confirming parts
+      (s, s.replace("-", "_"), true)
     }
+  }
 
-    override def afterAll() = {
-        if (makeTestSubject) {
-            disposeAdditionalTestSubject(vanityNamespace)
-        }
-    }
+  private val wskPropsForSubdomainTest = if (makeTestSubject) {
+    getAdditionalTestSubject(vanityNamespace) // create new subject for the test
+  } else {
+    WskProps()
+  }
 
-    "test subdomain" should "have conforming parts" in {
-        vanitySubdomain should fullyMatch regex subdomainRegex.r
-        vanitySubdomain.length should be <= 63
-    }
-
-    "vanity subdomain" should "access a web action via namespace subdomain" in withAssetCleaner(wskPropsForSubdomainTest) {
-        (wp, assetHelper) =>
-            val actionName = "webaction"
-
-            val file = Some(TestUtils.getTestActionFilename("echo.js"))
-            assetHelper.withCleaner(wsk.action, actionName) {
-                (action, _) => action.create(actionName, file, web = Some(true.toString))(wp)
-            }
-
-            val url = getServiceApiHost(vanitySubdomain, true) + s"/default/$actionName.text/a?a=A"
-            println(s"url: $url")
-
-            // try the rest assured path first, failing that, try curl with explicit resolve
-            Try {
-                val response = RestAssured.given().config(sslconfig).get(url)
-                val responseCode = response.statusCode
-                responseCode shouldBe 200
-                response.body.asString shouldBe "A"
-            } match {
-                case Failure(t) =>
-                    println(s"RestAssured path failed, trying curl: $t")
-                    implicit val tid = TransactionId.testing
-                    implicit val logger = new PrintStreamLogging(Console.out)
-                    val host = getServiceApiHost(vanitySubdomain, false)
-                    // if the edge host is a name, try to resolve it, otherwise, it should be an ip address already
-                    val edgehost = WhiskProperties.getEdgeHost
-                    val ip = Try(java.net.InetAddress.getByName(edgehost).getHostAddress) getOrElse "???"
-                    println(s"edge: $edgehost, ip: $ip")
-                    val cmd = Seq("curl", "-k", url, "--resolve", s"$host:$ip")
-                    val (stdout, stderr, exitCode) = SimpleExec.syncRunCmd(cmd)
-                    withClue(s"\n$stderr\n") {
-                        stdout shouldBe "A"
-                        exitCode shouldBe 0
-                    }
-
-                case _ =>
-            }
+  override def afterAll() = {
+    if (makeTestSubject) {
+      disposeAdditionalTestSubject(vanityNamespace)
     }
+  }
+
+  "test subdomain" should "have conforming parts" in {
+    vanitySubdomain should fullyMatch regex subdomainRegex.r
+    vanitySubdomain.length should be <= 63
+  }
+
+  "vanity subdomain" should "access a web action via namespace subdomain" in withAssetCleaner(wskPropsForSubdomainTest) {
+    (wp, assetHelper) =>
+      val actionName = "webaction"
+
+      val file = Some(TestUtils.getTestActionFilename("echo.js"))
+      assetHelper.withCleaner(wsk.action, actionName) { (action, _) =>
+        action.create(actionName, file, web = Some(true.toString))(wp)
+      }
+
+      val url = getServiceApiHost(vanitySubdomain, true) + s"/default/$actionName.text/a?a=A"
+      println(s"url: $url")
+
+      // try the rest assured path first, failing that, try curl with explicit resolve
+      Try {
+        val response = RestAssured.given().config(sslconfig).get(url)
+        val responseCode = response.statusCode
+        responseCode shouldBe 200
+        response.body.asString shouldBe "A"
+      } match {
+        case Failure(t) =>
+          println(s"RestAssured path failed, trying curl: $t")
+          implicit val tid = TransactionId.testing
+          implicit val logger = new PrintStreamLogging(Console.out)
+          val host = getServiceApiHost(vanitySubdomain, false)
+          // if the edge host is a name, try to resolve it, otherwise, it should be an ip address already
+          val edgehost = WhiskProperties.getEdgeHost
+          val ip = Try(java.net.InetAddress.getByName(edgehost).getHostAddress) getOrElse "???"
+          println(s"edge: $edgehost, ip: $ip")
+          val cmd = Seq("curl", "-k", url, "--resolve", s"$host:$ip")
+          val (stdout, stderr, exitCode) = SimpleExec.syncRunCmd(cmd)
+          withClue(s"\n$stderr\n") {
+            stdout shouldBe "A"
+            exitCode shouldBe 0
+          }
+
+        case _ =>
+      }
+  }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>.