Fix missing binding resolution for actions referenced by rules.
diff --git a/tests/src/system/basic/WskRuleTests.scala b/tests/src/system/basic/WskRuleTests.scala
index c128d68..6bbcfa6 100644
--- a/tests/src/system/basic/WskRuleTests.scala
+++ b/tests/src/system/basic/WskRuleTests.scala
@@ -46,9 +46,12 @@
* Sets up trigger -> rule -> action triplets. Deduplicates triggers and rules
* and links it all up.
*
- * @param rules Tuple3s containing (rule, trigger, (actionName, actionFile))
+ * @param rules Tuple3s containing
+ * (rule, trigger, (action name for created action, action name for the rule binding, actionFile))
+ * where the action name for the created action is allowed to differ from that used by the rule binding
+ * for cases that reference actions in a package binding.
*/
- def ruleSetup(rules: Seq[(String, String, (String, String))], assetHelper: AssetCleaner) = {
+ def ruleSetup(rules: Seq[(String, String, (String, String, String))], assetHelper: AssetCleaner) = {
val triggers = rules.map(_._2).distinct
val actions = rules.map(_._3).distinct
@@ -59,7 +62,7 @@
}
actions.foreach {
- case (actionName, file) =>
+ case (actionName, _, file) =>
assetHelper.withCleaner(wsk.action, actionName) {
(action, name) => action.create(name, Some(file))
}
@@ -68,7 +71,7 @@
rules.foreach {
case (ruleName, triggerName, action) =>
assetHelper.withCleaner(wsk.rule, ruleName) {
- (rule, name) => rule.create(name, triggerName, action._1)
+ (rule, name) => rule.create(name, triggerName, action._2)
}
}
}
@@ -82,7 +85,7 @@
val actionName = "a1 to 1" // spaces in name intended for greater test coverage
ruleSetup(Seq(
- (ruleName, triggerName, (actionName, defaultAction))),
+ (ruleName, triggerName, (actionName, actionName, defaultAction))),
assetHelper)
val now = Instant.now
@@ -116,7 +119,45 @@
}
ruleSetup(Seq(
- (ruleName, triggerName, (pkgActionName, defaultAction))),
+ (ruleName, triggerName, (pkgActionName, pkgActionName, defaultAction))),
+ assetHelper)
+
+ val now = Instant.now
+ val run = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
+
+ withActivation(wsk.activation, run) {
+ triggerActivation =>
+ triggerActivation.cause shouldBe None
+
+ withActivationsFromEntity(wsk.activation, ruleName, since = Some(Instant.ofEpochMilli(triggerActivation.start))) {
+ _.head.cause shouldBe Some(triggerActivation.activationId)
+ }
+
+ withActivationsFromEntity(wsk.activation, actionName, since = Some(Instant.ofEpochMilli(triggerActivation.start))) {
+ _.head.response.result shouldBe Some(testResult)
+ }
+ }
+ }
+
+ it should "invoke the action from a package binding attached on trigger fire, creating an activation for each entity including the cause" in withAssetCleaner(wskprops) {
+ (wp, assetHelper) =>
+ val ruleName = "pr1to1"
+ val triggerName = "pt1to1"
+ val pkgName = "rule pkg" // spaces in name intended to test uri path encoding
+ val pkgBindingName = "rule pkg binding"
+ val actionName = "a1 to 1"
+ val pkgActionName = s"$pkgName/$actionName"
+
+ assetHelper.withCleaner(wsk.pkg, pkgName) {
+ (pkg, name) => pkg.create(name)
+ }
+
+ assetHelper.withCleaner(wsk.pkg, pkgBindingName) {
+ (pkg, name) => pkg.bind(pkgName, pkgBindingName)
+ }
+
+ ruleSetup(Seq(
+ (ruleName, triggerName, (pkgActionName, s"$pkgBindingName/$actionName", defaultAction))),
assetHelper)
val now = Instant.now
@@ -172,7 +213,7 @@
val actionName = "ruleDisableAction"
ruleSetup(Seq(
- (ruleName, triggerName, (actionName, defaultAction))),
+ (ruleName, triggerName, (actionName, actionName, defaultAction))),
assetHelper)
val first = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
@@ -233,8 +274,8 @@
val actionName = "a2to1"
ruleSetup(Seq(
- ("r2to1a", triggerName1, (actionName, defaultAction)),
- ("r2to1b", triggerName2, (actionName, defaultAction))),
+ ("r2to1a", triggerName1, (actionName, actionName, defaultAction)),
+ ("r2to1b", triggerName2, (actionName, actionName, defaultAction))),
assetHelper)
val testPayloads = Seq("got three words", "got four words, period")
@@ -263,8 +304,8 @@
val actionName2 = "a1to2b"
ruleSetup(Seq(
- ("r1to2a", triggerName, (actionName1, defaultAction)),
- ("r1to2b", triggerName, (actionName2, secondAction))),
+ ("r1to2a", triggerName, (actionName1, actionName1, defaultAction)),
+ ("r1to2b", triggerName, (actionName2, actionName2, secondAction))),
assetHelper)
val run = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
@@ -288,10 +329,10 @@
val actionName2 = "a1to1b"
ruleSetup(Seq(
- ("r2to2a", triggerName1, (actionName1, defaultAction)),
- ("r2to2b", triggerName1, (actionName2, secondAction)),
- ("r2to2c", triggerName2, (actionName1, defaultAction)),
- ("r2to2d", triggerName2, (actionName2, secondAction))),
+ ("r2to2a", triggerName1, (actionName1, actionName1, defaultAction)),
+ ("r2to2b", triggerName1, (actionName2, actionName2, secondAction)),
+ ("r2to2c", triggerName2, (actionName1, actionName1, defaultAction)),
+ ("r2to2d", triggerName2, (actionName2, actionName2, secondAction))),
assetHelper)
val testPayloads = Seq("got three words", "got four words, period")
diff --git a/tests/src/whisk/core/controller/test/RulesApiTests.scala b/tests/src/whisk/core/controller/test/RulesApiTests.scala
index ed5c366..5f61171 100644
--- a/tests/src/whisk/core/controller/test/RulesApiTests.scala
+++ b/tests/src/whisk/core/controller/test/RulesApiTests.scala
@@ -311,6 +311,34 @@
}
}
+ it should "create rule with an action in a binding" in {
+ implicit val tid = transid()
+
+ val provider = WhiskPackage(namespace, aname(), publish = true)
+ val reference = WhiskPackage(namespace, aname(), provider.bind)
+ val action = WhiskAction(provider.path, aname(), Exec.js("??"))
+ val trigger = WhiskTrigger(namespace, aname())
+ val actionReference = reference.binding.map(b => b.namespace.addpath(b.name)).get
+ val rule = WhiskRule(namespace, aname(), trigger.fullyQualifiedName(false), FullyQualifiedEntityName(actionReference, action.name))
+ val content = WhiskRulePut(Some(rule.trigger), Some(rule.action))
+
+ put(entityStore, provider)
+ put(entityStore, reference)
+ put(entityStore, trigger, false)
+ put(entityStore, action)
+
+ Put(s"$collectionPath/${rule.name}", content) ~> sealRoute(routes(creds)) ~> check {
+ val t = get(entityStore, trigger.docid, WhiskTrigger)
+ deleteTrigger(t.docid)
+ deleteRule(rule.docid)
+
+ status should be(OK)
+ val response = responseAs[WhiskRuleResponse]
+ response should be(rule.withStatus(Status.ACTIVE))
+ t.rules.get(rule.fullyQualifiedName(false)) shouldBe ReducedRule(action.fullyQualifiedName(false), Status.ACTIVE)
+ }
+ }
+
it should "reject create rule with annotations which are too big" in {
implicit val tid = transid()