You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@openwhisk.apache.org by GitBox <gi...@apache.org> on 2018/04/03 17:02:34 UTC

[GitHub] drcariel closed pull request #262: rely on single base test versions from incubator openwhisk

drcariel closed pull request #262: rely on single base test versions from incubator openwhisk
URL: https://github.com/apache/incubator-openwhisk-cli/pull/262
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/tests/src/test/scala/apigw/healthtests/ApiGwEndToEndTests.scala b/tests/src/test/scala/apigw/healthtests/ApiGwEndToEndTests.scala
deleted file mode 100644
index 5cc1ef61..00000000
--- a/tests/src/test/scala/apigw/healthtests/ApiGwEndToEndTests.scala
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package apigw.healthtests
-
-import java.io.BufferedWriter
-import java.io.File
-import java.io.FileWriter
-
-import scala.concurrent.duration.DurationInt
-
-import org.junit.runner.RunWith
-import org.scalatest.BeforeAndAfterAll
-import org.scalatest.FlatSpec
-import org.scalatest.Matchers
-import org.scalatest.junit.JUnitRunner
-
-import com.jayway.restassured.RestAssured
-
-import common.TestHelpers
-import common.TestCLIUtils
-import common.TestUtils._
-import common.BaseWsk
-import common.WskProps
-import common.WskTestHelpers
-import spray.json._
-import spray.json.DefaultJsonProtocol._
-import system.rest.RestUtil
-
-/**
- * Basic tests of the download link for Go CLI binaries
- */
-@RunWith(classOf[JUnitRunner])
-abstract class ApiGwEndToEndTests
-    extends FlatSpec
-    with Matchers
-    with RestUtil
-    with TestHelpers
-    with WskTestHelpers
-    with BeforeAndAfterAll {
-
-  implicit val wskprops: common.WskProps = WskProps()
-  val wsk: BaseWsk
-  val namespace: String = wsk.namespace.whois()
-  val createCode: Int
-
-  // Custom CLI properties file
-  val cliWskPropsFile: java.io.File = File.createTempFile("wskprops", ".tmp")
-
-  /*
-   * Create a CLI properties file for use by the tests
-   */
-  override def beforeAll: Unit = {
-    cliWskPropsFile.deleteOnExit()
-    val wskprops = WskProps(token = "SOME TOKEN")
-    wskprops.writeFile(cliWskPropsFile)
-    println(s"wsk temporary props file created here: ${cliWskPropsFile.getCanonicalPath()}")
-  }
-
-  def verifyAPICreated(rr: RunResult): Unit = {
-    rr.stdout should include("ok: created API")
-    val apiurl = rr.stdout.split("\n")(1)
-    println(s"apiurl: '$apiurl'")
-  }
-
-  def verifyAPIList(rr: RunResult,
-                    actionName: String,
-                    testurlop: String,
-                    testapiname: String,
-                    testbasepath: String,
-                    testrelpath: String): Unit = {
-    rr.stdout should include("ok: APIs")
-    rr.stdout should include regex (s"$actionName\\s+$testurlop\\s+$testapiname\\s+")
-    rr.stdout should include(testbasepath + testrelpath)
-  }
-
-  def verifyAPISwaggerCreated(rr: RunResult): Unit = {
-    rr.stdout should include("ok: created API")
-  }
-
-  def writeSwaggerFile(rr: RunResult): File = {
-    val swaggerfile = File.createTempFile("api", ".json")
-    swaggerfile.deleteOnExit()
-    val bw = new BufferedWriter(new FileWriter(swaggerfile))
-    bw.write(rr.stdout)
-    bw.close()
-    return swaggerfile
-  }
-
-  def getSwaggerApiUrl(rr: RunResult): String = {
-    return rr.stdout.split("\n")(1)
-  }
-
-  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("Namespace: " + namespace)
-
-      // Delete any lingering stale api from previous run that may not have been deleted properly
-      wsk.api.delete(
-        basepathOrApiName = testbasepath,
-        expectedExitCode = DONTCARE_EXIT,
-        cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
-
-      // Create the action for the API.  It must be a "web-action" action.
-      val file = TestCLIUtils.getTestActionFilename(s"echo-web-http.js")
-      println("action creation Namespace: " + namespace)
-      wsk.action.create(
-        name = actionName,
-        artifact = Some(file),
-        expectedExitCode = createCode,
-        annotations = Map("web-export" -> true.toJson))
-
-      println("creation Namespace: " + namespace)
-      // 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()))
-      verifyAPICreated(rr)
-
-      // 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()))
-      verifyAPIList(rr, actionName, testurlop, testapiname, testbasepath, testrelpath)
-
-      // Recreate the API using a JSON swagger file
-      rr = wsk.api.get(basepathOrApiName = Some(testbasepath), cliCfgFile = Some(cliWskPropsFile.getCanonicalPath()))
-      val swaggerfile = writeSwaggerFile(rr)
-
-      // 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()))
-      verifyAPISwaggerCreated(rr)
-      val swaggerapiurl = getSwaggerApiUrl(rr)
-      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
deleted file mode 100644
index f825e333..00000000
--- a/tests/src/test/scala/system/basic/WskActionTests.scala
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package system.basic
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-
-import common.ActivationResult
-import common.JsHelpers
-import common.TestHelpers
-import common.TestCLIUtils
-import common.TestUtils._
-import common.BaseWsk
-import common.Wsk
-import common.WskProps
-import common.WskTestHelpers
-import spray.json._
-import spray.json.DefaultJsonProtocol._
-import spray.json.JsObject
-import spray.json.pimpAny
-
-@RunWith(classOf[JUnitRunner])
-abstract class WskActionTests extends TestHelpers with WskTestHelpers with JsHelpers {
-
-  implicit val wskprops = WskProps()
-  val wsk: BaseWsk
-
-  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
-    }
-  }
-
-  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)
-    }
-  }
-
-  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")
-      }
-    }
-  }
-
-  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)
-    }
-  }
-
-  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 = getJSONFromResponse(wsk.action.get(copiedActionName).stdout, wsk.isInstanceOf[Wsk])
-      val origAction = getJSONFromResponse(wsk.action.get(copiedActionName).stdout, wsk.isInstanceOf[Wsk])
-
-      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(TestCLIUtils.getTestActionFilename("echo.js"))
-        (action, _) =>
-          action.create(origName, file, parameters = origParams, annotations = origAnnots)
-      }
-
-      assetHelper.withCleaner(wsk.action, copiedName) { (action, _) =>
-        println("created copied ")
-        action.create(copiedName, Some(origName), Some("copy"), parameters = copiedParams, annotations = copiedAnnots)
-      }
-
-      val copiedAction = getJSONFromResponse(wsk.action.get(copiedName).stdout, wsk.isInstanceOf[Wsk])
-
-      // 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(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")
-    }
-  }
-
-  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 "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")))
-    }
-  }
-
-  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 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())
-    }
-  }
-
-  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(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")
-    }
-  }
-
-  it should "not be able to use --kind and --docker at the same time when running action create" in {
-    val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-    val out = wsk.action.create(name = "kindAndDockerAction", artifact = Some(file), expectedExitCode = NOT_ALLOWED,
-        kind = Some("nodejs:6"), docker = Some("mydockerimagename"))
-    out.stderr should include("Cannot specify both --kind and --docker at the same time")
-  }
-
-  it should "not be able to use --kind and --docker at the same time when running action update" in {
-    val file = TestCLIUtils.getTestActionFilename(s"echo.js")
-    val out = wsk.action.create(name = "kindAndDockerAction", artifact = Some(file), expectedExitCode = NOT_ALLOWED,
-      kind = Some("nodejs:6"), docker = Some("mydockerimagename"), update = true)
-    out.stderr should include("Cannot specify both --kind and --docker at the same time")
-  }
-}
diff --git a/tests/src/test/scala/system/basic/WskBasicJavaTests.scala b/tests/src/test/scala/system/basic/WskBasicJavaTests.scala
deleted file mode 100644
index 87b38ccb..00000000
--- a/tests/src/test/scala/system/basic/WskBasicJavaTests.scala
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package system.basic
-
-import scala.concurrent.duration.DurationInt
-
-import common.TestHelpers
-import common.TestCLIUtils
-import common.TestUtils.ANY_ERROR_EXIT
-import common.WskTestHelpers
-import common.WskProps
-import common.BaseWsk
-
-import org.junit.runner.RunWith
-import org.scalatest.Matchers
-import org.scalatest.junit.JUnitRunner
-
-import spray.json.JsString
-
-@RunWith(classOf[JUnitRunner])
-abstract class WskBasicJavaTests extends TestHelpers with WskTestHelpers with Matchers {
-
-  implicit val wskprops = WskProps()
-  val wsk: BaseWsk
-  val expectedDuration = 120.seconds
-  val activationPollDuration = 60.seconds
-
-  behavior of "Java Actions"
-
-  /**
-   * Test the Java "hello world" demo sequence
-   */
-  it should "Invoke a java action" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val name = "helloJava"
-    val file = Some(TestCLIUtils.getTestActionFilename("helloJava.jar"))
-
-    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-      action.create(name, file, main = Some("hello.HelloJava"))
-    }
-
-    val start = System.currentTimeMillis()
-    withActivation(wsk.activation, wsk.action.invoke(name), totalWait = activationPollDuration) {
-      _.response.result.get.toString should include("Hello stranger!")
-    }
-
-    withActivation(
-      wsk.activation,
-      wsk.action.invoke(name, Map("name" -> JsString("Sir"))),
-      totalWait = activationPollDuration) {
-      _.response.result.get.toString should include("Hello Sir!")
-    }
-
-    withClue("Test duration exceeds expectation (ms)") {
-      val duration = System.currentTimeMillis() - start
-      duration should be <= expectedDuration.toMillis
-    }
-  }
-
-  /*
-   * Example from the docs.
-   */
-  it should "Invoke a Java action where main is in the default package" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "helloJavaDefaultPkg"
-      val file = Some(TestCLIUtils.getTestActionFilename("helloJavaDefaultPackage.jar"))
-
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, file, main = Some("Hello"))
-      }
-
-      withActivation(wsk.activation, wsk.action.invoke(name, Map()), totalWait = activationPollDuration) {
-        _.response.result.get.toString should include("Hello stranger!")
-      }
-  }
-
-  it should "Ensure that Java actions cannot be created without a specified main method" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "helloJavaWithNoMainSpecified"
-      val file = Some(TestCLIUtils.getTestActionFilename("helloJava.jar"))
-
-      val createResult = assetHelper.withCleaner(wsk.action, name, confirmDelete = false) { (action, _) =>
-        action.create(name, file, expectedExitCode = ANY_ERROR_EXIT)
-      }
-
-      val output = s"${createResult.stdout}\n${createResult.stderr}"
-
-      output should include("main")
-  }
-}
diff --git a/tests/src/test/scala/system/basic/WskBasicNodeTests.scala b/tests/src/test/scala/system/basic/WskBasicNodeTests.scala
deleted file mode 100644
index 4242c729..00000000
--- a/tests/src/test/scala/system/basic/WskBasicNodeTests.scala
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package system.basic
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-
-import common.JsHelpers
-import common.TestHelpers
-import common.TestCLIUtils
-import common.TestUtils.ANY_ERROR_EXIT
-import common.TestUtils.RunResult
-import common.BaseWsk
-import common.WskProps
-import common.WskTestHelpers
-import spray.json._
-import spray.json.DefaultJsonProtocol._
-
-@RunWith(classOf[JUnitRunner])
-abstract class WskBasicNodeTests extends TestHelpers with WskTestHelpers with JsHelpers {
-
-  implicit val wskprops = WskProps()
-  val wsk: BaseWsk
-  val defaultAction = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-  val currentNodeJsDefaultKind = "nodejs:6"
-
-  behavior of "NodeJS runtime"
-
-  it should "Map a kind of nodejs:default to the current default NodeJS runtime" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "usingDefaultNodeAlias"
-
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, defaultAction, kind = Some("nodejs:default"))
-      }
-
-      val result = wsk.action.get(name)
-      withPrintOnFailure(result) { () =>
-        val action = convertRunResultToJsObject(result)
-        action.getFieldPath("exec", "kind") should be(Some(currentNodeJsDefaultKind.toJson))
-      }
-  }
-
-  it should "Ensure that NodeJS actions can have a non-default entrypoint" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "niamNpmAction"
-      val file = Some(TestCLIUtils.getTestActionFilename("niam.js"))
-
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, file, main = Some("niam"))
-      }
-
-      withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
-        val response = activation.response
-        response.result.get.fields.get("error") shouldBe empty
-        response.result.get.fields.get("greetings") should be(Some(JsString("Hello from a non-standard entrypoint.")))
-      }
-  }
-
-  it should "Ensure that zipped actions are encoded and uploaded as NodeJS actions" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "zippedNpmAction"
-      val file = Some(TestCLIUtils.getTestActionFilename("zippedaction.zip"))
-
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, file, kind = Some("nodejs:default"))
-      }
-
-      withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
-        val response = activation.response
-        response.result.get.fields.get("error") shouldBe empty
-        response.result.get.fields.get("author") shouldBe defined
-      }
-  }
-
-  it should "Ensure that zipped actions cannot be created without a kind specified" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "zippedNpmActionWithNoKindSpecified"
-      val file = Some(TestCLIUtils.getTestActionFilename("zippedaction.zip"))
-
-      val createResult = assetHelper.withCleaner(wsk.action, name, confirmDelete = false) { (action, _) =>
-        action.create(name, file, expectedExitCode = ANY_ERROR_EXIT)
-      }
-
-      val output = s"${createResult.stdout}\n${createResult.stderr}"
-
-      output should include("kind")
-  }
-
-  it should "Ensure that JS actions created with no explicit kind use the current default NodeJS runtime" in withAssetCleaner(
-    wskprops) { (wp, assetHelper) =>
-    val name = "jsWithNoKindSpecified"
-
-    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-      action.create(name, defaultAction)
-    }
-
-    val result = wsk.action.get(name)
-    withPrintOnFailure(result) { () =>
-      val action = convertRunResultToJsObject(result)
-      action.getFieldPath("exec", "kind") should be(Some(currentNodeJsDefaultKind.toJson))
-    }
-  }
-
-  it should "Ensure that returning an empty rejected Promise results in an errored activation" in withAssetCleaner(
-    wskprops) { (wp, assetHelper) =>
-    val name = "jsEmptyRejectPromise"
-
-    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-      action.create(name, Some(TestCLIUtils.getTestActionFilename("issue-1562.js")))
-    }
-
-    withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
-      val response = activation.response
-      response.success should be(false)
-      response.result.get.fields.get("error") shouldBe defined
-    }
-  }
-
-  def convertRunResultToJsObject(result: RunResult): JsObject = {
-    val stdout = result.stdout
-    val firstNewline = stdout.indexOf("\n")
-    stdout.substring(firstNewline + 1).parseJson.asJsObject
-  }
-}
diff --git a/tests/src/test/scala/system/basic/WskBasicPythonTests.scala b/tests/src/test/scala/system/basic/WskBasicPythonTests.scala
deleted file mode 100644
index 6cb5861e..00000000
--- a/tests/src/test/scala/system/basic/WskBasicPythonTests.scala
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package system.basic
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-import org.scalatest.Matchers
-import scala.concurrent.duration.DurationInt
-import spray.json._
-import spray.json.DefaultJsonProtocol.StringJsonFormat
-import common.JsHelpers
-import common.TestHelpers
-import common.TestCLIUtils
-import common.BaseWsk
-import common.WskProps
-import common.WskTestHelpers
-import common.WhiskProperties
-
-@RunWith(classOf[JUnitRunner])
-abstract class WskBasicPythonTests extends TestHelpers with WskTestHelpers with Matchers with JsHelpers {
-
-  implicit val wskprops = WskProps()
-  val wsk: BaseWsk
-
-  behavior of "Native Python Action"
-
-  it should "invoke an action and get the result" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val name = "basicInvoke"
-    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-      action.create(name, Some(TestCLIUtils.getTestActionFilename("hello.py")))
-    }
-
-    withActivation(wsk.activation, wsk.action.invoke(name, Map("name" -> "Prince".toJson))) {
-      _.response.result.get.toString should include("Prince")
-    }
-  }
-
-  it should "invoke an action with a non-default entry point" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val name = "nonDefaultEntryPoint"
-    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-      action.create(name, Some(TestCLIUtils.getTestActionFilename("niam.py")), main = Some("niam"))
-    }
-
-    withActivation(wsk.activation, wsk.action.invoke(name, Map())) {
-      _.response.result.get.fields.get("greetings") should be(Some(JsString("Hello from a non-standard entrypoint.")))
-    }
-  }
-
-  it should "invoke an action from a zip file with a non-default entry point" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "pythonZipWithNonDefaultEntryPoint"
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(
-          name,
-          Some(TestCLIUtils.getTestActionFilename("python.zip")),
-          main = Some("niam"),
-          kind = Some("python:default"))
-      }
-
-      withActivation(wsk.activation, wsk.action.invoke(name, Map("name" -> "Prince".toJson))) {
-        _.response.result.get shouldBe JsObject("greeting" -> JsString("Hello Prince!"))
-      }
-  }
-
-  Seq("python:2", "python:3").foreach { kind =>
-    it should s"invoke a $kind action" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-      val name = s"${kind.replace(":", "")}-action"
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, Some(TestCLIUtils.getTestActionFilename("pythonVersion.py")), kind = Some(kind))
-      }
-
-      withActivation(wsk.activation, wsk.action.invoke(name)) {
-        _.response.result.get shouldBe JsObject("version" -> JsNumber(kind.takeRight(1).toInt))
-      }
-    }
-  }
-
-  it should "invoke an action and confirm expected environment is defined" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "stdenv"
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, Some(TestCLIUtils.getTestActionFilename("stdenv.py")))
-      }
-
-      withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
-        val result = activation.response.result.get
-        result.fields.get("error") shouldBe empty
-        result.fields.get("auth") shouldBe Some(
-          JsString(WhiskProperties.readAuthKey(WhiskProperties.getAuthFileForTesting)))
-        result.fields.get("edge").toString.trim should not be empty
-      }
-  }
-
-  it should "invoke an invalid action and get error back" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val name = "bad code"
-    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-      action.create(name, Some(TestCLIUtils.getTestActionFilename("malformed.py")))
-    }
-
-    withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
-      activation.response.result.get.fields.get("error") shouldBe Some(
-        JsString("The action failed to generate or locate a binary. See logs for details."))
-      activation.logs.get.mkString("\n") should { not include ("pythonaction.py") and not include ("flask") }
-    }
-  }
-
-  behavior of "Python virtualenv"
-
-  Seq(("python2_virtualenv.zip", "python:2"), ("python3_virtualenv.zip", "python:3")).foreach {
-    case (filename, kind) =>
-      it should s"invoke a zipped $kind action with virtualenv package" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-          val name = filename
-          val zippedPythonAction = Some(TestCLIUtils.getTestActionFilename(filename))
-
-          assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-            action.create(name, zippedPythonAction, kind = Some(kind))
-          }
-
-          withActivation(wsk.activation, wsk.action.invoke(name), totalWait = 120.seconds) { activation =>
-            val response = activation.response
-            response.result.get.fields.get("error") shouldBe empty
-            response.result.get.fields.get("Networkinfo: ") shouldBe defined
-          }
-      }
-  }
-}
diff --git a/tests/src/test/scala/system/basic/WskBasicSwift3Tests.scala b/tests/src/test/scala/system/basic/WskBasicSwift3Tests.scala
deleted file mode 100644
index 632730a9..00000000
--- a/tests/src/test/scala/system/basic/WskBasicSwift3Tests.scala
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package system.basic
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-
-import common.JsHelpers
-import common.TestHelpers
-import common.TestCLIUtils
-import common.BaseWsk
-import common.WskProps
-import common.WskTestHelpers
-import spray.json.pimpString
-import spray.json.JsString
-import common.TestUtils.RunResult
-import spray.json.JsObject
-
-@RunWith(classOf[JUnitRunner])
-abstract class WskBasicSwift3Tests extends TestHelpers with WskTestHelpers with JsHelpers {
-
-  implicit val wskprops: common.WskProps = WskProps()
-  val wsk: BaseWsk
-  val defaultAction: Some[String] = Some(TestCLIUtils.getTestActionFilename("hello.swift"))
-  lazy val currentSwiftDefaultKind = "swift:3.1.1"
-
-  behavior of "Swift runtime"
-
-  it should "Ensure that Swift actions can have a non-default entrypoint" in withAssetCleaner(wskprops) {
-    (wp, assetHelper) =>
-      val name = "niamSwiftAction"
-      val file = Some(TestCLIUtils.getTestActionFilename("niam.swift"))
-
-      assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-        action.create(name, file, main = Some("niam"))
-      }
-
-      withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
-        val response = activation.response
-        response.result.get.fields.get("error") shouldBe empty
-        response.result.get.fields.get("greetings") should be(Some(JsString("Hello from a non-standard entrypoint.")))
-      }
-  }
-
-  def convertRunResultToJsObject(result: RunResult): JsObject = {
-    val stdout = result.stdout
-    val firstNewline = stdout.indexOf("\n")
-    stdout.substring(firstNewline + 1).parseJson.asJsObject
-  }
-}
diff --git a/tests/src/test/scala/system/basic/WskCliActionTests.scala b/tests/src/test/scala/system/basic/WskCliActionTests.scala
index b7649f6d..273299f7 100644
--- a/tests/src/test/scala/system/basic/WskCliActionTests.scala
+++ b/tests/src/test/scala/system/basic/WskCliActionTests.scala
@@ -20,9 +20,21 @@ package system.basic
 import org.junit.runner.RunWith
 import org.scalatest.junit.JUnitRunner
 
