dubeejw closed pull request #139: fix failing test and refactor others into 
appropriate suites
URL: https://github.com/apache/incubator-openwhisk-package-alarms/pull/139
 
 
   

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/system/health/AlarmsHealthFeedTests.scala 
b/tests/src/test/scala/system/health/AlarmsHealthFeedTests.scala
index 90ae224..3db4b0b 100644
--- a/tests/src/test/scala/system/health/AlarmsHealthFeedTests.scala
+++ b/tests/src/test/scala/system/health/AlarmsHealthFeedTests.scala
@@ -18,10 +18,10 @@ package system.health
 
 import common._
 import org.junit.runner.RunWith
+import org.scalatest.FlatSpec
 import org.scalatest.junit.JUnitRunner
-import org.scalatest.{FlatSpec, Inside}
-import spray.json.DefaultJsonProtocol.{BooleanJsonFormat, IntJsonFormat, 
LongJsonFormat, StringJsonFormat}
-import spray.json.{JsObject, JsString, pimpAny}
+import spray.json.DefaultJsonProtocol.{IntJsonFormat, LongJsonFormat, 
StringJsonFormat}
+import spray.json.pimpAny
 
 /**
  * Tests for alarms trigger service
@@ -30,7 +30,6 @@ import spray.json.{JsObject, JsString, pimpAny}
 class AlarmsHealthFeedTests
     extends FlatSpec
     with TestHelpers
-    with Inside
     with WskTestHelpers {
 
     val wskprops = WskProps()
@@ -196,274 +195,4 @@ class AlarmsHealthFeedTests
             activationsAfterInterval should be(2)
     }
 
-    it should "update cron, startDate and stopDate parameters" in 
withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskProps = wp
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyAlarmsPackage"
-
-            // the package alarms should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
-            println("fetched package alarms")
-            packageGetResult.stdout should include("ok")
-
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
-            }
-
-            val cron = "* * * * *"
-            val startDate = System.currentTimeMillis + (1000 * 30)
-            val stopDate = startDate + (1000 * 100)
-
-            // create trigger feed
-            println(s"Creating trigger: $triggerName")
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/alarm"), 
parameters = Map(
-                        "cron" -> cron.toJson,
-                        "startDate" -> startDate.toJson,
-                        "stopDate" -> stopDate.toJson))
-            }
-
-
-            val actionName = s"$packageName/alarm"
-            val readRunResult = wsk.action.invoke(actionName, parameters = Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "READ".toJson,
-                "authKey" -> wskProps.authKey.toJson
-            ))
-
-            withActivation(wsk.activation, readRunResult) {
-                activation => activation.response.success shouldBe true
-
-                    inside(activation.response.result) {
-                        case Some(result) =>
-                            val config = 
result.getFields("config").head.asInstanceOf[JsObject].fields
-                            val status = 
result.getFields("status").head.asInstanceOf[JsObject].fields
-
-                            config should contain("cron" -> cron.toJson)
-                            config should contain("startDate" -> 
startDate.toJson)
-                            config should contain("stopDate" -> 
stopDate.toJson)
-
-                            status should contain("active" -> true.toJson)
-                            status should contain key "dateChanged"
-                            status should contain key "dateChangedISO"
-                            status should not(contain key "reason")
-                    }
-            }
-
-            val updatedCron = "*/2 * * * *"
-            val updatedStartDate = System.currentTimeMillis + (1000 * 30)
-            val updatedStopDate = updatedStartDate + (1000 * 100)
-
-            val updateRunAction = wsk.action.invoke(actionName, parameters = 
Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "UPDATE".toJson,
-                "authKey" -> wskProps.authKey.toJson,
-                "cron" -> updatedCron.toJson,
-                "startDate" -> updatedStartDate.toJson,
-                "stopDate" -> updatedStopDate.toJson
-            ))
-
-            withActivation(wsk.activation, updateRunAction) {
-                activation => activation.response.success shouldBe true
-            }
-
-            val runResult = wsk.action.invoke(actionName, parameters = Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "READ".toJson,
-                "authKey" -> wskProps.authKey.toJson
-            ))
-
-            withActivation(wsk.activation, runResult) {
-                activation => activation.response.success shouldBe true
-
-                    inside(activation.response.result) {
-                        case Some(result) =>
-                            val config = 
result.getFields("config").head.asInstanceOf[JsObject].fields
-
-                            config should contain("cron" -> updatedCron.toJson)
-                            config should contain("startDate" -> 
updatedStartDate.toJson)
-                            config should contain("stopDate" -> 
updatedStopDate.toJson)
-                    }
-            }
-    }
-
-    it should "update fireOnce and payload parameters" in 
withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskProps = wp
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyAlarmsPackage"
-
-            // the package alarms should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
-            println("fetched package alarms")
-            packageGetResult.stdout should include("ok")
-
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
-            }
-
-            val futureDate = System.currentTimeMillis + (1000 * 30)
-            val payload = JsObject(
-                "test" -> JsString("alarmsTest")
-            )
-
-            // create trigger feed
-            println(s"Creating trigger: $triggerName")
-            assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = 
false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/once"), 
parameters = Map(
-                        "trigger_payload" -> payload,
-                        "date" -> futureDate.toJson,
-                        "deleteAfterFire" -> "true".toJson))
-            }
-
-            val actionName = s"$packageName/alarm"
-            val readRunResult = wsk.action.invoke(actionName, parameters = Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "READ".toJson,
-                "authKey" -> wskProps.authKey.toJson
-            ))
-
-            withActivation(wsk.activation, readRunResult) {
-                activation => activation.response.success shouldBe true
-
-                    inside(activation.response.result) {
-                        case Some(result) =>
-                            val config = 
result.getFields("config").head.asInstanceOf[JsObject].fields
-
-                            config should contain("date" -> futureDate.toJson)
-                            config should contain("payload" -> payload)
-                            config should contain("deleteAfterFire" -> 
"true".toJson)
-                    }
-            }
-
-            val updatedFutureDate = System.currentTimeMillis + (1000 * 30)
-            val updatedPayload = JsObject(
-                "update_test" -> JsString("alarmsTest")
-            )
-
-            val updateRunAction = wsk.action.invoke(actionName, parameters = 
Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "UPDATE".toJson,
-                "authKey" -> wskProps.authKey.toJson,
-                "trigger_payload" ->updatedPayload,
-                "date" -> updatedFutureDate.toJson,
-                "deleteAfterFire" -> "rules".toJson
-            ))
-
-            withActivation(wsk.activation, updateRunAction) {
-                activation => activation.response.success shouldBe true
-            }
-
-            val runResult = wsk.action.invoke(actionName, parameters = Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "READ".toJson,
-                "authKey" -> wskProps.authKey.toJson
-            ))
-
-            withActivation(wsk.activation, runResult) {
-                activation => activation.response.success shouldBe true
-
-                    inside(activation.response.result) {
-                        case Some(result) =>
-                            val config = 
result.getFields("config").head.asInstanceOf[JsObject].fields
-
-                            config should contain("date" -> 
updatedFutureDate.toJson)
-                            config should contain("payload" -> updatedPayload)
-                            config should contain("deleteAfterFire" -> 
"rules".toJson)
-                    }
-            }
-    }
-
-    it should "update minutes parameter for interval feed" in 
withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskProps = wp
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyAlarmsPackage"
-
-            // the package alarms should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
-            println("fetched package alarms")
-            packageGetResult.stdout should include("ok")
-
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
-            }
-
-            val minutes = 1
-            val startDate = System.currentTimeMillis + (1000 * 30)
-            val stopDate = startDate + (1000 * 100)
-
-            // create trigger feed
-            println(s"Creating trigger: $triggerName")
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) =>
-                    trigger.create(name, feed = 
Some(s"$packageName/interval"), parameters = Map(
-                        "minutes" -> minutes.toJson,
-                        "startDate" -> startDate.toJson,
-                        "stopDate" -> stopDate.toJson))
-            }
-
-
-            val actionName = s"$packageName/alarm"
-            val readRunResult = wsk.action.invoke(actionName, parameters = Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "READ".toJson,
-                "authKey" -> wskProps.authKey.toJson
-            ))
-
-            withActivation(wsk.activation, readRunResult) {
-                activation => activation.response.success shouldBe true
-
-                    inside(activation.response.result) {
-                        case Some(result) =>
-                            val config = 
result.getFields("config").head.asInstanceOf[JsObject].fields
-
-                            config should contain("minutes" -> minutes.toJson)
-                            config should contain("startDate" -> 
startDate.toJson)
-                            config should contain("stopDate" -> 
stopDate.toJson)
-                    }
-            }
-
-            val updatedMinutes = 2
-            val updatedStartDate = System.currentTimeMillis + (1000 * 30)
-            val updatedStopDate = updatedStartDate + (1000 * 100)
-
-            val updateRunAction = wsk.action.invoke(actionName, parameters = 
Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "UPDATE".toJson,
-                "authKey" -> wskProps.authKey.toJson,
-                "minutes" -> updatedMinutes.toJson,
-                "startDate" -> updatedStartDate.toJson,
-                "stopDate" -> updatedStopDate.toJson
-            ))
-
-            withActivation(wsk.activation, updateRunAction) {
-                activation => activation.response.success shouldBe true
-            }
-
-            val runResult = wsk.action.invoke(actionName, parameters = Map(
-                "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "READ".toJson,
-                "authKey" -> wskProps.authKey.toJson
-            ))
-
-            withActivation(wsk.activation, runResult) {
-                activation => activation.response.success shouldBe true
-
-                    inside(activation.response.result) {
-                        case Some(result) =>
-                            val config = 
result.getFields("config").head.asInstanceOf[JsObject].fields
-
-                            config should contain("minutes" -> 
updatedMinutes.toJson)
-                            config should contain("startDate" -> 
updatedStartDate.toJson)
-                            config should contain("stopDate" -> 
updatedStopDate.toJson)
-                    }
-            }
-    }
 }
