Add Property Projections
- Allows projections for actions, activations, packages, rules, and triggers
diff --git a/tests/src/common/Wsk.scala b/tests/src/common/Wsk.scala
index 1bc5938..371bd9d 100644
--- a/tests/src/common/Wsk.scala
+++ b/tests/src/common/Wsk.scala
@@ -145,11 +145,14 @@
def get(
name: String,
expectedExitCode: Int = SUCCESS_EXIT,
- summary: Boolean = false)(
+ summary: Boolean = false,
+ fieldFilter: Option[String] = None)(
implicit wp: WskProps): RunResult = {
val params = Seq(noun, "get", "--auth", wp.authKey) ++
Seq(fqn(name)) ++
- { if (summary) Seq("--summary") else Seq() }
+ { if (summary) Seq("--summary") else Seq() } ++
+ { fieldFilter map { f => Seq(f) } getOrElse Seq() }
+
cli(wp.overrides ++ params, expectedExitCode)
}
}
@@ -543,9 +546,11 @@
*/
def get(
activationId: String,
- expectedExitCode: Int = SUCCESS_EXIT)(
+ expectedExitCode: Int = SUCCESS_EXIT,
+ fieldFilter: Option[String] = None)(
implicit wp: WskProps): RunResult = {
- cli(wp.overrides ++ Seq(noun, "get", "--auth", wp.authKey, activationId), expectedExitCode)
+ val params = { fieldFilter map { f => Seq(f) } getOrElse Seq() }
+ cli(wp.overrides ++ Seq(noun, "get", "--auth", wp.authKey, activationId) ++ params, expectedExitCode)
}
/**
diff --git a/tests/src/system/basic/WskBasicTests.scala b/tests/src/system/basic/WskBasicTests.scala
index bda657a..ded6890 100644
--- a/tests/src/system/basic/WskBasicTests.scala
+++ b/tests/src/system/basic/WskBasicTests.scala
@@ -28,6 +28,7 @@
import common.TestUtils.SUCCESS_EXIT
import common.TestUtils.UNAUTHORIZED
import common.TestUtils.FORBIDDEN
+import common.TestUtils.ERROR_EXIT
import common.Wsk
import common.WskProps
import common.WskTestHelpers
@@ -162,6 +163,30 @@
res.stdout should include(s"ok: created package $name")
}
+ it should "create a package, and get its individual fields" in withAssetCleaner(wskprops) {
+ val name = "packageFields"
+ val paramInput = Map("payload" -> "test".toJson)
+ val successMsg = s"ok: got package $name, displaying field"
+
+ (wp, assetHelper) =>
+ assetHelper.withCleaner(wsk.pkg, name) {
+ (action, _) => action.create(name, parameters = paramInput)
+ }
+
+ val expectedParam = JsObject(
+ "payload" -> JsString("test")
+ )
+
+ val ns_regex_list = wsk.namespace.list().stdout.trim.replace('\n', '|')
+
+ wsk.pkg.get(name, fieldFilter = Some("namespace")).stdout should include regex (s"""(?i)$successMsg namespace\n$ns_regex_list""")
+ wsk.pkg.get(name, fieldFilter = Some("name")).stdout should include (s"""$successMsg name\n"$name"""")
+ wsk.pkg.get(name, fieldFilter = Some("version")).stdout should include (s"""$successMsg version\n"0.0.1"""")
+ wsk.pkg.get(name, fieldFilter = Some("publish")).stdout should include (s"""$successMsg publish\nfalse""")
+ wsk.pkg.get(name, fieldFilter = Some("binding")).stdout should include regex (s"""\\{\\}""")
+ wsk.pkg.get(name, fieldFilter = Some("invalid"), expectedExitCode = ERROR_EXIT).stderr should include ("error: Invalid field filter 'invalid'.")
+ }
+
behavior of "Wsk Action CLI"
it should "create the same action twice with different cases" in withAssetCleaner(wskprops) {
@@ -269,6 +294,33 @@
}
}
+ it should "create an action, and get its individual fields" in withAssetCleaner(wskprops) {
+ val name = "actionFields"
+ val paramInput = Map("payload" -> "test".toJson)
+ val successMsg = s"ok: got action $name, displaying field"
+
+ (wp, assetHelper) =>
+ assetHelper.withCleaner(wsk.action, name) {
+ (action, _) => action.create(name, defaultAction, parameters = paramInput)
+ }
+
+ val expectedParam = JsObject(
+ "payload" -> JsString("test")
+ )
+
+ val ns_regex_list = wsk.namespace.list().stdout.trim.replace('\n', '|')
+
+ wsk.action.get(name, fieldFilter = Some("name")).stdout should include (s"""$successMsg name\n"$name"""")
+ wsk.action.get(name, fieldFilter = Some("version")).stdout should include (s"""$successMsg version\n"0.0.1"""")
+ wsk.action.get(name, fieldFilter = Some("publish")).stdout should include (s"""$successMsg publish\nfalse""")
+ wsk.action.get(name, fieldFilter = Some("exec")).stdout should include regex (s"""$successMsg exec\n\\{\\s+"kind":\\s+"nodejs:6",\\s+"code":\\s+"\\/\\*\\*\\\\n \\* Hello, world.\\\\n \\*\\/\\\\nfunction main\\(params\\) \\{\\\\n console.log\\('hello', params.payload\\+'!'\\);\\\\n\\}\\\\n"\n\\}""")
+ wsk.action.get(name, fieldFilter = Some("parameters")).stdout should include regex (s"""$successMsg parameters\n\\[\\s+\\{\\s+"key":\\s+"payload",\\s+"value":\\s+"test"\\s+\\}\\s+\\]""")
+ wsk.action.get(name, fieldFilter = Some("annotations")).stdout should include regex (s"""$successMsg annotations\n\\[\\]""")
+ wsk.action.get(name, fieldFilter = Some("limits")).stdout should include regex (s"""$successMsg limits\n\\{\\s+"timeout":\\s+60000,\\s+"memory":\\s+256,\\s+"logs":\\s+10\\s+\\}""")
+ wsk.action.get(name, fieldFilter = Some("namespace")).stdout should include regex (s"""(?i)$successMsg namespace\n$ns_regex_list""")
+ wsk.action.get(name, fieldFilter = Some("invalid"), expectedExitCode = ERROR_EXIT).stderr should include ("error: Invalid field filter 'invalid'.")
+ }
+
/**
* Tests creating an action from a malformed js file. This should fail in
* some way - preferably when trying to create the action. If not, then
@@ -459,6 +511,32 @@
}
}
+ it should "create a trigger, and get its individual fields" in withAssetCleaner(wskprops) {
+ val name = "triggerFields"
+ val paramInput = Map("payload" -> "test".toJson)
+ val successMsg = s"ok: got trigger $name, displaying field"
+
+ (wp, assetHelper) =>
+ assetHelper.withCleaner(wsk.trigger, name) {
+ (action, _) => action.create(name, parameters = paramInput)
+ }
+
+ val expectedParam = JsObject(
+ "payload" -> JsString("test")
+ )
+
+ val ns_regex_list = wsk.namespace.list().stdout.trim.replace('\n', '|')
+
+ wsk.trigger.get(name, fieldFilter = Some("namespace")).stdout should include regex (s"""(?i)$successMsg namespace\n$ns_regex_list""")
+ wsk.trigger.get(name, fieldFilter = Some("name")).stdout should include (s"""$successMsg name\n"$name"""")
+ wsk.trigger.get(name, fieldFilter = Some("version")).stdout should include (s"""$successMsg version\n"0.0.1"""")
+ wsk.trigger.get(name, fieldFilter = Some("publish")).stdout should include (s"""$successMsg publish\nfalse""")
+ wsk.trigger.get(name, fieldFilter = Some("annotations")).stdout should include (s"""$successMsg annotations\n[]""")
+ wsk.trigger.get(name, fieldFilter = Some("parameters")).stdout should include regex (s"""$successMsg parameters\n\\[\\s+\\{\\s+"key":\\s+"payload",\\s+"value":\\s+"test"\\s+\\}\\s+\\]""")
+ wsk.trigger.get(name, fieldFilter = Some("limits")).stdout should include (s"""$successMsg limits\n{}""")
+ wsk.trigger.get(name, fieldFilter = Some("invalid"), expectedExitCode = ERROR_EXIT).stderr should include ("error: Invalid field filter 'invalid'.")
+ }
+
behavior of "Wsk Rule CLI"
it should "create rule, get rule, update rule and list rule" in withAssetCleaner(wskprops) {
@@ -536,6 +614,34 @@
stdout should include regex (s"(?i)rule /${ns_regex_list}/${ruleName}\\s*\\(status: active\\)")
}
+ it should "create a rule, and get its individual fields" in withAssetCleaner(wskprops) {
+ val ruleName = "ruleFields"
+ val triggerName = "ruleTriggerFields"
+ val actionName = "ruleActionFields";val paramInput = Map("payload" -> "test".toJson)
+ val successMsg = s"ok: got rule $ruleName, displaying field"
+
+ (wp, assetHelper) =>
+
+ 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)
+ }
+
+ val ns_regex_list = wsk.namespace.list().stdout.trim.replace('\n', '|')
+
+ wsk.rule.get(ruleName, fieldFilter = Some("namespace")).stdout should include regex (s"""(?i)$successMsg namespace\n$ns_regex_list""")
+ wsk.rule.get(ruleName, fieldFilter = Some("name")).stdout should include (s"""$successMsg name\n"$ruleName"""")
+ wsk.rule.get(ruleName, fieldFilter = Some("version")).stdout should include (s"""$successMsg version\n"0.0.1"""")
+ wsk.rule.get(ruleName, fieldFilter = Some("status")).stdout should include (s"""$successMsg status\n"active"""")
+ wsk.rule.get(ruleName, fieldFilter = Some("trigger")).stdout should include regex (s"""$successMsg trigger\n"$triggerName"""")
+ wsk.rule.get(ruleName, fieldFilter = Some("action")).stdout should include regex (s"""$successMsg action\n"$actionName"""")
+ }
+
behavior of "Wsk Namespace CLI"
it should "list namespaces" in {
@@ -556,4 +662,34 @@
stderr should include(s"Unable to obtain the list of entities for namespace '${namespace}'")
}
+
+ behavior of "Wsk Activation CLI"
+
+ it should "create a trigger, and fire a trigger to get its individual fields from an activation" in withAssetCleaner(wskprops) {
+ (wp, assetHelper) =>
+ val name = "activationFields"
+
+ assetHelper.withCleaner(wsk.trigger, name) {
+ (trigger, _) =>
+ trigger.create(name)
+ }
+
+ val ns_regex_list = wsk.namespace.list().stdout.trim.replace('\n', '|')
+
+ val run = wsk.trigger.fire(name)
+ withActivation(wsk.activation, run) {
+ activation =>
+ val successMsg = s"ok: got activation ${activation.activationId}, displaying field"
+ wsk.activation.get(activation.activationId, fieldFilter = Some("namespace")).stdout should include regex (s"""(?i)$successMsg namespace\n$ns_regex_list""")
+ wsk.activation.get(activation.activationId, fieldFilter = Some("name")).stdout should include (s"""$successMsg name\n"$name"""")
+ wsk.activation.get(activation.activationId, fieldFilter = Some("version")).stdout should include (s"""$successMsg version\n"0.0.1"""")
+ wsk.activation.get(activation.activationId, fieldFilter = Some("publish")).stdout should include (s"""$successMsg publish\nfalse""")
+ wsk.activation.get(activation.activationId, fieldFilter = Some("subject")).stdout should include regex (s"""(?i)$successMsg subject\n$ns_regex_list""")
+ wsk.activation.get(activation.activationId, fieldFilter = Some("activationid")).stdout should include (s"""$successMsg activationid\n"${activation.activationId}""")
+ wsk.activation.get(activation.activationId, fieldFilter = Some("start")).stdout should include regex (s"""$successMsg start\n\\d""")
+ wsk.activation.get(activation.activationId, fieldFilter = Some("end")).stdout should include regex (s"""$successMsg end\n\\d""")
+ wsk.activation.get(activation.activationId, fieldFilter = Some("duration")).stdout should include regex (s"""$successMsg duration\n\\d""")
+ wsk.activation.get(activation.activationId, fieldFilter = Some("annotations")).stdout should include (s"""$successMsg annotations\n[]""")
+ }
+ }
}
diff --git a/tests/src/whisk/core/cli/test/WskBasicUsageTests.scala b/tests/src/whisk/core/cli/test/WskBasicUsageTests.scala
index f149163..77ac738 100644
--- a/tests/src/whisk/core/cli/test/WskBasicUsageTests.scala
+++ b/tests/src/whisk/core/cli/test/WskBasicUsageTests.scala
@@ -902,14 +902,14 @@
(Seq("action", "delete"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
(Seq("action", "delete", "actionName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
(Seq("action", "get"), s"${tooFewArgsMsg} ${actionNameReqMsg}"),
- (Seq("action", "get", "actionName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+ (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", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+ (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}"),
@@ -924,7 +924,7 @@
(Seq("package", "update"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
(Seq("package", "update", "packageName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
(Seq("package", "get"), s"${tooFewArgsMsg} ${packageNameReqMsg}"),
- (Seq("package", "get", "packageName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+ (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}."),
@@ -951,7 +951,7 @@
(Seq("rule", "update", "ruleName", "triggerName", "actionName", invalidArg),
s"${tooManyArgsMsg}${invalidArg}."),
(Seq("rule", "get"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"),
- (Seq("rule", "get", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+ (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}"),
@@ -963,7 +963,7 @@
(Seq("trigger", "update"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
(Seq("trigger", "update", "triggerName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
(Seq("trigger", "get"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"),
- (Seq("trigger", "get", "triggerName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."),
+ (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}"))