diff --git a/mistral/services/triggers.py b/mistral/services/triggers.py index e371c820b..19ec8a94c 100644 --- a/mistral/services/triggers.py +++ b/mistral/services/triggers.py @@ -15,6 +15,7 @@ import croniter import datetime import six +import time from mistral.db.v2 import api as db_api from mistral.engine.rpc_backend import rpc @@ -25,14 +26,19 @@ from mistral.workbook import parser def get_next_execution_time(pattern, start_time): - return croniter.croniter(pattern, start_time).get_next(datetime.datetime) + local_time = croniter.croniter(pattern, start_time).get_next( + datetime.datetime + ) + epoch_second = time.mktime(local_time.timetuple()) + utc_time = datetime.datetime.utcfromtimestamp(epoch_second) + return utc_time # Triggers v2. def get_next_cron_triggers(): return db_api.get_next_cron_triggers( - datetime.datetime.now() + datetime.timedelta(0, 2) + datetime.datetime.utcnow() + datetime.timedelta(0, 2) ) @@ -42,7 +48,10 @@ def validate_cron_trigger_input(pattern, first_time, count): 'Pattern or first_execution_time must be specified.' ) if first_time: - if (datetime.datetime.now() + datetime.timedelta(0, 60)) > first_time: + first_second = time.mktime(first_time.timetuple()) + first_utc_time = datetime.datetime.utcfromtimestamp(first_second) + sum_time = datetime.datetime.utcnow() + datetime.timedelta(0, 60) + if sum_time > first_utc_time: raise exc.InvalidModelException( 'first_execution_time must be at least 1 minute in the future.' ) @@ -76,8 +85,12 @@ def create_cron_trigger(name, workflow_name, workflow_input, validate_cron_trigger_input(pattern, first_time, count) + first_utc_time = first_time + if first_time: - next_time = first_time + first_second = time.mktime(first_time.timetuple()) + first_utc_time = datetime.datetime.utcfromtimestamp(first_second) + next_time = first_utc_time if not (pattern or count): count = 1 @@ -98,7 +111,7 @@ def create_cron_trigger(name, workflow_name, workflow_input, values = { 'name': name, 'pattern': pattern, - 'first_execution_time': first_time, + 'first_execution_time': first_utc_time, 'next_execution_time': next_time, 'remaining_executions': count, 'workflow_name': wf_def.name, diff --git a/mistral/tests/unit/engine/test_cron_trigger.py b/mistral/tests/unit/engine/test_cron_trigger.py index 26c559b85..d65f452ac 100644 --- a/mistral/tests/unit/engine/test_cron_trigger.py +++ b/mistral/tests/unit/engine/test_cron_trigger.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import datetime +import time import mock from oslo_config import cfg @@ -145,8 +146,11 @@ class ProcessCronTriggerTest(base.EngineTestCase): None ) + first_second = time.mktime(first_time.timetuple()) + first_utc_time = datetime.datetime.utcfromtimestamp(first_second) + self.assertEqual( - first_time, + first_utc_time, cron_trigger.next_execution_time ) diff --git a/mistral/tests/unit/services/test_trigger_service.py b/mistral/tests/unit/services/test_trigger_service.py index 6aed8d23e..80ba1d40b 100644 --- a/mistral/tests/unit/services/test_trigger_service.py +++ b/mistral/tests/unit/services/test_trigger_service.py @@ -329,3 +329,9 @@ class TriggerServiceV2Test(base.DbTestCase): eventlet.sleep(1) return trigger_count == start_wf_mock.call_count + + def test_get_next_execution_time(self): + pattern = '*/20 * * * *' + start_time = datetime.datetime(2016, 3, 22, 23, 40) + result = t_s.get_next_execution_time(pattern, start_time) + self.assertEqual(result, datetime.datetime(2016, 3, 23, 0, 0))