diff --git a/tests/src/test/scala/system/packages/AlarmsFeedNegativeTests.scala 
b/tests/src/test/scala/system/packages/AlarmsFeedNegativeTests.scala
new file mode 100644
index 0000000..d5730b1
--- /dev/null
+++ b/tests/src/test/scala/system/packages/AlarmsFeedNegativeTests.scala
@@ -0,0 +1,432 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package system.packages
+
+import common._
+import org.junit.runner.RunWith
+import org.scalatest.FlatSpec
+import org.scalatest.junit.JUnitRunner
+import spray.json.DefaultJsonProtocol.{BooleanJsonFormat, IntJsonFormat, 
LongJsonFormat, StringJsonFormat}
+import spray.json.{JsString, pimpAny}
+
+/**
+ * Tests for alarms trigger service
+ */
+@RunWith(classOf[JUnitRunner])
+class AlarmsFeedNegativeTests
+    extends FlatSpec
+    with TestHelpers
+    with WskTestHelpers {
+
+    val wskprops = WskProps()
+    val wsk = new Wsk
+
+    val defaultAction = Some(TestUtils.getTestActionFilename("hello.js"))
+
+    behavior of "Alarms feed negative tests"
+
+    it should "return error message when alarm action does not include cron 
parameter" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            implicit val wskprops = wp // shadow global props and make implicit
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+            val feed = "alarm"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            // create trigger with feed
+            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
+                (trigger, name) =>
+                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
+                        "trigger_payload" -> "alarmTest".toJson),
+                        expectedExitCode = 246)
+            }
+            feedCreationResult.stderr should include("alarms trigger feed is 
missing the cron parameter")
+
+    }
+
+    it should "return error message when alarms once action does not include 
date parameter" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            implicit val wskprops = wp // shadow global props and make implicit
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+            val feed = "once"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            // create trigger with feed
+            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
+                (trigger, name) =>
+                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
+                        "trigger_payload" -> "alarmTest".toJson),
+                        expectedExitCode = 246)
+            }
+            feedCreationResult.stderr should include("alarms once trigger feed 
is missing the date parameter")
+
+    }
+
+    it should "return error message when alarm action includes invalid cron 
parameter" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            implicit val wskprops = wp // shadow global props and make implicit
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+            val feed = "alarm"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            val cron = System.currentTimeMillis
+
+            // create trigger with feed
+            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
+                (trigger, name) =>
+                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
+                        "trigger_payload" -> "alarmTest".toJson,
+                        "cron" -> cron.toJson),
+                        expectedExitCode = 246)
+            }
+            feedCreationResult.stderr should include(s"cron pattern '${cron}' 
is not valid")
+
+    }
+
+    it should "return error message when alarms once action includes an 
invalid date parameter" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            implicit val wskprops = wp // shadow global props and make implicit
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+            val feed = "once"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            // create trigger with feed
+            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
+                (trigger, name) =>
+                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
+                        "trigger_payload" -> "alarmTest".toJson,
+                        "date" -> "tomorrow".toJson),
+                        expectedExitCode = 246)
+            }
+            feedCreationResult.stderr should include("date parameter 
'tomorrow' is not a valid Date")
+
+    }
+
+    it should "return error message when alarms once action date parameter is 
not a future date" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            implicit val wskprops = wp // shadow global props and make implicit
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+            val feed = "once"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            val pastDate = System.currentTimeMillis - 5000
+
+            // create trigger with feed
+            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
+                (trigger, name) =>
+                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
+                        "trigger_payload" -> "alarmTest".toJson,
+                        "date" -> pastDate.toJson),
+                        expectedExitCode = 246)
+            }
+            feedCreationResult.stderr should include(s"date parameter 
'${pastDate}' must be in the future")
+
+    }
+
+    it should "return error message when alarms startDate parameter is not a 
future date" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            implicit val wskprops = wp // shadow global props and make implicit
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+            val feed = "alarm"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            val pastDate = System.currentTimeMillis - 5000
+
+            // create trigger with feed
+            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
+                (trigger, name) =>
+                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
+                        "startDate" -> pastDate.toJson,
+                        "cron" -> "* * * * *".toJson),
+                        expectedExitCode = 246)
+            }
+            feedCreationResult.stderr should include(s"startDate parameter 
'${pastDate}' must be in the future")
+
+    }
+
+    it should "return error message when alarms stopDate parameter is not 
greater than startDate" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            implicit val wskprops = wp // shadow global props and make implicit
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+            val feed = "alarm"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            val stopDate = System.currentTimeMillis + 30000
+            val startDate = stopDate
+
+            // create trigger with feed
+            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
+                (trigger, name) =>
+                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
+                        "startDate" -> startDate.toJson,
+                        "stopDate" -> stopDate.toJson,
+                        "cron" -> "* * * * *".toJson),
+                        expectedExitCode = 246)
+            }
+            feedCreationResult.stderr should include(s"stopDate parameter 
'${stopDate}' must be greater than the startDate")
+
+    }
+
+    it should "return error message when interval action does not include 
minutes parameter" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            implicit val wskprops = wp // shadow global props and make implicit
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+            val feed = "interval"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            // create trigger with feed
+            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
+                (trigger, name) =>
+                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
+                        "trigger_payload" -> "alarmTest".toJson),
+                        expectedExitCode = 246)
+            }
+            feedCreationResult.stderr should include("interval trigger feed is 
missing the minutes parameter")
+
+    }
+
+    it should "return error message when interval action includes invalid 
minutes parameter" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            implicit val wskprops = wp // shadow global props and make implicit
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+            val feed = "interval"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            // create trigger with feed
+            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
+                (trigger, name) =>
+                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
+                        "trigger_payload" -> "alarmTest".toJson,
+                        "minutes" -> "five".toJson),
+                        expectedExitCode = 246)
+            }
+            feedCreationResult.stderr should include("the minutes parameter 
must be an integer")
+
+    }
+
+    it should "return error message when alarms trigger update contains no 
updatable parameters" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            implicit val wskProps = wp
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            val futureDate = System.currentTimeMillis + (1000 * 20)
+
+            // create trigger feed
+            println(s"Creating trigger: $triggerName")
+            assetHelper.withCleaner(wsk.trigger, triggerName) {
+                (trigger, name) =>
+                    trigger.create(name, feed = Some(s"$packageName/once"), 
parameters = Map(
+                        "date" -> futureDate.toJson))
+            }
+
+            val actionName = s"$packageName/alarm"
+            val updatedStartDate = System.currentTimeMillis + (1000 * 20)
+            val updatedStopDate = updatedStartDate + (1000 * 10)
+
+            val updateRunAction = wsk.action.invoke(actionName, parameters = 
Map(
+                "triggerName" -> triggerName.toJson,
+                "lifecycleEvent" -> "UPDATE".toJson,
+                "authKey" -> wskProps.authKey.toJson,
+                "startDate" -> updatedStartDate.toJson,
+                "stopDate" -> updatedStopDate.toJson
+            ))
+
+            withActivation(wsk.activation, updateRunAction) {
+                activation =>
+                    activation.response.success shouldBe false
+                    val error = 
activation.response.result.get.fields("error").asJsObject
+                    error.fields("error") shouldBe JsString("no updatable 
parameters were specified")
+            }
+    }
+
+    it should "return error message when startDate is updated to be greater 
than the stopDate" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            implicit val wskProps = wp
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            val minutes = 1
+            val startDate = System.currentTimeMillis + (1000 * 20)
+            val stopDate = startDate + (1000 * 10)
+
+            // create trigger feed
+            println(s"Creating trigger: $triggerName")
+            assetHelper.withCleaner(wsk.trigger, triggerName) {
+                (trigger, name) =>
+                    trigger.create(name, feed = 
Some(s"$packageName/interval"), parameters = Map(
+                        "minutes" -> minutes.toJson,
+                        "startDate" -> startDate.toJson,
+                        "stopDate" -> stopDate.toJson))
+            }
+
+            val actionName = s"$packageName/alarm"
+            val updatedStartDate = System.currentTimeMillis + (1000 * 2000)
+
+            val updateRunAction = wsk.action.invoke(actionName, parameters = 
Map(
+                "triggerName" -> triggerName.toJson,
+                "lifecycleEvent" -> "UPDATE".toJson,
+                "authKey" -> wskProps.authKey.toJson,
+                "startDate" -> updatedStartDate.toJson
+            ))
+
+            withActivation(wsk.activation, updateRunAction) {
+                activation =>
+                    activation.response.success shouldBe false
+                    val error = 
activation.response.result.get.fields("error").asJsObject
+                    error.fields("error") shouldBe JsString(s"startDate 
parameter '${updatedStartDate}' must be less than the stopDate parameter 
'${stopDate}'")
+            }
+    }
+
+    it should "return error message when limitCronFields is true and 6 cron 
fields are used" in withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            implicit val wskprops = wp // shadow global props and make implicit
+            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
+            val packageName = "dummyAlarmsPackage"
+            val feed = "alarm"
+
+            // the package alarms should be there
+            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
+            println("fetched package alarms")
+            packageGetResult.stdout should include("ok")
+
+            // create package binding
+            assetHelper.withCleaner(wsk.pkg, packageName) {
+                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+            }
+
+            // create trigger with feed
+            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
+                (trigger, name) =>
+                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
+                        "cron" -> "* * * * * *".toJson,
+                        "limitCronFields" -> true.toJson),
+                        expectedExitCode = 246)
+            }
+            feedCreationResult.stderr should include("cron pattern is limited 
to 5 fields with 1 minute as the finest granularity")
+
+    }
+}
diff --git a/tests/src/test/scala/system/packages/AlarmsFeedTests.scala 
b/tests/src/test/scala/system/packages/AlarmsFeedTests.scala
index 56e7e74..b9c9fbf 100644
--- a/tests/src/test/scala/system/packages/AlarmsFeedTests.scala
+++ b/tests/src/test/scala/system/packages/AlarmsFeedTests.scala
@@ -18,10 +18,10 @@ package system.packages
 
 import common._
 import org.junit.runner.RunWith
