You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by du...@apache.org on 2018/02/22 18:34:17 UTC

[incubator-openwhisk-cli] branch master updated: sync tests with openwhisk (#228)

This is an automated email from the ASF dual-hosted git repository.

dubeejw pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-cli.git


The following commit(s) were added to refs/heads/master by this push:
     new abc668c  sync tests with openwhisk (#228)
abc668c is described below

commit abc668cde7d19ec4d9ebacbe199bf94d51a44d3e
Author: Mark Deuser <md...@us.ibm.com>
AuthorDate: Thu Feb 22 13:34:16 2018 -0500

    sync tests with openwhisk (#228)
---
 .../src/test/scala/system/basic/WskRuleTests.scala | 253 +++++++++++----------
 .../test/scala/system/basic/WskSequenceTests.scala |   8 +-
 2 files changed, 132 insertions(+), 129 deletions(-)

diff --git a/tests/src/test/scala/system/basic/WskRuleTests.scala b/tests/src/test/scala/system/basic/WskRuleTests.scala
index c740caf..8ceff99 100644
--- a/tests/src/test/scala/system/basic/WskRuleTests.scala
+++ b/tests/src/test/scala/system/basic/WskRuleTests.scala
@@ -25,6 +25,7 @@ import common.TestUtils.RunResult
 import common.BaseWsk
 import common.WskProps
 import common.WskTestHelpers
+import common.RuleActivationResult
 import spray.json._
 import spray.json.DefaultJsonProtocol._
 import java.time.Instant
@@ -40,14 +41,6 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
   val testResult = JsObject("count" -> testString.split(" ").length.toJson)
 
   /**
-   * Invoker clock skew can sometimes make it appear as if an action was invoked
-   * _before_ the trigger was fired. The "fudge factor" below allows the test to look
-   * for action activations that occur starting at most this amount of time before
-   * the trigger was fired.
-   */
-  val activationTimeSkewFactorMs = 500
-
-  /**
    * Sets up trigger -> rule -> action triplets. Deduplicates triggers and rules
    * and links it all up.
    *
@@ -56,7 +49,7 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
    *   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, String))], assetHelper: AssetCleaner) = {
+  def ruleSetup(rules: Seq[(String, String, (String, String, String))], assetHelper: AssetCleaner): Unit = {
     val triggers = rules.map(_._2).distinct
     val actions = rules.map(_._3).distinct
 
@@ -84,10 +77,35 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
   /**
    * Append the current timestamp in ms
    */
-  def withTimestamp(text: String) = s"${text}-${System.currentTimeMillis}"
+  def withTimestamp(text: String) = s"$text-${System.currentTimeMillis}"
 
   behavior of "Whisk rules"
 
+  it should "preserve rule status when a rule is updated" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val ruleName = withTimestamp("r1to1")
+    val triggerName = withTimestamp("t1to1")
+    val actionName = withTimestamp("a1 to 1")
+    val triggerName2 = withTimestamp("t2to1")
+    val active = Some("active".toJson)
+    val inactive = Some("inactive".toJson)
+    val statusPermutations =
+      Seq((triggerName, active), (triggerName, inactive), (triggerName2, active), (triggerName2, inactive))
+
+    ruleSetup(Seq((ruleName, triggerName, (actionName, actionName, defaultAction))), assetHelper)
+    assetHelper.withCleaner(wsk.trigger, triggerName2) { (trigger, name) =>
+      trigger.create(name)
+    }
+
+    statusPermutations.foreach {
+      case (trigger, status) =>
+        if (status == active) wsk.rule.enable(ruleName) else wsk.rule.disable(ruleName)
+        // CLI stdout must strip out the preamble text (i.e. "ok: got rule XXXXX") to get at the JSON
+        wsk.rule.create(ruleName, trigger, actionName, update = true)
+        val getStdout = wsk.rule.get(ruleName).stdout
+        getStdout.substring(getStdout.indexOf('{')).parseJson.asJsObject.fields.get("status") shouldBe status
+    }
+  }
+
   it should "invoke the action attached on trigger fire, creating an activation for each entity including the cause" in withAssetCleaner(
     wskprops) { (wp, assetHelper) =>
     val ruleName = withTimestamp("r1to1")
@@ -100,18 +118,16 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
 
     withActivation(wsk.activation, run) { triggerActivation =>
       triggerActivation.cause shouldBe None
-      triggerActivation.logs.get.size shouldBe (1)
-      val logs = triggerActivation.logs.get.mkString(" ")
-      logs should include(""""statusCode":0""")
-      logs should include(""""activationId":""")
-      logs should include(""""success":true""")
-
-      withActivationsFromEntity(
-        wsk.activation,
-        actionName,
-        since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) { activationList =>
-        activationList.head.response.result shouldBe Some(testResult)
-        activationList.head.cause shouldBe None
+
+      val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
+      ruleActivations should have size 1
+      val ruleActivation = ruleActivations.head
+      ruleActivation.success shouldBe true
+      ruleActivation.statusCode shouldBe 0
+
+      withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
+        actionActivation.response.result shouldBe Some(testResult)
+        actionActivation.cause shouldBe None
       }
     }
   }
@@ -135,17 +151,15 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
 
     withActivation(wsk.activation, run) { triggerActivation =>
       triggerActivation.cause shouldBe None
-      triggerActivation.logs.get.size shouldBe (1)
-      val logs = triggerActivation.logs.get.mkString(" ")
-      logs should include(""""statusCode":0""")
-      logs should include(""""activationId":""")
-      logs should include(""""success":true""")
-
-      withActivationsFromEntity(
-        wsk.activation,
-        pkgActionName,
-        since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-        _.head.response.result shouldBe Some(testResult)
+
+      val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
+      ruleActivations should have size 1
+      val ruleActivation = ruleActivations.head
+      ruleActivation.success shouldBe true
+      ruleActivation.statusCode shouldBe 0
+
+      withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
+        actionActivation.response.result shouldBe Some(testResult)
       }
     }
   }
@@ -155,7 +169,7 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
     val ruleName = withTimestamp("pr1to1")
     val triggerName = withTimestamp("pt1to1")
     val pkgName = withTimestamp("rule pkg") // spaces in name intended to test uri path encoding
-  val pkgBindingName = withTimestamp("rule pkg binding")
+    val pkgBindingName = withTimestamp("rule pkg binding")
     val actionName = withTimestamp("a1 to 1")
     val pkgActionName = s"$pkgName/$actionName"
 
@@ -173,17 +187,16 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
 
     withActivation(wsk.activation, run) { triggerActivation =>
       triggerActivation.cause shouldBe None
-      triggerActivation.logs.get.size shouldBe (1)
-      val logs = triggerActivation.logs.get.mkString(" ")
-      logs should include(""""statusCode":0""")
-      logs should include(""""activationId":""")
-      logs should include(""""success":true""")
-
-      withActivationsFromEntity(
-        wsk.activation,
-        pkgActionName,
-        since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-        _.head.response.result shouldBe Some(testResult)
+
+      val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
+      ruleActivations should have size 1
+      val ruleActivation = ruleActivations.head
+      ruleActivation.success shouldBe true
+      ruleActivation.statusCode shouldBe 0
+
+      withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
+        actionActivation.response.result shouldBe Some(testResult)
+        actionActivation.cause shouldBe None
       }
     }
   }
