From a41c86a51503f75f664ebda4f5cef0903eda918a Mon Sep 17 00:00:00 2001 From: Lingxian Kong Date: Tue, 28 Aug 2018 16:33:58 +1200 Subject: [PATCH] Fix first_execution_time when used together with pattern When specifying pattern only in the API request, the returned first_execution_time should be the calculated according to the pattern. When specifying first_execution_time and pattern both in the API request, the first_execution_time will be tweaked according to the pattern. Change-Id: I0c71c2d76584c9b8335d6b379361779191e8c8d2 Story: 2003483 Task: 24750 --- .../tests/unit/api/controllers/v1/test_job.py | 27 +++++++++++++++++++ qinling/utils/jobs.py | 17 +++++++----- test-requirements.txt | 2 +- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/qinling/tests/unit/api/controllers/v1/test_job.py b/qinling/tests/unit/api/controllers/v1/test_job.py index 96e9937f..6f052bb4 100644 --- a/qinling/tests/unit/api/controllers/v1/test_job.py +++ b/qinling/tests/unit/api/controllers/v1/test_job.py @@ -15,6 +15,8 @@ from datetime import datetime from datetime import timedelta +from dateutil import parser + from qinling import context as auth_context from qinling.db import api as db_api from qinling import status @@ -99,6 +101,31 @@ class TestJobController(base.APITest): self.assertEqual(201, resp.status_int) + res = resp.json + self.assertEqual( + res["first_execution_time"], + res["next_execution_time"] + ) + + def test_post_both_pattern_and_first_execution_time(self): + body = { + 'name': self.rand_name('job', prefix=self.prefix), + 'function_id': self.function_id, + 'pattern': '0 21 * * *', + 'first_execution_time': str( + datetime.utcnow() + timedelta(hours=1)), + 'count': 10 + } + resp = self.app.post_json('/v1/jobs', body) + + self.assertEqual(201, resp.status_int) + + res = resp.json + self.assertGreaterEqual( + parser.parse(res["next_execution_time"], ignoretz=True), + parser.parse(res["first_execution_time"], ignoretz=True) + ) + def test_delete(self): job_id = self.create_job( self.function_id, diff --git a/qinling/utils/jobs.py b/qinling/utils/jobs.py index 7594bb59..727c60c5 100644 --- a/qinling/utils/jobs.py +++ b/qinling/utils/jobs.py @@ -56,26 +56,29 @@ def validate_job(params): if not (first_time or pattern): raise exc.InputException( - 'Pattern or first_execution_time must be specified.' + 'pattern or first_execution_time must be specified.' ) if first_time: first_time = validate_next_time(first_time) if not pattern and count and count > 1: raise exc.InputException( - 'Pattern must be provided if count is greater than 1.' + 'pattern must be provided if count is greater than 1.' ) next_time = first_time if not (pattern or count): count = 1 - if pattern: validate_pattern(pattern) - if not first_time: - next_time = croniter.croniter(pattern, start_time).get_next( - datetime.datetime - ) + + if first_time: + start_time = first_time - datetime.timedelta(minutes=1) + + next_time = croniter.croniter(pattern, start_time).get_next( + datetime.datetime + ) + first_time = next_time return first_time, next_time, count diff --git a/test-requirements.txt b/test-requirements.txt index 73f74455..845ebb72 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -10,5 +10,5 @@ testscenarios>=0.4 # Apache-2.0/BSD testtools>=2.2.0 # MIT tempest>=17.1.0 # Apache-2.0 futurist>=1.2.0 # Apache-2.0 - kubernetes>=6.0.0 # Apache-2.0 +python-dateutil>=2.5.3 # BSD