-import org.scalatest.FlatSpec
+import org.scalatest.{FlatSpec, Inside}
 import org.scalatest.junit.JUnitRunner
 import spray.json.DefaultJsonProtocol.{BooleanJsonFormat, IntJsonFormat, 
LongJsonFormat, StringJsonFormat}
-import spray.json.{JsString, pimpAny}
+import spray.json.{JsObject, JsString, pimpAny}
 
 /**
  * Tests for alarms trigger service
@@ -29,6 +29,7 @@ import spray.json.{JsString, pimpAny}
 @RunWith(classOf[JUnitRunner])
 class AlarmsFeedTests
     extends FlatSpec
+    with Inside
     with TestHelpers
     with WskTestHelpers {
 
@@ -82,12 +83,11 @@ class AlarmsFeedTests
             activations should be(3)
     }
 
-    it should "return error message when alarm action does not include cron 
parameter" in withAssetCleaner(wskprops) {
+    it should "update cron, startDate and stopDate parameters" in 
withAssetCleaner(wskprops) {
         (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
+            implicit val wskProps = wp
             val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
             val packageName = "dummyAlarmsPackage"
-            val feed = "alarm"
 
             // the package alarms should be there
             val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
@@ -99,142 +99,89 @@ class AlarmsFeedTests
                 (pkg, name) => pkg.bind("/whisk.system/alarms", name)
             }
 
-            // create trigger with feed
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
-                        "trigger_payload" -> "alarmTest".toJson),
-                        expectedExitCode = 246)
-            }
-            feedCreationResult.stderr should include("alarms trigger feed is 
missing the cron parameter")
-
-    }
-
-    it should "return error message when alarms once action does not include 
date parameter" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyAlarmsPackage"
-            val feed = "once"
-
-            // the package alarms should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
-            println("fetched package alarms")
-            packageGetResult.stdout should include("ok")
-
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
-            }
+            val cron = "* * * * *"
+            val startDate = System.currentTimeMillis + (1000 * 30)
+            val stopDate = startDate + (1000 * 100)
 
-            // create trigger with feed
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
+            // create trigger feed
+            println(s"Creating trigger: $triggerName")
+            assetHelper.withCleaner(wsk.trigger, triggerName) {
                 (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
-                        "trigger_payload" -> "alarmTest".toJson),
-                        expectedExitCode = 246)
+                    trigger.create(name, feed = Some(s"$packageName/alarm"), 
parameters = Map(
+                        "cron" -> cron.toJson,
+                        "startDate" -> startDate.toJson,
+                        "stopDate" -> stopDate.toJson))
             }
-            feedCreationResult.stderr should include("alarms once trigger feed 
is missing the date parameter")
 
-    }
 
-    it should "return error message when alarm action includes invalid cron 
parameter" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyAlarmsPackage"
-            val feed = "alarm"
+            val actionName = s"$packageName/alarm"
+            val readRunResult = wsk.action.invoke(actionName, parameters = Map(
+                "triggerName" -> triggerName.toJson,
+                "lifecycleEvent" -> "READ".toJson,
+                "authKey" -> wskProps.authKey.toJson
+            ))
 
-            // the package alarms should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
-            println("fetched package alarms")
-            packageGetResult.stdout should include("ok")
+            withActivation(wsk.activation, readRunResult) {
+                activation => activation.response.success shouldBe true
 
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
-            }
+                    inside(activation.response.result) {
+                        case Some(result) =>
+                            val config = 
result.getFields("config").head.asInstanceOf[JsObject].fields
+                            val status = 
result.getFields("status").head.asInstanceOf[JsObject].fields
 
-            val cron = System.currentTimeMillis
+                            config should contain("cron" -> cron.toJson)
+                            config should contain("startDate" -> 
startDate.toJson)
+                            config should contain("stopDate" -> 
stopDate.toJson)
 
-            // create trigger with feed
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
-                        "trigger_payload" -> "alarmTest".toJson,
-                        "cron" -> cron.toJson),
-                        expectedExitCode = 246)
+                            status should contain("active" -> true.toJson)
+                            status should contain key "dateChanged"
+                            status should contain key "dateChangedISO"
+                            status should not(contain key "reason")
+                    }
             }
-            feedCreationResult.stderr should include(s"cron pattern '${cron}' 
is not valid")
 
-    }
-
-    it should "return error message when alarms once action includes an 
invalid date parameter" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyAlarmsPackage"
-            val feed = "once"
+            val updatedCron = "*/2 * * * *"
+            val updatedStartDate = System.currentTimeMillis + (1000 * 30)
+            val updatedStopDate = updatedStartDate + (1000 * 100)
 