@@ -200,24 +213,16 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
       assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
         action.create(name, Some(defaultAction))
       }
-      assetHelper.withCleaner(wsk.rule, ruleName, false) { (rule, name) =>
+      assetHelper.withCleaner(wsk.rule, ruleName, confirmDelete = false) { (rule, name) =>
         rule.create(name, triggerName, actionName)
       }
 
       val first = wsk.trigger.fire(triggerName, Map("payload" -> "bogus".toJson))
       wsk.rule.delete(ruleName)
-      wsk.trigger.fire(triggerName, Map("payload" -> "bogus2".toJson))
-
-      withActivation(wsk.activation, first) { activation =>
-        // tries to find 2 activations for the action, should only find 1
-        val activations = wsk.activation.pollFor(
-          2,
-          Some(actionName),
-          since = Some(activation.start.minusMillis(activationTimeSkewFactorMs)),
-          retries = 30)
+      val second = wsk.trigger.fire(triggerName, Map("payload" -> "bogus2".toJson))
 
-        activations.length shouldBe 1
-      }
+      withActivation(wsk.activation, first)(activation => activation.logs.get should have size 1)
+    // there won't be an activation for the second fire since there is no rule
   }
 
   it should "enable and disable a rule and check action is activated only when rule is enabled" in withAssetCleaner(
@@ -230,18 +235,27 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
 
     val first = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
     wsk.rule.disable(ruleName)
-    wsk.trigger.fire(triggerName, Map("payload" -> s"$testString with added words".toJson))
+    val second = wsk.trigger.fire(triggerName, Map("payload" -> s"$testString with added words".toJson))
     wsk.rule.enable(ruleName)
-    wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
+    val third = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
 
     withActivation(wsk.activation, first) { triggerActivation =>
-      withActivationsFromEntity(
-        wsk.activation,
-        actionName,
-        N = 2,
-        since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) { activations =>
-        val results = activations.map(_.response.result)
-        results should contain theSameElementsAs Seq(Some(testResult), Some(testResult))
+      val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
+      ruleActivations should have size 1
+      val ruleActivation = ruleActivations.head
+      withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
+        actionActivation.response.result shouldBe Some(testResult)
+      }
+    }
+
+    // second fire will not write an activation
+
+    withActivation(wsk.activation, third) { triggerActivation =>
+      val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
+      ruleActivations should have size 1
+      val ruleActivation = ruleActivations.head
+      withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
+        actionActivation.response.result shouldBe Some(testResult)
       }
     }
   }