+import common.TestCLIUtils
+import common.TestUtils.NOT_ALLOWED
 import common.Wsk
 
 @RunWith(classOf[JUnitRunner])
 class WskCliActionTests extends WskActionTests {
   override val wsk = new Wsk
+  override val cli = true
+
+  it should "not be able to use --kind and --docker at the same time when running action create or update" in {
+    val file = TestCLIUtils.getTestActionFilename(s"echo.js")
+    Seq(false, true).foreach { updateValue =>
+      val out = wsk.action.create(name = "kindAndDockerAction", artifact = Some(file), expectedExitCode = NOT_ALLOWED,
+      kind = Some("nodejs:6"), docker = Some("mydockerimagename"), update = updateValue)
+      out.stderr should include("Cannot specify both --kind and --docker at the same time")
+    }
+  }
 }
diff --git a/tests/src/test/scala/system/basic/WskCliBasicNode6Tests.scala b/tests/src/test/scala/system/basic/WskCliBasicNode6Tests.scala
new file mode 100644
index 00000000..9bcec867
--- /dev/null
+++ b/tests/src/test/scala/system/basic/WskCliBasicNode6Tests.scala
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package system.basic
+
+import common.Wsk
+
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+
+@RunWith(classOf[JUnitRunner])
+class WskCliBasicNode6Tests extends WskBasicNode6Tests {
+  override val wsk: Wsk = new Wsk
+}
diff --git a/tests/src/test/scala/system/basic/WskCliBasicNode8Tests.scala b/tests/src/test/scala/system/basic/WskCliBasicNode8Tests.scala
new file mode 100644
index 00000000..a6beb9f3
--- /dev/null
+++ b/tests/src/test/scala/system/basic/WskCliBasicNode8Tests.scala
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package system.basic
+
+import common.Wsk
+
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+
+@RunWith(classOf[JUnitRunner])
+class WskCliBasicNode8Tests extends WskBasicNode8Tests {
+  override val wsk: Wsk = new Wsk
+}
diff --git a/tests/src/test/scala/system/basic/WskCliBasicNodeTests.scala b/tests/src/test/scala/system/basic/WskCliBasicNodeTests.scala
index 5c923b93..80f25cab 100644
--- a/tests/src/test/scala/system/basic/WskCliBasicNodeTests.scala
+++ b/tests/src/test/scala/system/basic/WskCliBasicNodeTests.scala
@@ -23,6 +23,6 @@ import org.junit.runner.RunWith
 import org.scalatest.junit.JUnitRunner
 
 @RunWith(classOf[JUnitRunner])