-            // the package alarms should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
-            println("fetched package alarms")
-            packageGetResult.stdout should include("ok")
-
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
-            }
+            val updateRunAction = wsk.action.invoke(actionName, parameters = 
Map(
+                "triggerName" -> triggerName.toJson,
+                "lifecycleEvent" -> "UPDATE".toJson,
+                "authKey" -> wskProps.authKey.toJson,
+                "cron" -> updatedCron.toJson,
+                "startDate" -> updatedStartDate.toJson,
+                "stopDate" -> updatedStopDate.toJson
+            ))
 
-            // create trigger with feed
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
-                        "trigger_payload" -> "alarmTest".toJson,
-                        "date" -> "tomorrow".toJson),
-                        expectedExitCode = 246)
+            withActivation(wsk.activation, updateRunAction) {
+                activation => activation.response.success shouldBe true
             }
-            feedCreationResult.stderr should include("date parameter 
'tomorrow' is not a valid Date")
 
-    }
+            val runResult = wsk.action.invoke(actionName, parameters = Map(
+                "triggerName" -> triggerName.toJson,
+                "lifecycleEvent" -> "READ".toJson,
+                "authKey" -> wskProps.authKey.toJson
+            ))
 
-    it should "return error message when alarms once action date parameter is 
not a future date" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyAlarmsPackage"
-            val feed = "once"
+            withActivation(wsk.activation, runResult) {
+                activation => activation.response.success shouldBe true
 
-            // the package alarms should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
-            println("fetched package alarms")
-            packageGetResult.stdout should include("ok")
+                    inside(activation.response.result) {
+                        case Some(result) =>
+                            val config = 
result.getFields("config").head.asInstanceOf[JsObject].fields
 
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+                            config should contain("cron" -> updatedCron.toJson)
+                            config should contain("startDate" -> 
updatedStartDate.toJson)
+                            config should contain("stopDate" -> 
updatedStopDate.toJson)
+                    }
             }
