Added swagger tests and updated swagger test docs
diff --git a/tests/src/common/WhiskProperties.java b/tests/src/common/WhiskProperties.java
index de4bdb8..f4f6ce9 100644
--- a/tests/src/common/WhiskProperties.java
+++ b/tests/src/common/WhiskProperties.java
@@ -235,6 +235,14 @@
         return Integer.parseInt(whiskProperties.getProperty("controller.host.port"));
     }
 
+    public static int getMaxActionInvokesPerMinute() {
+        String valStr = whiskProperties.getProperty("limits.actions.invokes.perMinute");
+        if (null == valStr) {
+            valStr = whiskProperties.getProperty("defaultLimits.actions.invokes.perMinute");
+        }
+        return Integer.parseInt(valStr);
+    }
+
     /**
      * read the contents of auth key file and return as a Pair
      * <username,password>
diff --git a/tests/src/whisk/core/cli/test/ApiGwTests.scala b/tests/src/whisk/core/cli/test/ApiGwTests.scala
index 89c140c..eae638e 100644
--- a/tests/src/whisk/core/cli/test/ApiGwTests.scala
+++ b/tests/src/whisk/core/cli/test/ApiGwTests.scala
@@ -16,11 +16,15 @@
 
 package whisk.core.cli.test
 
+import java.time.Instant
+import scala.concurrent.duration._
 import org.junit.runner.RunWith
+import org.scalatest.BeforeAndAfterAll
 import org.scalatest.junit.JUnitRunner
 import common.TestHelpers
 import common.TestUtils._
 import common.TestUtils
+import common.WhiskProperties
 import common.Wsk
 import common.WskAdmin
 import common.WskProps
@@ -32,24 +36,115 @@
 @RunWith(classOf[JUnitRunner])
 class ApiGwTests
     extends TestHelpers
-    with WskTestHelpers {
+    with WskTestHelpers
+    with BeforeAndAfterAll {
 
     implicit val wskprops = WskProps()
     val wsk = new Wsk
     val (cliuser, clinamespace) = WskAdmin.getUser(wskprops.authKey)
 
+    // 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 throttleWindow = 1.minute
+    var cliCallCount = 5  // Set to >0 to allow for other action invocations in prior tests
+    var clearedThrottleTime = Instant.now
+    val maxActionsPerMin = WhiskProperties.getMaxActionInvokesPerMinute()
+
+    /**
+      * Expected to be called before or after each CLI invocation
+      * If number of CLI invocations in this suite have reached the throttle limit
+      * then pause the test for enough time so that the throttle restriction is gone
+      */
+    def checkThrottle() = {
+      // If the # CLI calls at the throttle limit, then wait enough time to avoid the CLI being blocked
+      cliCallCount += 1
+      if ( cliCallCount > maxActionsPerMin ) {
+        println(s"Action invokes ${cliCallCount} exceeds per minute thottle limit of ${maxActionsPerMin}")
+        val waitedAlready = Duration.fromNanos(java.time.Duration.between(clearedThrottleTime, Instant.now).toNanos)
+        settleThrottle(waitedAlready)
+        cliCallCount = 0
+        clearedThrottleTime = Instant.now
+      }
+    }
+
+    /**
+     * Settles throttles of 1 minute. Waits up to 1 minute depending on the time already waited.
+     *
+     * @param waitedAlready the time already gone after the last invoke or fire
+     */
+    def settleThrottle(waitedAlready: FiniteDuration) = {
+      val timeToWait = (throttleWindow - waitedAlready).max(Duration.Zero)
+      println(s"Waiting for ${timeToWait.toSeconds} seconds, already waited for ${waitedAlready.toSeconds} seconds")
+      Thread.sleep(timeToWait.toMillis)
+    }
+
+    /*
+     * Forcibly clear the throttle so that downstream tests are not affected by
+     * this test suite
+     */
+    override def afterAll() = {
+      // If this test suite is exiting with over 30 action invocations since the last throttle clearing, clear the throttle
+      if (cliCallCount > 30) {
+        val waitedAlready = Duration.fromNanos(java.time.Duration.between(clearedThrottleTime, Instant.now).toNanos)
+        settleThrottle(waitedAlready)
+      }
+    }
+
+    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,
+      expectedExitCode: Int = SUCCESS_EXIT): RunResult = {
+        checkThrottle()
+        wsk.api.create(basepath, relpath, operation, action, apiname, swagger, expectedExitCode)
+    }
+
+    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,
+      expectedExitCode: Int = SUCCESS_EXIT): RunResult = {
+        checkThrottle()
+        wsk.api.list(basepathOrApiName, relpath, operation, limit, since, full, expectedExitCode)
+    }
+
+    def apiGet(
+      basepathOrApiName: Option[String] = None,
+      full: Option[Boolean] = None,
+      expectedExitCode: Int = SUCCESS_EXIT): RunResult = {
+        checkThrottle()
+        wsk.api.get(basepathOrApiName, full, expectedExitCode)
+    }
+
+    def apiDelete(
+      basepathOrApiName: String,
+      relpath: Option[String] = None,
+      operation: Option[String] = None,
+      expectedExitCode: Int = SUCCESS_EXIT): RunResult = {
+        checkThrottle()
+        wsk.api.delete(basepathOrApiName, relpath, operation, expectedExitCode)
+    }
+
     behavior of "Wsk api"
 
     it should "reject an api commands with an invalid path parameter" in {
         val badpath = "badpath"
 
-        var rr = wsk.api.create(basepath = Some("/basepath"), relpath = Some(badpath), operation = Some("GET"), action = Some("action"), expectedExitCode = ANY_ERROR_EXIT)
+        var rr = apiCreate(basepath = Some("/basepath"), relpath = Some(badpath), operation = Some("GET"), action = Some("action"), expectedExitCode = ANY_ERROR_EXIT)
         rr.stderr should include (s"'${badpath}' must begin with '/'")
 
-        rr = wsk.api.delete(basepathOrApiName = "/basepath", relpath = Some(badpath), operation = Some("GET"), expectedExitCode = ANY_ERROR_EXIT)
+        rr = apiDelete(basepathOrApiName = "/basepath", relpath = Some(badpath), operation = Some("GET"), expectedExitCode = ANY_ERROR_EXIT)
         rr.stderr should include (s"'${badpath}' must begin with '/'")
 
-        rr = wsk.api.list(basepathOrApiName = Some("/basepath"), relpath = Some(badpath), operation = Some("GET"), expectedExitCode = ANY_ERROR_EXIT)
+        rr = apiList(basepathOrApiName = Some("/basepath"), relpath = Some(badpath), operation = Some("GET"), expectedExitCode = ANY_ERROR_EXIT)
         rr.stderr should include (s"'${badpath}' must begin with '/'")
     }
 
