This is an automated email from the ASF dual-hosted git repository. csantanapr pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-cli.git
commit 76f855cea945a204f2ce8f13281d0517a06bc18e Author: Mark Deuser <mdeu...@us.ibm.com> AuthorDate: Wed May 10 16:18:04 2017 -0400 Add wsk cli support for importing/exporting API configuration in YAML format (#2209) * Update CLI to support YAML API configuration - `wsk api get --format yaml` - wsk api create --config-file api.yaml * YAML API configuration tests * Code review updates * Improve action throttling check --- .../scala/whisk/core/cli/test/ApiGwTests.scala | 1809 +++++++++++--------- 1 file changed, 963 insertions(+), 846 deletions(-) diff --git a/tests/src/test/scala/whisk/core/cli/test/ApiGwTests.scala b/tests/src/test/scala/whisk/core/cli/test/ApiGwTests.scala index 50ede51..eb63bac 100644 --- a/tests/src/test/scala/whisk/core/cli/test/ApiGwTests.scala +++ b/tests/src/test/scala/whisk/core/cli/test/ApiGwTests.scala @@ -18,9 +18,8 @@ package whisk.core.cli.test import java.io.File import java.time.Instant +import scala.collection.mutable.ArrayBuffer import scala.concurrent.duration._ -import spray.json._ -import spray.json.DefaultJsonProtocol._ import org.junit.runner.RunWith import org.scalatest.BeforeAndAfterAll import org.scalatest.junit.JUnitRunner @@ -51,10 +50,8 @@ class ApiGwTests // 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() + val invocationTimes = new ArrayBuffer[Instant]() // Custom CLI properties file val cliWskPropsFile = File.createTempFile("wskprops", ".tmp") @@ -64,39 +61,42 @@ class ApiGwTests * 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 - println(s"Action invokes ${cliCallCount}; per minute thottle limit ${maxActionsPerMin}") - if ( cliCallCount > (maxActionsPerMin - 10) ) { // Allow for some margin...10 invocations - println(s"Action invokes ${cliCallCount} close to exceeding 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) + def checkThrottle(maxInvocationsBeforeThrottle: Int = maxActionsPerMin) = { + var t = Instant.now + var tminus60 = t.minusSeconds(60) + var invocationsLast60Seconds = invocationTimes.filter(_.isAfter(tminus60)).sorted + var invocationCount = invocationsLast60Seconds.length + println(s"Action invokes within last minute: ${invocationCount}") + + if (invocationCount >= maxInvocationsBeforeThrottle) { + // Instead of waiting a fixed 60 seconds to settle the throttle, + // calculate a wait time that will clear out about half of the + // current invocations (assuming even distribution) from the + // next 60 second period. + var oldestInvocationInLast60Seconds = invocationsLast60Seconds.head + + // Take the oldest invocation time in this 60 second period. To clear + // this invocation from the next 60 second period, the wait time will be + // (60sec - oldest invocation's delta time away from the period end). + // This will clear all of the invocations from the next period at the + // expense of potentially waiting uncessarily long. Instead, this calculation + // halves the delta time as a compromise. + var throttleTime = 60.seconds.toMillis - ((t.toEpochMilli - oldestInvocationInLast60Seconds.toEpochMilli) /2) + println(s"Waiting ${throttleTime} milliseconds to settle the throttle") + Thread.sleep(throttleTime) + } + invocationTimes += Instant.now } /* * Create a CLI properties file for use by the tests */ override def beforeAll() = { - //cliWskPropsFile = File.createTempFile("wskprops", ".tmp") - cliWskPropsFile.deleteOnExit() - val wskprops = WskPropsV2(token = "SOME TOKEN") - wskprops.writeFile(cliWskPropsFile) - println(s"wsk temporary props file created here: ${cliWskPropsFile.getCanonicalPath()}") + //cliWskPropsFile = File.createTempFile("wskprops", ".tmp") + cliWskPropsFile.deleteOnExit() + val wskprops = WskPropsV2(token = "SOME TOKEN") + wskprops.writeFile(cliWskPropsFile) + println(s"wsk temporary props file created here: ${cliWskPropsFile.getCanonicalPath()}") } /* @@ -104,101 +104,107 @@ class ApiGwTests * 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) - } + // Check and settle the throttle so that this test won't cause issues with and follow on tests + checkThrottle(30) } def apiCreateExperimental( - 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 = { + 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.apiexperimental.create(basepath, relpath, operation, action, apiname, swagger, expectedExitCode) } def apiListExperimental( - 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 = { + 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.apiexperimental.list(basepathOrApiName, relpath, operation, limit, since, full, expectedExitCode) } def apiGetExperimental( - basepathOrApiName: Option[String] = None, - full: Option[Boolean] = None, - expectedExitCode: Int = SUCCESS_EXIT): RunResult = { + basepathOrApiName: Option[String] = None, + full: Option[Boolean] = None, + expectedExitCode: Int = SUCCESS_EXIT): RunResult = { + checkThrottle() wsk.apiexperimental.get(basepathOrApiName, full, expectedExitCode) } def apiDeleteExperimental( - basepathOrApiName: String, - relpath: Option[String] = None, - operation: Option[String] = None, - expectedExitCode: Int = SUCCESS_EXIT): RunResult = { + basepathOrApiName: String, + relpath: Option[String] = None, + operation: Option[String] = None, + expectedExitCode: Int = SUCCESS_EXIT): RunResult = { + checkThrottle() wsk.apiexperimental.delete(basepathOrApiName, relpath, operation, expectedExitCode) } 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())): RunResult = { + 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())): RunResult = { + checkThrottle() wsk.api.create(basepath, relpath, operation, action, apiname, swagger, responsetype, expectedExitCode, cliCfgFile) } 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, - cliCfgFile: Option[String] = Some(cliWskPropsFile.getCanonicalPath())): RunResult = { + 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, + cliCfgFile: Option[String] = Some(cliWskPropsFile.getCanonicalPath())): RunResult = { + checkThrottle() wsk.api.list(basepathOrApiName, relpath, operation, limit, since, full, expectedExitCode, cliCfgFile) } def apiGet( - basepathOrApiName: Option[String] = None, - full: Option[Boolean] = None, - expectedExitCode: Int = SUCCESS_EXIT, - cliCfgFile: Option[String] = Some(cliWskPropsFile.getCanonicalPath())): RunResult = { + 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) + 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 = { + basepathOrApiName: String, + relpath: Option[String] = None, + operation: Option[String] = None, + expectedExitCode: Int = SUCCESS_EXIT, + cliCfgFile: Option[String] = Some(cliWskPropsFile.getCanonicalPath())): RunResult = { + checkThrottle() wsk.api.delete(basepathOrApiName, relpath, operation, expectedExitCode, cliCfgFile) } - behavior of "Wsk api-experimental" + behavior of "Wsk api-experimental" it should "reject an api commands with an invalid path parameter" in { val badpath = "badpath" @@ -214,33 +220,33 @@ class ApiGwTests } it should "verify full list output" in { - val testName = "CLI_APIGWTEST_RO1" - val testbasepath = "/" + testName + "_bp" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName + " API Name" - val actionName = testName + "_action" - try { - println("cli user: " + cliuser + "; cli namespace: " + clinamespace) - - var rr = apiCreateExperimental(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 = apiListExperimental(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), full = Some(true)) - println("api list: " + rr.stdout) - rr.stdout should include("ok: APIs") - rr.stdout should include regex (s"Action:\\s+/${clinamespace}/${actionName}\n") - rr.stdout should include regex (s"Verb:\\s+${testurlop}\n") - rr.stdout should include regex (s"Base path:\\s+${testbasepath}\n") - rr.stdout should include regex (s"Path:\\s+${testrelpath}\n") - rr.stdout should include regex (s"API Name:\\s+${testapiname}\n") - rr.stdout should include regex (s"URL:\\s+") - rr.stdout should include(testbasepath + testrelpath) - } - finally { - val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath) - } + val testName = "CLI_APIGWTEST_RO1" + val testbasepath = "/" + testName + "_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName + " API Name" + val actionName = testName + "_action" + try { + println("cli user: " + cliuser + "; cli namespace: " + clinamespace) + + var rr = apiCreateExperimental(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 = apiListExperimental(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), full = Some(true)) + println("api list: " + rr.stdout) + rr.stdout should include("ok: APIs") + rr.stdout should include regex (s"Action:\\s+/${clinamespace}/${actionName}\n") + rr.stdout should include regex (s"Verb:\\s+${testurlop}\n") + rr.stdout should include regex (s"Base path:\\s+${testbasepath}\n") + rr.stdout should include regex (s"Path:\\s+${testrelpath}\n") + rr.stdout should include regex (s"API Name:\\s+${testapiname}\n") + rr.stdout should include regex (s"URL:\\s+") + rr.stdout should include(testbasepath + testrelpath) + } + finally { + val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath) + } } it should "verify successful creation and deletion of a new API" in { @@ -289,792 +295,903 @@ class ApiGwTests } it should "verify delete API name " in { - val testName = "CLI_APIGWTEST4" - val testbasepath = "/"+testName+"_bp" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - try { - var rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiDeleteExperimental(basepathOrApiName = testapiname) - rr.stdout should include("ok: deleted API") - } - finally { - val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - } + val testName = "CLI_APIGWTEST4" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + try { + var rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiDeleteExperimental(basepathOrApiName = testapiname) + rr.stdout should include("ok: deleted API") + } + finally { + val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } it should "verify delete API basepath " in { - val testName = "CLI_APIGWTEST5" - val testbasepath = "/"+testName+"_bp" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - try { - var rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiDeleteExperimental(basepathOrApiName = testbasepath) - rr.stdout should include("ok: deleted API") - } - finally { - val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - } + val testName = "CLI_APIGWTEST5" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + try { + var rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiDeleteExperimental(basepathOrApiName = testbasepath) + rr.stdout should include("ok: deleted API") + } + finally { + val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } it should "verify adding endpoints to existing api" in { - val testName = "CLI_APIGWTEST6" - val testbasepath = "/"+testName+"_bp" - val testrelpath = "/path2" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - val newEndpoint = "/newEndpoint" - try { - var rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - } + val testName = "CLI_APIGWTEST6" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path2" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + val newEndpoint = "/newEndpoint" + try { + var rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } it should "verify successful creation with swagger doc as input" in { - // NOTE: These values must match the swagger file contents - val testName = "CLI_APIGWTEST7" - val testbasepath = "/"+testName+"_bp" - val testrelpath = "/path" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - val swaggerPath = TestUtils.getTestApiGwFilename("testswaggerdoc1") - try { - var rr = apiCreateExperimental(swagger = Some(swaggerPath)) - rr.stdout should include("ok: created API") - rr = apiListExperimental(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop)) - println("list stdout: "+rr.stdout) - println("list stderr: "+rr.stderr) - rr.stdout should include("ok: APIs") - // Actual CLI namespace will vary from local dev to automated test environments, so don't check - rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") - rr.stdout should include(testbasepath + testrelpath) - } - finally { - val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - } + // NOTE: These values must match the swagger file contents + val testName = "CLI_APIGWTEST7" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + val swaggerPath = TestUtils.getTestApiGwFilename("testswaggerdoc1") + try { + var rr = apiCreateExperimental(swagger = Some(swaggerPath)) + rr.stdout should include("ok: created API") + rr = apiListExperimental(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop)) + println("list stdout: "+rr.stdout) + println("list stderr: "+rr.stderr) + rr.stdout should include("ok: APIs") + // Actual CLI namespace will vary from local dev to automated test environments, so don't check + rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr.stdout should include(testbasepath + testrelpath) + } + finally { + val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } it should "verify adding endpoints to two existing apis" in { - val testName = "CLI_APIGWTEST8" - val testbasepath = "/"+testName+"_bp" - val testbasepath2 = "/"+testName+"_bp2" - val testrelpath = "/path2" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - val newEndpoint = "/newEndpoint" - try { - var rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiCreateExperimental(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 = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName)) - rr.stdout should include("ok: created API") - rr = apiCreateExperimental(basepath = Some(testbasepath2), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName)) - rr.stdout should include("ok: created API") - - rr = apiListExperimental(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 = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT) - } + val testName = "CLI_APIGWTEST8" + val testbasepath = "/"+testName+"_bp" + val testbasepath2 = "/"+testName+"_bp2" + val testrelpath = "/path2" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + val newEndpoint = "/newEndpoint" + try { + var rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiCreateExperimental(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 = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName)) + rr.stdout should include("ok: created API") + rr = apiCreateExperimental(basepath = Some(testbasepath2), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName)) + rr.stdout should include("ok: created API") + + rr = apiListExperimental(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 = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT) + } } it should "verify successful creation of a new API using an action name using all allowed characters" in { - // Be aware: full action name is close to being truncated by the 'list' command - // e.g. /l...@us.ibm.com/CLI_APIGWTEST9a-c@t ion is currently at the 40 char 'list' display max - val testName = "CLI_APIGWTEST9" - val testbasepath = "/" + testName + "_bp" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"a-c@t ion" - try { - println("cli user: "+cliuser+"; cli namespace: "+clinamespace) - - var rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath) - deleteresult.stdout should include("ok: deleted API") - } - finally { - val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - } + // Be aware: full action name is close to being truncated by the 'list' command + // e.g. /l...@us.ibm.com/CLI_APIGWTEST9a-c@t ion is currently at the 40 char 'list' display max + val testName = "CLI_APIGWTEST9" + val testbasepath = "/" + testName + "_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"a-c@t ion" + try { + println("cli user: "+cliuser+"; cli namespace: "+clinamespace) + + var rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath) + deleteresult.stdout should include("ok: deleted API") + } + finally { + val deleteresult = apiDeleteExperimental(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 = apiCreateExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - } + 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 = apiCreateExperimental(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 = apiDeleteExperimental(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 = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - var rr2 = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testnewrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr2.stdout should include("ok: created API") - rr = apiDeleteExperimental(basepathOrApiName = testbasepath, relpath = Some(testrelpath)) - rr.stdout should include("ok: deleted " + testrelpath +" from "+ testbasepath) - rr2 = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - } + 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 = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + var rr2 = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testnewrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr2.stdout should include("ok: created API") + rr = apiDeleteExperimental(basepathOrApiName = testbasepath, relpath = Some(testrelpath)) + rr.stdout should include("ok: deleted " + testrelpath +" from "+ testbasepath) + rr2 = apiListExperimental(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 = apiDeleteExperimental(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 = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop2), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath,relpath = Some(testrelpath), operation = Some(testurlop2)) - rr.stdout should include("ok: deleted " + testrelpath + " " + "POST" +" from "+ testbasepath) - rr = apiListExperimental(basepathOrApiName = Some(testbasepath)) - rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") - } finally { - val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - } + 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 = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop2), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath,relpath = Some(testrelpath), operation = Some(testurlop2)) + rr.stdout should include("ok: deleted " + testrelpath + " " + "POST" +" from "+ testbasepath) + rr = apiListExperimental(basepathOrApiName = Some(testbasepath)) + rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + } finally { + val deleteresult = apiDeleteExperimental(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 = apiCreateExperimental(swagger = Some(swaggerPath)) - println("api create stdout: " + rr.stdout) - println("api create stderror: " + rr.stderr) - rr.stdout should include("ok: created API") - rr = apiListExperimental(basepathOrApiName = Some(testbasepath)) - rr.stdout should include("ok: APIs") - // Actual CLI namespace will vary from local dev to automated test environments, so don't check - rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") - rr.stdout should include(testbasepath + testrelpath) - rr.stdout should include(testbasepath + testrelpath2) - } finally { - val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - } + 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 = apiCreateExperimental(swagger = Some(swaggerPath)) + println("api create stdout: " + rr.stdout) + println("api create stderror: " + rr.stderr) + rr.stdout should include("ok: created API") + rr = apiListExperimental(basepathOrApiName = Some(testbasepath)) + rr.stdout should include("ok: APIs") + // Actual CLI namespace will vary from local dev to automated test environments, so don't check + rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr.stdout should include(testbasepath + testrelpath) + rr.stdout should include(testbasepath + testrelpath2) + } finally { + val deleteresult = apiDeleteExperimental(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 = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiListExperimental(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 = apiCreateExperimental(basepath = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath2) - rr.stdout should include("ok: deleted API") - rr = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath) - rr.stdout should include("ok: deleted API") - } finally { - var deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT) - } + 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 = apiCreateExperimental(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiListExperimental(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 = apiCreateExperimental(basepath = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath2) + rr.stdout should include("ok: deleted API") + rr = apiListExperimental(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 = apiDeleteExperimental(basepathOrApiName = testbasepath) + rr.stdout should include("ok: deleted API") + } finally { + var deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT) + } } - behavior of "Wsk api" - - it should "reject an api commands with an invalid path parameter" in { - val badpath = "badpath" - - var rr = apiCreate(basepath = Some("/basepath"), relpath = Some(badpath), operation = Some("GET"), action = Some("action"), expectedExitCode = ANY_ERROR_EXIT) - rr.stderr should include (s"'${badpath}' must begin with '/'") - - rr = apiDelete(basepathOrApiName = "/basepath", relpath = Some(badpath), operation = Some("GET"), expectedExitCode = ANY_ERROR_EXIT) - rr.stderr should include (s"'${badpath}' must begin with '/'") - - rr = apiList(basepathOrApiName = Some("/basepath"), relpath = Some(badpath), operation = Some("GET"), expectedExitCode = ANY_ERROR_EXIT) - rr.stderr should include (s"'${badpath}' must begin with '/'") - } - - it should "verify full list output" in { - val testName = "CLI_APIGWTEST_RO1" - val testbasepath = "/" + testName + "_bp" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName + " API Name" - val actionName = testName + "_action" - try { - println("cli user: " + cliuser + "; cli namespace: " + clinamespace) - // Create the action for the API. It must be a "web-action" action. - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson)) - - var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - println("api create: " + rr.stdout) - rr.stdout should include("ok: created API") - rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), full = Some(true)) - println("api list: " + rr.stdout) - rr.stdout should include("ok: APIs") - rr.stdout should include regex (s"Action:\\s+/${clinamespace}/${actionName}\n") - rr.stdout should include regex (s"Verb:\\s+${testurlop}\n") - rr.stdout should include regex (s"Base path:\\s+${testbasepath}\n") - rr.stdout should include regex (s"Path:\\s+${testrelpath}\n") - rr.stdout should include regex (s"API Name:\\s+${testapiname}\n") - rr.stdout should include regex (s"URL:\\s+") - rr.stdout should include(testbasepath + testrelpath) - } - finally { - val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - val deleteresult = apiDelete(basepathOrApiName = testbasepath) - } - } - - it should "verify successful creation and deletion of a new API" in { - val testName = "CLI_APIGWTEST1" - val testbasepath = "/"+testName+"_bp" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - try { - println("cli user: "+cliuser+"; cli namespace: "+clinamespace) - - // Create the action for the API. It must be a "web-action" action. - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson)) - - var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop)) - rr.stdout should include("ok: APIs") - rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") - rr.stdout should include(testbasepath + testrelpath) - val deleteresult = apiDelete(basepathOrApiName = testbasepath) - deleteresult.stdout should include("ok: deleted API") - } - finally { - val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - } - } - - it should "verify get API name " in { - val testName = "CLI_APIGWTEST3" - val testbasepath = "/"+testName+"_bp" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - try { - // Create the action for the API. It must be a "web-action" action. - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson)) - - var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiGet(basepathOrApiName = Some(testapiname)) - rr.stdout should include(testbasepath) - rr.stdout should include(s"${actionName}") - rr.stdout should include regex (""""cors":\s*\{\s*\n\s*"enabled":\s*true""") - rr.stdout should include regex (s""""target-url":\\s+.*${actionName}.json""") - } - finally { - val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + behavior of "Wsk api" + + it should "reject an api commands with an invalid path parameter" in { + val badpath = "badpath" + + var rr = apiCreate(basepath = Some("/basepath"), relpath = Some(badpath), operation = Some("GET"), action = Some("action"), expectedExitCode = ANY_ERROR_EXIT) + rr.stderr should include (s"'${badpath}' must begin with '/'") + + rr = apiDelete(basepathOrApiName = "/basepath", relpath = Some(badpath), operation = Some("GET"), expectedExitCode = ANY_ERROR_EXIT) + rr.stderr should include (s"'${badpath}' must begin with '/'") + + rr = apiList(basepathOrApiName = Some("/basepath"), relpath = Some(badpath), operation = Some("GET"), expectedExitCode = ANY_ERROR_EXIT) + rr.stderr should include (s"'${badpath}' must begin with '/'") } - } - - it should "verify delete API name " in { - val testName = "CLI_APIGWTEST4" - val testbasepath = "/"+testName+"_bp" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - try { - // Create the action for the API. It must be a "web-action" action. - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson)) - - var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiDelete(basepathOrApiName = testapiname) - rr.stdout should include("ok: deleted API") + + it should "verify full list output" in { + val testName = "CLI_APIGWTEST_RO1" + val testbasepath = "/" + testName + "_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName + " API Name" + val actionName = testName + "_action" + try { + println("cli user: " + cliuser + "; cli namespace: " + clinamespace) + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + println("api create: " + rr.stdout) + rr.stdout should include("ok: created API") + rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), full = Some(true)) + println("api list: " + rr.stdout) + rr.stdout should include("ok: APIs") + rr.stdout should include regex (s"Action:\\s+/${clinamespace}/${actionName}\n") + rr.stdout should include regex (s"Verb:\\s+${testurlop}\n") + rr.stdout should include regex (s"Base path:\\s+${testbasepath}\n") + rr.stdout should include regex (s"Path:\\s+${testrelpath}\n") + rr.stdout should include regex (s"API Name:\\s+${testapiname}\n") + rr.stdout should include regex (s"URL:\\s+") + rr.stdout should include(testbasepath + testrelpath) + } + finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + val deleteresult = apiDelete(basepathOrApiName = testbasepath) + } } - finally { - val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + + it should "verify successful creation and deletion of a new API" in { + val testName = "CLI_APIGWTEST1" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + try { + println("cli user: "+cliuser+"; cli namespace: "+clinamespace) + + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop)) + rr.stdout should include("ok: APIs") + rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr.stdout should include(testbasepath + testrelpath) + val deleteresult = apiDelete(basepathOrApiName = testbasepath) + deleteresult.stdout should include("ok: deleted API") + } + finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - } - - it should "verify delete API basepath " in { - val testName = "CLI_APIGWTEST5" - val testbasepath = "/"+testName+"_bp" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - try { - // Create the action for the API. It must be a "web-action" action. - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson)) - - var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiDelete(basepathOrApiName = testbasepath) - rr.stdout should include("ok: deleted API") + + it should "verify get API name " in { + val testName = "CLI_APIGWTEST3" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + try { + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiGet(basepathOrApiName = Some(testapiname)) + rr.stdout should include(testbasepath) + rr.stdout should include(s"${actionName}") + rr.stdout should include regex (""""cors":\s*\{\s*\n\s*"enabled":\s*true""") + rr.stdout should include regex (s""""target-url":\\s+.*${actionName}.json""") + } + finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - finally { - val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + + it should "verify delete API name " in { + val testName = "CLI_APIGWTEST4" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + try { + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiDelete(basepathOrApiName = testapiname) + rr.stdout should include("ok: deleted API") + } + finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - } - - it should "verify adding endpoints to existing api" in { - val testName = "CLI_APIGWTEST6" - val testbasepath = "/"+testName+"_bp" - val testrelpath = "/path2" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - val newEndpoint = "/newEndpoint" - try { - // Create the action for the API. It must be a "web-action" action. - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson)) - - var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiCreate(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiList(basepathOrApiName = Some(testbasepath)) - rr.stdout should include("ok: APIs") - rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") - rr.stdout should include(testbasepath + testrelpath) - rr.stdout should include(testbasepath + newEndpoint) + + it should "verify delete API basepath " in { + val testName = "CLI_APIGWTEST5" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + try { + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiDelete(basepathOrApiName = testbasepath) + rr.stdout should include("ok: deleted API") + } + finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - finally { - val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + + it should "verify adding endpoints to existing api" in { + val testName = "CLI_APIGWTEST6" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path2" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + val newEndpoint = "/newEndpoint" + try { + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiCreate(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiList(basepathOrApiName = Some(testbasepath)) + rr.stdout should include("ok: APIs") + rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr.stdout should include(testbasepath + testrelpath) + rr.stdout should include(testbasepath + newEndpoint) + } + finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - } - - it should "verify successful creation with swagger doc as input" in { - // NOTE: These values must match the swagger file contents - val testName = "CLI_APIGWTEST7" - val testbasepath = "/"+testName+"_bp" - val testrelpath = "/path" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - val swaggerPath = TestUtils.getTestApiGwFilename("testswaggerdoc1V2") - try { - var rr = apiCreate(swagger = Some(swaggerPath)) - rr.stdout should include("ok: created API") - rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop)) - println("list stdout: "+rr.stdout) - println("list stderr: "+rr.stderr) - rr.stdout should include("ok: APIs") - // Actual CLI namespace will vary from local dev to automated test environments, so don't check - rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") - rr.stdout should include(testbasepath + testrelpath) + + it should "verify successful creation with swagger doc as input" in { + // NOTE: These values must match the swagger file contents + val testName = "CLI_APIGWTEST7" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + val swaggerPath = TestUtils.getTestApiGwFilename("testswaggerdoc1V2") + try { + var rr = apiCreate(swagger = Some(swaggerPath)) + rr.stdout should include("ok: created API") + rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop)) + println("list stdout: "+rr.stdout) + println("list stderr: "+rr.stderr) + rr.stdout should include("ok: APIs") + // Actual CLI namespace will vary from local dev to automated test environments, so don't check + rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr.stdout should include(testbasepath + testrelpath) + } + finally { + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - finally { - val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + + it should "verify adding endpoints to two existing apis" in { + val testName = "CLI_APIGWTEST8" + val testbasepath = "/"+testName+"_bp" + val testbasepath2 = "/"+testName+"_bp2" + val testrelpath = "/path2" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + val newEndpoint = "/newEndpoint" + try { + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiCreate(basepath = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + + // Update both APIs - each with a new endpoint + rr = apiCreate(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName)) + rr.stdout should include("ok: created API") + rr = apiCreate(basepath = Some(testbasepath2), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName)) + rr.stdout should include("ok: created API") + + rr = apiList(basepathOrApiName = Some(testbasepath)) + rr.stdout should include("ok: APIs") + rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr.stdout should include(testbasepath + testrelpath) + rr.stdout should include(testbasepath + newEndpoint) + + rr = apiList(basepathOrApiName = Some(testbasepath2)) + rr.stdout should include("ok: APIs") + rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr.stdout should include(testbasepath2 + testrelpath) + rr.stdout should include(testbasepath2 + newEndpoint) + } + finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + var deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + deleteresult = apiDelete(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT) + } } - } - - it should "verify adding endpoints to two existing apis" in { - val testName = "CLI_APIGWTEST8" - val testbasepath = "/"+testName+"_bp" - val testbasepath2 = "/"+testName+"_bp2" - val testrelpath = "/path2" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - val newEndpoint = "/newEndpoint" - try { - // Create the action for the API. It must be a "web-action" action. - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson)) - - var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiCreate(basepath = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - - // Update both APIs - each with a new endpoint - rr = apiCreate(basepath = Some(testbasepath), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName)) - rr.stdout should include("ok: created API") - rr = apiCreate(basepath = Some(testbasepath2), relpath = Some(newEndpoint), operation = Some(testurlop), action = Some(actionName)) - rr.stdout should include("ok: created API") - - rr = apiList(basepathOrApiName = Some(testbasepath)) - rr.stdout should include("ok: APIs") - rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") - rr.stdout should include(testbasepath + testrelpath) - rr.stdout should include(testbasepath + newEndpoint) - - rr = apiList(basepathOrApiName = Some(testbasepath2)) - rr.stdout should include("ok: APIs") - rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") - rr.stdout should include(testbasepath2 + testrelpath) - rr.stdout should include(testbasepath2 + newEndpoint) + + it should "verify successful creation of a new API using an action name using all allowed characters" in { + // Be aware: full action name is close to being truncated by the 'list' command + // e.g. /l...@us.ibm.com/CLI_APIGWTEST9a-c@t ion is currently at the 40 char 'list' display max + val testName = "CLI_APIGWTEST9" + val testbasepath = "/" + testName + "_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"a-c@t ion" + try { + println("cli user: "+cliuser+"; cli namespace: "+clinamespace) + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop)) + rr.stdout should include("ok: APIs") + rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr.stdout should include(testbasepath + testrelpath) + val deleteresult = apiDelete(basepathOrApiName = testbasepath) + deleteresult.stdout should include("ok: deleted API") + } + finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - finally { - val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - var deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - deleteresult = apiDelete(basepathOrApiName = testbasepath2, 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 successful creation of a new API using an action name using all allowed characters" in { - // Be aware: full action name is close to being truncated by the 'list' command - // e.g. /l...@us.ibm.com/CLI_APIGWTEST9a-c@t ion is currently at the 40 char 'list' display max - val testName = "CLI_APIGWTEST9" - val testbasepath = "/" + testName + "_bp" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"a-c@t ion" - try { - println("cli user: "+cliuser+"; cli namespace: "+clinamespace) - // Create the action for the API. It must be a "web-action" action. - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson)) - - var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) - rr.stdout should include("ok: created API") - rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop)) - rr.stdout should include("ok: APIs") - rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") - rr.stdout should include(testbasepath + testrelpath) - val deleteresult = apiDelete(basepathOrApiName = testbasepath) - deleteresult.stdout should include("ok: deleted API") + + it should "verify delete basepath/path " in { + val testName = "CLI_APIGWTEST11" + val testbasepath = "/" + testName + "_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName + " API Name" + val actionName = testName + "_action" + try { + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + var rr2 = apiCreate(basepath = Some(testbasepath), relpath = Some(testnewrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr2.stdout should include("ok: created API") + rr = apiDelete(basepathOrApiName = testbasepath, relpath = Some(testrelpath)) + rr.stdout should include("ok: deleted " + testrelpath +" from "+ testbasepath) + rr2 = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testnewrelpath)) + rr2.stdout should include("ok: APIs") + rr2.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr2.stdout should include(testbasepath + testnewrelpath) + } finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - finally { - val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - 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 { + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop2), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiList(basepathOrApiName = Some(testbasepath)) + rr.stdout should include("ok: APIs") + rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr.stdout should include(testbasepath + testrelpath) + rr = apiDelete(basepathOrApiName = testbasepath,relpath = Some(testrelpath), operation = Some(testurlop2)) + rr.stdout should include("ok: deleted " + testrelpath + " " + "POST" +" from "+ testbasepath) + rr = apiList(basepathOrApiName = Some(testbasepath)) + rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + } finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, 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 successful creation with complex swagger doc as input" in { + val testName = "CLI_APIGWTEST13" + val testbasepath = "/test1/v1" + val testrelpath = "/whisk_system/utils/echo" + val testrelpath2 = "/whisk_system/utils/split" + val testurlop = "get" + val testapiname = testName + " API Name" + val actionName = "test1a" + val swaggerPath = TestUtils.getTestApiGwFilename(s"testswaggerdoc2V2") + try { + var rr = apiCreate(swagger = Some(swaggerPath)) + println("api create stdout: " + rr.stdout) + println("api create stderror: " + rr.stderr) + rr.stdout should include("ok: created API") + rr = apiList(basepathOrApiName = Some(testbasepath)) + rr.stdout should include("ok: APIs") + // Actual CLI namespace will vary from local dev to automated test environments, so don't check + rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr.stdout should include(testbasepath + testrelpath) + rr.stdout should include(testbasepath + testrelpath2) + } finally { + 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 { - // Create the action for the API. It must be a "web-action" action. - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson)) - - 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 finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - 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 { + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname)) + rr.stdout should include("ok: created API") + rr = apiList(basepathOrApiName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop)) + rr.stdout should include("ok: APIs") + rr.stdout should include regex (s"/${clinamespace}/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr.stdout should include(testbasepath + testrelpath) + rr = apiCreate(basepath = Some(testbasepath2), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(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 { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + var deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + deleteresult = apiDelete(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT) + } } - } - - it should "verify delete single operation from existing API basepath/path/operation(s) " in { - val testName = "CLI_APIGWTEST12" - val testbasepath = "/" + testName + "_bp" - val testrelpath = "/path2" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testurlop2 = "post" - val testapiname = testName + " API Name" - val actionName = testName + "_action" - try { - // Create the action for the API. It must be a "web-action" action. - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson)) - - 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 finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + + it should "reject an API created with a non-existent action" in { + val testName = "CLI_APIGWTEST15" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + try { + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname), expectedExitCode = ANY_ERROR_EXIT) + rr.stderr should include("does not exist") + } + finally { + val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - } - - it should "verify successful creation with complex swagger doc as input" in { - val testName = "CLI_APIGWTEST13" - val testbasepath = "/test1/v1" - val testrelpath = "/whisk_system/utils/echo" - val testrelpath2 = "/whisk_system/utils/split" - val testurlop = "get" - val testapiname = testName + " API Name" - val actionName = "test1a" - val swaggerPath = TestUtils.getTestApiGwFilename(s"testswaggerdoc2V2") - try { - var rr = apiCreate(swagger = Some(swaggerPath)) - println("api create stdout: " + rr.stdout) - println("api create stderror: " + rr.stderr) - rr.stdout should include("ok: created API") - rr = apiList(basepathOrApiName = Some(testbasepath)) - rr.stdout should include("ok: APIs") - // Actual CLI namespace will vary from local dev to automated test environments, so don't check - rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") - rr.stdout should include(testbasepath + testrelpath) - rr.stdout should include(testbasepath + testrelpath2) - } finally { - val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + + it should "reject an API created with an action that is not a web action" in { + val testName = "CLI_APIGWTEST16" + val testbasepath = "/" + testName + "_bp" + val testbasepath2 = "/" + testName + "_bp2" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName + " API Name" + val actionName = testName + "_action" + try { + // Create the action for the API. It must NOT be a "web-action" action for this test + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT) + + var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname), expectedExitCode = ANY_ERROR_EXIT) + rr.stderr should include("is not a web action") + } finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + var 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 { - // Create the action for the API. It must be a "web-action" action. - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson)) - - 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 { - val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - var deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) - deleteresult = apiDelete(basepathOrApiName = testbasepath2, expectedExitCode = DONTCARE_EXIT) + + it should "verify API with http response type " in { + val testName = "CLI_APIGWTEST17" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + val responseType = "http" + try { + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate( + basepath = Some(testbasepath), + relpath = Some(testrelpath), + operation = Some(testurlop), + action = Some(actionName), + apiname = Some(testapiname), + responsetype = Some(responseType) + ) + rr.stdout should include("ok: created API") + rr = apiGet(basepathOrApiName = Some(testapiname)) + rr.stdout should include(testbasepath) + rr.stdout should include(s"${actionName}") + rr.stdout should include regex (s""""target-url":\\s+.*${actionName}.${responseType}""") + } + finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - } - - it should "reject an API created with a non-existent action" in { - val testName = "CLI_APIGWTEST15" - val testbasepath = "/"+testName+"_bp" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - try { - var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname), expectedExitCode = ANY_ERROR_EXIT) - rr.stderr should include("API action does not exist") + + it should "reject API export when export type is invalid" in { + val testName = "CLI_APIGWTEST18" + val testbasepath = "/"+testName+"_bp" + + var rr = apiGet(basepathOrApiName = Some(testbasepath), format = Some("BadType"), expectedExitCode = ANY_ERROR_EXIT) + rr.stderr should include("Invalid format type") } - finally { - val deleteresult = apiDeleteExperimental(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + + it should "successfully export an API in YAML format" in { + val testName = "CLI_APIGWTEST19" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + val responseType = "http" + try { + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate( + basepath = Some(testbasepath), + relpath = Some(testrelpath), + operation = Some(testurlop), + action = Some(actionName), + apiname = Some(testapiname), + responsetype = Some(responseType) + ) + rr.stdout should include("ok: created API") + rr = apiGet(basepathOrApiName = Some(testapiname), format = Some("yaml")) + rr.stdout should include (s"basePath: ${testbasepath}") + } + finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - } - - it should "reject an API created with an action that is not a web action" in { - val testName = "CLI_APIGWTEST16" - val testbasepath = "/" + testName + "_bp" - val testbasepath2 = "/" + testName + "_bp2" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName + " API Name" - val actionName = testName + "_action" - try { - // Create the action for the API. It must NOT be a "web-action" action for this test - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT) - - var rr = apiCreate(basepath = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop), action = Some(actionName), apiname = Some(testapiname), expectedExitCode = ANY_ERROR_EXIT) - rr.stderr should include("is not a web action") - } finally { - val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - var deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + + it should "successfully export an API when JSON format is explcitly specified" in { + val testName = "CLI_APIGWTEST20" + val testbasepath = "/"+testName+"_bp" + val testrelpath = "/path" + val testnewrelpath = "/path_new" + val testurlop = "get" + val testapiname = testName+" API Name" + val actionName = testName+"_action" + val responseType = "http" + try { + // Create the action for the API. It must be a "web-action" action. + val file = TestUtils.getTestActionFilename(s"echo.js") + wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, web = Some("true")) + + var rr = apiCreate( + basepath = Some(testbasepath), + relpath = Some(testrelpath), + operation = Some(testurlop), + action = Some(actionName), + apiname = Some(testapiname), + responsetype = Some(responseType) + ) + rr.stdout should include("ok: created API") + rr = apiGet(basepathOrApiName = Some(testapiname), format = Some("json")) + rr.stdout should include(testbasepath) + rr.stdout should include(s"${actionName}") + rr.stdout should include regex (s""""target-url":\\s+.*${actionName}.${responseType}""") + } + finally { + val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - } - - it should "verify API with http response type " in { - val testName = "CLI_APIGWTEST17" - val testbasepath = "/"+testName+"_bp" - val testrelpath = "/path" - val testnewrelpath = "/path_new" - val testurlop = "get" - val testapiname = testName+" API Name" - val actionName = testName+"_action" - val responseType = "http" - try { - // Create the action for the API. It must be a "web-action" action. - val file = TestUtils.getTestActionFilename(s"echo.js") - wsk.action.create(name = actionName, artifact = Some(file), expectedExitCode = SUCCESS_EXIT, annotations = Map("web-export" -> true.toJson)) - - var rr = apiCreate( - basepath = Some(testbasepath), - relpath = Some(testrelpath), - operation = Some(testurlop), - action = Some(actionName), - apiname = Some(testapiname), - responsetype = Some(responseType) - ) - rr.stdout should include("ok: created API") - rr = apiGet(basepathOrApiName = Some(testapiname)) - rr.stdout should include(testbasepath) - rr.stdout should include(s"${actionName}") - rr.stdout should include regex (s""""target-url":\\s+.*${actionName}.${responseType}""") + + it should "successfully create an API from a YAML formatted API configuration file" in { + val testName = "CLI_APIGWTEST21" + val testbasepath = "/bp" + val testrelpath = "/rp" + val testurlop = "get" + val testapiname = testbasepath + val actionName = "webhttpecho" + val swaggerPath = TestUtils.getTestApiGwFilename(s"local.api.yaml") + try { + var rr = apiCreate(swagger = Some(swaggerPath)) + println("api create stdout: " + rr.stdout) + println("api create stderror: " + rr.stderr) + rr.stdout should include("ok: created API") + rr = apiList(basepathOrApiName = Some(testbasepath)) + rr.stdout should include("ok: APIs") + // Actual CLI namespace will vary from local dev to automated test environments, so don't check + rr.stdout should include regex (s"/[@\\w._\\-]+/${actionName}\\s+${testurlop}\\s+${testapiname}\\s+") + rr.stdout should include(testbasepath + testrelpath) + } finally { + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - finally { - val finallydeleteActionResult = wsk.action.delete(name = actionName, expectedExitCode = DONTCARE_EXIT) - val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + + it should "reject creation of an API from invalid YAML formatted API configuration file" in { + val testName = "CLI_APIGWTEST22" + val testbasepath = "/bp" + val swaggerPath = TestUtils.getTestApiGwFilename(s"local.api.bad.yaml") + try { + var rr = apiCreate(swagger = Some(swaggerPath), expectedExitCode = ANY_ERROR_EXIT) + println("api create stdout: " + rr.stdout) + println("api create stderror: " + rr.stderr) + rr.stderr should include("Unable to parse YAML configuration file") + } finally { + val deleteresult = apiDelete(basepathOrApiName = testbasepath, expectedExitCode = DONTCARE_EXIT) + } } - } } -- To stop receiving notification emails like this one, please contact "commits@openwhisk.apache.org" <commits@openwhisk.apache.org>.