-
-            val pastDate = System.currentTimeMillis - 5000
-
-            // create trigger with feed
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
-                        "trigger_payload" -> "alarmTest".toJson,
-                        "date" -> pastDate.toJson),
-                        expectedExitCode = 246)
-            }
-            feedCreationResult.stderr should include(s"date parameter 
'${pastDate}' must be in the future")
-
     }
 
-    it should "return error message when alarms startDate parameter is not a 
future date" in withAssetCleaner(wskprops) {
+    it should "update fireOnce and payload parameters" in 
withAssetCleaner(wskprops) {
         (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
+            implicit val wskProps = wp
             val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
             val packageName = "dummyAlarmsPackage"
-            val feed = "alarm"
 
             // the package alarms should be there
             val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
@@ -246,111 +193,80 @@ class AlarmsFeedTests
                 (pkg, name) => pkg.bind("/whisk.system/alarms", name)
             }
 
-            val pastDate = System.currentTimeMillis - 5000
+            val futureDate = System.currentTimeMillis + (1000 * 30)
+            val payload = JsObject(
+                "test" -> JsString("alarmsTest")
+            )
 
-            // create trigger with feed
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
+            // create trigger feed
+            println(s"Creating trigger: $triggerName")
+            assetHelper.withCleaner(wsk.trigger, triggerName, confirmDelete = 
false) {
                 (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
-                        "startDate" -> pastDate.toJson,
-                        "cron" -> "* * * * *".toJson),
-                        expectedExitCode = 246)
+                    trigger.create(name, feed = Some(s"$packageName/once"), 
parameters = Map(
+                        "trigger_payload" -> payload,
+                        "date" -> futureDate.toJson,
+                        "deleteAfterFire" -> "true".toJson))
             }