@@ -64,10 +159,10 @@
       try {
         println("cli user: " + cliuser + "; cli namespace: " + clinamespace)
 
-        var rr = wsk.api.create(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
         println("api create: " + rr.stdout)
         rr.stdout should include("ok: created API")
-        rr = wsk.api.list(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), full = Some(true))
+        rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), full = Some(true))
         println("api list: " + rr.stdout)
         rr.stdout should include("ok: APIs")
         rr.stdout should include regex (s"Action:\\s+/${clinamespace}/${actionName}\n")
@@ -79,7 +174,7 @@
         rr.stdout should include(testbasepath + testrelpath)
       }
       finally {
-        val deleteresult = wsk.api.delete(basepathOrApiName = testbasepath)
+        val deleteresult = apiDelete(basepathOrApiName = testbasepath)
       }
     }
 
@@ -94,17 +189,17 @@
         try {
             println("cli user: "+cliuser+"; cli namespace: "+clinamespace)
 
-            var rr = wsk.api.create(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
             rr.stdout should include("ok: created API")
-            rr = wsk.api.list(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+            rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
             rr.stdout should include("ok: APIs")
             rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
             rr.stdout should include(testbasepath + testrelpath)
-            val deleteresult = wsk.api.delete(basepathOrApiName = testbasepath)
+            val deleteresult = apiDelete(basepathOrApiName = testbasepath)
             deleteresult.stdout should include("ok: deleted API")
         }
         finally {
-            val deleteresult = wsk.api.delete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+            val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
         }
     }
 
@@ -117,14 +212,14 @@
         val testapiname = testName+" API Name"
         val actionName = testName+"_action"
         try {
-            var rr = wsk.api.create(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+            var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
             rr.stdout should include("ok: created API")
-            rr = wsk.api.get(basepathOrApiName = Some(testapiname))
+            rr = apiGet(basepathOrApiName = Some(testapiname))
             rr.stdout should include(testbasepath)
             rr.stdout should include(s"${actionName}")
         }
         finally {
-            val deleteresult = wsk.api.delete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+            val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
         }
     }
 
@@ -137,13 +232,13 @@
       val testapiname = testName+" API Name"
       val actionName = testName+"_action"
       try {
-        var rr = wsk.api.create(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
         rr.stdout should include("ok: created API")
-        rr = wsk.api.delete(basepathOrApiName = testapiname)
+        rr = apiDelete(basepathOrApiName = testapiname)
         rr.stdout should include("ok: deleted API")
       }
       finally {
-        val deleteresult = wsk.api.delete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+        val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
       }
     }
 
@@ -156,13 +251,13 @@
       val testapiname = testName+" API Name"
       val actionName = testName+"_action"
       try {
-        var rr = wsk.api.create(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
         rr.stdout should include("ok: created API")
-        rr = wsk.api.delete(basepathOrApiName = testbasepath)
+        rr = apiDelete(basepathOrApiName = testbasepath)
         rr.stdout should include("ok: deleted API")
       }
       finally {
-        val deleteresult = wsk.api.delete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+        val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
       }
     }
 
@@ -176,18 +271,18 @@
       val actionName = testName+"_action"
       val newEndpoint = "/newEndpoint"
       try {
-        var rr = wsk.api.create(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
         rr.stdout should include("ok: created API")
-        rr = wsk.api.create(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        rr = apiCreate(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
         rr.stdout should include("ok: created API")
-        rr = wsk.api.list(basepathOrApiName = Some(testbasepath))
+        rr = apiList(basepathOrApiName = Some(testbasepath))
         rr.stdout should include("ok: APIs")
         rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
         rr.stdout should include(testbasepath + testrelpath)
         rr.stdout should include(testbasepath + newEndpoint)
       }
       finally {
-        val deleteresult = wsk.api.delete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+        val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
       }
     }
 
@@ -201,9 +296,9 @@
       val actionName = testName+"_action"
       val swaggerPath = TestUtils.getTestApiGwFilename("testswaggerdoc1")
       try {
-        var rr = wsk.api.create(swagger = Some(swaggerPath))
+        var rr = apiCreate(swagger = Some(swaggerPath))
         rr.stdout should include("ok: created API")
-        rr = wsk.api.list(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+        rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
         println("list stdout: "+rr.stdout)
         println("list stderr: "+rr.stderr)
         rr.stdout should include("ok: APIs")
@@ -212,7 +307,7 @@
         rr.stdout should include(testbasepath + testrelpath)
       }
       finally {
-        val deleteresult = wsk.api.delete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+        val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
       }
     }
 
@@ -227,32 +322,32 @@
       val actionName = testName+"_action"
       val newEndpoint = "/newEndpoint"
       try {
-        var rr = wsk.api.create(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
         rr.stdout should include("ok: created API")
-        rr = wsk.api.create(basepath = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        rr = apiCreate(basepath = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
         rr.stdout should include("ok: created API")
 
         // Update both APIs - each with a new endpoint
-        rr = wsk.api.create(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName))
+        rr = apiCreate(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName))
         rr.stdout should include("ok: created API")
-        rr = wsk.api.create(basepath = Some(testbasepath2), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName))
+        rr = apiCreate(basepath = Some(testbasepath2), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName))
         rr.stdout should include("ok: created API")
 
-        rr = wsk.api.list(basepathOrApiName = Some(testbasepath))
+        rr = apiList(basepathOrApiName = Some(testbasepath))
         rr.stdout should include("ok: APIs")
         rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
         rr.stdout should include(testbasepath + testrelpath)
         rr.stdout should include(testbasepath + newEndpoint)
 
-        rr = wsk.api.list(basepathOrApiName = Some(testbasepath2))
+        rr = apiList(basepathOrApiName = Some(testbasepath2))
         rr.stdout should include("ok: APIs")
         rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
         rr.stdout should include(testbasepath2 + testrelpath)
         rr.stdout should include(testbasepath2 + newEndpoint)
       }
       finally {
-        var deleteresult = wsk.api.delete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
-        deleteresult = wsk.api.delete(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT)
+        var deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+        deleteresult = apiDelete(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT)
       }
     }
 
@@ -260,7 +355,7 @@
       // Be aware: full action name is close to being truncated by the 'list' command
       // e.g. /lime@us.ibm.com/CLI_APIGWTEST9a-c@t ion  is currently at the 40 char 'list' display max
       val testName = "CLI_APIGWTEST9"
-      val testbasepath = "/"+testName+"_bp"
+      val testbasepath = "/" + testName + "_bp"
       val testrelpath = "/path"
       val testnewrelpath = "/path_new"
       val testurlop = "get"
@@ -269,19 +364,148 @@
       try {
         println("cli user: "+cliuser+"; cli namespace: "+clinamespace)
 
-        var rr = wsk.api.create(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
         rr.stdout should include("ok: created API")
-        rr = wsk.api.list(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+        rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
         rr.stdout should include("ok: APIs")
         rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
         rr.stdout should include(testbasepath + testrelpath)
-        val deleteresult = wsk.api.delete(basepathOrApiName = testbasepath)
+        val deleteresult = apiDelete(basepathOrApiName = testbasepath)
         deleteresult.stdout should include("ok: deleted API")
       }
       finally {
-        val deleteresult = wsk.api.delete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+        val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
       }
     }
 
-}
+    it should "verify failed creation with invalid swagger doc as input" in {
+      val testName = "CLI_APIGWTEST10"
+      val testbasepath = "/" + testName + "_bp"
+      val testrelpath = "/path"
+      val testnewrelpath = "/path_new"
+      val testurlop = "get"
+      val testapiname = testName + " API Name"
+      val actionName = testName + "_action"
+      val swaggerPath = TestUtils.getTestApiGwFilename(s"testswaggerdocinvalid")
+      try {
+        var rr = apiCreate(swagger = Some(swaggerPath), expectedExitCode = ANY_ERROR_EXIT)
+        println("api create stdout: " + rr.stdout)
+        println("api create stderr: " + rr.stderr)
+        rr.stderr should include(s"Swagger file is invalid")
+      } finally {
+        val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+      }
+    }
 
+    it should "verify delete basepath/path " in {
+      val testName = "CLI_APIGWTEST11"
+      val testbasepath = "/" + testName + "_bp"
+      val testrelpath = "/path"
+      val testnewrelpath = "/path_new"
+      val testurlop = "get"
+      val testapiname = testName + " API Name"
+      val actionName = testName + "_action"
+      try {
+        var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        rr.stdout should include("ok: created API")
+        var rr2 = apiCreate(basepath = Some(testbasepath), relpath = Some(testnewrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        rr2.stdout should include("ok: created API")
+        rr = apiDelete(basepathOrApiName = testbasepath, relpath = Some(testrelpath))
+        rr.stdout should include("ok: deleted " + testrelpath +" from "+ testbasepath)
+        rr2 = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testnewrelpath))
+        rr2.stdout should include("ok: APIs")
+        rr2.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+        rr2.stdout should include(testbasepath + testnewrelpath)
+      } finally {
+        val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+      }
+    }
+
+    it should "verify delete single operation from existing API basepath/path/operation(s) " in {
+      val testName = "CLI_APIGWTEST12"
+      val testbasepath = "/" + testName + "_bp"
+      val testrelpath = "/path2"
+      val testnewrelpath = "/path_new"
+      val testurlop = "get"
+      val testurlop2 = "post"
+      val testapiname = testName + " API Name"
+      val actionName = testName + "_action"
+      try {
+        var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        rr.stdout should include("ok: created API")
+        rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop2), action = Some(actionName), apiname = Some(testapiname))
+        rr.stdout should include("ok: created API")
+        rr = apiList(basepathOrApiName = Some(testbasepath))
+        rr.stdout should include("ok: APIs")
+        rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+        rr.stdout should include(testbasepath + testrelpath)
+        rr = apiDelete(basepathOrApiName = testbasepath,relpath = Some(testrelpath), operation = Some(testurlop2))
+        rr.stdout should include("ok: deleted " + testrelpath + " " + "POST" +" from "+ testbasepath)
+        rr = apiList(basepathOrApiName = Some(testbasepath))
+        rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+      } finally {
+        val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+      }
+    }
+
+    it should "verify successful creation with complex swagger doc as input" in {
+      val testName = "CLI_APIGWTEST13"
+      val testbasepath = "/test1/v1"
+      val testrelpath = "/whisk.system/utils/echo"
+      val testrelpath2 = "/whisk.system/utils/split"
+      val testurlop = "get"
+      val testapiname = "/test1/v1"
+      val actionName = "test1a"
+      val swaggerPath = TestUtils.getTestApiGwFilename(s"testswaggerdoc2")
+      try {
+        var rr = apiCreate(swagger = Some(swaggerPath))
+        println("api create stdout: " + rr.stdout)
+        println("api create stderror: " + rr.stderr)
+        rr.stdout should include("ok: created API")
+        rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+        rr.stdout should include("ok: APIs")
+        // Actual CLI namespace will vary from local dev to automated test environments, so don't check
+        rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+        rr.stdout should include(testbasepath + testrelpath)
+        rr.stdout should include(testbasepath + testrelpath2)
+      } finally {
+        val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+      }
+    }
+
+    it should "verify successful creation and deletion with multiple base paths" in {
+      val testName = "CLI_APIGWTEST14"
+      val testbasepath = "/" + testName + "_bp"
+      val testbasepath2 = "/" + testName + "_bp2"
+      val testrelpath = "/path"
+      val testnewrelpath = "/path_new"
+      val testurlop = "get"
+      val testapiname = testName + " API Name"
+      val actionName = testName + "_action"
+      try {
+        var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        rr.stdout should include("ok: created API")
+        rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+        rr.stdout should include("ok: APIs")
+        rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+        rr.stdout should include(testbasepath + testrelpath)
+        rr = apiCreate(basepath = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname))
+        rr.stdout should include("ok: created API")
+        rr = apiList(basepathOrApiName = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop))
+        rr.stdout should include("ok: APIs")
+        rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+        rr.stdout should include(testbasepath2 + testrelpath)
+        rr = apiDelete(basepathOrApiName = testbasepath2)
+        rr.stdout should include("ok: deleted API")
+        rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+        rr.stdout should include("ok: APIs")
+        rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+")
+        rr.stdout should include(testbasepath + testrelpath)
+        rr = apiDelete(basepathOrApiName = testbasepath)
+        rr.stdout should include("ok: deleted API")
+      } finally {
+        var deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT)
+        deleteresult = apiDelete(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT)
+      }
+    }
+}