rabbah closed pull request #2996: Rewrite WskBasicUsageTests
URL: https://github.com/apache/incubator-openwhisk/pull/2996
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/tests/src/test/scala/common/rest/WskRest.scala
b/tests/src/test/scala/common/rest/WskRest.scala
index a3f870b3eb..7c31deec4b 100644
--- a/tests/src/test/scala/common/rest/WskRest.scala
+++ b/tests/src/test/scala/common/rest/WskRest.scala
@@ -265,53 +265,43 @@ class WskRestAction
expectedExitCode: Int = OK.intValue)(implicit wp: WskProps): RestResult = {
val (namespace, actName) = getNamespaceEntityName(name)
- var exec = Map[String, JsValue]()
- var code = ""
- var kindType = ""
- var artifactName = ""
- artifact match {
+ val (kindTypeByAction, code, artifactName) = artifact match {
case Some(artifactFile) => {
val ext = getExt(artifactFile)
- artifactName = artifactFile
ext match {
case ".jar" => {
- kindType = "java:default"
val jar = FileUtils.readFileToByteArray(new File(artifactFile))
- code = Base64.getEncoder.encodeToString(jar)
+ ("java:default", Base64.getEncoder.encodeToString(jar),
artifactFile)
}
case ".zip" => {
val zip = FileUtils.readFileToByteArray(new File(artifactFile))
- code = Base64.getEncoder.encodeToString(zip)
+ ("", Base64.getEncoder.encodeToString(zip), artifactFile)
}
case ".js" => {
- kindType = "nodejs:default"
- code = FileUtils.readFileToString(new File(artifactFile))
+ ("nodejs:default", FileUtils.readFileToString(new
File(artifactFile)), artifactFile)
}
case ".py" => {
- kindType = "python:default"
- code = FileUtils.readFileToString(new File(artifactFile))
+ ("python:default", FileUtils.readFileToString(new
File(artifactFile)), artifactFile)
}
case ".swift" => {
- kindType = "swift:default"
- code = FileUtils.readFileToString(new File(artifactFile))
+ ("swift:default", FileUtils.readFileToString(new
File(artifactFile)), artifactFile)
}
case ".php" => {
- kindType = "php:default"
- code = FileUtils.readFileToString(new File(artifactFile))
+ ("php:default", FileUtils.readFileToString(new
File(artifactFile)), artifactFile)
}
- case _ =>
+ case _ => ("", "", artifactFile)
}
}
- case None =>
+ case None => ("", "", "")
}
- kindType = docker map { d =>
+ val kindType = docker map { d =>
"blackbox"
- } getOrElse kindType
+ } getOrElse kindTypeByAction
- var (params, annos) = getParamsAnnos(parameters, annotations,
parameterFile, annotationFile, web = web)
+ val (paramsInput, annosInput) = getParamsAnnos(parameters, annotations,
parameterFile, annotationFile, web = web)
- kind match {
+ val (params, annos, execByKind) = kind match {
case Some(k) => {
k match {
case "copy" => {
@@ -322,27 +312,35 @@ class WskRestAction
return new RestResult(NotFound)
else {
val result = new RestResult(resp.status, getRespData(resp))
- params = JsArray(result.getFieldListJsObject("parameters"))
- annos = JsArray(result.getFieldListJsObject("annotations"))
- exec = result.getFieldJsObject("exec").fields
+ val params =
result.getFieldListJsObject("parameters").toArray[JsValue]
+ val annos =
result.getFieldListJsObject("annotations").toArray[JsValue]
+ val exec = result.getFieldJsObject("exec").fields
+ (params, annos, exec)
}
}
case "sequence" => {
val comps = convertIntoComponents(artifactName)
- exec = Map("components" -> comps.toJson, "kind" -> k.toJson)
+ val exec =
+ if (comps.size > 0) Map("components" -> comps.toJson, "kind" ->
k.toJson)
+ else
+ Map("kind" -> k.toJson)
+ (paramsInput, annosInput, exec)
}
case "native" => {
- exec = Map("code" -> code.toJson, "kind" -> "blackbox".toJson,
"image" -> "openwhisk/dockerskeleton".toJson)
+ val exec =
+ Map("code" -> code.toJson, "kind" -> "blackbox".toJson, "image"
-> "openwhisk/dockerskeleton".toJson)
+ (paramsInput, annosInput, exec)
}
case _ => {
- exec = Map("code" -> code.toJson, "kind" -> k.toJson)
+ val exec = Map("code" -> code.toJson, "kind" -> k.toJson)
+ (paramsInput, annosInput, exec)
}
}
}
- case None => exec = Map("code" -> code.toJson, "kind" -> kindType.toJson)
+ case None => (paramsInput, annosInput, Map("code" -> code.toJson, "kind"
-> kindType.toJson))
}
- exec = exec ++ {
+ val exec = execByKind ++ {
main map { m =>
Map("main" -> m.toJson)
} getOrElse Map[String, JsValue]()
@@ -352,32 +350,46 @@ class WskRestAction
} getOrElse Map[String, JsValue]()
}
- var bodyContent = Map("name" -> name.toJson, "namespace" ->
namespace.toJson)
+ val bodyHead = Map("name" -> name.toJson, "namespace" -> namespace.toJson)
- if (update) {
- kind match {
- case Some(k) if (k == "sequence" || k == "native") => {
- bodyContent = bodyContent ++ Map("exec" -> exec.toJson)
- }
- case _ =>
+ val (updateExistence, resultExistence) = update match {
+ case true => {
+ val (ns, entity) = getNamespaceEntityName(name)
+ val entPath = Path(s"$basePath/namespaces/$ns/$noun/$entity")
+ val resp = requestEntity(GET, entPath)(wp)
+ val result = if (resp == None) new RestResult(NotFound) else new
RestResult(resp.status, getRespData(resp))
+ if (result.statusCode == NotFound) (false, result) else (true, result)
}
+ case _ => (false, new RestResult(NotFound))
+ }
+
+ val bodyWithParamsAnnos = if (updateExistence) {
+ val oldAnnos = resultExistence.getFieldListJsObject("annotations")
+ val inputParams = convertMapIntoKeyValue(parameters)
+ val inputAnnos = convertMapIntoKeyValue(annotations, web = web,
oldParams = oldAnnos.toList)
- bodyContent = bodyContent ++ {
+ bodyHead ++ {
+ kind match {
+ case Some(k) if (k == "sequence" || k == "native") => {
+ Map("exec" -> exec.toJson)
+ }
+ case _ => Map[String, JsValue]()
+ }
+ } ++ {
shared map { s =>
Map("publish" -> s.toJson)
} getOrElse Map[String, JsValue]()
- }
-
- val inputParams = convertMapIntoKeyValue(parameters)
- if (inputParams.elements.size > 0) {
- bodyContent = bodyContent ++ Map("parameters" -> params)
- }
- val inputAnnos = convertMapIntoKeyValue(annotations)
- if (inputAnnos.elements.size > 0) {
- bodyContent = bodyContent ++ Map("annotations" -> annos)
+ } ++ {
+ if (inputParams.size > 0) {
+ Map("parameters" -> params.toJson)
+ } else Map[String, JsValue]()
+ } ++ {
+ if (inputAnnos.size > 0) {
+ Map("annotations" -> inputAnnos.toJson)
+ } else Map[String, JsValue]()
}
} else {
- bodyContent = bodyContent ++ Map("exec" -> exec.toJson, "parameters" ->
params, "annotations" -> annos)
+ bodyHead ++ Map("exec" -> exec.toJson, "parameters" -> params.toJson,
"annotations" -> annos.toJson)
}
val limits = Map[String, JsValue]() ++ {
@@ -394,8 +406,11 @@ class WskRestAction
} getOrElse Map[String, JsValue]()
}
- if (!limits.isEmpty)
- bodyContent = bodyContent ++ Map("limits" -> limits.toJson)
+ val bodyContent =
+ if (!limits.isEmpty)
+ bodyWithParamsAnnos ++ Map("limits" -> limits.toJson)
+ else bodyWithParamsAnnos
+
val path = Path(s"$basePath/namespaces/$namespace/$noun/$actName")
val resp =
if (update) requestEntity(PUT, path, Map("overwrite" -> "true"),
Some(JsObject(bodyContent).toString))
@@ -450,19 +465,19 @@ class WskRestTrigger
val published = shared.getOrElse(false)
bodyContent = JsObject(
bodyContent.fields + ("publish" -> published.toJson,
- "parameters" -> params, "annotations" -> annos))
+ "parameters" -> params.toJson, "annotations" -> annos.toJson))
} else {
bodyContent = shared map { s =>
JsObject(bodyContent.fields + ("publish" -> s.toJson))
} getOrElse bodyContent
val inputParams = convertMapIntoKeyValue(parameters)
- if (inputParams.elements.size > 0) {
- bodyContent = JsObject(bodyContent.fields + ("parameters" -> params))
+ if (inputParams.size > 0) {
+ bodyContent = JsObject(bodyContent.fields + ("parameters" ->
params.toJson))
}
val inputAnnos = convertMapIntoKeyValue(annotations)
- if (inputAnnos.elements.size > 0) {
- bodyContent = JsObject(bodyContent.fields + ("annotations" -> annos))
+ if (inputAnnos.size > 0) {
+ bodyContent = JsObject(bodyContent.fields + ("annotations" ->
annos.toJson))
}
}
@@ -486,10 +501,12 @@ class WskRestTrigger
body = body ++ parameters
val resp = requestEntity(POST, path, paramMap,
Some(body.toJson.toString()))
val resultInvoke = new RestResult(resp.status, getRespData(resp))
- expectedExitCode shouldBe resultInvoke.statusCode.intValue
+ if ((expectedExitCode != DONTCARE_EXIT) && (expectedExitCode !=
ANY_ERROR_EXIT))
+ expectedExitCode shouldBe resultInvoke.statusCode.intValue
if (resultInvoke.statusCode != OK) {
// Remove the trigger, because the feed failed to invoke.
this.delete(triggerName)
+ new RestResult(NotFound)
} else {
result
}
@@ -557,7 +574,7 @@ class WskRestRule
"publish" -> published.toJson,
"name" -> name.toJson,
"status" -> "".toJson,
- "annotations" -> annos)
+ "annotations" -> annos.toJson)
val resp =
if (update) requestEntity(PUT, path, Map("overwrite" -> "true"),
Some(bodyContent.toString))
@@ -902,7 +919,7 @@ class WskRestPackage
val published = shared.getOrElse(false)
bodyContent = JsObject(
bodyContent.fields + ("publish" -> published.toJson,
- "parameters" -> params, "annotations" -> annos))
+ "parameters" -> params.toJson, "annotations" -> annos.toJson))
} else {
if (shared != None)
bodyContent = shared map { s =>
@@ -910,12 +927,12 @@ class WskRestPackage
} getOrElse bodyContent
val inputParams = convertMapIntoKeyValue(parameters)
- if (inputParams.elements.size > 0) {
- bodyContent = JsObject(bodyContent.fields + ("parameters" -> params))
+ if (inputParams.size > 0) {
+ bodyContent = JsObject(bodyContent.fields + ("parameters" ->
params.toJson))
}
val inputAnnos = convertMapIntoKeyValue(annotations)
- if (inputAnnos.elements.size > 0) {
- bodyContent = JsObject(bodyContent.fields + ("annotations" -> annos))
+ if (inputAnnos.size > 0) {
+ bodyContent = JsObject(bodyContent.fields + ("annotations" ->
annos.toJson))
}
}
@@ -945,7 +962,8 @@ class WskRestPackage
val (ns, packageName) = this.getNamespaceEntityName(provider)
val path = getNamePath(noun, name)
val binding = JsObject("namespace" -> ns.toJson, "name" ->
packageName.toJson)
- val bodyContent = JsObject("binding" -> binding.toJson, "parameters" ->
params, "annotations" -> annos)
+ val bodyContent =
+ JsObject("binding" -> binding.toJson, "parameters" -> params.toJson,
"annotations" -> annos.toJson)
val resp = requestEntity(PUT, path, Map("overwrite" -> "false"),
Some(bodyContent.toString))
val r = new RestResult(resp.status, getRespData(resp))
validateStatusCode(expectedExitCode, r.statusCode.intValue)
@@ -1279,7 +1297,7 @@ class RunWskRestCmd() extends FlatSpec with RunWskCmd
with Matchers with ScalaFu
parameterFile: Option[String] = None,
annotationFile: Option[String] = None,
feed: Option[String] = None,
- web: Option[String] = None): (JsArray, JsArray) = {
+ web: Option[String] = None): (Array[JsValue],
Array[JsValue]) = {
val params = parameterFile map { pf =>
convertStringIntoKeyValue(pf)
} getOrElse convertMapIntoKeyValue(parameters)
@@ -1289,7 +1307,9 @@ class RunWskRestCmd() extends FlatSpec with RunWskCmd
with Matchers with ScalaFu
(params, annos)
}
- def convertStringIntoKeyValue(file: String, feed: Option[String] = None,
web: Option[String] = None): JsArray = {
+ def convertStringIntoKeyValue(file: String,
+ feed: Option[String] = None,
+ web: Option[String] = None): Array[JsValue] = {
val input = FileUtils.readFileToString(new File(file))
val in = input.parseJson.convertTo[Map[String, JsValue]]
convertMapIntoKeyValue(in, feed, web)
@@ -1297,28 +1317,39 @@ class RunWskRestCmd() extends FlatSpec with RunWskCmd
with Matchers with ScalaFu
def convertMapIntoKeyValue(params: Map[String, JsValue],
feed: Option[String] = None,
- web: Option[String] = None): JsArray = {
- var paramsList = Vector[JsObject]()
- params foreach { case (key, value) => paramsList :+= JsObject("key" ->
key.toJson, "value" -> value.toJson) }
- paramsList = feed map { f =>
- paramsList :+ JsObject("key" -> "feed".toJson, "value" -> f.toJson)
- } getOrElse paramsList
- paramsList = web match {
- case Some("true") =>
- paramsList :+ JsObject("key" -> "web-export".toJson, "value" ->
true.toJson) :+ JsObject(
- "key" -> "raw-http".toJson,
- "value" -> false.toJson) :+ JsObject("key" -> "final".toJson,
"value" -> true.toJson)
- case Some("false") =>
- paramsList :+ JsObject("key" -> "web-export".toJson, "value" ->
false.toJson) :+ JsObject(
- "key" -> "raw-http".toJson,
- "value" -> false.toJson) :+ JsObject("key" -> "final".toJson,
"value" -> false.toJson)
- case Some("raw") =>
- paramsList :+ JsObject("key" -> "web-export".toJson, "value" ->
true.toJson) :+ JsObject(
- "key" -> "raw-http".toJson,
- "value" -> true.toJson) :+ JsObject("key" -> "final".toJson, "value"
-> true.toJson)
- case _ => paramsList
+ web: Option[String] = None,
+ oldParams: List[JsObject] = List[JsObject]()):
Array[JsValue] = {
+ val newParams =
+ params
+ .map { case (key, value) => JsObject("key" -> key.toJson, "value" ->
value) } ++ feed.map(f =>
+ JsObject("key" -> "feed".toJson, "value" -> f.toJson))
+
+ val paramsList =
+ if (newParams.nonEmpty) newParams
+ else
+ oldParams
+ val webOpt = web.map {
+ case "true" | "yes" =>
+ Seq(
+ JsObject("key" -> "web-export".toJson, "value" -> true.toJson),
+ JsObject("key" -> "raw-http".toJson, "value" -> false.toJson),
+ JsObject("key" -> "final".toJson, "value" -> true.toJson))
+ case "false" | "no" =>
+ Seq(
+ JsObject("key" -> "web-export".toJson, "value" -> false.toJson),
+ JsObject("key" -> "raw-http".toJson, "value" -> false.toJson),
+ JsObject("key" -> "final".toJson, "value" -> false.toJson))
+ case "raw" =>
+ Seq(
+ JsObject("key" -> "web-export".toJson, "value" -> true.toJson),
+ JsObject("key" -> "raw-http".toJson, "value" -> true.toJson),
+ JsObject("key" -> "final".toJson, "value" -> true.toJson))
+ case _ =>
+ Seq()
}
- JsArray(paramsList)
+ (webOpt map { web =>
+ paramsList ++ web
+ } getOrElse paramsList).toArray
}
def entityName(name: String)(implicit wp: WskProps) = {
@@ -1328,19 +1359,25 @@ class RunWskRestCmd() extends FlatSpec with RunWskCmd
with Matchers with ScalaFu
}
def fullEntityName(name: String)(implicit wp: WskProps) = {
- val sep = "/"
- if (name.startsWith(sep)) name
- else s"/${wp.namespace}/$name"
+ name.split("/") match {
+ // Example: /namespace/package_name/entity_name
+ case Array(empty, namespace, packageName, entityName) if empty.isEmpty
=> s"/$namespace/$packageName/$entityName"
+ // Example: /namespace/entity_name
+ case Array(empty, namespace, entityName) if empty.isEmpty =>
s"/$namespace/$entityName"
+ // Example: namespace/package_name/entity_name
+ case Array(namespace, packageName, entityName) =>
s"/$namespace/$packageName/$entityName"
+ // Example: /namespace
+ case Array(empty, namespace) if empty.isEmpty => namespace
+ // Example: package_name/entity_name
+ case Array(packageName, entityName) if !packageName.isEmpty =>
s"/${wp.namespace}/$packageName/$entityName"
+ // Example: entity_name
+ case Array(entityName) => s"/${wp.namespace}/$name"
+ case _ => s"/${wp.namespace}/$name"
+ }
}
- def convertIntoComponents(comps: String)(implicit wp: WskProps): JsArray = {
- var paramsList = Vector[JsString]()
- comps.split(",") foreach {
- case (value) =>
- val fullName = fullEntityName(value)
- paramsList :+= JsString(fullName)
- }
- JsArray(paramsList)
+ def convertIntoComponents(comps: String)(implicit wp: WskProps):
Array[JsValue] = {
+ comps.split(",").filter(_.nonEmpty).map(comp =>
fullEntityName(comp).toJson)
}
def getRespData(resp: HttpResponse): String = {
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
index eae45c0717..963eb4c67c 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
@@ -17,11 +17,13 @@
package whisk.core.cli.test
+import akka.http.scaladsl.model.StatusCodes.NotFound
+import akka.http.scaladsl.model.StatusCodes.OK
+import akka.http.scaladsl.model.StatusCodes.BadRequest
+import akka.http.scaladsl.model.StatusCodes.Conflict
+
import java.time.Instant
-import java.net.URLEncoder
-import java.nio.charset.StandardCharsets
import java.time.Clock
-import java.io.File
import scala.language.postfixOps
import scala.concurrent.duration.Duration
@@ -33,9 +35,9 @@ import common.TestHelpers
import common.TestUtils
import common.TestUtils._
import common.WhiskProperties
-import common.Wsk
import common.WskProps
import common.WskTestHelpers
+import common.rest.WskRest
import spray.json.DefaultJsonProtocol._
import spray.json._
import whisk.core.entity._
@@ -43,7 +45,6 @@ import whisk.core.entity.LogLimit._
import whisk.core.entity.MemoryLimit._
import whisk.core.entity.TimeLimit._
import whisk.core.entity.size.SizeInt
-import whisk.utils.retry
import JsonArgsForTests._
import whisk.http.Messages
@@ -53,42 +54,13 @@ import whisk.http.Messages
@RunWith(classOf[JUnitRunner])
class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
- implicit val wskprops = WskProps()
- val wsk = new Wsk
- val defaultAction = Some(TestUtils.getTestActionFilename("hello.js"))
- val usrAgentHeaderRegEx = """\bUser-Agent\b": \[\s+"OpenWhisk\-CLI/1.\d+.*"""
+ implicit val wskprops: common.WskProps = WskProps()
+ val wsk: common.rest.WskRest = new WskRest
+ val defaultAction: Some[String] =
Some(TestUtils.getTestActionFilename("hello.js"))
+ val usrAgentHeaderRegEx: String = """\bUser-Agent\b":
\[\s+"OpenWhisk\-CLI/1.\d+.*"""
behavior of "Wsk CLI usage"
- it should "show help and usage info" in {
- val stdout = wsk.cli(Seq()).stdout
- stdout should include regex ("""(?i)Usage:""")
- stdout should include regex ("""(?i)Flags""")
- stdout should include regex ("""(?i)Available commands""")
- stdout should include regex ("""(?i)--help""")
- }
-
- it should "show help and usage info using the default language" in {
- val env = Map("LANG" -> "de_DE")
- // Call will fail with exit code 2 if language not supported
- wsk.cli(Seq("-h"), env = env)
- }
-
- it should "show cli build version" in {
- val stdout = wsk.cli(Seq("property", "get", "--cliversion")).stdout
- stdout should include regex ("""(?i)whisk CLI version\s+201.*""")
- }
-
- it should "show api version" in {
- val stdout = wsk.cli(Seq("property", "get", "--apiversion")).stdout
- stdout should include regex ("""(?i)whisk API version\s+v1""")
- }
-
- it should "reject bad command" in {
- val result = wsk.cli(Seq("bogus"), expectedExitCode = ERROR_EXIT)
- result.stderr should include regex ("""(?i)Run 'wsk --help' for usage""")
- }
-
it should "allow a 3 part Fully Qualified Name (FQN) without a leading '/'"
in withAssetCleaner(wskprops) {
(wp, assetHelper) =>
val guestNamespace = wsk.namespace.whois()
@@ -112,25 +84,25 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
rule.create(ruleName, trigger = triggerName, action =
fullQualifiedName)
}
- wsk.action.invoke(fullQualifiedName).stdout should include(s"ok: invoked
/$fullQualifiedName")
- wsk.action.get(fullQualifiedName).stdout should include(s"ok: got action
${packageName}/${actionName}")
- }
-
- it should "include CLI user agent headers with outbound requests" in {
- val stdout = wsk.cli(Seq("list", "--auth", wskprops.authKey) ++
wskprops.overrides, verbose = true).stdout
- stdout should include regex (usrAgentHeaderRegEx)
+ val run = wsk.action.invoke(fullQualifiedName)
+ withActivation(wsk.activation, run) { activation =>
+ activation.response.status shouldBe "success"
+ }
+ val action = wsk.action.get(fullQualifiedName)
+ action.getField("name") shouldBe actionName
+ action.getField("namespace") shouldBe s"${guestNamespace}/${packageName}"
}
behavior of "Wsk actions"
it should "reject creating entities with invalid names" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
val names = Seq(
- ("", ERROR_EXIT),
- (" ", BAD_REQUEST),
- ("hi+there", BAD_REQUEST),
- ("$hola", BAD_REQUEST),
- ("dora?", BAD_REQUEST),
- ("|dora|dora?", BAD_REQUEST))
+ ("", NotFound.intValue),
+ (" ", BadRequest.intValue),
+ ("hi+there", BadRequest.intValue),
+ ("$hola", BadRequest.intValue),
+ ("dora?", BadRequest.intValue),
+ ("|dora|dora?", BadRequest.intValue))
names foreach {
case (name, ec) =>
@@ -140,46 +112,30 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
}
}
- it should "reject create with missing file" in {
- val name = "notfound"
- wsk.action.create("missingFile", Some(name), expectedExitCode =
MISUSE_EXIT).stderr should include(
- s"File '$name' is not a valid file or it does not exist")
- }
-
- it should "reject action update when specified file is missing" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- // Create dummy action to update
- val name = "updateMissingFile"
- val file = Some(TestUtils.getTestActionFilename("hello.js"))
- assetHelper.withCleaner(wsk.action, name) { (action, name) =>
- action.create(name, file)
- }
- // Update it with a missing file
- wsk.action.create(name, Some("notfound"), update = true, expectedExitCode
= MISUSE_EXIT)
- }
-
it should "reject action update for sequence with no components" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
val name = "updateMissingComponents"
val file = Some(TestUtils.getTestActionFilename("hello.js"))
assetHelper.withCleaner(wsk.action, name) { (action, name) =>
action.create(name, file)
}
- wsk.action.create(name, None, update = true, kind = Some("sequence"),
expectedExitCode = MISUSE_EXIT)
+ wsk.action
+ .create(name, None, update = true, kind = Some("sequence"),
expectedExitCode = BadRequest.intValue)
+ .stderr should include regex "The request content was
malformed:\n'components' must be defined for sequence kind"
}
it should "create, and get an action to verify parameter and annotation
parsing" in withAssetCleaner(wskprops) {
(wp, assetHelper) =>
val name = "actionAnnotations"
val file = Some(TestUtils.getTestActionFilename("hello.js"))
-
assetHelper.withCleaner(wsk.action, name) { (action, _) =>
action.create(name, file, annotations = getValidJSONTestArgInput,
parameters = getValidJSONTestArgInput)
}
- val stdout = wsk.action.get(name).stdout
- assert(stdout.startsWith(s"ok: got action $name\n"))
+ val action = wsk.action.get(name)
+ action.getField("name") shouldBe name
- val receivedParams =
wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
- val receivedAnnots =
wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+ val receivedParams =
wsk.parseJsonString(action.stdout).fields("parameters").convertTo[JsArray].elements
+ val receivedAnnots =
wsk.parseJsonString(action.stdout).fields("annotations").convertTo[JsArray].elements
val escapedJSONArr =
getValidJSONTestArgOutput.convertTo[JsArray].elements
for (expectedItem <- escapedJSONArr) {
@@ -198,11 +154,11 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
action.create(name, file, annotationFile = argInput, parameterFile =
argInput)
}
- val stdout = wsk.action.get(name).stdout
- assert(stdout.startsWith(s"ok: got action $name\n"))
+ val action = wsk.action.get(name)
+ action.getField("name") shouldBe name
- val receivedParams =
wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
- val receivedAnnots =
wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+ val receivedParams =
wsk.parseJsonString(action.stdout).fields("parameters").convertTo[JsArray].elements
+ val receivedAnnots =
wsk.parseJsonString(action.stdout).fields("annotations").convertTo[JsArray].elements
val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
for (expectedItem <- escapedJSONArr) {
@@ -220,11 +176,11 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
action.create(name, file, parameters = getEscapedJSONTestArgInput,
annotations = getEscapedJSONTestArgInput)
}
- val stdout = wsk.action.get(name).stdout
- assert(stdout.startsWith(s"ok: got action $name\n"))
+ val action = wsk.action.get(name)
+ action.getField("name") shouldBe name
- val receivedParams =
wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
- val receivedAnnots =
wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+ val receivedParams =
wsk.parseJsonString(action.stdout).fields("parameters").convertTo[JsArray].elements
+ val receivedAnnots =
wsk.parseJsonString(action.stdout).fields("annotations").convertTo[JsArray].elements
val escapedJSONArr =
getEscapedJSONTestArgOutput.convertTo[JsArray].elements
for (expectedItem <- escapedJSONArr) {
@@ -275,57 +231,6 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
}
}
- it should "retrieve the last activation using --last flag" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- val auth: Seq[String] = Seq("--auth", wskprops.authKey)
- val includeStr = "hello, undefined!"
-
- assetHelper.withCleaner(wsk.action, "lastName") { (action, _) =>
- wsk.action.create("lastName", defaultAction)
- }
- retry(
- {
- val lastInvoke = wsk.action.invoke("lastName")
- withActivation(wsk.activation, lastInvoke) {
- activation =>
- val lastFlag = Seq(
- (Seq("activation", "get", "publish", "--last"),
activation.activationId),
- (Seq("activation", "get", "--last"), activation.activationId),
- (Seq("activation", "logs", "--last"), includeStr),
- (Seq("activation", "result", "--last"), includeStr))
-
- retry({
- lastFlag foreach {
- case (cmd, output) =>
- val stdout = wsk.cli(cmd ++ wskprops.overrides ++ auth,
expectedExitCode = SUCCESS_EXIT).stdout
- stdout should include(output)
- }
- }, waitBeforeRetry = Some(500.milliseconds))
-
- }
- },
- waitBeforeRetry = Some(1.second),
- N = 5)
- }
-
- it should "ensure timestamp and stream are stripped from log lines" in
withAssetCleaner(wskprops) {
- val name = "activationLogStripTest"
- val auth: Seq[String] = Seq("--auth", wskprops.authKey)
-
- (wp, assetHelper) =>
- assetHelper.withCleaner(wsk.action, name) { (action, _) =>
- action.create(name, Some(TestUtils.getTestActionFilename("log.js")))
- }
-
- withActivation(wsk.activation, wsk.action.invoke(name)) { activation =>
- val cmd = Seq("activation", "logs", "--strip", activation.activationId)
- val run = wsk.cli(cmd ++ wskprops.overrides ++ auth, expectedExitCode
= SUCCESS_EXIT)
- run.stdout should {
- be("this is stdout\nthis is stderr\n") or
- be("this is stderr\nthis is stdout\n")
- }
- }
- }
-
it should "ensure keys are not omitted from activation record" in
withAssetCleaner(wskprops) {
val name = "activationRecordTest"
@@ -387,7 +292,7 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
name,
Some(TestUtils.getTestActionFilename("echo.js")),
kind = Some("foobar"),
- expectedExitCode = BAD_REQUEST)
+ expectedExitCode = BadRequest.intValue)
}
rr.stderr should include regex "kind 'foobar' not in Set"
}
@@ -400,7 +305,7 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
action.create(name, zippedPythonAction, expectedExitCode =
ANY_ERROR_EXIT)
}
- createResult.stderr should include regex "requires specifying the action
kind"
+ createResult.stderr should include regex "kind '' not in Set"
}
it should "create, and invoke an action that utilizes an invalid docker
container with appropriate error" in withAssetCleaner(
@@ -442,7 +347,7 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
activation.logs.get.mkString(" ") should include("action list has this
many actions")
}
- wsk.action.delete(name, expectedExitCode = TestUtils.NOT_FOUND)
+ wsk.action.delete(name, expectedExitCode = NotFound.intValue)
}
it should "invoke an action receiving context properties" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
@@ -534,11 +439,10 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
val webEnabled = flag.toLowerCase == "true" || flag.toLowerCase == "yes"
val rawEnabled = flag.toLowerCase == "raw"
- wsk.action.create(name, file, web = Some(flag), update = true)
+ wsk.action.create(name, file, web = Some(flag.toLowerCase), update =
true)
- val stdout = wsk.action.get(name, fieldFilter =
Some("annotations")).stdout
- assert(stdout.startsWith(s"ok: got action $name, displaying field
annotations\n"))
- removeCLIHeader(stdout).parseJson shouldBe JsArray(
+ val action = wsk.action.get(name)
+ action.getFieldJsValue("annotations") shouldBe JsArray(
JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6")),
JsObject("key" -> JsString("web-export"), "value" ->
JsBoolean(webEnabled || rawEnabled)),
JsObject("key" -> JsString("raw-http"), "value" ->
JsBoolean(rawEnabled)),
@@ -566,9 +470,8 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
wsk.action.create(name, file, web = Some("true"), update = true)
- val existinAnnots = wsk.action.get(name, fieldFilter =
Some("annotations")).stdout
- assert(existinAnnots.startsWith(s"ok: got action $name, displaying field
annotations\n"))
- removeCLIHeader(existinAnnots).parseJson shouldBe JsArray(
+ val action = wsk.action.get(name)
+ action.getFieldJsValue("annotations") shouldBe JsArray(
JsObject("key" -> JsString("web-export"), "value" -> JsBoolean(true)),
JsObject("key" -> JsString(origKey), "value" -> origValue),
JsObject("key" -> JsString("raw-http"), "value" -> JsBoolean(false)),
@@ -578,9 +481,8 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
wsk.action.create(name, file, web = Some("true"), update = true,
annotations = updateAnnots)
- val updatedAnnots = wsk.action.get(name, fieldFilter =
Some("annotations")).stdout
- assert(updatedAnnots.startsWith(s"ok: got action $name, displaying field
annotations\n"))
- removeCLIHeader(updatedAnnots).parseJson shouldBe JsArray(
+ val updatedAction = wsk.action.get(name)
+ updatedAction.getFieldJsValue("annotations") shouldBe JsArray(
JsObject("key" -> JsString("web-export"), "value" -> JsBoolean(true)),
JsObject("key" -> JsString(origKey), "value" -> overwrittenValue),
JsObject("key" -> JsString(updateKey), "value" -> updateValue),
@@ -598,29 +500,14 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
action.create(name, file, web = Some("true"), update = true)
}
- val stdout = wsk.action.get(name, fieldFilter =
Some("annotations")).stdout
- assert(stdout.startsWith(s"ok: got action $name, displaying field
annotations\n"))
- removeCLIHeader(stdout).parseJson shouldBe JsArray(
+ val action = wsk.action.get(name)
+ action.getFieldJsValue("annotations") shouldBe JsArray(
JsObject("key" -> JsString("web-export"), "value" -> JsBoolean(true)),
JsObject("key" -> JsString("raw-http"), "value" -> JsBoolean(false)),
JsObject("key" -> JsString("final"), "value" -> JsBoolean(true)),
JsObject("key" -> JsString("exec"), "value" -> JsString("nodejs:6")))
}
- it should "reject action create and update with invalid web flag input" in
withAssetCleaner(wskprops) {
- (wp, assetHelper) =>
- val name = "webaction"
- val file = Some(TestUtils.getTestActionFilename("echo.js"))
- val invalidInput = "bogus"
- val errorMsg =
- s"Invalid argument '$invalidInput' for --web flag. Valid input consist
of 'yes', 'true', 'raw', 'false', or 'no'."
- wsk.action.create(name, file, web = Some(invalidInput), expectedExitCode
= MISUSE_EXIT).stderr should include(
- errorMsg)
- wsk.action
- .create(name, file, web = Some(invalidInput), update = true,
expectedExitCode = MISUSE_EXIT)
- .stderr should include(errorMsg)
- }
-
it should "invoke action while not encoding &, <, > characters" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
val name = "nonescape"
val file = Some(TestUtils.getTestActionFilename("hello.js"))
@@ -639,259 +526,12 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
}
}
- it should "get an action URL" in withAssetCleaner(wskprops) { (wp,
assetHelper) =>
- val actionName = "action name@_-."
- val packageName = "package name@_-."
- val defaultPackageName = "default"
- val webActionName = "web action name@_-."
- val nonExistentActionName = "non-existence action"
- val packagedAction = s"$packageName/$actionName"
- val packagedWebAction = s"$packageName/$webActionName"
- val namespace = wsk.namespace.whois()
- val encodedActionName = URLEncoder.encode(actionName,
StandardCharsets.UTF_8.name).replace("+", "%20")
- val encodedPackageName = URLEncoder.encode(packageName,
StandardCharsets.UTF_8.name).replace("+", "%20")
- val encodedWebActionName = URLEncoder.encode(webActionName,
StandardCharsets.UTF_8.name).replace("+", "%20")
- val encodedNamespace = URLEncoder.encode(namespace,
StandardCharsets.UTF_8.name).replace("+", "%20")
- val scheme = "https"
- val actionPath = "%s://%s/api/%s/namespaces/%s/actions/%s"
- val packagedActionPath = s"$actionPath/%s"
- val webActionPath = "%s://%s/api/%s/web/%s/%s/%s"
-
- assetHelper.withCleaner(wsk.action, actionName) { (action, _) =>
- action.create(actionName, defaultAction)
- }
-
- assetHelper.withCleaner(wsk.action, webActionName) { (action, _) =>
- action.create(webActionName, defaultAction, web = Some("true"))
- }
-
- assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
- pkg.create(packageName)
- }
-
- assetHelper.withCleaner(wsk.action, packagedAction) { (action, _) =>
- action.create(packagedAction, defaultAction)
- }
-
- assetHelper.withCleaner(wsk.action, packagedWebAction) { (action, _) =>
- action.create(packagedWebAction, defaultAction, web = Some("true"))
- }
-
- wsk.action.get(actionName, url = Some(true)).stdout should include(
- actionPath.format(scheme, wskprops.apihost, wskprops.apiversion,
encodedNamespace, encodedActionName))
-
- // Ensure url flag works when a field filter and summary flag are specified
- wsk.action.get(actionName, url = Some(true), fieldFilter = Some("field"),
summary = true).stdout should include(
- actionPath.format(scheme, wskprops.apihost, wskprops.apiversion,
encodedNamespace, encodedActionName))
-
- wsk.action.get(webActionName, url = Some(true)).stdout should include(
- webActionPath
- .format(
- scheme,
- wskprops.apihost,
- wskprops.apiversion,
- encodedNamespace,
- defaultPackageName,
- encodedWebActionName))
-
- wsk.action.get(packagedAction, url = Some(true)).stdout should include(
- packagedActionPath
- .format(scheme, wskprops.apihost, wskprops.apiversion,
encodedNamespace, encodedPackageName, encodedActionName))
-
- wsk.action.get(packagedWebAction, url = Some(true)).stdout should include(
- webActionPath
- .format(
- scheme,
- wskprops.apihost,
- wskprops.apiversion,
- encodedNamespace,
- encodedPackageName,
- encodedWebActionName))
-
- wsk.action.get(nonExistentActionName, url = Some(true), expectedExitCode =
NOT_FOUND)
-
- val httpsProps = WskProps(apihost = "https://" + wskprops.apihost)
- wsk.action.get(actionName, url = Some(true))(httpsProps).stdout should
include(
- actionPath
- .format("https", wskprops.apihost, wskprops.apiversion,
encodedNamespace, encodedActionName))
- wsk.action.get(webActionName, url = Some(true))(httpsProps).stdout should
include(
- webActionPath
- .format(
- "https",
- wskprops.apihost,
- wskprops.apiversion,
- encodedNamespace,
- defaultPackageName,
- encodedWebActionName))
-
- }
- it should "limit length of HTTP request and response bodies for --verbose"
in withAssetCleaner(wskprops) {
- (wp, assetHelper) =>
- val name = "limitVerbose"
- val msg = "will be truncated"
- val params = Seq("-p", "bigValue", "a" * 1000)
-
- assetHelper.withCleaner(wsk.action, name) { (action, _) =>
- action.create(name, Some(TestUtils.getTestActionFilename("echo.js")))
- }
-
- val truncated = wsk
- .cli(Seq("action", "invoke", name, "-b", "-v", "--auth",
wskprops.authKey) ++ params ++ wskprops.overrides)
- .stdout
- msg.r.findAllIn(truncated).length shouldBe 2
-
- val notTruncated = wsk
- .cli(Seq("action", "invoke", name, "-b", "-d", "--auth",
wskprops.authKey) ++ params ++ wskprops.overrides)
- .stdout
- msg.r.findAllIn(notTruncated).length shouldBe 0
- }
-
- it should "denote bound and finalized action parameters for action
summaries" in withAssetCleaner(wskprops) {
- (wp, assetHelper) =>
- val nameBoundParams = "actionBoundParams"
- val nameFinalParams = "actionFinalParams"
- val paramAnnot = "paramAnnot"
- val paramOverlap = "paramOverlap"
- val paramBound = "paramBound"
- val annots = Map(
- "parameters" -> JsArray(
- JsObject("name" -> JsString(paramAnnot), "description" ->
JsString("Annotated")),
- JsObject("name" -> JsString(paramOverlap), "description" ->
JsString("Annotated And Bound"))))
- val annotsFinal = Map(
- "final" -> JsBoolean(true),
- "parameters" -> JsArray(
- JsObject("name" -> JsString(paramAnnot), "description" ->
JsString("Annotated Parameter description")),
- JsObject("name" -> JsString(paramOverlap), "description" ->
JsString("Annotated And Bound"))))
- val paramsBound = Map(paramBound -> JsString("Bound"), paramOverlap ->
JsString("Bound And Annotated"))
-
- assetHelper.withCleaner(wsk.action, nameBoundParams) { (action, _) =>
- action.create(nameBoundParams, defaultAction, annotations = annots,
parameters = paramsBound)
- }
- assetHelper.withCleaner(wsk.action, nameFinalParams) { (action, _) =>
- action.create(nameFinalParams, defaultAction, annotations =
annotsFinal, parameters = paramsBound)
- }
-
- val stdoutBound = wsk.action.get(nameBoundParams, summary = true).stdout
- val stdoutFinal = wsk.action.get(nameFinalParams, summary = true).stdout
-
- stdoutBound should include(s"(parameters: $paramAnnot, *$paramBound,
*$paramOverlap)")
- stdoutFinal should include(s"(parameters: $paramAnnot, **$paramBound,
**$paramOverlap)")
- }
-
- it should "create, and get an action summary without a description and/or
defined parameters" in withAssetCleaner(
- wskprops) { (wp, assetHelper) =>
- val actNameNoParams = "actionNoParams"
- val actNameNoDesc = "actionNoDesc"
- val actNameNoDescOrParams = "actionNoDescOrParams"
- val desc = "Action description"
- val descFromParamsResp = "Returns a result based on parameters"
- val annotsNoParams = Map("description" -> JsString(desc))
- val annotsNoDesc = Map(
- "parameters" -> JsArray(
- JsObject("name" -> JsString("paramName1"), "description" ->
JsString("Parameter description 1")),
- JsObject("name" -> JsString("paramName2"), "description" ->
JsString("Parameter description 2"))))
-
- assetHelper.withCleaner(wsk.action, actNameNoDesc) { (action, _) =>
- action.create(actNameNoDesc, defaultAction, annotations = annotsNoDesc)
- }
- assetHelper.withCleaner(wsk.action, actNameNoParams) { (action, _) =>
- action.create(actNameNoParams, defaultAction, annotations =
annotsNoParams)
- }
- assetHelper.withCleaner(wsk.action, actNameNoDescOrParams) { (action, _) =>
- action.create(actNameNoDescOrParams, defaultAction)
- }
-
- val stdoutNoDesc = wsk.action.get(actNameNoDesc, summary = true).stdout
- val stdoutNoParams = wsk.action.get(actNameNoParams, summary = true).stdout
- val stdoutNoDescOrParams = wsk.action.get(actNameNoDescOrParams, summary =
true).stdout
- val namespace = wsk.namespace.whois()
-
- stdoutNoDesc should include regex (s"(?i)action
/${namespace}/${actNameNoDesc}: ${descFromParamsResp} paramName1 and
paramName2\\s*\\(parameters: paramName1, paramName2\\)")
- stdoutNoParams should include regex (s"(?i)action
/${namespace}/${actNameNoParams}: ${desc}\\s*\\(parameters: none defined\\)")
- stdoutNoDescOrParams should include regex (s"(?i)action
/${namespace}/${actNameNoDescOrParams}\\s*\\(parameters: none defined\\)")
- }
-
- it should "save action code to file" in withAssetCleaner(wskprops) { (wp,
assetHelper) =>
- val name = "saveAction"
- val seqName = "seqName"
- val dockerName = "dockerName"
- val containerName =
s"bogus${Random.alphanumeric.take(16).mkString.toLowerCase}"
- val saveName = s"save-as-$name.js"
- val badSaveName = s"bad-directory${File.separator}$saveName"
-
- // Test for successful --save
- assetHelper.withCleaner(wsk.action, name) { (action, _) =>
- action.create(name, defaultAction)
- }
-
- val saveMsg = wsk.action.get(name, save = Some(true)).stdout
-
- saveMsg should include(s"saved action code to ")
-
- val savePath = saveMsg.split("ok: saved action code to ")(1).trim()
- val saveFile = new File(savePath);
-
- try {
- saveFile.exists shouldBe true
-
- // Test for failure saving file when it already exist
- wsk.action.get(name, save = Some(true), expectedExitCode =
MISUSE_EXIT).stderr should include(
- s"The file '$name.js' already exists")
- } finally {
- saveFile.delete()
- }
-
- // Test for successful --save-as
- val saveAsMsg = wsk.action.get(name, saveAs = Some(saveName)).stdout
-
- saveAsMsg should include(s"saved action code to ")
-
- val saveAsPath = saveAsMsg.split("ok: saved action code to ")(1).trim()
- val saveAsFile = new File(saveAsPath);
-
- try {
- saveAsFile.exists shouldBe true
-
- // Test for failure saving file when it already exist
- wsk.action.get(name, saveAs = Some(saveName), expectedExitCode =
MISUSE_EXIT).stderr should include(
- s"The file '$saveName' already exists")
- } finally {
- saveAsFile.delete()
- }
-
- // Test for failure when using an invalid filename
- wsk.action.get(name, saveAs = Some(badSaveName), expectedExitCode =
MISUSE_EXIT).stderr should include(
- s"Cannot create file '$badSaveName'")
-
- // Test for failure saving Docker images
- assetHelper.withCleaner(wsk.action, dockerName) { (action, _) =>
- action.create(dockerName, None, docker = Some(containerName))
- }
-
- wsk.action.get(dockerName, save = Some(true), expectedExitCode =
MISUSE_EXIT).stderr should include(
- "Cannot save Docker images")
-
- wsk.action.get(dockerName, saveAs = Some(dockerName), expectedExitCode =
MISUSE_EXIT).stderr should include(
- "Cannot save Docker images")
-
- // Tes for failure saving sequences
- assetHelper.withCleaner(wsk.action, seqName) { (action, _) =>
- action.create(seqName, Some(name), kind = Some("sequence"))
- }
-
- wsk.action.get(seqName, save = Some(true), expectedExitCode =
MISUSE_EXIT).stderr should include(
- "Cannot save action sequences")
-
- wsk.action.get(seqName, saveAs = Some(seqName), expectedExitCode =
MISUSE_EXIT).stderr should include(
- "Cannot save action sequences")
- }
-
behavior of "Wsk packages"
it should "create, and delete a package" in {
val name = "createDeletePackage"
- wsk.pkg.create(name).stdout should include(s"ok: created package $name")
- wsk.pkg.delete(name).stdout should include(s"ok: deleted package $name")
+ wsk.pkg.create(name).statusCode shouldBe OK
+ wsk.pkg.delete(name).statusCode shouldBe OK
}
it should "create, and get a package to verify parameter and annotation
parsing" in withAssetCleaner(wskprops) {
@@ -902,11 +542,10 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
pkg.create(name, annotations = getValidJSONTestArgInput, parameters =
getValidJSONTestArgInput)
}
- val stdout = wsk.pkg.get(name).stdout
- assert(stdout.startsWith(s"ok: got package $name\n"))
+ val pack = wsk.pkg.get(name)
- val receivedParams =
wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
- val receivedAnnots =
wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+ val receivedParams =
wsk.parseJsonString(pack.stdout).fields("parameters").convertTo[JsArray].elements
+ val receivedAnnots =
wsk.parseJsonString(pack.stdout).fields("annotations").convertTo[JsArray].elements
val escapedJSONArr =
getValidJSONTestArgOutput.convertTo[JsArray].elements
for (expectedItem <- escapedJSONArr) {
@@ -926,8 +565,6 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
}
val stdout = wsk.pkg.get(name).stdout
- assert(stdout.startsWith(s"ok: got package $name\n"))
-
val receivedParams =
wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
val receivedAnnots =
wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
val escapedJSONArr = getJSONFileOutput.convertTo[JsArray].elements
@@ -946,11 +583,9 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
pkg.create(name, parameters = getEscapedJSONTestArgInput, annotations
= getEscapedJSONTestArgInput)
}
- val stdout = wsk.pkg.get(name).stdout
- assert(stdout.startsWith(s"ok: got package $name\n"))
-
- val receivedParams =
wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
- val receivedAnnots =
wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
+ val pack = wsk.pkg.get(name)
+ val receivedParams =
wsk.parseJsonString(pack.stdout).fields("parameters").convertTo[JsArray].elements
+ val receivedAnnots =
wsk.parseJsonString(pack.stdout).fields("annotations").convertTo[JsArray].elements
val escapedJSONArr =
getEscapedJSONTestArgOutput.convertTo[JsArray].elements
for (expectedItem <- escapedJSONArr) {
@@ -966,72 +601,16 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
action.create(name, file)
}
- wsk.pkg.get(name, expectedExitCode = CONFLICT).stderr should
include(Messages.conformanceMessage)
+ wsk.pkg.get(name, expectedExitCode = Conflict.intValue).stderr should
include(Messages.conformanceMessage)
- wsk.pkg.bind(name, "bogus", expectedExitCode = CONFLICT).stderr should
include(Messages.requestedBindingIsNotValid)
+ wsk.pkg.bind(name, "bogus", expectedExitCode = Conflict.intValue).stderr
should include(
+ Messages.requestedBindingIsNotValid)
- wsk.pkg.bind("bogus", "alsobogus", expectedExitCode = BAD_REQUEST).stderr
should include(
+ wsk.pkg.bind("bogus", "alsobogus", expectedExitCode =
BadRequest.intValue).stderr should include(
Messages.bindingDoesNotExist)
}
- it should "create, and get a package summary without a description and/or
parameters" in withAssetCleaner(wskprops) {
- (wp, assetHelper) =>
- val pkgNoDesc = "pkgNoDesc"
- val pkgNoParams = "pkgNoParams"
- val pkgNoDescOrParams = "pkgNoDescOrParams"
- val pkgDesc = "Package description"
- val descFromParams = "Returns a result based on parameters"
- val namespace = wsk.namespace.whois()
- val qualpkgNoDesc = s"/${namespace}/${pkgNoDesc}"
- val qualpkgNoParams = s"/${namespace}/${pkgNoParams}"
- val qualpkgNoDescOrParams = s"/${namespace}/${pkgNoDescOrParams}"
-
- val pkgAnnotsNoParams = Map("description" -> JsString(pkgDesc))
- val pkgAnnotsNoDesc = Map(
- "parameters" -> JsArray(
- JsObject("name" -> JsString("paramName1"), "description" ->
JsString("Parameter description 1")),
- JsObject("name" -> JsString("paramName2"), "description" ->
JsString("Parameter description 2"))))
-
- assetHelper.withCleaner(wsk.pkg, pkgNoDesc) { (pkg, _) =>
- pkg.create(pkgNoDesc, annotations = pkgAnnotsNoDesc)
- }
- assetHelper.withCleaner(wsk.pkg, pkgNoParams) { (pkg, _) =>
- pkg.create(pkgNoParams, annotations = pkgAnnotsNoParams)
- }
- assetHelper.withCleaner(wsk.pkg, pkgNoDescOrParams) { (pkg, _) =>
- pkg.create(pkgNoDescOrParams)
- }
-
- val stdoutNoDescPkg = wsk.pkg.get(pkgNoDesc, summary = true).stdout
- val stdoutNoParamsPkg = wsk.pkg.get(pkgNoParams, summary = true).stdout
- val stdoutNoDescOrParams = wsk.pkg.get(pkgNoDescOrParams, summary =
true).stdout
-
- stdoutNoDescPkg should include regex (s"(?i)package ${qualpkgNoDesc}:
${descFromParams} paramName1 and paramName2\\s*\\(parameters: paramName1,
paramName2\\)")
- stdoutNoParamsPkg should include regex (s"(?i)package
${qualpkgNoParams}: ${pkgDesc}\\s*\\(parameters: none defined\\)")
- stdoutNoDescOrParams should include regex (s"(?i)package
${qualpkgNoDescOrParams}\\s*\\(parameters: none defined\\)")
- }
-
- it should "denote bound package parameters for package summaries" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- val pkgBoundParams = "pkgBoundParams"
- val pkgParamAnnot = "pkgParamAnnot"
- val pkgParamOverlap = "pkgParamOverlap"
- val pkgParamBound = "pkgParamBound"
- val pkgAnnots = Map(
- "parameters" -> JsArray(
- JsObject("name" -> JsString(pkgParamAnnot), "description" ->
JsString("Annotated")),
- JsObject("name" -> JsString(pkgParamOverlap), "description" ->
JsString("Annotated And Bound"))))
- val pkgParamsBound = Map(pkgParamBound -> JsString("Bound"),
pkgParamOverlap -> JsString("Bound And Annotated"))
-
- assetHelper.withCleaner(wsk.pkg, pkgBoundParams) { (pkg, _) =>
- pkg.create(pkgBoundParams, annotations = pkgAnnots, parameters =
pkgParamsBound)
- }
-
- val pkgStdoutBound = wsk.pkg.get(pkgBoundParams, summary = true).stdout
-
- pkgStdoutBound should include(s"(parameters: $pkgParamAnnot,
*$pkgParamBound, *$pkgParamOverlap)")
- }
-
behavior of "Wsk triggers"
it should "create, and get a trigger to verify parameter and annotation
parsing" in withAssetCleaner(wskprops) {
@@ -1043,7 +622,6 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
}
val stdout = wsk.trigger.get(name).stdout
- assert(stdout.startsWith(s"ok: got trigger $name\n"))
val receivedParams =
wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
val receivedAnnots =
wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
@@ -1066,7 +644,6 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
}
val stdout = wsk.trigger.get(name).stdout
- assert(stdout.startsWith(s"ok: got trigger $name\n"))
val receivedParams =
wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
val receivedAnnots =
wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
@@ -1078,19 +655,6 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
}
}
- it should "display a trigger summary when --summary flag is used with 'wsk
trigger get'" in withAssetCleaner(wskprops) {
- (wp, assetHelper) =>
- val triggerName = "mySummaryTrigger"
- assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = false)
{ (trigger, name) =>
- trigger.create(name)
- }
-
- // Summary namespace should match one of the allowable namespaces
(typically 'guest')
- val ns = wsk.namespace.whois()
- val stdout = wsk.trigger.get(triggerName, summary = true).stdout
- stdout should include regex (s"(?i)trigger\\s+/$ns/$triggerName")
- }
-
it should "create a trigger with the proper parameter and annotation
escapes" in withAssetCleaner(wskprops) {
(wp, assetHelper) =>
val name = "triggerEscapes"
@@ -1100,7 +664,6 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
}
val stdout = wsk.trigger.get(name).stdout
- assert(stdout.startsWith(s"ok: got trigger $name\n"))
val receivedParams =
wsk.parseJsonString(stdout).fields("parameters").convertTo[JsArray].elements
val receivedAnnots =
wsk.parseJsonString(stdout).fields("annotations").convertTo[JsArray].elements
@@ -1115,11 +678,11 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
it should "not create a trigger when feed fails to initialize" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
assetHelper.withCleaner(wsk.trigger, "badfeed", confirmDelete = false) {
(trigger, name) =>
trigger.create(name, feed = Some(s"bogus"), expectedExitCode =
ANY_ERROR_EXIT).exitCode should equal(NOT_FOUND)
- trigger.get(name, expectedExitCode = NOT_FOUND)
+ trigger.get(name, expectedExitCode = NotFound.intValue)
trigger.create(name, feed = Some(s"bogus/feed"), expectedExitCode =
ANY_ERROR_EXIT).exitCode should equal(
NOT_FOUND)
- trigger.get(name, expectedExitCode = NOT_FOUND)
+ trigger.get(name, expectedExitCode = NotFound.intValue)
}
}
@@ -1133,564 +696,11 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
}
try {
- wsk.trigger.create(triggerName, feed = Some(actionName)).stdout should
include(""""lifecycleEvent": "CREATE"""")
+ wsk.trigger.create(triggerName, feed = Some(actionName)).statusCode
shouldBe OK
- wsk.trigger.get(triggerName).stdout should include(""""lifecycleEvent":
"READ"""")
+ wsk.trigger.get(triggerName).statusCode shouldBe OK
} finally {
- wsk.trigger.delete(triggerName).stdout should
include(""""lifecycleEvent": "DELETE"""")
- }
- }
-
- it should "denote bound trigger parameters for trigger summaries" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- val trgBoundParams = "trgBoundParams"
- val trgParamAnnot = "trgParamAnnot"
- val trgParamOverlap = "trgParamOverlap"
- val trgParamBound = "trgParamBound"
- val trgAnnots = Map(
- "parameters" -> JsArray(
- JsObject("name" -> JsString(trgParamAnnot), "description" ->
JsString("Annotated")),
- JsObject("name" -> JsString(trgParamOverlap), "description" ->
JsString("Annotated And Bound"))))
- val trgParamsBound = Map(trgParamBound -> JsString("Bound"),
trgParamOverlap -> JsString("Bound And Annotated"))
-
- assetHelper.withCleaner(wsk.trigger, trgBoundParams) { (trigger, _) =>
- trigger.create(trgBoundParams, annotations = trgAnnots, parameters =
trgParamsBound)
- }
-
- val trgStdoutBound = wsk.trigger.get(trgBoundParams, summary = true).stdout
-
- trgStdoutBound should include(s"(parameters: $trgParamAnnot,
*$trgParamBound, *$trgParamOverlap)")
- }
-
- it should "create, and get a trigger summary without a description and/or
parameters" in withAssetCleaner(wskprops) {
- (wp, assetHelper) =>
- val trgNoDesc = "trgNoDesc"
- val trgNoParams = "trgNoParams"
- val trgNoDescOrParams = "trgNoDescOrParams"
- val trgDesc = "Package description"
- val descFromParams = "Returns a result based on parameters"
- val namespace = wsk.namespace.whois()
- val qualtrgNoDesc = s"/${namespace}/${trgNoDesc}"
- val qualtrgNoParams = s"/${namespace}/${trgNoParams}"
- val qualtrgNoDescOrParams = s"/${namespace}/${trgNoDescOrParams}"
-
- val trgAnnotsNoParams = Map("description" -> JsString(trgDesc))
- val trgAnnotsNoDesc = Map(
- "parameters" -> JsArray(
- JsObject("name" -> JsString("paramName1"), "description" ->
JsString("Parameter description 1")),
- JsObject("name" -> JsString("paramName2"), "description" ->
JsString("Parameter description 2"))))
-
- assetHelper.withCleaner(wsk.trigger, trgNoDesc) { (trigger, _) =>
- trigger.create(trgNoDesc, annotations = trgAnnotsNoDesc)
- }
- assetHelper.withCleaner(wsk.trigger, trgNoParams) { (trigger, _) =>
- trigger.create(trgNoParams, annotations = trgAnnotsNoParams)
- }
- assetHelper.withCleaner(wsk.trigger, trgNoDescOrParams) { (trigger, _) =>
- trigger.create(trgNoDescOrParams)
- }
-
- val stdoutNoDescPkg = wsk.trigger.get(trgNoDesc, summary = true).stdout
- val stdoutNoParamsPkg = wsk.trigger.get(trgNoParams, summary =
true).stdout
- val stdoutNoDescOrParams = wsk.trigger.get(trgNoDescOrParams, summary =
true).stdout
-
- stdoutNoDescPkg should include regex (s"(?i)trigger ${qualtrgNoDesc}:
${descFromParams} paramName1 and paramName2\\s*\\(parameters: paramName1,
paramName2\\)")
- stdoutNoParamsPkg should include regex (s"(?i)trigger
${qualtrgNoParams}: ${trgDesc}\\s*\\(parameters: none defined\\)")
- stdoutNoDescOrParams should include regex (s"(?i)trigger
${qualtrgNoDescOrParams}\\s*\\(parameters: none defined\\)")
- }
-
- behavior of "Wsk entity list formatting"
-
- it should "create, and list a package with a long name" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- val name = "x" * 70
- assetHelper.withCleaner(wsk.pkg, name) { (pkg, _) =>
- pkg.create(name)
- }
- retry({
- wsk.pkg.list().stdout should include(s"$name private")
- }, 5, Some(1 second))
- }
-
- it should "create, and list an action with a long name" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- val name = "x" * 70
- val file = Some(TestUtils.getTestActionFilename("hello.js"))
- assetHelper.withCleaner(wsk.action, name) { (action, _) =>
- action.create(name, file)
- }
- retry({
- wsk.action.list().stdout should include(s"$name private nodejs")
- }, 5, Some(1 second))
- }
-
- it should "create, and list a trigger with a long name" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- val name = "x" * 70
- assetHelper.withCleaner(wsk.trigger, name) { (trigger, _) =>
- trigger.create(name)
- }
- retry({
- wsk.trigger.list().stdout should include(s"$name private")
- }, 5, Some(1 second))
- }
-
- it should "create, and list a rule with a long name" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- val ruleName = "x" * 70
- val triggerName = "listRulesTrigger"
- val actionName = "listRulesAction";
- assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
- trigger.create(name)
- }
- assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
- action.create(name, defaultAction)
- }
- assetHelper.withCleaner(wsk.rule, ruleName) { (rule, name) =>
- rule.create(name, trigger = triggerName, action = actionName)
- }
- retry({
- wsk.rule.list().stdout should include(s"$ruleName private")
- }, 5, Some(1 second))
- }
-
- it should "return a list of alphabetized actions" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- // Declare 4 actions, create them out of alphabetical order
- val actionName = "actionAlphaTest"
- for (i <- 1 to 3) {
- val name = s"$actionName$i"
- assetHelper.withCleaner(wsk.action, name) { (action, name) =>
- action.create(name, defaultAction)
- }
- }
- retry({
- val original = wsk.action.list(nameSort = Some(true)).stdout
- // Create list with action names in correct order
- val scalaSorted = List(s"${actionName}1", s"${actionName}2",
s"${actionName}3")
- // Filter out everything not previously created
- val regex = s"${actionName}[1-3]".r
- // Retrieve action names into list as found in original
- val list = (regex.findAllMatchIn(original)).toList
- scalaSorted.toString shouldEqual list.toString
- }, 5, Some(1 second))
- }
-
- it should "return an alphabetized list with default package actions on top"
in withAssetCleaner(wskprops) {
- (wp, assetHelper) =>
- // Declare 4 actions, create them out of alphabetical order
- val actionName = "actionPackageAlphaTest"
- val packageName = "packageAlphaTest"
- assetHelper.withCleaner(wsk.action, actionName) { (action, actionName) =>
- action.create(actionName, defaultAction)
- }
- assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, packageName) =>
- pkg.create(packageName)
- }
- for (i <- 1 to 3) {
- val name = s"${packageName}/${actionName}$i"
- assetHelper.withCleaner(wsk.action, name) { (action, name) =>
- action.create(name, defaultAction)
- }
- }
- retry(
- {
- val original = wsk.action.list(nameSort = Some(true)).stdout
- // Create list with action names in correct order
- val scalaSorted = List(
- s"$actionName",
- s"${packageName}/${actionName}1",
- s"${packageName}/${actionName}2",
- s"${packageName}/${actionName}3")
- // Filter out everything not previously created
- val regexNoPackage = s"$actionName".r
- val regexWithPackage = s"${packageName}/${actionName}[1-3]".r
- // Retrieve action names into list as found in original
- val list = regexNoPackage.findFirstIn(original).get ::
(regexWithPackage.findAllMatchIn(original)).toList
- scalaSorted.toString shouldEqual list.toString
- },
- 5,
- Some(1 second))
- }
-
- it should "return a list of alphabetized packages" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- // Declare 3 packages, create them out of alphabetical order
- val packageName = "pkgAlphaTest"
- for (i <- 1 to 3) {
- val name = s"$packageName$i"
- assetHelper.withCleaner(wsk.pkg, name) { (pkg, name) =>
- pkg.create(name)
- }
- }
- retry({
- val original = wsk.pkg.list(nameSort = Some(true)).stdout
- // Create list with package names in correct order
- val scalaSorted = List(s"${packageName}1", s"${packageName}2",
s"${packageName}3")
- // Filter out everything not previously created
- val regex = s"${packageName}[1-3]".r
- // Retrieve package names into list as found in original
- val list = (regex.findAllMatchIn(original)).toList
- scalaSorted.toString shouldEqual list.toString
- }, 5, Some(1 second))
- }
-
- it should "return a list of alphabetized triggers" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- // Declare 4 triggers, create them out of alphabetical order
- val triggerName = "triggerAlphaTest"
- for (i <- 1 to 3) {
- val name = s"$triggerName$i"
- assetHelper.withCleaner(wsk.trigger, name) { (trigger, name) =>
- trigger.create(name)
- }
- }
- retry({
- val original = wsk.trigger.list(nameSort = Some(true)).stdout
- // Create list with trigger names in correct order
- val scalaSorted = List(s"${triggerName}1", s"${triggerName}2",
s"${triggerName}3")
- // Filter out everything not previously created
- val regex = s"${triggerName}[1-3]".r
- // Retrieve trigger names into list as found in original
- val list = (regex.findAllMatchIn(original)).toList
- scalaSorted.toString shouldEqual list.toString
- }, 5, Some(1 second))
- }
-
- it should "return a list of alphabetized rules" in
withAssetCleaner(wskprops) { (wp, assetHelper) =>
- // Declare a trigger and an action for the purposes of creating rules
- val triggerName = "listRulesTrigger"
- val actionName = "listRulesAction"
-
- assetHelper.withCleaner(wsk.trigger, triggerName) { (trigger, name) =>
- trigger.create(name)
- }
- assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
- action.create(name, defaultAction)
- }
- // Declare 3 rules, create them out of alphabetical order
- val ruleName = "ruleAlphaTest"
- for (i <- 1 to 3) {
- val name = s"$ruleName$i"
- assetHelper.withCleaner(wsk.rule, name) { (rule, name) =>
- rule.create(name, trigger = triggerName, action = actionName)
- }
- }
- retry({
- val original = wsk.rule.list(nameSort = Some(true)).stdout
- // Create list with rule names in correct order
- val scalaSorted = List(s"${ruleName}1", s"${ruleName}2", s"${ruleName}3")
- // Filter out everything not previously created
- val regex = s"${ruleName}[1-3]".r
- // Retrieve rule names into list as found in original
- val list = (regex.findAllMatchIn(original)).toList
- scalaSorted.toString shouldEqual list.toString
- })
- }
-
- behavior of "Wsk params and annotations"
-
- it should "reject commands that are executed with invalid JSON for
annotations and parameters" in {
- val invalidJSONInputs = getInvalidJSONInput
- val invalidJSONFiles = Seq(
- TestUtils.getTestActionFilename("malformed.js"),
- TestUtils.getTestActionFilename("invalidInput1.json"),
- TestUtils.getTestActionFilename("invalidInput2.json"),
- TestUtils.getTestActionFilename("invalidInput3.json"),
- TestUtils.getTestActionFilename("invalidInput4.json"))
- val paramCmds = Seq(
- Seq("action", "create", "actionName",
TestUtils.getTestActionFilename("hello.js")),
- Seq("action", "update", "actionName",
TestUtils.getTestActionFilename("hello.js")),
- Seq("action", "invoke", "actionName"),
- Seq("package", "create", "packageName"),
- Seq("package", "update", "packageName"),
- Seq("package", "bind", "packageName", "boundPackageName"),
- Seq("trigger", "create", "triggerName"),
- Seq("trigger", "update", "triggerName"),
- Seq("trigger", "fire", "triggerName"))
- val annotCmds = Seq(
- Seq("action", "create", "actionName",
TestUtils.getTestActionFilename("hello.js")),
- Seq("action", "update", "actionName",
TestUtils.getTestActionFilename("hello.js")),
- Seq("package", "create", "packageName"),
- Seq("package", "update", "packageName"),
- Seq("package", "bind", "packageName", "boundPackageName"),
- Seq("trigger", "create", "triggerName"),
- Seq("trigger", "update", "triggerName"))
-
- for (cmd <- paramCmds) {
- for (invalid <- invalidJSONInputs) {
- wsk
- .cli(cmd ++ Seq("-p", "key", invalid) ++ wskprops.overrides,
expectedExitCode = ERROR_EXIT)
- .stderr should include("Invalid parameter argument")
- }
-
- for (invalid <- invalidJSONFiles) {
- wsk.cli(cmd ++ Seq("-P", invalid) ++ wskprops.overrides,
expectedExitCode = ERROR_EXIT).stderr should include(
- "Invalid parameter argument")
-
- }
- }
-
- for (cmd <- annotCmds) {
- for (invalid <- invalidJSONInputs) {
- wsk
- .cli(cmd ++ Seq("-a", "key", invalid) ++ wskprops.overrides,
expectedExitCode = ERROR_EXIT)
- .stderr should include("Invalid annotation argument")
- }
-
- for (invalid <- invalidJSONFiles) {
- wsk.cli(cmd ++ Seq("-A", invalid) ++ wskprops.overrides,
expectedExitCode = ERROR_EXIT).stderr should include(
- "Invalid annotation argument")
- }
- }
- }
-
- it should "reject commands that are executed with a missing or invalid
parameter or annotation file" in {
- val emptyFile = TestUtils.getTestActionFilename("emtpy.js")
- val missingFile = "notafile"
- val emptyFileMsg = s"File '$emptyFile' is not a valid file or it does not
exist"
- val missingFileMsg = s"File '$missingFile' is not a valid file or it does
not exist"
- val invalidArgs = Seq(
- (
- Seq("action", "create", "actionName",
TestUtils.getTestActionFilename("hello.js"), "-P", emptyFile),
- emptyFileMsg),
- (
- Seq("action", "update", "actionName",
TestUtils.getTestActionFilename("hello.js"), "-P", emptyFile),
- emptyFileMsg),
- (Seq("action", "invoke", "actionName", "-P", emptyFile), emptyFileMsg),
- (Seq("action", "create", "actionName", "-P", emptyFile), emptyFileMsg),
- (Seq("action", "update", "actionName", "-P", emptyFile), emptyFileMsg),
- (Seq("action", "invoke", "actionName", "-P", emptyFile), emptyFileMsg),
- (Seq("package", "create", "packageName", "-P", emptyFile), emptyFileMsg),
- (Seq("package", "update", "packageName", "-P", emptyFile), emptyFileMsg),
- (Seq("package", "bind", "packageName", "boundPackageName", "-P",
emptyFile), emptyFileMsg),
- (Seq("package", "create", "packageName", "-P", emptyFile), emptyFileMsg),
- (Seq("package", "update", "packageName", "-P", emptyFile), emptyFileMsg),
- (Seq("package", "bind", "packageName", "boundPackageName", "-P",
emptyFile), emptyFileMsg),
- (Seq("trigger", "create", "triggerName", "-P", emptyFile), emptyFileMsg),
- (Seq("trigger", "update", "triggerName", "-P", emptyFile), emptyFileMsg),
- (Seq("trigger", "fire", "triggerName", "-P", emptyFile), emptyFileMsg),
- (Seq("trigger", "create", "triggerName", "-P", emptyFile), emptyFileMsg),
- (Seq("trigger", "update", "triggerName", "-P", emptyFile), emptyFileMsg),
- (Seq("trigger", "fire", "triggerName", "-P", emptyFile), emptyFileMsg),
- (
- Seq("action", "create", "actionName",
TestUtils.getTestActionFilename("hello.js"), "-A", missingFile),
- missingFileMsg),
- (
- Seq("action", "update", "actionName",
TestUtils.getTestActionFilename("hello.js"), "-A", missingFile),
- missingFileMsg),
- (Seq("action", "invoke", "actionName", "-A", missingFile),
missingFileMsg),
- (Seq("action", "create", "actionName", "-A", missingFile),
missingFileMsg),
- (Seq("action", "update", "actionName", "-A", missingFile),
missingFileMsg),
- (Seq("action", "invoke", "actionName", "-A", missingFile),
missingFileMsg),
- (Seq("package", "create", "packageName", "-A", missingFile),
missingFileMsg),
- (Seq("package", "update", "packageName", "-A", missingFile),
missingFileMsg),
- (Seq("package", "bind", "packageName", "boundPackageName", "-A",
missingFile), missingFileMsg),
- (Seq("package", "create", "packageName", "-A", missingFile),
missingFileMsg),
- (Seq("package", "update", "packageName", "-A", missingFile),
missingFileMsg),
- (Seq("package", "bind", "packageName", "boundPackageName", "-A",
missingFile), missingFileMsg),
- (Seq("trigger", "create", "triggerName", "-A", missingFile),
missingFileMsg),
- (Seq("trigger", "update", "triggerName", "-A", missingFile),
missingFileMsg),
- (Seq("trigger", "fire", "triggerName", "-A", missingFile),
missingFileMsg),
- (Seq("trigger", "create", "triggerName", "-A", missingFile),
missingFileMsg),
- (Seq("trigger", "update", "triggerName", "-A", missingFile),
missingFileMsg),
- (Seq("trigger", "fire", "triggerName", "-A", missingFile),
missingFileMsg))
-
- invalidArgs foreach {
- case (cmd, err) =>
- val stderr = wsk.cli(cmd, expectedExitCode = MISUSE_EXIT).stderr
- stderr should include(err)
- stderr should include("Run 'wsk --help' for usage.")
- }
- }
-
- it should "reject commands that are executed with not enough param or annot
arguments" in {
- val invalidParamMsg = "Arguments for '-p' must be a key/value pair"
- val invalidAnnotMsg = "Arguments for '-a' must be a key/value pair"
- val invalidParamFileMsg = "An argument must be provided for '-P'"
- val invalidAnnotFileMsg = "An argument must be provided for '-A'"
- val invalidArgs = Seq(
- (Seq("action", "create", "actionName", "-p"), invalidParamMsg),
- (Seq("action", "create", "actionName", "-p", "key"), invalidParamMsg),
- (Seq("action", "create", "actionName", "-P"), invalidParamFileMsg),
- (Seq("action", "update", "actionName", "-p"), invalidParamMsg),
- (Seq("action", "update", "actionName", "-p", "key"), invalidParamMsg),
- (Seq("action", "update", "actionName", "-P"), invalidParamFileMsg),
- (Seq("action", "invoke", "actionName", "-p"), invalidParamMsg),
- (Seq("action", "invoke", "actionName", "-p", "key"), invalidParamMsg),
- (Seq("action", "invoke", "actionName", "-P"), invalidParamFileMsg),
- (Seq("action", "create", "actionName", "-a"), invalidAnnotMsg),
- (Seq("action", "create", "actionName", "-a", "key"), invalidAnnotMsg),
- (Seq("action", "create", "actionName", "-A"), invalidAnnotFileMsg),
- (Seq("action", "update", "actionName", "-a"), invalidAnnotMsg),
- (Seq("action", "update", "actionName", "-a", "key"), invalidAnnotMsg),
- (Seq("action", "update", "actionName", "-A"), invalidAnnotFileMsg),
- (Seq("action", "invoke", "actionName", "-a"), invalidAnnotMsg),
- (Seq("action", "invoke", "actionName", "-a", "key"), invalidAnnotMsg),
- (Seq("action", "invoke", "actionName", "-A"), invalidAnnotFileMsg),
- (Seq("package", "create", "packageName", "-p"), invalidParamMsg),
- (Seq("package", "create", "packageName", "-p", "key"), invalidParamMsg),
- (Seq("package", "create", "packageName", "-P"), invalidParamFileMsg),
- (Seq("package", "update", "packageName", "-p"), invalidParamMsg),
- (Seq("package", "update", "packageName", "-p", "key"), invalidParamMsg),
- (Seq("package", "update", "packageName", "-P"), invalidParamFileMsg),
- (Seq("package", "bind", "packageName", "boundPackageName", "-p"),
invalidParamMsg),
- (Seq("package", "bind", "packageName", "boundPackageName", "-p", "key"),
invalidParamMsg),
- (Seq("package", "bind", "packageName", "boundPackageName", "-P"),
invalidParamFileMsg),
- (Seq("package", "create", "packageName", "-a"), invalidAnnotMsg),
- (Seq("package", "create", "packageName", "-a", "key"), invalidAnnotMsg),
- (Seq("package", "create", "packageName", "-A"), invalidAnnotFileMsg),
- (Seq("package", "update", "packageName", "-a"), invalidAnnotMsg),
- (Seq("package", "update", "packageName", "-a", "key"), invalidAnnotMsg),
- (Seq("package", "update", "packageName", "-A"), invalidAnnotFileMsg),
- (Seq("package", "bind", "packageName", "boundPackageName", "-a"),
invalidAnnotMsg),
- (Seq("package", "bind", "packageName", "boundPackageName", "-a", "key"),
invalidAnnotMsg),
- (Seq("package", "bind", "packageName", "boundPackageName", "-A"),
invalidAnnotFileMsg),
- (Seq("trigger", "create", "triggerName", "-p"), invalidParamMsg),
- (Seq("trigger", "create", "triggerName", "-p", "key"), invalidParamMsg),
- (Seq("trigger", "create", "triggerName", "-P"), invalidParamFileMsg),
- (Seq("trigger", "update", "triggerName", "-p"), invalidParamMsg),
- (Seq("trigger", "update", "triggerName", "-p", "key"), invalidParamMsg),
- (Seq("trigger", "update", "triggerName", "-P"), invalidParamFileMsg),
- (Seq("trigger", "fire", "triggerName", "-p"), invalidParamMsg),
- (Seq("trigger", "fire", "triggerName", "-p", "key"), invalidParamMsg),
- (Seq("trigger", "fire", "triggerName", "-P"), invalidParamFileMsg),
- (Seq("trigger", "create", "triggerName", "-a"), invalidAnnotMsg),
- (Seq("trigger", "create", "triggerName", "-a", "key"), invalidAnnotMsg),
- (Seq("trigger", "create", "triggerName", "-A"), invalidAnnotFileMsg),
- (Seq("trigger", "update", "triggerName", "-a"), invalidAnnotMsg),
- (Seq("trigger", "update", "triggerName", "-a", "key"), invalidAnnotMsg),
- (Seq("trigger", "update", "triggerName", "-A"), invalidAnnotFileMsg),
- (Seq("trigger", "fire", "triggerName", "-a"), invalidAnnotMsg),
- (Seq("trigger", "fire", "triggerName", "-a", "key"), invalidAnnotMsg),
- (Seq("trigger", "fire", "triggerName", "-A"), invalidAnnotFileMsg))
-
- invalidArgs foreach {
- case (cmd, err) =>
- val stderr = wsk.cli(cmd, expectedExitCode = ERROR_EXIT).stderr
- stderr should include(err)
- stderr should include("Run 'wsk --help' for usage.")
- }
- }
-
- behavior of "Wsk invalid argument handling"
-
- it should "reject commands that are executed with invalid arguments" in {
- val invalidArgsMsg = "error: Invalid argument(s)"
- val tooFewArgsMsg = invalidArgsMsg + "."
- val tooManyArgsMsg = invalidArgsMsg + ": "
- val actionNameActionReqMsg = "An action name and code artifact are
required."
- val actionNameReqMsg = "An action name is required."
- val actionOptMsg = "A code artifact is optional."
- val packageNameReqMsg = "A package name is required."
- val packageNameBindingReqMsg = "A package name and binding name are
required."
- val ruleNameReqMsg = "A rule name is required."
- val ruleTriggerActionReqMsg = "A rule, trigger and action name are
required."
- val activationIdReq = "An activation ID is required."
- val triggerNameReqMsg = "A trigger name is required."
- val optNamespaceMsg = "An optional namespace is the only valid argument."
- val optPayloadMsg = "A payload is optional."
- val noArgsReqMsg = "No arguments are required."
- val invalidArg = "invalidArg"
- val apiCreateReqMsg =
- "Specify a swagger file or specify an API base path with an API path, an
API verb, and an action name."
- val apiGetReqMsg = "An API base path or API name is required."
- val apiDeleteReqMsg =
- "An API base path or API name is required. An optional API relative
path and operation may also be provided."
- val apiListReqMsg = "Optional parameters are: API base path (or API name),
API relative path and operation."
- val invalidShared = s"Cannot use value '$invalidArg' for shared"
- val entityNameMsg =
- s"An entity name, '$invalidArg', was provided instead of a namespace.
Valid namespaces are of the following format: /NAMESPACE."
- val invalidArgs = Seq(
- (Seq("api", "create"), s"${tooFewArgsMsg} ${apiCreateReqMsg}"),
- (
- Seq("api", "create", "/basepath", "/path", "GET", "action",
invalidArg),
- s"${tooManyArgsMsg}${invalidArg}. ${apiCreateReqMsg}"),
- (Seq("api", "get"), s"${tooFewArgsMsg} ${apiGetReqMsg}"),
- (Seq("api", "get", "/basepath", invalidArg),
s"${tooManyArgsMsg}${invalidArg}. ${apiGetReqMsg}"),
- (Seq("api", "delete"), s"${tooFewArgsMsg} ${apiDeleteReqMsg}"),
- (
- Seq("api", "delete", "/basepath", "/path", "GET", invalidArg),
- s"${tooManyArgsMsg}${invalidArg}. ${apiDeleteReqMsg}"),
- (
- Seq("api", "list", "/basepath", "/path", "GET", invalidArg),
- s"${tooManyArgsMsg}${invalidArg}. ${apiListReqMsg}"),
- (Seq("action", "create"), s"${tooFewArgsMsg} ${actionNameActionReqMsg}"),
- (Seq("action", "create", "someAction"), s"${tooFewArgsMsg}
${actionNameActionReqMsg}"),
- (Seq("action", "create", "actionName", "artifactName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("action", "update"), s"${tooFewArgsMsg} ${actionNameReqMsg}
${actionOptMsg}"),
- (
- Seq("action", "update", "actionName", "artifactName", invalidArg),
- s"${tooManyArgsMsg}${invalidArg}. ${actionNameReqMsg}
${actionOptMsg}"),
- (Seq("action", "delete"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
- (Seq("action", "delete", "actionName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("action", "get"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
- (Seq("action", "get", "actionName", "namespace", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("action", "list", "namespace", invalidArg),
s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
- (Seq("action", "invoke"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
- (Seq("action", "invoke", "actionName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("activation", "list", "namespace", invalidArg),
s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
- (Seq("activation", "get"), s"${tooFewArgsMsg} ${activationIdReq}"),
- (Seq("activation", "get", "activationID", "namespace", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("activation", "logs"), s"${tooFewArgsMsg} ${activationIdReq}"),
- (Seq("activation", "logs", "activationID", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("activation", "result"), s"${tooFewArgsMsg} ${activationIdReq}"),
- (Seq("activation", "result", "activationID", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("activation", "poll", "activationID", invalidArg),
s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
- (Seq("namespace", "list", invalidArg), s"${tooManyArgsMsg}${invalidArg}.
${noArgsReqMsg}"),
- (Seq("namespace", "get", invalidArg), s"${tooManyArgsMsg}${invalidArg}.
${noArgsReqMsg}"),
- (Seq("package", "create"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
- (Seq("package", "create", "packageName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("package", "create", "packageName", "--shared", invalidArg),
invalidShared),
- (Seq("package", "update"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
- (Seq("package", "update", "packageName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("package", "update", "packageName", "--shared", invalidArg),
invalidShared),
- (Seq("package", "get"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
- (Seq("package", "get", "packageName", "namespace", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("package", "bind"), s"${tooFewArgsMsg}
${packageNameBindingReqMsg}"),
- (Seq("package", "bind", "packageName"), s"${tooFewArgsMsg}
${packageNameBindingReqMsg}"),
- (Seq("package", "bind", "packageName", "bindingName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("package", "list", "namespace", invalidArg),
s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
- (Seq("package", "list", invalidArg), entityNameMsg),
- (Seq("package", "delete"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
- (Seq("package", "delete", "namespace", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("package", "refresh", "namespace", invalidArg),
s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
- (Seq("package", "refresh", invalidArg), entityNameMsg),
- (Seq("rule", "enable"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
- (Seq("rule", "enable", "ruleName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("rule", "disable"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
- (Seq("rule", "disable", "ruleName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("rule", "status"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
- (Seq("rule", "status", "ruleName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("rule", "create"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
- (Seq("rule", "create", "ruleName"), s"${tooFewArgsMsg}
${ruleTriggerActionReqMsg}"),
- (Seq("rule", "create", "ruleName", "triggerName"), s"${tooFewArgsMsg}
${ruleTriggerActionReqMsg}"),
- (Seq("rule", "create", "ruleName", "triggerName", "actionName",
invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("rule", "update"), s"${tooFewArgsMsg} ${ruleTriggerActionReqMsg}"),
- (Seq("rule", "update", "ruleName"), s"${tooFewArgsMsg}
${ruleTriggerActionReqMsg}"),
- (Seq("rule", "update", "ruleName", "triggerName"), s"${tooFewArgsMsg}
${ruleTriggerActionReqMsg}"),
- (Seq("rule", "update", "ruleName", "triggerName", "actionName",
invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("rule", "get"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
- (Seq("rule", "get", "ruleName", "namespace", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("rule", "delete"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
- (Seq("rule", "delete", "ruleName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("rule", "list", "namespace", invalidArg),
s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
- (Seq("rule", "list", invalidArg), entityNameMsg),
- (Seq("trigger", "fire"), s"${tooFewArgsMsg} ${triggerNameReqMsg}
${optPayloadMsg}"),
- (
- Seq("trigger", "fire", "triggerName", "triggerPayload", invalidArg),
- s"${tooManyArgsMsg}${invalidArg}. ${triggerNameReqMsg}
${optPayloadMsg}"),
- (Seq("trigger", "create"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
- (Seq("trigger", "create", "triggerName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("trigger", "update"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
- (Seq("trigger", "update", "triggerName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("trigger", "get"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
- (Seq("trigger", "get", "triggerName", "namespace", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("trigger", "delete"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
- (Seq("trigger", "delete", "triggerName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
- (Seq("trigger", "list", "namespace", invalidArg),
s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"),
- (Seq("trigger", "list", invalidArg), entityNameMsg))
-
- invalidArgs foreach {
- case (cmd, err) =>
- withClue(cmd) {
- val rr = wsk.cli(cmd ++ wskprops.overrides, expectedExitCode =
ANY_ERROR_EXIT)
- rr.exitCode should (be(ERROR_EXIT) or be(MISUSE_EXIT))
- rr.stderr should include(err)
- rr.stderr should include("Run 'wsk --help' for usage.")
- }
+ wsk.trigger.delete(triggerName).statusCode shouldBe OK
}
}
@@ -1727,7 +737,7 @@ class WskBasicUsageTests extends TestHelpers with
WskTestHelpers {
}
if (ec == SUCCESS_EXIT) {
- val JsObject(parsedAction) =
wsk.action.get(name).stdout.split("\n").tail.mkString.parseJson.asJsObject
+ val JsObject(parsedAction) = wsk.action.get(name).respBody
parsedAction("limits") shouldBe limits
} else {
createResult.stderr should include("allowed threshold")
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services