-            feedCreationResult.stderr should include(s"startDate parameter 
'${pastDate}' must be in the future")
 
-    }
+            val actionName = s"$packageName/alarm"
+            val readRunResult = wsk.action.invoke(actionName, parameters = Map(
+                "triggerName" -> triggerName.toJson,
+                "lifecycleEvent" -> "READ".toJson,
+                "authKey" -> wskProps.authKey.toJson
+            ))
 
-    it should "return error message when alarms stopDate parameter is not 
greater than startDate" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyAlarmsPackage"
-            val feed = "alarm"
+            withActivation(wsk.activation, readRunResult) {
+                activation => activation.response.success shouldBe true
 
-            // the package alarms should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
-            println("fetched package alarms")
-            packageGetResult.stdout should include("ok")
+                    inside(activation.response.result) {
+                        case Some(result) =>
+                            val config = 
result.getFields("config").head.asInstanceOf[JsObject].fields
 
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
-            }
-
-            val stopDate = System.currentTimeMillis + 30000
-            val startDate = stopDate
-
-            // create trigger with feed
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
-                        "startDate" -> startDate.toJson,
-                        "stopDate" -> stopDate.toJson,
-                        "cron" -> "* * * * *".toJson),
-                        expectedExitCode = 246)
+                            config should contain("date" -> futureDate.toJson)
+                            config should contain("payload" -> payload)
+                            config should contain("deleteAfterFire" -> 
"true".toJson)
+                    }
             }
-            feedCreationResult.stderr should include(s"stopDate parameter 
'${stopDate}' must be greater than the startDate")
-
-    }
-
-    it should "return error message when interval action does not include 
minutes parameter" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyAlarmsPackage"
-            val feed = "interval"
 
-            // the package alarms should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
-            println("fetched package alarms")
-            packageGetResult.stdout should include("ok")
+            val updatedFutureDate = System.currentTimeMillis + (1000 * 30)
+            val updatedPayload = JsObject(
+                "update_test" -> JsString("alarmsTest")
+            )
 
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
-            }
+            val updateRunAction = wsk.action.invoke(actionName, parameters = 
Map(
+                "triggerName" -> triggerName.toJson,
+                "lifecycleEvent" -> "UPDATE".toJson,
+                "authKey" -> wskProps.authKey.toJson,
+                "trigger_payload" ->updatedPayload,
+                "date" -> updatedFutureDate.toJson,
+                "deleteAfterFire" -> "rules".toJson
+            ))
 
-            // create trigger with feed
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
-                        "trigger_payload" -> "alarmTest".toJson),
-                        expectedExitCode = 246)
+            withActivation(wsk.activation, updateRunAction) {
+                activation => activation.response.success shouldBe true
             }
-            feedCreationResult.stderr should include("interval trigger feed is 
missing the minutes parameter")
 
-    }
+            val runResult = wsk.action.invoke(actionName, parameters = Map(
+                "triggerName" -> triggerName.toJson,
+                "lifecycleEvent" -> "READ".toJson,
+                "authKey" -> wskProps.authKey.toJson
+            ))
 
-    it should "return error message when interval action includes invalid 
minutes parameter" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyAlarmsPackage"
-            val feed = "interval"
+            withActivation(wsk.activation, runResult) {
+                activation => activation.response.success shouldBe true
 
-            // the package alarms should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
-            println("fetched package alarms")
-            packageGetResult.stdout should include("ok")
+                    inside(activation.response.result) {
+                        case Some(result) =>
+                            val config = 
result.getFields("config").head.asInstanceOf[JsObject].fields
 
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+                            config should contain("date" -> 
updatedFutureDate.toJson)
+                            config should contain("payload" -> updatedPayload)
+                            config should contain("deleteAfterFire" -> 
"rules".toJson)
+                    }
             }
-
-            // create trigger with feed
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
-                        "trigger_payload" -> "alarmTest".toJson,
-                        "minutes" -> "five".toJson),
-                        expectedExitCode = 246)
-            }
-            feedCreationResult.stderr should include("the minutes parameter 
must be an integer")
-
     }
 
