You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by cs...@apache.org on 2017/06/26 15:59:53 UTC
[incubator-openwhisk-cli] 13/36: API GW V2 - Update backend actions
(#2067)
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 774291e6bd74e32d135702c2b3b509e50f1cc66f
Author: Mark Deuser <md...@us.ibm.com>
AuthorDate: Fri Apr 7 08:49:27 2017 -0400
API GW V2 - Update backend actions (#2067)
* API GW V2 backend - action test updates
* API GW V2 backend - ansible update
- Add a new API GW V2 host property
* API GW V2 backend - action updates
- Dual support for existing "V1" API GW (to be deprecated) and new "V2" API GW
- Create new V2 package for containing actions defined without "require-whisk-auth"
---
.../actions/test/ApiGwRoutemgmtActionTests.scala | 295 ++++++++++++++++++++-
1 file changed, 286 insertions(+), 9 deletions(-)
diff --git a/tests/src/test/scala/whisk/core/apigw/actions/test/ApiGwRoutemgmtActionTests.scala b/tests/src/test/scala/whisk/core/apigw/actions/test/ApiGwRoutemgmtActionTests.scala
index d289d7a..96a1002 100644
--- a/tests/src/test/scala/whisk/core/apigw/actions/test/ApiGwRoutemgmtActionTests.scala
+++ b/tests/src/test/scala/whisk/core/apigw/actions/test/ApiGwRoutemgmtActionTests.scala
@@ -148,7 +148,7 @@ class ApiGwRoutemgmtActionTests
return rr
}
- def apiMatch(
+ def apiMatchExperimental(
apiarr: Vector[JsValue],
basepath: String = "/",
relpath: String = "",
@@ -173,7 +173,7 @@ class ApiGwRoutemgmtActionTests
if (endpointMatches) {
System.out.println("endpoint exists/matches : " + relpath + " " + operation)
val actionConfig = JsObjectHelper(api.asJsObject).getFieldPath("value", "apidoc", "paths", relpath, operation, "x-ibm-op-ext").get.asJsObject
- val actionMatches = actionMatch(actionConfig, action)
+ val actionMatches = actionMatchExperimental(actionConfig, action)
if (actionMatches) {
System.out.println("endpoint action matches")
matches = true;
@@ -187,7 +187,7 @@ class ApiGwRoutemgmtActionTests
return matches
}
- def actionMatch(
+ def actionMatchExperimental(
jsAction: JsObject,
action: ApiAction): Boolean = {
val matches = jsAction.fields("backendMethod").convertTo[String] == action.backendMethod &&
@@ -197,6 +197,150 @@ class ApiGwRoutemgmtActionTests
return matches
}
+ def getApisV2(
+ bpOrName: Option[String],
+ relpath: Option[String] = None,
+ operation: Option[String] = None,
+ docid: Option[String] = None,
+ accesstoken: Option[String] = Some("AnAccessToken"),
+ spaceguid: Option[String] = Some("ASpaceGuid") ): Vector[JsValue] = {
+ val parms = Map[String, JsValue]() ++
+ Map("__ow_user" -> wskprops.namespace.toJson) ++
+ { bpOrName map { b => Map("basepath" -> b.toJson) } getOrElse Map[String, JsValue]() } ++
+ { relpath map { r => Map("relpath" -> r.toJson) } getOrElse Map[String, JsValue]() } ++
+ { operation map { o => Map("operation" -> o.toJson) } getOrElse Map[String, JsValue]() } ++
+ { docid map { d => Map("docid" -> d.toJson) } getOrElse Map[String, JsValue]() } ++
+ { accesstoken map { t => Map("accesstoken" -> t.toJson) } getOrElse Map[String, JsValue]() } ++
+ { spaceguid map { s => Map("spaceguid" -> s.toJson) } getOrElse Map[String, JsValue]() }
+
+ val rr = wsk.action.invoke(
+ name = "apimgmt/getApi",
+ parameters = parms,
+ blocking = true,
+ result = true,
+ expectedExitCode = SUCCESS_EXIT)(wskprops)
+ var apiJsArray: JsArray =
+ try {
+ var apisobj = rr.stdout.parseJson.asJsObject.fields("apis")
+ apisobj.convertTo[JsArray]
+ } catch {
+ case e: Exception =>
+ JsArray.empty
+ }
+ return apiJsArray.elements
+ }
+
+ def createApiV2(
+ namespace: Option[String] = Some("_"),
+ basepath: Option[String] = Some("/"),
+ relpath: Option[String],
+ operation: Option[String],
+ apiname: Option[String],
+ action: Option[ApiAction],
+ swagger: Option[String] = None,
+ accesstoken: Option[String] = Some("AnAccessToken"),
+ spaceguid: Option[String] = Some("ASpaceGuid"),
+ expectedExitCode: Int = SUCCESS_EXIT): RunResult = {
+ val parms = Map[String, JsValue]() ++
+ { namespace map { n => Map("namespace" -> n.toJson) } getOrElse Map[String, JsValue]() } ++
+ { basepath map { b => Map("gatewayBasePath" -> b.toJson) } getOrElse Map[String, JsValue]() } ++
+ { relpath map { r => Map("gatewayPath" -> r.toJson) } getOrElse Map[String, JsValue]() } ++
+ { operation map { o => Map("gatewayMethod" -> o.toJson) } getOrElse Map[String, JsValue]() } ++
+ { apiname map { an => Map("apiName" -> an.toJson) } getOrElse Map[String, JsValue]() } ++
+ { action map { a => Map("action" -> a.toJson) } getOrElse Map[String, JsValue]() } ++
+ { swagger map { s => Map("swagger" -> s.toJson) } getOrElse Map[String, JsValue]() }
+ val parm = Map[String, JsValue]("apidoc" -> JsObject(parms)) ++
+ { namespace map { n => Map("__ow_user" -> n.toJson) } getOrElse Map[String, JsValue]() } ++
+ { accesstoken map { t => Map("accesstoken" -> t.toJson) } getOrElse Map[String, JsValue]() } ++
+ { spaceguid map { s => Map("spaceguid" -> s.toJson) } getOrElse Map[String, JsValue]() }
+
+ val rr = wsk.action.invoke(
+ name = "apimgmt/createApi",
+ parameters = parm,
+ blocking = true,
+ result = true,
+ expectedExitCode = expectedExitCode)(wskprops)
+ return rr
+ }
+
+ def deleteApiV2(
+ namespace: Option[String] = Some("_"),
+ basepath: Option[String] = Some("/"),
+ relpath: Option[String] = None,
+ operation: Option[String] = None,
+ apiname: Option[String] = None,
+ accesstoken: Option[String] = Some("AnAccessToken"),
+ spaceguid: Option[String] = Some("ASpaceGuid"),
+ expectedExitCode: Int = SUCCESS_EXIT): RunResult = {
+ val parms = Map[String, JsValue]() ++
+ { namespace map { n => Map("__ow_user" -> n.toJson) } getOrElse Map[String, JsValue]() } ++
+ { basepath map { b => Map("basepath" -> b.toJson) } getOrElse Map[String, JsValue]() } ++
+ { relpath map { r => Map("relpath" -> r.toJson) } getOrElse Map[String, JsValue]() } ++
+ { operation map { o => Map("operation" -> o.toJson) } getOrElse Map[String, JsValue]() } ++
+ { apiname map { an => Map("apiname" -> an.toJson) } getOrElse Map[String, JsValue]() } ++
+ { accesstoken map { t => Map("accesstoken" -> t.toJson) } getOrElse Map[String, JsValue]() } ++
+ { spaceguid map { s => Map("spaceguid" -> s.toJson) } getOrElse Map[String, JsValue]() }
+
+ val rr = wsk.action.invoke(
+ name = "apimgmt/deleteApi",
+ parameters = parms,
+ blocking = true,
+ result = true,
+ expectedExitCode = expectedExitCode)(wskprops)
+ return rr
+ }
+
+ def apiMatch(
+ apiarr: Vector[JsValue],
+ basepath: String = "/",
+ relpath: String = "",
+ operation: String = "",
+ apiname: String = "",
+ action: ApiAction = null): Boolean = {
+ var matches: Boolean = false
+ for (api <- apiarr) {
+ val basepathExists = JsObjectHelper(api.asJsObject).fieldPathExists("value", "apidoc", "basePath")
+ if (basepathExists) {
+ System.out.println("basePath exists")
+ val basepathMatches = (JsObjectHelper(api.asJsObject).getFieldPath("value", "apidoc", "basePath").get.convertTo[String] == basepath)
+ if (basepathMatches) {
+ System.out.println("basePath matches: " + basepath)
+ val apinameExists = JsObjectHelper(api.asJsObject).fieldPathExists("value", "apidoc", "info", "title")
+ if (apinameExists) {
+ System.out.println("api name exists")
+ val apinameMatches = (JsObjectHelper(api.asJsObject).getFieldPath("value", "apidoc", "info", "title").get.convertTo[String] == apiname)
+ if (apinameMatches) {
+ System.out.println("api name matches: " + apiname)
+ val endpointMatches = JsObjectHelper(api.asJsObject).fieldPathExists("value", "apidoc", "paths", relpath, operation)
+ if (endpointMatches) {
+ System.out.println("endpoint exists/matches : " + relpath + " " + operation)
+ val actionConfig = JsObjectHelper(api.asJsObject).getFieldPath("value", "apidoc", "paths", relpath, operation, "x-openwhisk").get.asJsObject
+ val actionMatches = actionMatch(actionConfig, action)
+ if (actionMatches) {
+ System.out.println("endpoint action matches")
+ matches = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return matches
+ }
+
+ def actionMatch(
+ jsAction: JsObject,
+ action: ApiAction): Boolean = {
+ System.out.println("actionMatch: url " + jsAction.fields("url").convertTo[String] + "; backendUrl " + action.backendUrl)
+ System.out.println("actionMatch: namespace " + jsAction.fields("namespace").convertTo[String] + "; namespace " + action.namespace)
+ System.out.println("actionMatch: action " + jsAction.fields("action").convertTo[String] + "; action " + action.name)
+ val matches = jsAction.fields("url").convertTo[String] == action.backendUrl &&
+ jsAction.fields("namespace").convertTo[String] == action.namespace &&
+ jsAction.fields("action").convertTo[String] == action.name
+ return matches
+ }
+
behavior of "API Gateway routemgmt action parameter validation"
it should "verify successful creation of a new API" in {
@@ -217,7 +361,7 @@ class ApiGwRoutemgmtActionTests
JsObjectHelper(createResult.stdout.parseJson.asJsObject).fieldPathExists("apidoc") should be(true)
val apiVector = getApis(bpOrName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
apiVector.size should be > 0
- apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
+ apiMatchExperimental(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
} finally {
val deleteResult = deleteApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), expectedExitCode = DONTCARE_EXIT)
}
@@ -241,10 +385,10 @@ class ApiGwRoutemgmtActionTests
JsObjectHelper(createResult.stdout.parseJson.asJsObject).fieldPathExists("apidoc") should be(true)
var apiVector = getApis(bpOrName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
apiVector.size should be > 0
- apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
+ apiMatchExperimental(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
val deleteResult = deleteApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath))
apiVector = getApis(bpOrName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
- apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(false)
+ apiMatchExperimental(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(false)
} finally {
val deleteResult = deleteApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), expectedExitCode = DONTCARE_EXIT)
}
@@ -272,8 +416,8 @@ class ApiGwRoutemgmtActionTests
JsObjectHelper(createResult.stdout.parseJson.asJsObject).fieldPathExists("apidoc") should be(true)
var apiVector = getApis(bpOrName = Some(testbasepath))
apiVector.size should be > 0
- apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
- apiMatch(apiVector, testbasepath, testnewrelpath, testnewurlop, testapiname, testaction) should be(true)
+ apiMatchExperimental(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
+ apiMatchExperimental(apiVector, testbasepath, testnewrelpath, testnewurlop, testapiname, testaction) should be(true)
} finally {
val deleteResult = deleteApi(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), expectedExitCode = DONTCARE_EXIT)
}
@@ -287,7 +431,7 @@ class ApiGwRoutemgmtActionTests
//deleteApi
("/whisk.system/routemgmt/deleteApi", ANY_ERROR_EXIT, "namespace is required", Seq("-p", "basepath", "/ApiGwRoutemgmtActionTests_bp")),
("/whisk.system/routemgmt/deleteApi", ANY_ERROR_EXIT, "basepath is required", Seq("-p", "__ow_meta_namespace", "_")),
- ("/whisk.system/routemgmt/deleteApi", ANY_ERROR_EXIT, "When specifying an operation, the relpath is required",
+ ("/whisk.system/routemgmt/deleteApi", ANY_ERROR_EXIT, "When specifying an operation, the path is required",
Seq("-p", "__ow_meta_namespace", "_", "-p", "basepath", "/ApiGwRoutemgmtActionTests_bp", "-p", "operation", "get")),
//createApi
@@ -329,4 +473,137 @@ class ApiGwRoutemgmtActionTests
rr.stderr should include regex (errmsg)
}
}
+
+ behavior of "API Gateway apimgmt action parameter validation"
+
+ it should "verify successful creation of a new V2 API" in {
+ val testName = "APIGWTEST1"
+ val testbasepath = "/" + testName + "_bp"
+ val testrelpath = "/path"
+ val testurlop = "get"
+ val testapiname = testName + " API Name"
+ val actionName = testName + "_action"
+ val actionNamespace = wskprops.namespace
+ val actionUrl = "https://some.whisk.host/api/v1/web/" + actionNamespace + "/default/" + actionName + ".http"
+ val actionAuthKey = testName + "_authkey"
+ val testaction = ApiAction(name = actionName, namespace = actionNamespace, backendUrl = actionUrl, authkey = actionAuthKey)
+
+ try {
+ val createResult = createApiV2(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), relpath = Some(testrelpath),
+ operation = Some(testurlop), apiname = Some(testapiname), action = Some(testaction))
+ JsObjectHelper(createResult.stdout.parseJson.asJsObject).fieldPathExists("apidoc") should be(true)
+ val apiVector = getApisV2(bpOrName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+ apiVector.size should be > 0
+ apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
+ } finally {
+ val deleteResult = deleteApiV2(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), expectedExitCode = DONTCARE_EXIT)
+ }
+ }
+
+ it should "verify successful V2 API deletion using basepath" in {
+ val testName = "APIGWTEST2"
+ val testbasepath = "/" + testName + "_bp"
+ val testrelpath = "/path"
+ val testurlop = "get"
+ val testapiname = testName + " API Name"
+ val actionName = testName + "_action"
+ val actionNamespace = wskprops.namespace
+ val actionUrl = "https://some.whisk.host/api/v1/web/" + actionNamespace + "/default/" + actionName + ".http"
+ val actionAuthKey = testName + "_authkey"
+ val testaction = ApiAction(name = actionName, namespace = actionNamespace, backendUrl = actionUrl, authkey = actionAuthKey)
+
+ try {
+ val createResult = createApiV2(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), relpath = Some(testrelpath),
+ operation = Some(testurlop), apiname = Some(testapiname), action = Some(testaction))
+ JsObjectHelper(createResult.stdout.parseJson.asJsObject).fieldPathExists("apidoc") should be(true)
+ var apiVector = getApisV2(bpOrName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+ apiVector.size should be > 0
+ apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
+ val deleteResult = deleteApiV2(namespace = Some(wskprops.namespace), basepath = Some(testbasepath))
+ apiVector = getApisV2(bpOrName = Some(testbasepath), relpath = Some(testrelpath), operation = Some(testurlop))
+ apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(false)
+ } finally {
+ val deleteResult = deleteApiV2(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), expectedExitCode = DONTCARE_EXIT)
+ }
+ }
+
+ it should "verify successful addition of new relative path to existing V2 API" in {
+ val testName = "APIGWTEST3"
+ val testbasepath = "/" + testName + "_bp"
+ val testrelpath = "/path"
+ val testnewrelpath = "/path_new"
+ val testurlop = "get"
+ val testnewurlop = "delete"
+ val testapiname = testName + " API Name"
+ val actionName = testName + "_action"
+ val actionNamespace = wskprops.namespace
+ val actionUrl = "https://some.whisk.host/api/v1/web/" + actionNamespace + "/default/" + actionName + ".http"
+ val actionAuthKey = testName + "_authkey"
+ val testaction = ApiAction(name = actionName, namespace = actionNamespace, backendUrl = actionUrl, authkey = actionAuthKey)
+
+ try {
+ var createResult = createApiV2(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), relpath = Some(testrelpath),
+ operation = Some(testurlop), apiname = Some(testapiname), action = Some(testaction))
+ createResult = createApiV2(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), relpath = Some(testnewrelpath),
+ operation = Some(testnewurlop), apiname = Some(testapiname), action = Some(testaction))
+ JsObjectHelper(createResult.stdout.parseJson.asJsObject).fieldPathExists("apidoc") should be(true)
+ var apiVector = getApisV2(bpOrName = Some(testbasepath))
+ apiVector.size should be > 0
+ apiMatch(apiVector, testbasepath, testrelpath, testurlop, testapiname, testaction) should be(true)
+ apiMatch(apiVector, testbasepath, testnewrelpath, testnewurlop, testapiname, testaction) should be(true)
+ } finally {
+ val deleteResult = deleteApiV2(namespace = Some(wskprops.namespace), basepath = Some(testbasepath), expectedExitCode = DONTCARE_EXIT)
+ }
+ }
+
+ it should "reject apimgmt actions that are invoked with not enough parameters" in {
+ val invalidArgs = Seq(
+ //getApi
+ ("/whisk.system/apimgmt/getApi", ANY_ERROR_EXIT, "namespace is required", Seq()),
+
+ //deleteApi
+ ("/whisk.system/apimgmt/deleteApi", ANY_ERROR_EXIT, "namespace is required", Seq("-p", "basepath", "/ApiGwRoutemgmtActionTests_bp")),
+ ("/whisk.system/apimgmt/deleteApi", ANY_ERROR_EXIT, "basepath is required", Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN")),
+ ("/whisk.system/apimgmt/deleteApi", ANY_ERROR_EXIT, "When specifying an operation, the path is required",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "basepath", "/ApiGwRoutemgmtActionTests_bp", "-p", "operation", "get")),
+
+ //createApi
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc is required", Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN")),
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc is missing the namespace field",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", "{}")),
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc is missing the gatewayBasePath field",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_"}""")),
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc is missing the gatewayPath field",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp"}""")),
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc is missing the gatewayMethod field",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp"}""")),
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc is missing the action field",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get"}""")),
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "action is missing the backendMethod field",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{}}""")),
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "action is missing the backendUrl field",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post"}}""")),
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "action is missing the namespace field",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post","backendUrl":"URL"}}""")),
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "action is missing the name field",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post","backendUrl":"URL","namespace":"_"}}""")),
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "action is missing the authkey field",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post","backendUrl":"URL","namespace":"_","name":"N"}}""")),
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "swagger and gatewayBasePath are mutually exclusive and cannot be specified together",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", """{"namespace":"_","gatewayBasePath":"/ApiGwRoutemgmtActionTests_bp","gatewayPath":"ApiGwRoutemgmtActionTests_rp","gatewayMethod":"get","action":{"backendMethod":"post","backendUrl":"URL","namespace":"_","name":"N","authkey":"XXXX"},"swagger":{}}""")),
+ ("/whisk.system/apimgmt/createApi", ANY_ERROR_EXIT, "apidoc field cannot be parsed. Ensure it is valid JSON",
+ Seq("-p", "__ow_user", "_", "-p", "accesstoken", "TOKEN", "-p", "apidoc", "{1:[}}}")))
+
+ invalidArgs foreach {
+ case (action: String, exitcode: Int, errmsg: String, params: Seq[String]) =>
+ val cmd: Seq[String] = Seq("action",
+ "invoke",
+ action,
+ "-i", "-b", "-r",
+ "--apihost", wskprops.apihost,
+ "--auth", wskprops.authKey) ++ params
+ val rr = wsk.cli(cmd, expectedExitCode = exitcode)
+ rr.stderr should include regex (errmsg)
+ }
+ }
}
--
To stop receiving notification emails like this one, please contact
"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>.