@@ -259,7 +273,7 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
       assetHelper.withCleaner(wsk.action, actionName) { (action, name) =>
         action.create(name, Some(defaultAction))
       }
-      assetHelper.withCleaner(wsk.rule, ruleName, false) { (rule, name) =>
+      assetHelper.withCleaner(wsk.rule, ruleName, confirmDelete = false) { (rule, name) =>
         rule.create(name, triggerName1, actionName)
       }
 
@@ -274,11 +288,11 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
 
       val first = wsk.trigger.fire(triggerName2, Map("payload" -> testString.toJson))
       withActivation(wsk.activation, first) { triggerActivation =>
-        withActivationsFromEntity(
-          wsk.activation,
-          actionName,
-          since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-          _.head.response.result shouldBe Some(testResult)
+        val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
+        ruleActivations should have size 1
+        val ruleActivation = ruleActivations.head
+        withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
+          actionActivation.response.result shouldBe Some(testResult)
         }
       }
   }
@@ -296,23 +310,18 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
         assetHelper)
 
       val testPayloads = Seq("got three words", "got four words, period")
-
-      val run = wsk.trigger.fire(triggerName1, Map("payload" -> testPayloads(0).toJson))
-      wsk.trigger.fire(triggerName2, Map("payload" -> testPayloads(1).toJson))
-
-      withActivation(wsk.activation, run) { triggerActivation =>
-        withActivationsFromEntity(
-          wsk.activation,
-          actionName,
-          N = 2,
-          since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) { activations =>
-          val results = activations.map(_.response.result)
-          val expectedResults = testPayloads.map { payload =>
-            Some(JsObject("count" -> payload.split(" ").length.toJson))
+      val runs = testPayloads.map(payload => wsk.trigger.fire(triggerName1, Map("payload" -> payload.toJson)))
+
+      runs.zip(testPayloads).foreach {
+        case (run, payload) =>
+          withActivation(wsk.activation, run) { triggerActivation =>
+            val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
+            ruleActivations should have size 1
+            val ruleActivation = ruleActivations.head
+            withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
+              actionActivation.response.result shouldBe Some(JsObject("count" -> payload.split(" ").length.toJson))
+            }
           }
-
-          results should contain theSameElementsAs expectedResults
-        }
       }
   }
 
@@ -331,17 +340,17 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
       val run = wsk.trigger.fire(triggerName, Map("payload" -> testString.toJson))
 
       withActivation(wsk.activation, run) { triggerActivation =>
-        withActivationsFromEntity(
-          wsk.activation,
-          actionName1,
-          since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-          _.head.response.result shouldBe Some(testResult)
+        val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
+        ruleActivations should have size 2
+
+        val action1Result = ruleActivations.find(_.action.contains(actionName1)).get
+        val action2Result = ruleActivations.find(_.action.contains(actionName2)).get
+
+        withActivation(wsk.activation, action1Result.activationId) { actionActivation =>
+          actionActivation.response.result shouldBe Some(testResult)
         }
-        withActivationsFromEntity(
-          wsk.activation,
-          actionName2,
-          since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) {
-          _.head.logs.get.mkString(" ") should include(s"hello, $testString")
+        withActivation(wsk.activation, action2Result.activationId) { actionActivation =>
+          actionActivation.logs.get.mkString(" ") should include(s"hello, $testString")
         }
       }
   }
@@ -362,35 +371,27 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
         assetHelper)
 
       val testPayloads = Seq("got three words", "got four words, period")
