From 85be004102bae9cfa6aba72c347a60be8870cde1 Mon Sep 17 00:00:00 2001 From: Ji zhaoxuan Date: Mon, 5 Dec 2016 14:42:04 +0800 Subject: [PATCH] change the cron-trigger execution time from localtime to UTC When a cron-trigger is created, in the output, the created time is shown in UTC but the next execution time is in localtime. It would be better if both times are shown in the same timezone. This patch changes the next execution time to UTC. Change-Id: Icae26cef37736cb55b9a2460f16e82afdb058165 Closes-Bug: #1592164 --- mistral/services/triggers.py | 23 +++++++++++++++---- .../tests/unit/engine/test_cron_trigger.py | 6 ++++- .../unit/services/test_trigger_service.py | 6 +++++ 3 files changed, 29 insertions(+), 6 deletions(-) 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))