You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by cs...@apache.org on 2017/11/17 19:24:27 UTC
[incubator-openwhisk-package-alarms] branch master updated: add
startDate and stopDate support for the alarms feed (#109)
This is an automated email from the ASF dual-hosted git repository.
csantanapr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-package-alarms.git
The following commit(s) were added to refs/heads/master by this push:
new d31c475 add startDate and stopDate support for the alarms feed (#109)
d31c475 is described below
commit d31c47582262ad3125a28d5905715a57c9a88fe5
Author: Jason Peterson <ja...@us.ibm.com>
AuthorDate: Fri Nov 17 14:24:25 2017 -0500
add startDate and stopDate support for the alarms feed (#109)
* add startDate and stopDate support for the alarms feed
* documentation for startDate, stopDate and date parameters
* remove unnecessary alarms once zip
* fix no eol travis error
---
README.md | 49 +++++++++++---
action/alarm.js | 2 +-
action/alarmOnce.js | 31 ---------
action/alarmOnce_package.json | 5 --
action/alarmWebAction.js | 76 +++++++++++++++++-----
installCatalog.sh | 20 ++----
package.json | 3 +-
provider/app.js | 1 -
provider/lib/cronAlarm.js | 44 +++++++++++--
provider/lib/dateAlarm.js | 2 +-
provider/lib/utils.js | 18 +++--
.../system/health/AlarmsHealthFeedTests.scala | 48 +++++++++++++-
.../scala/system/packages/AlarmsFeedTests.scala | 66 +++++++++++++++++++
13 files changed, 269 insertions(+), 96 deletions(-)
diff --git a/README.md b/README.md
index 66d3dee..33f383c 100644
--- a/README.md
+++ b/README.md
@@ -5,12 +5,13 @@
The `/whisk.system/alarms` package can be used to fire a trigger at a specified frequency. This is useful for setting up recurring jobs or tasks, such as invoking a system backup action every hour.
-The package includes the following feed.
+The package includes the following feeds.
| Entity | Type | Parameters | Description |
| --- | --- | --- | --- |
| `/whisk.system/alarms` | package | - | Alarms and periodic utility |
-| `/whisk.system/alarms/alarm` | feed | cron, trigger_payload, maxTriggers | Fire trigger event periodically |
+| `/whisk.system/alarms/alarm` | feed | cron, trigger_payload, maxTriggers, startDate, stopDate | Fire trigger event periodically |
+| `/whisk.system/alarms/once` | feed | date, trigger_payload | Fire trigger event once on a specific date |
## Firing a trigger event periodically
@@ -24,24 +25,54 @@ For more details about using cron syntax, see: http://crontab.org. Following are
- `0 * * * *`: top of every hour.
- `0 */2 * * *`: every 2 hours (i.e. 02:00:00, 04:00:00, ...)
- `0 9 8 * *`: at 9:00:00AM (UTC) on the eighth day of every month
+
+ **Note**: The parameter `cron` also supports a custom syntax of six fields, where the first field represents seconds.
+ For more details about using this custom cron syntax, see: https://github.com/ncb000gt/node-cron.
+ Here is an example using six fields notation:
+ - `*/30 * * * * *`: every thirty seconds.
- `trigger_payload`: The value of this parameter becomes the content of the trigger every time the trigger is fired.
-- `maxTriggers`: Stop firing triggers when this limit is reached. Defaults to 1,000,000. You can set it to infinite (-1).
+- `maxTriggers`: Stop firing triggers when this limit is reached. Defaults to infinite (-1).
-The following is an example of creating a trigger that will be fired once every 2 minutes with `name` and `place` values in the trigger event.
+- `startDate`: The date when the trigger will start running. The trigger will fire based on the schedule specified by the `cron` parameter.
+
+- `stopDate`: The date when the trigger will stop running. Triggers will no longer be fired once this date has been reached.
+
+ **Note**: The `startDate` and `stopDate` parameters support an integer or string value. The integer value represents the number of milliseconds
+ since 1 January 1970 00:00:00 UTC and the string value should be in the ISO 8601 format (http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15).
+
+
+The following is an example of creating a trigger that will be fired once every 2 minutes with `name` and `place` values in the trigger event. The trigger will not start firing until
+January 1, 2019, 00:00:00 UTC and will stop firing January 31, 2019, 23:59:00 UTC.
```
wsk trigger create periodic \
--feed /whisk.system/alarms/alarm \
--param cron "*/2 * * * *" \
- --param trigger_payload "{\"name\":\"Odin\",\"place\":\"Asgard\"}"
+ --param trigger_payload "{\"name\":\"Odin\",\"place\":\"Asgard\"}" \
+ --param startDate "2019-01-01T00:00:00.000Z" \
+ --param stopDate "2019-01-31T23:59:00.000Z"
```
Each generated event will include as parameters the properties specified in the `trigger_payload` value. In this case, each trigger event will have parameters `name=Odin` and `place=Asgard`.
-**Note**: The parameter `cron` also supports a custom syntax of six fields, where the first field represents seconds.
-For more details about using this custom cron syntax, see: https://github.com/ncb000gt/node-cron.
-Here is an example using six fields notation:
- - `*/30 * * * * *`: every thirty seconds.
+## Firing a trigger event once
+
+The `/whisk.system/alarms/once` feed configures the Alarm service to fire a trigger event on a specified date. The parameters are as follows:
+- `date`: The date when the trigger will be fired. The trigger will be fired just once at the given time.
+
+ **Note**: The `date` parameter supports an integer or string value. The integer value represents the number of milliseconds
+ since 1 January 1970 00:00:00 UTC and the string value should be in the ISO 8601 format (http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15).
+
+- `trigger_payload`: The value of this parameter becomes the content of the trigger when the trigger is fired.
+
+The following is an example of creating a trigger that will be fired once on December 25, 2017, 12:30:00 UTC.
+
+ ```
+ wsk trigger create fireOnce \
+ --feed /whisk.system/alarms/once \
+ --param trigger_payload "{\"name\":\"Odin\",\"place\":\"Asgard\"}" \
+ --param date "2017-12-25T12:30:00.000Z"
+ ```
diff --git a/action/alarm.js b/action/alarm.js
index 6e72985..ef624b3 100644
--- a/action/alarm.js
+++ b/action/alarm.js
@@ -3,7 +3,7 @@ const common = require('./lib/common');
function main(msg) {
let eventMap = {
- CREATE: 'put',
+ CREATE: 'post',
READ: 'get',
// UPDATE: 'put',
DELETE: 'delete'
diff --git a/action/alarmOnce.js b/action/alarmOnce.js
deleted file mode 100644
index 38a7ebc..0000000
--- a/action/alarmOnce.js
+++ /dev/null
@@ -1,31 +0,0 @@
-const common = require('./lib/common');
-
-function main(msg) {
-
- let eventMap = {
- CREATE: 'put',
- READ: 'get',
- // UPDATE: 'put',
- DELETE: 'delete'
- };
- // for creation -> CREATE
- // for reading -> READ
- // for deletion -> DELETE
- var lifecycleEvent = msg.lifecycleEvent;
-
- var endpoint = msg.apihost;
- var webparams = common.createWebParams(msg);
- webparams.fireOnce = true;
-
- var url = `https://${endpoint}/api/v1/web/whisk.system/alarmsWeb/alarmWebAction.http`;
-
- if (lifecycleEvent in eventMap) {
- var method = eventMap[lifecycleEvent];
- return common.requestHelper(url, webparams, method);
- } else {
- return Promise.reject('unsupported lifecycleEvent');
- }
-}
-
-
-exports.main = main;
diff --git a/action/alarmOnce_package.json b/action/alarmOnce_package.json
deleted file mode 100644
index e48cd14..0000000
--- a/action/alarmOnce_package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "alarmOnce",
- "version": "1.0.0",
- "main": "alarmOnce.js"
-}
diff --git a/action/alarmWebAction.js b/action/alarmWebAction.js
index 4ba3a73..9f8789c 100644
--- a/action/alarmWebAction.js
+++ b/action/alarmWebAction.js
@@ -20,7 +20,7 @@ function main(params) {
var workers = params.workers instanceof Array ? params.workers : [];
var db;
- if (params.__ow_method === "put") {
+ if (params.__ow_method === "post") {
if (typeof params.trigger_payload === 'string') {
params.trigger_payload = {payload: params.trigger_payload};
@@ -42,30 +42,49 @@ function main(params) {
if (!params.date) {
return common.sendError(400, 'alarms once trigger feed is missing the date parameter');
}
- else {
- var date = new Date(params.date);
- if (isNaN(date.getTime())) {
- return common.sendError(400, `date parameter '${params.date}' is not a valid Date`);
- }
- else if (Date.now() >= date.getTime()) {
- return common.sendError(400, `date parameter '${params.date}' must be in the future`);
- }
- else {
- newTrigger.date = params.date;
- }
+ var date = validateDate(params.date, 'date');
+ if (date !== params.date) {
+ return common.sendError(400, date);
}
+ newTrigger.date = date;
}
else {
if (!params.cron) {
return common.sendError(400, 'alarms trigger feed is missing the cron parameter');
}
- else {
- try {
- new CronJob(params.cron, function() {});
- newTrigger.cron = params.cron;
- } catch(ex) {
- return common.sendError(400, `cron pattern '${params.cron}' is not valid`);
+
+ var cronHandle;
+ try {
+ cronHandle = new CronJob(params.cron, function() {});
+ newTrigger.cron = params.cron;
+ } catch(ex) {
+ return common.sendError(400, `cron pattern '${params.cron}' is not valid`);
+ }
+
+ if (params.startDate) {
+ var startDate = validateDate(params.startDate, 'startDate');
+ if (startDate !== params.startDate) {
+ return common.sendError(400, startDate);
+ }
+ newTrigger.startDate = startDate;
+ }
+
+ if (params.stopDate) {
+ if (params.maxTriggers) {
+ return common.sendError(400, 'maxTriggers is not allowed when the stopDate parameter is specified');
+ }
+
+ var stopDate = validateDate(params.stopDate, 'stopDate', params.startDate);
+ if (stopDate !== params.stopDate) {
+ return common.sendError(400, stopDate);
}
+ //verify that the next scheduled trigger fire will occur before the stop date
+ var triggerDate = cronHandle.nextDate();
+ if (triggerDate.isAfter(new Date(params.stopDate))) {
+ return common.sendError(400, 'the next scheduled trigger fire is not until after the stop date');
+ }
+
+ newTrigger.stopDate = stopDate;
}
}
@@ -119,6 +138,8 @@ function main(params) {
}
else {
body.config.cron = doc.cron;
+ body.config.startDate = doc.startDate;
+ body.config.stopDate = doc.stopDate;
}
resolve({
statusCode: 200,
@@ -159,6 +180,25 @@ function main(params) {
}
}
+function validateDate(date, paramName, startDate) {
+
+ var dateObject = new Date(date);
+
+ if (isNaN(dateObject.getTime())) {
+ return `${paramName} parameter '${date}' is not a valid Date`;
+ }
+ else if (Date.now() >= dateObject.getTime()) {
+ return `${paramName} parameter '${date}' must be in the future`;
+ }
+ else if (startDate && dateObject <= new Date(startDate).getTime()) {
+ return `${paramName} parameter '${date}' must be greater than the startDate parameter ${startDate}`;
+ }
+ else {
+ return date;
+ }
+
+}
+
exports.main = main;
diff --git a/installCatalog.sh b/installCatalog.sh
index 63fde64..3b34e49 100755
--- a/installCatalog.sh
+++ b/installCatalog.sh
@@ -50,9 +50,8 @@ echo Installing Alarms package.
$WSK_CLI -i --apihost "$EDGEHOST" package update --auth "$AUTH" --shared yes alarms \
-a description 'Alarms and periodic utility' \
- -a parameters '[ {"name":"cron", "required":true}, {"name":"trigger_payload", "required":false} ]' \
+ -a parameters '[ {"name":"trigger_payload", "required":false} ]' \
-p apihost "$APIHOST" \
- -p cron '' \
-p trigger_payload ''
# make alarmFeed.zip
@@ -68,21 +67,14 @@ zip -r alarmFeed.zip lib package.json alarm.js
$WSK_CLI -i --apihost "$EDGEHOST" action update --kind nodejs:6 --auth "$AUTH" alarms/alarm "$PACKAGE_HOME/action/alarmFeed.zip" \
-a description 'Fire trigger when alarm occurs' \
+ -a parameters '[ {"name":"cron", "required":true}, {"name":"startDate", "required":false}, {"name":"stopDate", "required":false} ]' \
-a feed true
-
-# make alarmOnce.zip
-if [ -e alarmOnce.zip ]
-then
- rm -rf alarmOnce.zip
-fi
-
-cp -f alarmOnce_package.json package.json
-zip -r alarmOnce.zip lib package.json alarmOnce.js
-
-$WSK_CLI -i --apihost "$EDGEHOST" action update --kind nodejs:6 --auth "$AUTH" alarms/once "$PACKAGE_HOME/action/alarmOnce.zip" \
+$WSK_CLI -i --apihost "$EDGEHOST" action update --kind nodejs:6 --auth "$AUTH" alarms/once "$PACKAGE_HOME/action/alarmFeed.zip" \
-a description 'Fire trigger once when alarm occurs' \
- -a feed true
+ -a parameters '[ {"name":"date", "required":true} ]' \
+ -a feed true \
+ -p fireOnce true
if [ -n "$WORKERS" ];
then
diff --git a/package.json b/package.json
index 6331109..7b89d74 100755
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"request-promise": "^1.0.2",
"redis":"^2.7.1",
"bluebird": "^3.5.0",
- "systeminformation": "^3.19.0"
+ "systeminformation": "^3.19.0",
+ "long-timeout": "^0.1.1"
}
}
\ No newline at end of file
diff --git a/provider/app.js b/provider/app.js
index 3d90fd3..9ba5f98 100755
--- a/provider/app.js
+++ b/provider/app.js
@@ -5,7 +5,6 @@
*/
var http = require('http');
var express = require('express');
-var request = require('request');
var bodyParser = require('body-parser');
var bluebird = require('bluebird');
var logger = require('./Logger');
diff --git a/provider/lib/cronAlarm.js b/provider/lib/cronAlarm.js
index efc68c9..98b691b 100644
--- a/provider/lib/cronAlarm.js
+++ b/provider/lib/cronAlarm.js
@@ -1,4 +1,5 @@
var CronJob = require('cron').CronJob;
+var lt = require('long-timeout');
var constants = require('./constants.js');
module.exports = function(logger, newTrigger) {
@@ -9,9 +10,7 @@ module.exports = function(logger, newTrigger) {
apikey: newTrigger.apikey,
name: newTrigger.name,
namespace: newTrigger.namespace,
- cron: newTrigger.cron,
- triggersLeft: maxTriggers,
- maxTriggers: maxTriggers
+ cron: newTrigger.cron
};
this.scheduleAlarm = function(triggerIdentifier, callback) {
@@ -21,11 +20,42 @@ module.exports = function(logger, newTrigger) {
return new Promise(function(resolve, reject) {
var cronHandle = new CronJob(newTrigger.cron, callback);
- logger.info(method, triggerIdentifier, 'starting cron job');
- cronHandle.start();
- cachedTrigger.cronHandle = cronHandle;
- resolve(cachedTrigger);
+ if (newTrigger.stopDate) {
+ cachedTrigger.stopDate = newTrigger.stopDate;
+ //do not create trigger if the stopDate is in the past
+ //or if it will never fire before the stopDate occurs
+ if (new Date(newTrigger.stopDate).getTime() <= Date.now()) {
+ return reject('the stop date has expired');
+ }
+ else if (cronHandle.nextDate().isAfter(new Date(newTrigger.stopDate))) {
+ return reject('the next scheduled trigger fire is after the stop date');
+ }
+ }
+ else {
+ cachedTrigger.triggersLeft = maxTriggers;
+ cachedTrigger.maxTriggers = maxTriggers;
+ }
+
+ if (newTrigger.startDate && new Date(newTrigger.startDate).getTime() > Date.now()) {
+ var startDate = new Date(newTrigger.startDate).getTime();
+ logger.info(method, triggerIdentifier, 'waiting for start date', startDate);
+ lt.setTimeout(function() {
+ logger.info(method, triggerIdentifier, 'starting cron job upon reaching start date', startDate);
+ cronHandle.start();
+
+ cachedTrigger.cronHandle = cronHandle;
+ resolve(cachedTrigger);
+ }, startDate - Date.now());
+ }
+ else {
+ logger.info(method, triggerIdentifier, 'starting cron job');
+ cronHandle.start();
+
+ cachedTrigger.cronHandle = cronHandle;
+ resolve(cachedTrigger);
+ }
+
});
} catch (err) {
return Promise.reject(err);
diff --git a/provider/lib/dateAlarm.js b/provider/lib/dateAlarm.js
index 656ac40..04d2ec0 100644
--- a/provider/lib/dateAlarm.js
+++ b/provider/lib/dateAlarm.js
@@ -26,7 +26,7 @@ module.exports = function(logger, newTrigger) {
resolve(cachedTrigger);
}
else {
- return reject("the fire once date has expired");
+ return reject('the fire once date has expired');
}
});
} catch (err) {
diff --git a/provider/lib/utils.js b/provider/lib/utils.js
index f5ee08f..8c7040b 100644
--- a/provider/lib/utils.js
+++ b/provider/lib/utils.js
@@ -1,4 +1,3 @@
-var _ = require('lodash');
var request = require('request');
var HttpStatus = require('http-status-codes');
var constants = require('./constants.js');
@@ -152,6 +151,13 @@ module.exports = function(
utils.disableTrigger(triggerIdentifier, undefined, 'Automatically disabled after firing once');
logger.info(method, 'the fire once date has expired, disabled', triggerIdentifier);
}
+ else if (dataTrigger.stopDate) {
+ //check if the next scheduled trigger is after the stop date
+ if (dataTrigger.cronHandle && dataTrigger.cronHandle.nextDate().isAfter(new Date(dataTrigger.stopDate))) {
+ utils.disableTrigger(triggerIdentifier, undefined, 'Automatically disabled after firing last scheduled trigger');
+ logger.info(method, 'last scheduled trigger before stop date, disabled', triggerIdentifier);
+ }
+ }
else if (dataTrigger.maxTriggers && dataTrigger.triggersLeft === 0) {
utils.disableTrigger(triggerIdentifier, undefined, 'Automatically disabled after reaching max triggers');
logger.warn(method, 'no more triggers left, disabled', triggerIdentifier);
@@ -240,7 +246,7 @@ module.exports = function(
}, function (error, response) {
//disable trigger in database if trigger is dead
if (!error && utils.shouldDisableTrigger(response.statusCode)) {
- var message = 'Automatically disabled after receiving a ' + response.statusCode + ' status code on init trigger';
+ var message = 'Automatically disabled after receiving a ' + response.statusCode + ' status code on trigger initialization';
utils.disableTrigger(triggerIdentifier, response.statusCode, message);
logger.error(method, 'trigger', triggerIdentifier, 'has been disabled due to status code:', response.statusCode);
}
@@ -251,9 +257,9 @@ module.exports = function(
logger.info(method, triggerIdentifier, 'created successfully');
})
.catch(err => {
- var message = 'Automatically disabled after receiving exception on init trigger: ' + err;
+ var message = 'Automatically disabled after receiving error on trigger initialization: ' + err;
utils.disableTrigger(triggerIdentifier, undefined, message);
- logger.error(method, 'Disabled trigger', triggerIdentifier, 'due to exception:', err);
+ logger.error(method, 'Disabled trigger', triggerIdentifier, err);
});
}
});
@@ -296,9 +302,9 @@ module.exports = function(
logger.info(method, triggerIdentifier, 'created successfully');
})
.catch(err => {
- var message = 'Automatically disabled after receiving exception on create trigger: ' + err;
+ var message = 'Automatically disabled after receiving error on trigger creation: ' + err;
utils.disableTrigger(triggerIdentifier, undefined, message);
- logger.error(method, 'Disabled trigger', triggerIdentifier, 'due to exception:', err);
+ logger.error(method, 'Disabled trigger', triggerIdentifier, err);
});
}
}
diff --git a/tests/src/test/scala/system/health/AlarmsHealthFeedTests.scala b/tests/src/test/scala/system/health/AlarmsHealthFeedTests.scala
index fe70822..fb7c6d8 100644
--- a/tests/src/test/scala/system/health/AlarmsHealthFeedTests.scala
+++ b/tests/src/test/scala/system/health/AlarmsHealthFeedTests.scala
@@ -106,7 +106,7 @@ class AlarmsHealthFeedTests
(pkg, name) => pkg.bind("/whisk.system/alarms", name)
}
- val futureDate = System.currentTimeMillis + (1000 * 30)
+ val futureDate = System.currentTimeMillis + (1000 * 20)
// create whisk stuff
println(s"Creating trigger: $triggerName")
@@ -119,7 +119,7 @@ class AlarmsHealthFeedTests
feedCreationResult.stdout should include("ok")
println("waiting for trigger")
- val activations = wsk.activation.pollFor(N = 1, Some(triggerName), retries = 60).length
+ val activations = wsk.activation.pollFor(N = 1, Some(triggerName), retries = 30).length
println(s"Found activation size (should be 1): $activations")
activations should be(1)
}
@@ -186,4 +186,48 @@ class AlarmsHealthFeedTests
}
}
+
+ it should "fire cron trigger using startDate and stopDate" in withAssetCleaner(wskprops) {
+ (wp, assetHelper) =>
+ implicit val wskprops = wp // shadow global props and make implicit
+ 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 startDate = System.currentTimeMillis + (1000 * 20)
+ val stopDate = startDate + (1000 * 10)
+
+ println(s"Creating trigger: $triggerName")
+ // create whisk stuff
+ val feedCreationResult = assetHelper.withCleaner(wsk.trigger, triggerName) {
+ (trigger, name) =>
+ trigger.create(name, feed = Some(s"$packageName/alarm"), parameters = Map(
+ "cron" -> "* * * * * *".toJson,
+ "startDate" -> startDate.toJson,
+ "stopDate" -> stopDate.toJson))
+ }
+ feedCreationResult.stdout should include("ok")
+
+ println("waiting for triggers")
+ val activations = wsk.activation.pollFor(N = 20, Some(triggerName), retries = 45).length
+ println(s"Found activation size (should be at least 5): $activations")
+ activations should be >= 5
+
+
+ // get activation list again, should be same as before sleeping
+ println("confirming no new triggers")
+ val activationsAfterWait = wsk.activation.pollFor(N = activations + 1, Some(triggerName)).length
+ println(s"Found activation size after wait: $activationsAfterWait")
+ println("Activation list after wait should equal with activation list after stopDate")
+ activationsAfterWait should be(activations)
+ }
}
diff --git a/tests/src/test/scala/system/packages/AlarmsFeedTests.scala b/tests/src/test/scala/system/packages/AlarmsFeedTests.scala
index 45ec618..2ad09c7 100644
--- a/tests/src/test/scala/system/packages/AlarmsFeedTests.scala
+++ b/tests/src/test/scala/system/packages/AlarmsFeedTests.scala
@@ -224,4 +224,70 @@ class AlarmsFeedTests
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"dummyCloudantTrigger-${System.currentTimeMillis}"
+ val packageName = "dummyCloudantPackage"
+ 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 whisk stuff
+ 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"dummyCloudantTrigger-${System.currentTimeMillis}"
+ val packageName = "dummyCloudantPackage"
+ 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 + 5000
+ val startDate = stopDate
+
+ // create whisk stuff
+ 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")
+
+ }
}
--
To stop receiving notification emails like this one, please contact
['"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>'].