-      val run = wsk.trigger.fire(triggerName1, Map("payload" -> testPayloads(0).toJson))
-      wsk.trigger.fire(triggerName2, Map("payload" -> testPayloads(1).toJson))
-
-      withActivation(wsk.activation, run) { triggerActivation =>
-        withActivationsFromEntity(
-          wsk.activation,
-          actionName1,
-          N = 2,
-          since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) { activations =>
-          val results = activations.map(_.response.result)
-          val expectedResults = testPayloads.map { payload =>
-            Some(JsObject("count" -> payload.split(" ").length.toJson))
-          }
+      val runs = Seq(triggerName1, triggerName2).zip(testPayloads).map {
+        case (trigger, payload) =>
+          payload -> wsk.trigger.fire(trigger, Map("payload" -> payload.toJson))
+      }
 
-          results should contain theSameElementsAs expectedResults
-        }
-        withActivationsFromEntity(
-          wsk.activation,
-          actionName2,
-          N = 2,
-          since = Some(triggerActivation.start.minusMillis(activationTimeSkewFactorMs))) { activations =>
-          // drops the leftmost 39 characters (timestamp + streamname)
-          val logs = activations.map(_.logs.get.map(_.drop(39))).flatten
-          val expectedLogs = testPayloads.map { payload =>
-            s"hello, $payload!"
+      runs.foreach {
+        case (payload, run) =>
+          withActivation(wsk.activation, run) { triggerActivation =>
+            val ruleActivations = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult])
+            ruleActivations should have size 2 // each trigger has 2 actions attached
+
+            val action1Result = ruleActivations.find(_.action.contains(actionName1)).get
+            val action2Result = ruleActivations.find(_.action.contains(actionName2)).get
+
+            withActivation(wsk.activation, action1Result.activationId) { actionActivation =>
+              actionActivation.response.result shouldBe Some(JsObject("count" -> payload.split(" ").length.toJson))
+            }
+            withActivation(wsk.activation, action2Result.activationId) { actionActivation =>
+              actionActivation.logs.get.mkString(" ") should include(s"hello, $payload")
+            }
           }
-
-          logs should contain theSameElementsAs expectedLogs
-        }
       }
   }
 
@@ -417,6 +418,6 @@ abstract class WskRuleTests extends TestHelpers with WskTestHelpers {
     val listOutput = ruleList.lines
     listOutput.find(_.contains(ruleNameEnable)).get should (include(ruleNameEnable) and include("active"))
     listOutput.find(_.contains(ruleName)).get should (include(ruleName) and include("inactive"))
-    ruleList should not include ("Unknown")
+    ruleList should not include "Unknown"
   }
 }
diff --git a/tests/src/test/scala/system/basic/WskSequenceTests.scala b/tests/src/test/scala/system/basic/WskSequenceTests.scala
index 440c2ba..b2b37b8 100644
--- a/tests/src/test/scala/system/basic/WskSequenceTests.scala
+++ b/tests/src/test/scala/system/basic/WskSequenceTests.scala
@@ -35,6 +35,7 @@ import common.TestUtils._
 import common.WhiskProperties
 import common.BaseWsk
 import common.WskProps
+import common.RuleActivationResult
 import common.WskTestHelpers
 
 import akka.http.scaladsl.testkit.ScalatestRouteTest
@@ -469,9 +470,10 @@ abstract class WskSequenceTests extends TestHelpers with ScalatestRouteTest with
    */
   private def checkEchoSeqRuleResult(triggerFireRun: RunResult, seqName: String, triggerPayload: JsObject) = {
     withActivation(wsk.activation, triggerFireRun) { triggerActivation =>
-      withActivationsFromEntity(wsk.activation, seqName, since = Some(triggerActivation.start)) { activationList =>
-        activationList.head.response.result shouldBe Some(triggerPayload)
-        activationList.head.cause shouldBe None
+      val ruleActivation = triggerActivation.logs.get.map(_.parseJson.convertTo[RuleActivationResult]).head
+      withActivation(wsk.activation, ruleActivation.activationId) { actionActivation =>
+        actionActivation.response.result shouldBe Some(triggerPayload)
+        actionActivation.cause shouldBe None
       }
     }
   }

-- 
To stop receiving notification emails like this one, please contact
dubeejw@apache.org.