-    it should "return error message when alarms trigger update contains no 
updatable parameters" in withAssetCleaner(wskprops) {
+    it should "update minutes parameter for interval feed" in 
withAssetCleaner(wskprops) {
         (wp, assetHelper) =>
             implicit val wskProps = wp
             val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
@@ -366,110 +282,75 @@ class AlarmsFeedTests
                 (pkg, name) => pkg.bind("/whisk.system/alarms", name)
             }
 
-            val futureDate = System.currentTimeMillis + (1000 * 20)
+            val minutes = 1
+            val startDate = System.currentTimeMillis + (1000 * 30)
+            val stopDate = startDate + (1000 * 100)
 
             // create trigger feed
             println(s"Creating trigger: $triggerName")
             assetHelper.withCleaner(wsk.trigger, triggerName) {
                 (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/once"), 
parameters = Map(
-                        "date" -> futureDate.toJson))
+                    trigger.create(name, feed = 
Some(s"$packageName/interval"), parameters = Map(
+                        "minutes" -> minutes.toJson,
+                        "startDate" -> startDate.toJson,
+                        "stopDate" -> stopDate.toJson))
             }
 
-            val actionName = s"$packageName/alarm"
-            val updatedStartDate = System.currentTimeMillis + (1000 * 20)
-            val updatedStopDate = updatedStartDate + (1000 * 10)
 