-class WskCliBasicNodeTests extends WskBasicNodeTests {
+class WskCliBasicNodeDefaultTests extends WskBasicNodeDefaultTests {
   override val wsk: Wsk = new Wsk
 }
diff --git a/tests/src/test/scala/system/basic/WskCliRuleTests.scala b/tests/src/test/scala/system/basic/WskCliRuleTests.scala
index 6c630772..fc84eea3 100644
--- a/tests/src/test/scala/system/basic/WskCliRuleTests.scala
+++ b/tests/src/test/scala/system/basic/WskCliRuleTests.scala
@@ -25,4 +25,5 @@ import common.Wsk
 @RunWith(classOf[JUnitRunner])
 class WskCliRuleTests extends WskRuleTests {
   override val wsk: Wsk = new Wsk
+  override val cli = true
 }
diff --git a/tests/src/test/scala/system/basic/WskCliSequenceTests.scala b/tests/src/test/scala/system/basic/WskCliSequenceTests.scala
index e1d0db75..5d036776 100644
--- a/tests/src/test/scala/system/basic/WskCliSequenceTests.scala
+++ b/tests/src/test/scala/system/basic/WskCliSequenceTests.scala
@@ -29,4 +29,5 @@ import common.Wsk
 @RunWith(classOf[JUnitRunner])
 class WskCliSequenceTests extends WskSequenceTests {
   override val wsk: common.Wsk = new Wsk
+  override val cli = true
 }
diff --git a/tests/src/test/scala/system/basic/WskConsoleTests.scala b/tests/src/test/scala/system/basic/WskConsoleTests.scala
deleted file mode 100644
index c513eec5..00000000
--- a/tests/src/test/scala/system/basic/WskConsoleTests.scala
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package system.basic;
-
-import java.time.Instant
-
-import scala.concurrent.duration.Duration
-import scala.concurrent.duration.DurationInt
-import scala.concurrent.duration.MILLISECONDS
-import scala.language.postfixOps
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-
-import common.TestHelpers
-import common.TestCLIUtils
-import common.BaseWsk
-import common.WskProps
-import common.WskTestHelpers
-import spray.json.DefaultJsonProtocol.IntJsonFormat
-import spray.json.DefaultJsonProtocol.StringJsonFormat
-import spray.json.pimpAny
-
-/**
- * Tests of the text console
- */
-@RunWith(classOf[JUnitRunner])
-abstract class WskConsoleTests extends TestHelpers with WskTestHelpers {
-
-  implicit val wskprops = WskProps()
-  val wsk: BaseWsk
-  val guestNamespace = wskprops.namespace
-
-  /**
-   * Append the current timestamp in ms
-   */
-  def withTimestamp(text: String) = s"${text}-${System.currentTimeMillis}"
-
-  behavior of "Wsk Activation Console"
-
-  it should "show an activation log message for hello world" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val packageName = withTimestamp("samples")
-    val actionName = withTimestamp("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")))
-    }
-
-    // Some contingency to make query more robust
-    // Account for time differences between controller and invoker
-    val start = Instant.now.minusSeconds(5)
-    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 = 30.seconds) { activation =>
-      // Time recorded by invoker, some contingency to make query more robust
-      val queryTime = activation.start.minusMillis(500)
-      // since: poll for activations since specified point in time (absolute)
-      val activations =
-        wsk.activation.pollFor(N = 1, Some(s"$packageName/$actionName"), since = Some(queryTime), retries = 80).length
-      withClue(
-        s"expected activations of action '$fullActionName' since $queryTime, initial activation ${activation.activationId}:") {
-        activations should be(1)
-      }
-
-      val duration = Duration(Instant.now.minusMillis(start.toEpochMilli).toEpochMilli, MILLISECONDS)
-      val pollTime = 10 seconds
-      // since: poll for activations since specified number of seconds ago (relative)
-      val console = wsk.activation.console(pollTime, since = Some(duration))
-      withClue(s"Polled since ${duration.toSeconds} seconds, did not find expected result:") {
-        console.stdout should include(payload)
-      }
-    }
-  }
-
-  it should "show repeated activations" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val name = withTimestamp("countdown")
-    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-      action.create(name, Some(TestCLIUtils.getTestActionFilename("countdown.js")))
-    }
-
-    val count = 3
-    // Some contingency to make query more robust
-    // Account for time differences between controller and invoker
-    val start = Instant.now.minusSeconds(5)
-    val run = wsk.action.invoke(name, Map("n" -> count.toJson))
-    withActivation(wsk.activation, run) { activation =>
-      // Time recorded by invoker, some contingency to make query more robust
-      val queryTime = activation.start.minusMillis(500)
-      // since: poll for activations since specified point in time (absolute)
-      val activations = wsk.activation.pollFor(N = 4, Some(name), since = Some(queryTime), retries = 80).length
-      withClue(
-        s"expected activations of action '$name' since $queryTime, initial activation ${activation.activationId}:") {
-        activations should be(count + 1)
-      }
-      val duration = Duration(Instant.now.minusMillis(start.toEpochMilli).toEpochMilli, MILLISECONDS)
-      val pollTime = 10 seconds
-      // since: poll for activations since specified number of seconds ago (relative)
-      val console = wsk.activation.console(pollTime, since = Some(duration))
-      withClue(s"Polled for ${duration.toSeconds} seconds, did not find expected result:") {
-        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
deleted file mode 100644
index 80686c5c..00000000
--- a/tests/src/test/scala/system/basic/WskPackageTests.scala
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package system.basic
-
-import java.util.Date
-import scala.language.postfixOps
-import scala.collection.mutable.HashMap
-import scala.concurrent.duration.DurationInt
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-import common.TestCLIUtils
-import common.BaseWsk
-import common.WskProps
-import spray.json._
-import spray.json.DefaultJsonProtocol.StringJsonFormat
-import common.TestHelpers
-import common.WskTestHelpers
-import common.TestHelpers
-import common.WskProps
-
-@RunWith(classOf[JUnitRunner])
-abstract class WskPackageTests extends TestHelpers with WskTestHelpers {
-
-  implicit val wskprops = WskProps()
-  val wsk: BaseWsk
-  val LOG_DELAY = 80 seconds
-
-  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())
-    }
-  }
-
-  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 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 "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)
-    }
-
-    // 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 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
deleted file mode 100644
index 8ceff996..00000000
--- a/tests/src/test/scala/system/basic/WskRuleTests.scala
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package system.basic
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-import common.TestHelpers
-import common.TestCLIUtils
-import common.TestUtils.RunResult
-import common.BaseWsk
-import common.WskProps
-import common.WskTestHelpers
-import common.RuleActivationResult
-import spray.json._
-import spray.json.DefaultJsonProtocol._
-import java.time.Instant
-
-@RunWith(classOf[JUnitRunner])
-abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
-
-  implicit val wskprops = WskProps()
-  val wsk: BaseWsk
-  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)
-
-  /**
-   * 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): Unit = {
-    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))
-        }
-    }
-
-    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 "preserve rule status when a rule is updated" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val ruleName = withTimestamp("r1to1")
-    val triggerName = withTimestamp("t1to1")
-    val actionName = withTimestamp("a1 to 1")
-    val triggerName2 = withTimestamp("t2to1")
-    val active = Some("active".toJson)
-    val inactive = Some("inactive".toJson)
-    val statusPermutations =
-      Seq((triggerName, active), (triggerName, inactive), (triggerName2, active), (triggerName2, inactive))
-
-    ruleSetup(Seq((ruleName, triggerName, (actionName, actionName, defaultAction))), assetHelper)
-    assetHelper.withCleaner(wsk.trigger, triggerName2) { (trigger, name) =>
-      trigger.create(name)
-    }
-
-    statusPermutations.foreach {
-      case (trigger, status) =>
-        if (status == active) wsk.rule.enable(ruleName) else wsk.rule.disable(ruleName)
-        // CLI stdout must strip out the preamble text (i.e. "ok: got rule XXXXX") to get at the JSON
-        wsk.rule.create(ruleName, trigger, actionName, update = true)
-        val getStdout = wsk.rule.get(ruleName).stdout
-        getStdout.substring(getStdout.indexOf('{')).parseJson.asJsObject.fields.get("status") shouldBe status
-    }
-  }
-
-  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
-
-      val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
-      ruleActivations should have size 1
-      val ruleActivation = ruleActivations.head
-      ruleActivation.success shouldBe true
-      ruleActivation.statusCode shouldBe 0
-
-      withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
-        actionActivation.response.result shouldBe Some(testResult)
-        actionActivation.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)
-    }
-
-    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
-
-      val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
-      ruleActivations should have size 1
-      val ruleActivation = ruleActivations.head
-      ruleActivation.success shouldBe true
-      ruleActivation.statusCode shouldBe 0
-
-      withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
-        actionActivation.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
-
-      val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
-      ruleActivations should have size 1
-      val ruleActivation = ruleActivations.head
-      ruleActivation.success shouldBe true
-      ruleActivation.statusCode shouldBe 0
-
-      withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
-        actionActivation.response.result shouldBe Some(testResult)
-        actionActivation.cause shouldBe None
-      }
-    }
-  }
-
-  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, confirmDelete = false) { (rule, name) =>
-        rule.create(name, triggerName, actionName)
-      }
-
-      val first = wsk.trigger.fire(triggerName, Map("payload" -> "bogus".toJson))
-      wsk.rule.delete(ruleName)
-      val second = wsk.trigger.fire(triggerName, Map("payload" -> "bogus2".toJson))
-
-      withActivation(wsk.activation, first)(activation => activation.logs.get should have size 1)
-    // there won't be an activation for the second fire since there is no rule
-  }
-
-  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)
-    val second = wsk.trigger.fire(triggerName, Map("payload" -> s"$testString with added words".toJson))
-    wsk.rule.enable(ruleName)
-    val third = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
-
-    withActivation(wsk.activation, first) { triggerActivation =>
-      val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
-      ruleActivations should have size 1
-      val ruleActivation = ruleActivations.head
-      withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
-        actionActivation.response.result shouldBe Some(testResult)
-      }
-    }
-
-    // second fire will not write an activation
-
-    withActivation(wsk.activation, third) { triggerActivation =>
-      val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
-      ruleActivations should have size 1
-      val ruleActivation = ruleActivations.head
-      withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
-        actionActivation.response.result shouldBe 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, confirmDelete = 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 =>
-        val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
-        ruleActivations should have size 1
-        val ruleActivation = ruleActivations.head
-        withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
-          actionActivation.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 runs = testPayloads.map(payload => wsk.trigger.fire(triggerName1, Map("payload" -> payload.toJson)))
-
-      runs.zip(testPayloads).foreach {
-        case (run, payload) =>
-          withActivation(wsk.activation, run) { triggerActivation =>
-            val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
-            ruleActivations should have size 1
-            val ruleActivation = ruleActivations.head
-            withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
-              actionActivation.response.result shouldBe Some(JsObject("count" -> payload.split(" ").length.toJson))
-            }
-          }
-      }
-  }
-
-  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 =>
-        val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
-        ruleActivations should have size 2
-
-        val action1Result = ruleActivations.find(_.action.contains(actionName1)).get
-        val action2Result = ruleActivations.find(_.action.contains(actionName2)).get
-
-        withActivation(wsk.activation, action1Result.activationId) { actionActivation =>
-          actionActivation.response.result shouldBe Some(testResult)
-        }
-        withActivation(wsk.activation, action2Result.activationId) { actionActivation =>
-          actionActivation.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 runs = Seq(triggerName1, triggerName2).zip(testPayloads).map {
-        case (trigger, payload) =>
-          payload -> wsk.trigger.fire(trigger, Map("payload" -> payload.toJson))
-      }
-
-      runs.foreach {
-        case (payload, run) =>
-          withActivation(wsk.activation, run) { triggerActivation =>
-            val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
-            ruleActivations should have size 2 // each trigger has 2 actions attached
-
-            val action1Result = ruleActivations.find(_.action.contains(actionName1)).get
-            val action2Result = ruleActivations.find(_.action.contains(actionName2)).get
-
-            withActivation(wsk.activation, action1Result.activationId) { actionActivation =>
-              actionActivation.response.result shouldBe Some(JsObject("count" -> payload.split(" ").length.toJson))
-            }
-            withActivation(wsk.activation, action2Result.activationId) { actionActivation =>
-              actionActivation.logs.get.mkString(" ") should include(s"hello, $payload")
-            }
-          }
-      }
-  }
-
-  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 ruleListResult = wsk.rule.list()
-      verifyRuleList(ruleListResult, ruleName2, ruleName)
-  }
-
-  def verifyRuleList(ruleListResult: RunResult, ruleNameEnable: String, ruleName: String) = {
-    val ruleList = ruleListResult.stdout
-    val listOutput = ruleList.lines
-    listOutput.find(_.contains(ruleNameEnable)).get should (include(ruleNameEnable) and include("active"))
-    listOutput.find(_.contains(ruleName)).get should (include(ruleName) and include("inactive"))
-    ruleList should not include "Unknown"
-  }
-}
diff --git a/tests/src/test/scala/system/basic/WskSequenceTests.scala b/tests/src/test/scala/system/basic/WskSequenceTests.scala
deleted file mode 100644
index b2b37b85..00000000
--- a/tests/src/test/scala/system/basic/WskSequenceTests.scala
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package system.basic
-
-import java.time.Instant
-import java.util.Date
-
-import scala.concurrent.duration.DurationInt
-import scala.language.postfixOps
-import scala.util.matching.Regex
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-
-import common.ActivationResult
-import common.StreamLogging
-import common.TestHelpers
-import common.TestCLIUtils
-import common.TestUtils._
-import common.WhiskProperties
-import common.BaseWsk
-import common.WskProps
-import common.RuleActivationResult
-import common.WskTestHelpers
-
-import akka.http.scaladsl.testkit.ScalatestRouteTest
-
-import spray.json._
-import spray.json.DefaultJsonProtocol._
-
-import whisk.http.Messages.sequenceIsTooLong
-
-/**
- * Tests sequence execution
- */
-@RunWith(classOf[JUnitRunner])
-abstract class WskSequenceTests extends TestHelpers with ScalatestRouteTest with WskTestHelpers with StreamLogging {
-
-  implicit val wskprops = WskProps()
-  val wsk: BaseWsk
-  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))
-        }
-      }
-
-      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(",")
-      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)
-      }
-
-      // 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 = 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)))
-    }
-  }
-
-  /**
-   * 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))
-
-    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("limits.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)
-      }
-    }
-  }
-
-  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))
-  }
-
-  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 -> 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.")))
-      }
-  }
-
-  /**
-   * 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.")))
-      }
-  }
-
-  /**
-   * 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.")))
-    }
-  }
-
-  /**
-   * 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))
-  }
-
-  /**
-   * 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 =>
-      val ruleActivation = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult]).head
-      withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
-        actionActivation.response.result shouldBe Some(triggerPayload)
-        actionActivation.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
-        val mem = extractMemoryAnnotation(componentActivation)
-        maxMemory = maxMemory max mem
-      }
-    }
-    // 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 =>
-        withClue(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]
-  }
-}
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
deleted file mode 100644
index 57449e69..00000000
--- a/tests/src/test/scala/whisk/core/apigw/actions/test/ApiGwRoutemgmtActionTests.scala
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package whisk.core.apigw.actions.test
-
-import org.junit.runner.RunWith
-import org.scalatest.BeforeAndAfterAll
-import org.scalatest.junit.JUnitRunner
-
-import common.JsHelpers
-import common.StreamLogging
-import common.TestHelpers
-import common.TestUtils.DONTCARE_EXIT
-import common.TestUtils.RunResult
-import common.TestUtils.SUCCESS_EXIT
-import common.BaseWsk
-import common.WskActorSystem
-import common.WskAdmin
-import common.WskProps
-import common.rest.ApiAction
-import common.WskTestHelpers
-import spray.json._
-import spray.json.DefaultJsonProtocol._
-
-/**
- * Tests for basic CLI usage. Some of these tests require a deployed backend.
- */
-@RunWith(classOf[JUnitRunner])
-abstract class ApiGwRoutemgmtActionTests
-    extends TestHelpers
-    with BeforeAndAfterAll
-    with WskActorSystem
-    with WskTestHelpers
-    with JsHelpers
-    with StreamLogging {
-
-  val systemId = "whisk.system"
-  implicit val wskprops = WskProps(authKey = WskAdmin.listKeys(systemId)(0)._1, namespace = systemId)
-  val wsk: BaseWsk
-
-  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 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 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/createApi",
-      parameters = parm,
-      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]()
-    }
-
-    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
-  }
-
-  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"
-
-  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 =
-      new 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)
-    }
-  }
-
-  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 =
-      new 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)
-    }
-  }
-
-  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 =
-      new 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)
-    }
-  }
-}
diff --git a/tests/src/test/scala/whisk/core/cli/test/BaseApiGwTests.scala b/tests/src/test/scala/whisk/core/cli/test/BaseApiGwTests.scala
deleted file mode 100644
index 8aa24fcf..00000000
--- a/tests/src/test/scala/whisk/core/cli/test/BaseApiGwTests.scala
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package whisk.core.cli.test
-
-import java.io.File
-import java.time.Instant
-
-import scala.collection.mutable.ArrayBuffer
-import scala.concurrent.duration._
-import scala.math.max
-
-import org.junit.runner.RunWith
-
-import org.scalatest.BeforeAndAfterAll
-import org.scalatest.BeforeAndAfterEach
-import org.scalatest.junit.JUnitRunner
-
-import common.TestHelpers
-import common.TestUtils._
-import common.WhiskProperties
-import common.BaseWsk
-import common.WskProps
-import common.WskTestHelpers
-
-/**
- * Tests for testing the CLI "api" subcommand.  Most of these tests require a deployed backend.
- */
-@RunWith(classOf[JUnitRunner])
-abstract class BaseApiGwTests extends TestHelpers with WskTestHelpers with BeforeAndAfterEach with BeforeAndAfterAll {
-
-  implicit val wskprops = WskProps()
-  val wsk: BaseWsk
-
-  // 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 action invocation to
-   * settle the throttle when there isn't enough capacity to handle the test.
-   */
-  def checkThrottle(maxInvocationsBeforeThrottle: Int = maxActionsPerMin, throttlePercent: Int = 50) = {
-    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 && throttlePercent >= 1) {
-      val numInvocationsToClear = max(invocationCount / (100 / throttlePercent), 1)
-      val invocationToClear = invocationsLast60Seconds(numInvocationsToClear - 1)
-      println(
-        s"throttling ${throttlePercent}% of action invocations within last minute = ($numInvocationsToClear) invocations")
-      val throttleTime = 60.seconds.toMillis - (t.toEpochMilli - invocationToClear.toEpochMilli)
-
-      println(s"Waiting ${throttleTime} milliseconds to settle the throttle")
-      Thread.sleep(throttleTime)
-    }
-
-    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 any follow on tests
-    checkThrottle(maxInvocationsBeforeThrottle = 1, throttlePercent = 100)
-  }
-
-  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)
-  }
-}
diff --git a/tests/src/test/scala/whisk/core/cli/test/JsonArgsForTests.scala b/tests/src/test/scala/whisk/core/cli/test/JsonArgsForTests.scala
deleted file mode 100644
index 9d8910ef..00000000
--- a/tests/src/test/scala/whisk/core/cli/test/JsonArgsForTests.scala
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package whisk.core.cli.test
-
-import spray.json.JsObject
-import spray.json.JsArray
-import spray.json.JsString
-import spray.json.JsNumber
-import spray.json.JsBoolean
-
-object JsonArgsForTests {
-
-  def getInvalidJSONInput =
-    Seq(
-      "{\"invalid1\": }",
-      "{\"invalid2\": bogus}",
-      "{\"invalid1\": \"aKey\"",
-      "invalid \"string\"",
-      "{\"invalid1\": [1, 2, \"invalid\"\"arr\"]}")
-
-  def getJSONFileOutput() =
-    JsArray(
-      JsObject("key" -> JsString("a key"), "value" -> JsString("a value")),
-      JsObject("key" -> JsString("a bool"), "value" -> JsBoolean(true)),
-      JsObject("key" -> JsString("objKey"), "value" -> JsObject("b" -> JsString("c"))),
-      JsObject(
-        "key" -> JsString("objKey2"),
-        "value" -> JsObject("another object" -> JsObject("some string" -> JsString("1111")))),
-      JsObject(
-        "key" -> JsString("objKey3"),
-        "value" -> JsObject("json object" -> JsObject("some int" -> JsNumber(1111)))),
-      JsObject("key" -> JsString("a number arr"), "value" -> JsArray(JsNumber(1), JsNumber(2), JsNumber(3))),
-      JsObject("key" -> JsString("a string arr"), "value" -> JsArray(JsString("1"), JsString("2"), JsString("3"))),
-      JsObject("key" -> JsString("a bool arr"), "value" -> JsArray(JsBoolean(true), JsBoolean(false), JsBoolean(true))),
-      JsObject("key" -> JsString("strThatLooksLikeJSON"), "value" -> JsString("{\"someKey\": \"someValue\"}")))
-
-  def getEscapedJSONTestArgInput() =
-    Map(
-      "key1" -> JsObject("nonascii" -> JsString("日本語")),
-      "key2" -> JsObject("valid" -> JsString("J\\SO\"N")),
-      "\"key\"with\\escapes" -> JsObject("valid" -> JsString("JSON")),
-      "another\"escape\"" -> JsObject("valid" -> JsString("\\nJ\\rO\\tS\\bN\\f")))
-
-  def getEscapedJSONTestArgOutput() =
-    JsArray(
-      JsObject("key" -> JsString("key1"), "value" -> JsObject("nonascii" -> JsString("日本語"))),
-      JsObject("key" -> JsString("key2"), "value" -> JsObject("valid" -> JsString("J\\SO\"N"))),
-      JsObject("key" -> JsString("\"key\"with\\escapes"), "value" -> JsObject("valid" -> JsString("JSON"))),
-      JsObject("key" -> JsString("another\"escape\""), "value" -> JsObject("valid" -> JsString("\\nJ\\rO\\tS\\bN\\f"))))
-
-  def getValidJSONTestArgOutput() =
-    JsArray(
-      JsObject("key" -> JsString("number"), "value" -> JsNumber(8)),
-      JsObject("key" -> JsString("bignumber"), "value" -> JsNumber(12345678912.123456789012)),
-      JsObject(
-        "key" -> JsString("objArr"),
-        "value" -> JsArray(
-          JsObject("name" -> JsString("someName"), "required" -> JsBoolean(true)),
-          JsObject("name" -> JsString("events"), "count" -> JsNumber(10)))),
-      JsObject("key" -> JsString("strArr"), "value" -> JsArray(JsString("44"), JsString("55"))),
-      JsObject("key" -> JsString("string"), "value" -> JsString("This is a string")),
-      JsObject("key" -> JsString("numArr"), "value" -> JsArray(JsNumber(44), JsNumber(55))),
-      JsObject(
-        "key" -> JsString("object"),
-        "value" -> JsObject(
-          "objString" -> JsString("aString"),
-          "objStrNum" -> JsString("123"),
-          "objNum" -> JsNumber(300),
-          "objBool" -> JsBoolean(false),
-          "objNumArr" -> JsArray(JsNumber(1), JsNumber(2)),
-          "objStrArr" -> JsArray(JsString("1"), JsString("2")))),
-      JsObject("key" -> JsString("strNum"), "value" -> JsString("9")))
-
-  def getValidJSONTestArgInput() =
-    Map(
-      "string" -> JsString("This is a string"),
-      "strNum" -> JsString("9"),
-      "number" -> JsNumber(8),
-      "bignumber" -> JsNumber(12345678912.123456789012),
-      "numArr" -> JsArray(JsNumber(44), JsNumber(55)),
-      "strArr" -> JsArray(JsString("44"), JsString("55")),
-      "objArr" -> JsArray(
-        JsObject("name" -> JsString("someName"), "required" -> JsBoolean(true)),
-        JsObject("name" -> JsString("events"), "count" -> JsNumber(10))),
-      "object" -> JsObject(
-        "objString" -> JsString("aString"),
-        "objStrNum" -> JsString("123"),
-        "objNum" -> JsNumber(300),
-        "objBool" -> JsBoolean(false),
-        "objNumArr" -> JsArray(JsNumber(1), JsNumber(2)),
-        "objStrArr" -> JsArray(JsString("1"), JsString("2"))))
-}
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskActionSequenceTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskActionSequenceTests.scala
deleted file mode 100644
index b46c94c5..00000000
--- a/tests/src/test/scala/whisk/core/cli/test/WskActionSequenceTests.scala
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package whisk.core.cli.test
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-
-import common.TestHelpers
-import common.TestCLIUtils
-import common.BaseWsk
-import common.WskProps
-import common.WskTestHelpers
-import common.TestUtils.RunResult
-import spray.json._
-import whisk.core.entity.EntityPath
-
-/**
- * Tests creation and retrieval of a sequence action
- */
-@RunWith(classOf[JUnitRunner])
-abstract class WskActionSequenceTests extends TestHelpers with WskTestHelpers {
-
-  implicit val wskprops = WskProps()
-  val wsk: BaseWsk
-  val defaultNamespace = EntityPath.DEFAULT.asString
-  val namespace = wsk.namespace.whois()
-
-  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"
-
-    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.action, fullCatActionName) {
-      val file = Some(TestCLIUtils.getTestActionFilename("cat.js"))
-      (action, _) =>
-        action.create(fullCatActionName, file)(wp)
-    }
-
-    val artifacts = s"$fullHelloActionName,$fullCatActionName"
-    val kindValue = JsString("sequence")
-    val compValue = JsArray(
-      JsString(resolveDefaultNamespace(fullHelloActionName)),
-      JsString(resolveDefaultNamespace(fullCatActionName)))
-
-    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-      action.create(name, Some(artifacts), kind = Some("sequence"))
-    }
-
-    val action = wsk.action.get(name)
-    verifyActionSequence(action, name, compValue, kindValue)
-  }
-
-  def verifyActionSequence(action: RunResult, name: String, compValue: JsArray, kindValue: JsString): Unit = {
-    val stdout = action.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 4d163f5b..cbacabae 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
@@ -45,7 +45,7 @@ import whisk.core.entity.MemoryLimit._
 import whisk.core.entity.TimeLimit._
 import whisk.core.entity.size.SizeInt
 import whisk.utils.retry
-import JsonArgsForTests._
+import whisk.core.cli.test.TestJsonArgs._
 import whisk.http.Messages
 
 /**
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala
deleted file mode 100644
index 926a4da3..00000000
--- a/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package whisk.core.cli.test
-
-import org.junit.runner.RunWith
-import org.scalatest.BeforeAndAfterAll
-import org.scalatest.junit.JUnitRunner
-
-import common.TestHelpers
-import common.TestCLIUtils
-import common.TestUtils.RunResult
-import common.BaseWsk
-import common.WskProps
-import common.WskTestHelpers
-import spray.json._
-import spray.json.DefaultJsonProtocol._
-import whisk.core.entity.Subject
-import whisk.core.entity.WhiskPackage
-
-@RunWith(classOf[JUnitRunner])
-abstract class WskEntitlementTests extends TestHelpers with WskTestHelpers with BeforeAndAfterAll {
-
-  val wsk: BaseWsk
-  lazy val defaultWskProps = WskProps()
-  lazy val guestWskProps = getAdditionalTestSubject(Subject().asString)
-  val forbiddenCode: Int
-  val timeoutCode: Int
-  val notFoundCode: Int
-
-  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(TestCLIUtils.getTestActionFilename("hello.js")))(wp)
-      }
-
-      val fullyQualifiedActionName = s"/$guestNamespace/$privateAction"
-      wsk.action
-        .get(fullyQualifiedActionName, expectedExitCode = forbiddenCode)(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 = forbiddenCode)(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 = forbiddenCode)(wp)
-          rr.stderr should include("not authorized")
-          rr
-        }
-      }
-
-      wsk.action
-        .delete(fullyQualifiedActionName, expectedExitCode = forbiddenCode)(defaultWskProps)
-        .stderr should include("not authorized")
-
-      wsk.action
-        .invoke(fullyQualifiedActionName, expectedExitCode = forbiddenCode)(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(TestCLIUtils.getTestActionFilename("empty.js"))
-        (action, _) =>
-          action.create(fullSampleActionName, file)(wp)
-      }
-
-      val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
-      wsk.action.get(fullyQualifiedActionName)(defaultWskProps)
-      wsk.action.delete(fullyQualifiedActionName, expectedExitCode = forbiddenCode)(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(TestCLIUtils.getTestActionFilename("empty.js"))
-
-      withAssetCleaner(defaultWskProps) { (wp, assetHelper) =>
-        assetHelper.withCleaner(wsk.action, fullyQualifiedActionName, confirmDelete = false) { (action, name) =>
-          action.create(name, file, expectedExitCode = forbiddenCode)(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(TestCLIUtils.getTestActionFilename("empty.js"))
-        (action, _) =>
-          action.create(fullSampleActionName, file)(wp)
-      }
-
-      val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
-      wsk.action.create(fullyQualifiedActionName, None, update = true, expectedExitCode = forbiddenCode)(
-        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 packageList = wsk.pkg.list(Some(s"/$guestNamespace"))(defaultWskProps)
-    verifyPackageSharedList(packageList, guestNamespace, samplePackage)
-  }
-
-  def verifyPackageSharedList(packageList: RunResult, namespace: String, packageName: String): Unit = {
-    val fullyQualifiedPackageName = s"/$namespace/$packageName"
-    packageList.stdout should include regex (fullyQualifiedPackageName + """\s+shared""")
-  }
-
-  it should "not list private packages" in withAssetCleaner(guestWskProps) { (wp, assetHelper) =>
-    assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
-      pkg.create(samplePackage)(wp)
-    }
-
-    val packageList = wsk.pkg.list(Some(s"/$guestNamespace"))(defaultWskProps)
-    verifyPackageNotSharedList(packageList, guestNamespace, samplePackage)
-  }
-
-  def verifyPackageNotSharedList(packageList: RunResult, namespace: String, packageName: String): Unit = {
-    val fullyQualifiedPackageName = s"/$namespace/$packageName"
-    packageList.stdout should not include regex(fullyQualifiedPackageName)
-  }
-
-  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 packageList = wsk.action.list(Some(fullyQualifiedPackageName))(defaultWskProps)
-    verifyPackageList(packageList, guestNamespace, samplePackage, sampleAction)
-  }
-
-  def verifyPackageList(packageList: RunResult, namespace: String, packageName: String, actionName: String): Unit = {
-    val result = packageList.stdout
-    result should include regex (s"/$namespace/$packageName/$actionName")
-  }
-
-  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 "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 = forbiddenCode)(wp)
-      }
-    }
-  }
-
-  behavior of "Wsk Package Action"
-
-  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)
-    }
-
-    assetHelper.withCleaner(wsk.action, fullSampleActionName) {
-      val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-      (action, _) =>
-        action.create(fullSampleActionName, file)(wp)
-    }
-
-    val fullyQualifiedActionName = s"/$guestNamespace/$fullSampleActionName"
-    val action = wsk.action.get(fullyQualifiedActionName)(defaultWskProps)
-    verifyAction(action)
-
-    val run = wsk.action.invoke(fullyQualifiedActionName)(defaultWskProps)
-
-    withActivation(wsk.activation, run)({
-      _.response.success shouldBe true
-    })(defaultWskProps)
-  }
-
-  def verifyAction(action: RunResult) = {
-    val stdout = action.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(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)
-    }
-  }
-
-  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"
-    Seq(samplePackage, privateSamplePackage).foreach { n =>
-      assetHelper.withCleaner(wsk.pkg, n) { (pkg, _) =>
-        pkg.create(n, parameters = Map("a" -> "A".toJson), shared = Some(true))(guestwp)
-      }
-    }
-
-    Seq(fullSampleActionName, s"$privateSamplePackage/$sampleAction").foreach { a =>
-      val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-      assetHelper.withCleaner(wsk.action, a) { (action, _) =>
-        action.create(a, 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 = forbiddenCode)(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"
-
-    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)
-  }
-
-  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 = timeoutCode)(wp)
-        }
-        wsk.trigger.get("badfeed", expectedExitCode = notFoundCode)(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
deleted file mode 100644
index fc5daf0e..00000000
--- a/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package whisk.core.cli.test
-
-import java.nio.charset.StandardCharsets
-import java.util.Base64
-
-import scala.util.Failure
-import scala.util.Try
-
-import org.junit.runner.RunWith
-import org.scalatest.BeforeAndAfterAll
-import org.scalatest.junit.JUnitRunner
-
-import com.jayway.restassured.RestAssured
-import com.jayway.restassured.response.Header
-
-import common.TestHelpers
-import common.TestCLIUtils
-import common.WhiskProperties
-import common.BaseWsk
-import common.WskProps
-import common.WskTestHelpers
-import common.SimpleExec
-
-import spray.json._
-import spray.json.DefaultJsonProtocol._
-
-import system.rest.RestUtil
-
-import whisk.common.PrintStreamLogging
-import whisk.common.TransactionId
-import whisk.core.entity.Subject
-
-/**
-  * Tests web actions.
-  */
-@RunWith(classOf[JUnitRunner])
-abstract class WskWebActionsTests extends TestHelpers with WskTestHelpers with RestUtil with BeforeAndAfterAll {
-  val MAX_URL_LENGTH = 8192 // 8K matching nginx default
-
-  val wsk: BaseWsk
-  private implicit val wskprops = WskProps()
-  val namespace = wsk.namespace.whois()
-
-  protected val testRoutePath: String = "/api/v1/web"
-
-  behavior of "Wsk Web Actions"
-
-  it should "ensure __ow_headers contains the proper content-type" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val name = "webContenttype"
-    val file = Some(TestCLIUtils.getTestActionFilename("echo.js"))
-    val bodyContent = JsObject("key" -> "value".toJson)
-    val host = getServiceURL()
-    val url = s"$host$testRoutePath/$namespace/default/$name.json"
-
-    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
-      action.create(name, file, web = Some("true"))
-    }
-
-    val resWithContentType =
-      RestAssured.given().contentType("application/json").body(bodyContent.compactPrint).config(sslconfig).post(url)
-
-    resWithContentType.statusCode shouldBe 200
-    resWithContentType.header("Content-type") shouldBe "application/json"
-    resWithContentType.body.asString.parseJson.asJsObject
-      .fields("__ow_headers")
-      .asJsObject
-      .fields("content-type") shouldBe "application/json".toJson
-
-    val resWithoutContentType =
-      RestAssured.given().config(sslconfig).get(url)
-
-    resWithoutContentType.statusCode shouldBe 200
-    resWithoutContentType.header("Content-type") shouldBe "application/json"
-    resWithoutContentType.body.asString.parseJson.asJsObject
-      .fields("__ow_headers")
-      .toString should not include ("content-type")
-  }
-
-  /**
-    * 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
-
-    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
-            }
-          }
-      }
-  }
-
-  /**
-    * 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))
-      }
-
-      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(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"
-  }
-
-  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"))
-    }
-
-    Seq(
-      RestAssured
-        .given()
-        .config(sslconfig)
-        .header("Access-Control-Request-Headers", "x-custom-header")
-        .options(s"$url.http"),
-      RestAssured
-        .given()
-        .config(sslconfig)
-        .header("Access-Control-Request-Headers", "x-custom-header")
-        .get(s"$url.json")).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 "x-custom-header"
-      response.header("Location") shouldBe null
-      response.header("Set-Cookie") shouldBe null
-    }
-
-    Seq(
-      RestAssured.given().config(sslconfig).options(s"$url.http"),
-      RestAssured.given().config(sslconfig).get(s"$url.json")).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(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
-  }
-
-  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"
-
-      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(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(TestCLIUtils.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
-  } else {
-    WskProps()
-  }
-
-  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(TestCLIUtils.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 _ =>
-      }
-  }
-}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services