-            val updateRunAction = wsk.action.invoke(actionName, parameters = 
Map(
+            val actionName = s"$packageName/alarm"
+            val readRunResult = wsk.action.invoke(actionName, parameters = Map(
                 "triggerName" -> triggerName.toJson,
-                "lifecycleEvent" -> "UPDATE".toJson,
-                "authKey" -> wskProps.authKey.toJson,
-                "startDate" -> updatedStartDate.toJson,
-                "stopDate" -> updatedStopDate.toJson
+                "lifecycleEvent" -> "READ".toJson,
+                "authKey" -> wskProps.authKey.toJson
             ))
 
-            withActivation(wsk.activation, updateRunAction) {
-                activation =>
-                    activation.response.success shouldBe false
-                    val error = 
activation.response.result.get.fields("error").asJsObject
-                    error.fields("error") shouldBe JsString("no updatable 
parameters were specified")
-            }
-    }
-
-    it should "return error message when startDate is updated to be greater 
than the stopDate" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskProps = wp
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyAlarmsPackage"
+            withActivation(wsk.activation, readRunResult) {
+                activation => activation.response.success shouldBe true
 
-            // the package alarms should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
-            println("fetched package alarms")
-            packageGetResult.stdout should include("ok")
+                    inside(activation.response.result) {
+                        case Some(result) =>
+                            val config = 
result.getFields("config").head.asInstanceOf[JsObject].fields
 
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
+                            config should contain("minutes" -> minutes.toJson)
+                            config should contain("startDate" -> 
startDate.toJson)
+                            config should contain("stopDate" -> 
stopDate.toJson)
+                    }
             }
 
-            val minutes = 1
-            val startDate = System.currentTimeMillis + (1000 * 20)
-            val stopDate = startDate + (1000 * 10)
-
-            // create trigger feed
-            println(s"Creating trigger: $triggerName")
-            assetHelper.withCleaner(wsk.trigger, triggerName) {
-                (trigger, name) =>
-                    trigger.create(name, feed = 
Some(s"$packageName/interval"), parameters = Map(
-                        "minutes" -> minutes.toJson,
-                        "startDate" -> startDate.toJson,
-                        "stopDate" -> stopDate.toJson))
-            }
-
-            val actionName = s"$packageName/alarm"
-            val updatedStartDate = System.currentTimeMillis + (1000 * 2000)
+            val updatedMinutes = 2
+            val updatedStartDate = System.currentTimeMillis + (1000 * 30)
+            val updatedStopDate = updatedStartDate + (1000 * 100)
 
             val updateRunAction = wsk.action.invoke(actionName, parameters = 
Map(
                 "triggerName" -> triggerName.toJson,
                 "lifecycleEvent" -> "UPDATE".toJson,
                 "authKey" -> wskProps.authKey.toJson,
-                "startDate" -> updatedStartDate.toJson
+                "minutes" -> updatedMinutes.toJson,
+                "startDate" -> updatedStartDate.toJson,
+                "stopDate" -> updatedStopDate.toJson
             ))
 
             withActivation(wsk.activation, updateRunAction) {
-                activation =>
-                    activation.response.success shouldBe false
-                    val error = 
activation.response.result.get.fields("error").asJsObject
-                    error.fields("error") shouldBe JsString(s"startDate 
parameter '${updatedStartDate}' must be less than the stopDate parameter 
'${stopDate}'")
+                activation => activation.response.success shouldBe true
             }
-    }
 
-    it should "return error message when limitCronFields is true and 6 cron 
fields are used" in withAssetCleaner(wskprops) {
-        (wp, assetHelper) =>
-            implicit val wskprops = wp // shadow global props and make implicit
-            val triggerName = s"dummyAlarmsTrigger-${System.currentTimeMillis}"
-            val packageName = "dummyAlarmsPackage"
-            val feed = "alarm"
+            val runResult = wsk.action.invoke(actionName, parameters = Map(
+                "triggerName" -> triggerName.toJson,
+                "lifecycleEvent" -> "READ".toJson,
+                "authKey" -> wskProps.authKey.toJson
+            ))
 
-            // the package alarms should be there
-            val packageGetResult = wsk.pkg.get("/whisk.system/alarms")
-            println("fetched package alarms")
-            packageGetResult.stdout should include("ok")
+            withActivation(wsk.activation, runResult) {
+                activation => activation.response.success shouldBe true
 
-            // create package binding
-            assetHelper.withCleaner(wsk.pkg, packageName) {
-                (pkg, name) => pkg.bind("/whisk.system/alarms", name)
-            }
+                    inside(activation.response.result) {
+                        case Some(result) =>
+                            val config = 
result.getFields("config").head.asInstanceOf[JsObject].fields
 
-            // create trigger with feed
-            val feedCreationResult = assetHelper.withCleaner(wsk.trigger, 
triggerName, confirmDelete = false) {
-                (trigger, name) =>
-                    trigger.create(name, feed = Some(s"$packageName/$feed"), 
parameters = Map(
-                        "cron" -> "* * * * * *".toJson,
-                        "limitCronFields" -> true.toJson),
-                        expectedExitCode = 246)
+                            config should contain("minutes" -> 
updatedMinutes.toJson)
+                            config should contain("startDate" -> 
updatedStartDate.toJson)
+                            config should contain("stopDate" -> 
updatedStopDate.toJson)
+                    }
             }
-            feedCreationResult.stderr should include("cron pattern is limited 
to 5 fields with 1 minute as the finest granularity")
-
     }
 }
diff --git a/tests/src/test/scala/system/packages/AlarmsMultiWorkersTests.scala 
b/tests/src/test/scala/system/packages/AlarmsMultiWorkersTests.scala
index 83e4f6d..d7cdd0f 100644
--- a/tests/src/test/scala/system/packages/AlarmsMultiWorkersTests.scala
+++ b/tests/src/test/scala/system/packages/AlarmsMultiWorkersTests.scala
@@ -27,8 +27,12 @@ import org.scalatest.{FlatSpec, Matchers}
 import spray.json.DefaultJsonProtocol.StringJsonFormat
 import spray.json.DefaultJsonProtocol._
 import spray.json.{pimpAny, _}
-import whisk.core.database.test.DatabaseScriptTestUtils
-import whisk.utils.JsHelpers
+import whisk.core.WhiskConfig
+import whisk.core.database.test.ExtendedCouchDbRestClient
+import whisk.utils.{JsHelpers, retry}
+
+import scala.concurrent.Await
+import scala.concurrent.duration.DurationInt
 
 
 @RunWith(classOf[JUnitRunner])
@@ -36,8 +40,7 @@ class AlarmsMultiWorkersTests extends FlatSpec
     with Matchers
     with WskActorSystem
     with WskTestHelpers
-    with StreamLogging
-    with DatabaseScriptTestUtils {
+    with StreamLogging {
 
     val wskprops = WskProps()
     val wsk = new Wsk
@@ -45,6 +48,13 @@ class AlarmsMultiWorkersTests extends FlatSpec
     val user = auth.fst
     val password = auth.snd
 
+    val dbProtocol = WhiskProperties.getProperty("db.protocol")
+    val dbHost = WhiskProperties.getProperty("db.host")
+    val dbPort = WhiskProperties.getProperty("db.port").toInt
+    val dbUsername = WhiskProperties.getProperty("db.username")
+    val dbPassword = WhiskProperties.getProperty("db.password")
+    val dbPrefix = WhiskProperties.getProperty(WhiskConfig.dbPrefix)
+
     val webAction = "/whisk.system/alarmsWeb/alarmWebAction"
     val webActionURL = 
s"https://${wskprops.apihost}/api/v1/web${webAction}.http";
 
@@ -81,14 +91,19 @@ class AlarmsMultiWorkersTests extends FlatSpec
                 makePostCallWithExpectedResult(worker11Params, 200)
 
                 val dbName = s"${dbPrefix}alarmservice"
-                val documents = getAllDocs(dbName)
-
-                val worker1Doc = documents
-                        .fields("rows")
-                        .convertTo[List[JsObject]]
-                        
.filter(_.fields("id").convertTo[String].equals(s"$user:$password/_/$worker11Trigger"))
-
-                JsHelpers.getFieldPath(worker1Doc(0), "doc", "worker") 
shouldBe Some(JsString("worker11"))
+                val client = new ExtendedCouchDbRestClient(dbProtocol, dbHost, 
dbPort, dbUsername, dbPassword, dbName)
+
+                retry({
+                    val result = Await.result(client.getAllDocs(includeDocs = 
Some(true)), 15.seconds)
+                    result should be('right)
+                    val documents = result.right.get
+                    val worker1Doc = documents
+                            .fields("rows")
+                            .convertTo[List[JsObject]]
+                            
.filter(_.fields("id").convertTo[String].equals(s"$user:$password/_/$worker11Trigger"))
+
+                    JsHelpers.getFieldPath(worker1Doc.head, "doc", "worker") 
shouldBe Some(JsString("worker11"))
+                })
             } finally {
                 //delete trigger feeds and triggers
                 makeDeleteCallWithExpectedResult(worker10Params, DONTCARE_EXIT)
@@ -117,5 +132,4 @@ class AlarmsMultiWorkersTests extends FlatSpec
         assert(expectedCode == DONTCARE_EXIT || response.statusCode() == 
expectedCode)
     }
 
-
 }


 

----------------------------------------------------------------
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:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to