blob: e4ff67a56b277ae9fa85a80c4e9c18f116e9b560 [file] [log] [blame]
Xixuan Wu64361fe2017-08-28 19:15:17 -07001# Copyright 2017 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Module for timed_event unittests."""
Xixuan Wu09962902018-12-11 10:49:27 -08006# pylint: disable=g-missing-super-call
Xixuan Wu64361fe2017-08-28 19:15:17 -07007
8import datetime
9import unittest
10
11import config_reader
12import datastore_client
13import mock
Xixuan Wu51bb7102019-03-18 14:51:44 -070014import task_config_reader
Xixuan Wu64361fe2017-08-28 19:15:17 -070015import time_converter
16import timed_event
17
18from google.appengine.ext import ndb
19from google.appengine.ext import testbed
20
21
22class FakeTask(object):
23
24 def __init__(self, name, day=None, hour=None):
25 self.name = name
26 self.day = day
27 self.hour = hour
28
29
30class TimedEventTestCase(unittest.TestCase):
31
32 def setUp(self):
33 mock_utc_now = mock.patch('time_converter.utc_now')
34 self._mock_utc_now = mock_utc_now.start()
35 self.addCleanup(mock_utc_now.stop)
36
37 self.testbed = testbed.Testbed()
38 self.testbed.activate()
39 self.addCleanup(self.testbed.deactivate)
40 self.testbed.init_datastore_v3_stub()
41 self.testbed.init_memcache_stub()
42 ndb.get_context().clear_cache()
43
44 self.config = config_reader.ConfigReader(None)
45
46
47class NightlyEventTestCase(TimedEventTestCase):
48
49 _KLASS = timed_event.Nightly
Xixuan Wubb3a2302017-12-05 17:39:20 -080050 _DEFAULT_PST_HOUR = _KLASS.DEFAULT_PST_HOUR
51 _DEFAULT_UTC_HOUR = time_converter.convert_time_info(
52 time_converter.TimeInfo(None, _DEFAULT_PST_HOUR)).hour
Xixuan Wu64361fe2017-08-28 19:15:17 -070053
54 def testCreateNightlyEventWithoutLastExec(self):
55 """Create a nightly event without last_exec_utc in datastore."""
56 utc_now = datetime.datetime(2017, 8, 1, 4, 15,
57 tzinfo=time_converter.UTC_TZ)
58 expected_last_exec_utc = datetime.datetime(2017, 8, 1, 4,
59 tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -070060 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wu64361fe2017-08-28 19:15:17 -070061 self._mock_utc_now.return_value = utc_now
62 last_exec_client = datastore_client.LastExecutionRecordStore()
63 event = self._KLASS(
64 task_config.get_event_setting(self._KLASS.section_name()),
65 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
66
67 self.assertEqual(event.target_exec_utc, expected_last_exec_utc)
68 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
69 self.assertFalse(event.should_handle)
70
71 def testCreateNightlyEventWithValidLastExecShouldNotHandle(self):
72 """Create a nightly event with last_exec_utc but shouldn't be handled."""
73 utc_now = datetime.datetime(2017, 8, 1, 4, 15,
74 tzinfo=time_converter.UTC_TZ)
75 expected_last_exec_utc = datetime.datetime(2017, 8, 1, 4,
76 tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -070077 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wu64361fe2017-08-28 19:15:17 -070078 self._mock_utc_now.return_value = utc_now
79 last_exec_client = datastore_client.LastExecutionRecordStore()
80 last_exec_client.set_last_execute_time(
81 self._KLASS.KEYWORD, expected_last_exec_utc)
82 event = self._KLASS(
83 task_config.get_event_setting(self._KLASS.section_name()),
84 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
85
86 self.assertEqual(event.target_exec_utc, expected_last_exec_utc)
87 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
88 self.assertFalse(event.should_handle)
89
Xixuan Wua5a29442017-10-11 11:03:02 -070090 def testCreateCantHandleNightlyEventWithValidLastExecWithGAETesting(self):
91 """Test a can't-be-handled event can be handled in testing on GAE."""
92 utc_now = datetime.datetime(2017, 8, 1, 4, 15,
93 tzinfo=time_converter.UTC_TZ)
94 expected_last_exec_utc = datetime.datetime(2017, 8, 1, 4,
95 tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -070096 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wua5a29442017-10-11 11:03:02 -070097 self._mock_utc_now.return_value = utc_now
98 last_exec_client = datastore_client.LastExecutionRecordStore()
99 last_exec_client.set_last_execute_time(
100 self._KLASS.KEYWORD, expected_last_exec_utc)
101
102 with mock.patch('global_config.GAE_TESTING', return_value=True):
103 event = self._KLASS(
104 task_config.get_event_setting(self._KLASS.section_name()),
105 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
106 self.assertEqual(event.target_exec_utc, expected_last_exec_utc)
107 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
108 self.assertTrue(event.should_handle)
109
Xixuan Wu64361fe2017-08-28 19:15:17 -0700110 def testCreateNightlyEventWithValidLastExecShouldHandle(self):
111 """Create a nightly event with last_exec_utc and should be handled."""
112 utc_now = datetime.datetime(2017, 8, 1, 5, 15,
113 tzinfo=time_converter.UTC_TZ)
114 expected_last_exec_utc = datetime.datetime(2017, 8, 1, 4,
115 tzinfo=time_converter.UTC_TZ)
116 expected_cur_exec_utc = datetime.datetime(2017, 8, 1, 5,
117 tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -0700118 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wu64361fe2017-08-28 19:15:17 -0700119 self._mock_utc_now.return_value = utc_now
120 last_exec_client = datastore_client.LastExecutionRecordStore()
121 last_exec_client.set_last_execute_time(
122 self._KLASS.KEYWORD, expected_last_exec_utc)
123 event = self._KLASS(
124 task_config.get_event_setting(self._KLASS.section_name()),
125 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
126
127 self.assertEqual(event.target_exec_utc, expected_cur_exec_utc)
128 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
129 self.assertTrue(event.should_handle)
130
131 def testCreateNightlyEventWithOutdatedLastExec(self):
132 """Create a nightly event with outdated last_exec_utc."""
133 utc_now = datetime.datetime(2017, 8, 1, 4, 15,
134 tzinfo=time_converter.UTC_TZ)
135 expected_last_exec_utc = datetime.datetime(2017, 8, 1, 4,
136 tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -0700137 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wu64361fe2017-08-28 19:15:17 -0700138 self._mock_utc_now.return_value = utc_now
139 last_exec_client = datastore_client.LastExecutionRecordStore()
140 last_exec_client.set_last_execute_time(
141 self._KLASS.KEYWORD,
142 expected_last_exec_utc - datetime.timedelta(hours=3))
143 event = self._KLASS(
144 task_config.get_event_setting(self._KLASS.section_name()),
145 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
146
147 self.assertEqual(event.target_exec_utc, expected_last_exec_utc)
148 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
149 self.assertFalse(event.should_handle)
150
Xixuan Wua5a29442017-10-11 11:03:02 -0700151 def testCreateNightlyEventWithOutdatedLastExecWithGAETesting(self):
152 """Test an event with old last exec can be handled in testing on GAE."""
153 utc_now = datetime.datetime(2017, 8, 1, 4, 15,
154 tzinfo=time_converter.UTC_TZ)
155 expected_last_exec_utc = datetime.datetime(2017, 8, 1, 4,
156 tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -0700157 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wua5a29442017-10-11 11:03:02 -0700158 self._mock_utc_now.return_value = utc_now
159 last_exec_client = datastore_client.LastExecutionRecordStore()
160 last_exec_client.set_last_execute_time(
161 self._KLASS.KEYWORD,
162 expected_last_exec_utc - datetime.timedelta(hours=3))
163
164 with mock.patch('global_config.GAE_TESTING', return_value=True):
165 event = self._KLASS(
166 task_config.get_event_setting(self._KLASS.section_name()),
167 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
168 self.assertEqual(event.target_exec_utc, expected_last_exec_utc)
169 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
170 self.assertTrue(event.should_handle)
171
Xixuan Wu64361fe2017-08-28 19:15:17 -0700172 def testFilterTasksWithTaskHourForNightlyEvent(self):
173 """Test filter_tasks with tasks which contain settings of hour."""
Xixuan Wu008ee832017-10-12 16:59:34 -0700174 default_pst_hour = time_converter.convert_time_info(
175 time_converter.TimeInfo(None, 0),
176 source_tz=time_converter.UTC_TZ,
177 target_tz=time_converter.PST_TZ).hour
Xixuan Wu64361fe2017-08-28 19:15:17 -0700178 utc_now = datetime.datetime(2017, 8, 1, 0, 15,
179 tzinfo=time_converter.UTC_TZ)
180 self._mock_utc_now.return_value = utc_now
181 event = self._KLASS(
Xixuan Wu51bb7102019-03-18 14:51:44 -0700182 task_config_reader.EventSettings(True, None),
Xixuan Wu64361fe2017-08-28 19:15:17 -0700183 datetime.datetime(2017, 7, 31, 23, tzinfo=time_converter.UTC_TZ))
184
Xixuan Wu008ee832017-10-12 16:59:34 -0700185 # It's in PST time.
186 task_list = [FakeTask('test1', day=None, hour=default_pst_hour+1),
187 FakeTask('test2', day=None, hour=default_pst_hour),
188 FakeTask('test3', day=None, hour=0),
189 FakeTask('test4', day=None, hour=default_pst_hour)]
Xixuan Wu64361fe2017-08-28 19:15:17 -0700190 event.set_task_list(task_list)
191 self.assertEqual(len(event.task_list), len(task_list))
192 event.filter_tasks()
Xixuan Wu008ee832017-10-12 16:59:34 -0700193 # Verify only tasks that should be run at 0:00 in UTC are kept,
194 # since current time is 0:15.
Xixuan Wu64361fe2017-08-28 19:15:17 -0700195 self.assertEqual(len(event.task_list), 2)
196 self.assertEqual(sorted([t.name for t in event.task_list]),
197 ['test2', 'test4'])
198
199 def testFilterTasksWithDefaultHourForNightlyEvent(self):
200 """Test filter_tasks with tasks which don't contain settings of hour."""
Xixuan Wubb3a2302017-12-05 17:39:20 -0800201 utc_now = datetime.datetime(2017, 8, 1, self._DEFAULT_UTC_HOUR, 15,
Xixuan Wu64361fe2017-08-28 19:15:17 -0700202 tzinfo=time_converter.UTC_TZ)
203 self._mock_utc_now.return_value = utc_now
204 event = self._KLASS(
Xixuan Wu51bb7102019-03-18 14:51:44 -0700205 task_config_reader.EventSettings(True, None),
Xixuan Wu64361fe2017-08-28 19:15:17 -0700206 datetime.datetime(2017, 8, 1, 3, tzinfo=time_converter.UTC_TZ))
207
Xixuan Wu008ee832017-10-12 16:59:34 -0700208 # It's in PST time.
Xixuan Wubb3a2302017-12-05 17:39:20 -0800209 task_list = [FakeTask('test1', day=None, hour=self._DEFAULT_PST_HOUR - 1),
210 FakeTask('test2', day=None, hour=self._DEFAULT_PST_HOUR),
211 FakeTask('test3', day=None, hour=self._DEFAULT_PST_HOUR + 1),
Xixuan Wu64361fe2017-08-28 19:15:17 -0700212 FakeTask('test4', day=None, hour=None)]
213 event.set_task_list(task_list)
214 self.assertEqual(len(event.task_list), len(task_list))
215 event.filter_tasks()
Xixuan Wu008ee832017-10-12 16:59:34 -0700216 # Verify only tasks that should be run at 21:00 (the default pst hour
217 # for nightly events) are kept.
Xixuan Wu64361fe2017-08-28 19:15:17 -0700218 self.assertEqual(len(event.task_list), 2)
219 self.assertEqual(sorted([t.name for t in event.task_list]),
220 ['test2', 'test4'])
221
Xixuan Wua5a29442017-10-11 11:03:02 -0700222 def testFilterTasksWithTaskHourWithGAETesting(self):
223 """Verify all tasks are kept when testing on GAE."""
224 utc_now = datetime.datetime(2017, 8, 1, 0, 15,
225 tzinfo=time_converter.UTC_TZ)
226 self._mock_utc_now.return_value = utc_now
227
228 with mock.patch('global_config.GAE_TESTING', return_value=True):
229 event = self._KLASS(
Xixuan Wu51bb7102019-03-18 14:51:44 -0700230 task_config_reader.EventSettings(True, None),
Xixuan Wua5a29442017-10-11 11:03:02 -0700231 datetime.datetime(2017, 7, 31, 23, tzinfo=time_converter.UTC_TZ))
232
233 task_list = [FakeTask('test1', day=None, hour=3),
234 FakeTask('test2', day=None, hour=0),
235 FakeTask('test3', day=None, hour=4),
236 FakeTask('test4', day=None, hour=0)]
237 event.set_task_list(task_list)
238 self.assertEqual(len(event.task_list), len(task_list))
239 event.filter_tasks()
240 self.assertEqual(len(event.task_list), 4)
241 self.assertEqual(sorted([t.name for t in event.task_list]),
242 ['test1', 'test2', 'test3', 'test4'])
243
Xixuan Wu008ee832017-10-12 16:59:34 -0700244 def testSetTaskListForNightlyEvent(self):
245 """Verify tasks' timeinfo are correctly converted to UTC."""
246 self._mock_utc_now.return_value = datetime.datetime.now(
247 time_converter.UTC_TZ)
248 event = self._KLASS(
Xixuan Wu51bb7102019-03-18 14:51:44 -0700249 task_config_reader.EventSettings(True, None), None)
Xixuan Wu008ee832017-10-12 16:59:34 -0700250
Xixuan Wu008ee832017-10-12 16:59:34 -0700251 # It's in PST time.
Xixuan Wubb3a2302017-12-05 17:39:20 -0800252 task_list = [FakeTask('test1', day=None, hour=self._DEFAULT_PST_HOUR),
Xixuan Wu008ee832017-10-12 16:59:34 -0700253 FakeTask('test2', day=None, hour=0),
Xixuan Wubb3a2302017-12-05 17:39:20 -0800254 FakeTask('test3', day=None, hour=self._DEFAULT_PST_HOUR+1),
Xixuan Wu008ee832017-10-12 16:59:34 -0700255 FakeTask('test4', day=None, hour=None)]
256 event.set_task_list(task_list)
257 tasks_with_default_utc_hour = [
Xixuan Wubb3a2302017-12-05 17:39:20 -0800258 t.name for t in event.task_list if t.hour == self._DEFAULT_UTC_HOUR]
Xixuan Wu008ee832017-10-12 16:59:34 -0700259 self.assertEqual(sorted(tasks_with_default_utc_hour),
260 ['test1', 'test4'])
261
Xixuan Wu64361fe2017-08-28 19:15:17 -0700262
263class WeeklyEventTestCase(TimedEventTestCase):
264
265 _KLASS = timed_event.Weekly
Xixuan Wubb3a2302017-12-05 17:39:20 -0800266 _DEFAULT_PST_DAY = _KLASS.DEFAULT_PST_DAY
267 _DEFAULT_PST_HOUR = _KLASS.DEFAULT_PST_HOUR
268 _DEFAULT_UTC_TIMEINFO = time_converter.convert_time_info(
269 time_converter.TimeInfo(_DEFAULT_PST_DAY, _DEFAULT_PST_HOUR))
270 _DEFAULT_UTC_DAY = _DEFAULT_UTC_TIMEINFO.weekday
271 _DEFAULT_UTC_HOUR = _DEFAULT_UTC_TIMEINFO.hour
Xixuan Wu64361fe2017-08-28 19:15:17 -0700272
273 def testCreateWeeklyEventWithoutLastExec(self):
Xixuan Wua5a29442017-10-11 11:03:02 -0700274 """Create a weekly event without last_exec_utc in datastore."""
Xixuan Wu64361fe2017-08-28 19:15:17 -0700275 utc_now = datetime.datetime(2017, 8, 1, 4, 15,
276 tzinfo=time_converter.UTC_TZ)
Xixuan Wubb3a2302017-12-05 17:39:20 -0800277 expected_last_exec_utc = datetime.datetime(
Xixuan Wu09962902018-12-11 10:49:27 -0800278 2017, 8, 1, 4, tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -0700279 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wu64361fe2017-08-28 19:15:17 -0700280 self._mock_utc_now.return_value = utc_now
281 last_exec_client = datastore_client.LastExecutionRecordStore()
282 event = self._KLASS(
283 task_config.get_event_setting(self._KLASS.section_name()),
284 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
285
286 self.assertEqual(event.target_exec_utc, expected_last_exec_utc)
287 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
288 self.assertFalse(event.should_handle)
289
Xixuan Wua5a29442017-10-11 11:03:02 -0700290 def testCreateWeeklyEventWithoutLastExecWithGAETesting(self):
291 """Test an event without last exec can be handled in testing on GAE."""
292 utc_now = datetime.datetime(2017, 8, 1, 4, 15,
293 tzinfo=time_converter.UTC_TZ)
Xixuan Wubb3a2302017-12-05 17:39:20 -0800294 expected_last_exec_utc = datetime.datetime(
Xixuan Wu09962902018-12-11 10:49:27 -0800295 2017, 8, 1, 4, tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -0700296 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wua5a29442017-10-11 11:03:02 -0700297 self._mock_utc_now.return_value = utc_now
298 last_exec_client = datastore_client.LastExecutionRecordStore()
299
300 with mock.patch('global_config.GAE_TESTING', return_value=True):
301 event = self._KLASS(
302 task_config.get_event_setting(self._KLASS.section_name()),
303 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
304
305 self.assertEqual(event.target_exec_utc, expected_last_exec_utc)
306 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
307 self.assertTrue(event.should_handle)
308
Xixuan Wu64361fe2017-08-28 19:15:17 -0700309 def testCreateWeeklyEventWithValidLastExecShouldNotHandle(self):
310 """Create a weekly event with last_exec_utc but shouldn't be handled."""
Xixuan Wubb3a2302017-12-05 17:39:20 -0800311 utc_now = datetime.datetime(2017, 8, 1, self._DEFAULT_UTC_HOUR-1, 15,
Xixuan Wu64361fe2017-08-28 19:15:17 -0700312 tzinfo=time_converter.UTC_TZ)
Xixuan Wubb3a2302017-12-05 17:39:20 -0800313 expected_last_exec_utc = datetime.datetime(
Xixuan Wu09962902018-12-11 10:49:27 -0800314 2017, 8, 1, self._DEFAULT_UTC_HOUR-1, tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -0700315 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wu64361fe2017-08-28 19:15:17 -0700316 self._mock_utc_now.return_value = utc_now
317 last_exec_client = datastore_client.LastExecutionRecordStore()
318 last_exec_client.set_last_execute_time(
319 self._KLASS.KEYWORD, expected_last_exec_utc)
320
321 event = self._KLASS(
322 task_config.get_event_setting(self._KLASS.section_name()),
323 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
324 self.assertEqual(event.target_exec_utc, expected_last_exec_utc)
325 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
326 self.assertFalse(event.should_handle)
327
Xixuan Wua5a29442017-10-11 11:03:02 -0700328 def testCreateCantHandleWeeklyEventWithValidLastExecWithGAETesting(self):
329 """Test a can't-be-handled event can be handled in testing on GAE."""
330 utc_now = datetime.datetime(2017, 8, 1, 4, 15,
331 tzinfo=time_converter.UTC_TZ)
Xixuan Wubb3a2302017-12-05 17:39:20 -0800332 expected_last_exec_utc = datetime.datetime(
Xixuan Wu09962902018-12-11 10:49:27 -0800333 2017, 8, 1, 4, tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -0700334 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wua5a29442017-10-11 11:03:02 -0700335 self._mock_utc_now.return_value = utc_now
336 last_exec_client = datastore_client.LastExecutionRecordStore()
337 last_exec_client.set_last_execute_time(
338 self._KLASS.KEYWORD, expected_last_exec_utc)
339
340 with mock.patch('global_config.GAE_TESTING', return_value=True):
341 event = self._KLASS(
342 task_config.get_event_setting(self._KLASS.section_name()),
343 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
344 self.assertEqual(event.target_exec_utc, expected_last_exec_utc)
345 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
346 self.assertTrue(event.should_handle)
347
Xixuan Wubb3a2302017-12-05 17:39:20 -0800348 def testCreateWeeklyEventWithValidLastExecShouldHandle(self):
Xixuan Wu64361fe2017-08-28 19:15:17 -0700349 """Create a nightly event with last_exec_utc and should be handled."""
Xixuan Wubb3a2302017-12-05 17:39:20 -0800350 utc_now = datetime.datetime(2017, 8, 1, self._DEFAULT_UTC_HOUR, 15,
Xixuan Wu64361fe2017-08-28 19:15:17 -0700351 tzinfo=time_converter.UTC_TZ)
Xixuan Wubb3a2302017-12-05 17:39:20 -0800352 expected_last_exec_utc = datetime.datetime(
353 2017, 7, 31, self._DEFAULT_UTC_HOUR, tzinfo=time_converter.UTC_TZ)
354 expected_cur_exec_utc = datetime.datetime(
355 2017, 8, 1, self._DEFAULT_UTC_HOUR, tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -0700356 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wu64361fe2017-08-28 19:15:17 -0700357 self._mock_utc_now.return_value = utc_now
358 last_exec_client = datastore_client.LastExecutionRecordStore()
359 last_exec_client.set_last_execute_time(
360 self._KLASS.KEYWORD, expected_last_exec_utc)
361
362 event = self._KLASS(
363 task_config.get_event_setting(self._KLASS.section_name()),
364 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
365 self.assertEqual(event.target_exec_utc, expected_cur_exec_utc)
366 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
367 self.assertTrue(event.should_handle)
368
369 def testCreateWeeklyEventWithOutdatedLastExec(self):
370 """Create a weekly event with outdated last_exec_utc."""
371 utc_now = datetime.datetime(2017, 8, 1, 4, 15,
372 tzinfo=time_converter.UTC_TZ)
Xixuan Wubb3a2302017-12-05 17:39:20 -0800373 expected_last_exec_utc = datetime.datetime(
Xixuan Wu09962902018-12-11 10:49:27 -0800374 2017, 8, 1, 4, tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -0700375 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wu64361fe2017-08-28 19:15:17 -0700376 self._mock_utc_now.return_value = utc_now
377 last_exec_client = datastore_client.LastExecutionRecordStore()
378 last_exec_client.set_last_execute_time(
379 self._KLASS.KEYWORD,
380 expected_last_exec_utc - datetime.timedelta(days=3))
381
382 event = self._KLASS(
383 task_config.get_event_setting(self._KLASS.section_name()),
384 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
385 self.assertEqual(event.target_exec_utc, expected_last_exec_utc)
386 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
387 self.assertFalse(event.should_handle)
388
Xixuan Wua5a29442017-10-11 11:03:02 -0700389 def testCreateWeeklyEventWithOutdatedLastExecWithGAETesting(self):
390 """Test an event with old last exec can be handled in testing on GAE."""
391 utc_now = datetime.datetime(2017, 8, 1, 4, 15,
392 tzinfo=time_converter.UTC_TZ)
Xixuan Wubb3a2302017-12-05 17:39:20 -0800393 expected_last_exec_utc = datetime.datetime(
Xixuan Wu09962902018-12-11 10:49:27 -0800394 2017, 8, 1, 4, tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -0700395 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wua5a29442017-10-11 11:03:02 -0700396 self._mock_utc_now.return_value = utc_now
397 last_exec_client = datastore_client.LastExecutionRecordStore()
398 last_exec_client.set_last_execute_time(
399 self._KLASS.KEYWORD,
400 expected_last_exec_utc - datetime.timedelta(days=3))
401
402 with mock.patch('global_config.GAE_TESTING', return_value=True):
403 event = self._KLASS(
404 task_config.get_event_setting(self._KLASS.section_name()),
405 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
406 self.assertEqual(event.target_exec_utc, expected_last_exec_utc)
407 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
408 self.assertTrue(event.should_handle)
409
Xixuan Wu64361fe2017-08-28 19:15:17 -0700410 def testCreateWeeklyEventWithEventHourSettings(self):
411 """Create a weekly event with setting event hour."""
412 self.config.add_section(self._KLASS.section_name())
413 # Set weekly default kick off time to everyday 14:00 PST (21:00 UTC).
414 self.config.set(self._KLASS.section_name(), 'hour', '14')
Xixuan Wubb3a2302017-12-05 17:39:20 -0800415 expected_utc_hour = time_converter.convert_time_info(
416 time_converter.TimeInfo(self._DEFAULT_PST_DAY, 14)).hour
417 utc_now = datetime.datetime(2017, 8, 1, expected_utc_hour, 15,
Xixuan Wu64361fe2017-08-28 19:15:17 -0700418 tzinfo=time_converter.UTC_TZ)
Xixuan Wubb3a2302017-12-05 17:39:20 -0800419 expected_last_exec_utc = datetime.datetime(
420 2017, 7, 31, expected_utc_hour, tzinfo=time_converter.UTC_TZ)
421 expected_cur_exec_utc = datetime.datetime(
422 2017, 8, 1, expected_utc_hour, tzinfo=time_converter.UTC_TZ)
Xixuan Wu51bb7102019-03-18 14:51:44 -0700423 task_config = task_config_reader.TaskConfig(self.config)
Xixuan Wu64361fe2017-08-28 19:15:17 -0700424 self._mock_utc_now.return_value = utc_now
425 last_exec_client = datastore_client.LastExecutionRecordStore()
426 last_exec_client.set_last_execute_time(
427 self._KLASS.KEYWORD, expected_last_exec_utc)
428
429 event = self._KLASS(
430 task_config.get_event_setting(self._KLASS.section_name()),
431 last_exec_client.get_last_execute_time(self._KLASS.KEYWORD))
432 self.assertEqual(event.target_exec_utc, expected_cur_exec_utc)
433 self.assertEqual(event.last_exec_utc, expected_last_exec_utc)
434 self.assertTrue(event.should_handle)
435
436 def testFilterTasksWithTaskDayForWeeklyEvent(self):
437 """Test filter_tasks with tasks which contain settings of day."""
Xixuan Wubb3a2302017-12-05 17:39:20 -0800438 utc_now = datetime.datetime(2017, 8, 6, self._DEFAULT_UTC_HOUR, 15,
Xixuan Wu64361fe2017-08-28 19:15:17 -0700439 tzinfo=time_converter.UTC_TZ)
440 self._mock_utc_now.return_value = utc_now
441 event = self._KLASS(
Xixuan Wu51bb7102019-03-18 14:51:44 -0700442 task_config_reader.EventSettings(True, None),
Xixuan Wubb3a2302017-12-05 17:39:20 -0800443 datetime.datetime(2017, 8, 5, self._DEFAULT_UTC_HOUR,
444 tzinfo=time_converter.UTC_TZ))
Xixuan Wu64361fe2017-08-28 19:15:17 -0700445
Xixuan Wu008ee832017-10-12 16:59:34 -0700446 # It's in PST time.
447 task_list = [FakeTask('test1', day=5),
Xixuan Wu64361fe2017-08-28 19:15:17 -0700448 FakeTask('test2', day=0),
449 FakeTask('test3', day=3),
Xixuan Wu008ee832017-10-12 16:59:34 -0700450 FakeTask('test4', day=5)]
Xixuan Wu64361fe2017-08-28 19:15:17 -0700451 event.set_task_list(task_list)
452 self.assertEqual(len(event.task_list), len(task_list))
453 event.filter_tasks()
Xixuan Wu008ee832017-10-12 16:59:34 -0700454 # Verify only tasks that should be run at Saturday 23:00 in PST are kept,
455 # since 2017-08-06 6:00 is Sunday in UTC.
Xixuan Wu64361fe2017-08-28 19:15:17 -0700456 self.assertEqual(len(event.task_list), 2)
457 self.assertEqual(sorted([t.name for t in event.task_list]),
458 ['test1', 'test4'])
459
460 def testFilterTasksWithDefaultDayForWeeklyEvent(self):
461 """Test filter_tasks with tasks which don't contain settings of day."""
Xixuan Wubb3a2302017-12-05 17:39:20 -0800462 utc_now = datetime.datetime(2017, 8, 6, self._DEFAULT_UTC_HOUR, 15,
Xixuan Wu64361fe2017-08-28 19:15:17 -0700463 tzinfo=time_converter.UTC_TZ)
464 self._mock_utc_now.return_value = utc_now
465 event = self._KLASS(
Xixuan Wu51bb7102019-03-18 14:51:44 -0700466 task_config_reader.EventSettings(True, None),
Xixuan Wubb3a2302017-12-05 17:39:20 -0800467 datetime.datetime(2017, 8, 5, self._DEFAULT_UTC_HOUR,
468 tzinfo=time_converter.UTC_TZ))
Xixuan Wu64361fe2017-08-28 19:15:17 -0700469
Xixuan Wu008ee832017-10-12 16:59:34 -0700470 # It's in PST time.
471 task_list = [FakeTask('test1', day=5),
472 FakeTask('test2', day=6),
473 FakeTask('test3', day=4),
Xixuan Wu64361fe2017-08-28 19:15:17 -0700474 FakeTask('test4', day=None)]
475 event.set_task_list(task_list)
476 self.assertEqual(len(event.task_list), len(task_list))
477 event.filter_tasks()
Xixuan Wu008ee832017-10-12 16:59:34 -0700478 # Verify only tasks that should be run at Saturday 23:00 in PST are kept,
479 # since 2017-08-06 6:00 is Sunday in UTC.
Xixuan Wu64361fe2017-08-28 19:15:17 -0700480 # If a task's day is not set, by default it should be run at
481 # 6:00 at every Sunday in UTC (equals to 23:00 at every Saturday in PST).
482 self.assertEqual(len(event.task_list), 2)
483 self.assertEqual(sorted([t.name for t in event.task_list]),
484 ['test1', 'test4'])
Xixuan Wua5a29442017-10-11 11:03:02 -0700485
486 def testFilterTasksWithTaskDayWithGAETesting(self):
487 """Verify all tasks are kept in testing on GAE."""
Xixuan Wubb3a2302017-12-05 17:39:20 -0800488 utc_now = datetime.datetime(2017, 8, 6, self._DEFAULT_UTC_HOUR, 15,
Xixuan Wua5a29442017-10-11 11:03:02 -0700489 tzinfo=time_converter.UTC_TZ)
490 self._mock_utc_now.return_value = utc_now
491
492 with mock.patch('global_config.GAE_TESTING', return_value=True):
493 event = self._KLASS(
Xixuan Wu51bb7102019-03-18 14:51:44 -0700494 task_config_reader.EventSettings(True, None),
Xixuan Wubb3a2302017-12-05 17:39:20 -0800495 datetime.datetime(2017, 8, 5, self._DEFAULT_UTC_HOUR,
496 tzinfo=time_converter.UTC_TZ))
Xixuan Wua5a29442017-10-11 11:03:02 -0700497 task_list = [FakeTask('test1', day=6),
498 FakeTask('test2', day=0),
499 FakeTask('test3', day=3),
500 FakeTask('test4', day=6)]
501 event.set_task_list(task_list)
502 self.assertEqual(len(event.task_list), len(task_list))
503 event.filter_tasks()
504 self.assertEqual(len(event.task_list), 4)
505 self.assertEqual(sorted([t.name for t in event.task_list]),
506 ['test1', 'test2', 'test3', 'test4'])
Xixuan Wu008ee832017-10-12 16:59:34 -0700507
508 def testSetTaskListForWeeklyEventCheckWeekday(self):
509 """Verify tasks' timeinfo are correctly converted to UTC."""
510 self._mock_utc_now.return_value = datetime.datetime.now(
511 time_converter.UTC_TZ)
512 event = self._KLASS(
Xixuan Wu51bb7102019-03-18 14:51:44 -0700513 task_config_reader.EventSettings(True, None), None)
Xixuan Wu008ee832017-10-12 16:59:34 -0700514
Xixuan Wu008ee832017-10-12 16:59:34 -0700515 # It's in PST time.
Xixuan Wubb3a2302017-12-05 17:39:20 -0800516 task_list = [FakeTask('test1', day=self._DEFAULT_PST_DAY),
Xixuan Wu008ee832017-10-12 16:59:34 -0700517 FakeTask('test2', day=0),
Xixuan Wubb3a2302017-12-05 17:39:20 -0800518 FakeTask('test3', day=self._DEFAULT_PST_DAY-1),
Xixuan Wu008ee832017-10-12 16:59:34 -0700519 FakeTask('test4', day=None)]
520 event.set_task_list(task_list)
521 tasks_with_default_utc_day = [
Xixuan Wubb3a2302017-12-05 17:39:20 -0800522 t.name for t in event.task_list if t.day == self._DEFAULT_UTC_DAY]
Xixuan Wu008ee832017-10-12 16:59:34 -0700523 self.assertEqual(sorted(tasks_with_default_utc_day),
524 ['test1', 'test4'])
525
526 def testSetTaskListForWeeklyEventCheckHour(self):
527 """Verify tasks' timeinfo are correctly converted to UTC."""
528 self._mock_utc_now.return_value = datetime.datetime.now(
529 time_converter.UTC_TZ)
530 event = self._KLASS(
Xixuan Wu51bb7102019-03-18 14:51:44 -0700531 task_config_reader.EventSettings(True, None), None)
Xixuan Wu008ee832017-10-12 16:59:34 -0700532
Xixuan Wu008ee832017-10-12 16:59:34 -0700533 # It's in PST time.
Xixuan Wubb3a2302017-12-05 17:39:20 -0800534 task_list = [FakeTask('test1', day=self._DEFAULT_PST_DAY),
535 FakeTask('test2', day=self._DEFAULT_PST_DAY, hour=0),
536 FakeTask('test3', day=self._DEFAULT_PST_DAY,
537 hour=self._DEFAULT_PST_HOUR)]
Xixuan Wu008ee832017-10-12 16:59:34 -0700538 event.set_task_list(task_list)
539 tasks_with_default_utc_hour = [
Xixuan Wubb3a2302017-12-05 17:39:20 -0800540 t.name for t in event.task_list if t.hour == self._DEFAULT_UTC_HOUR]
Xixuan Wu008ee832017-10-12 16:59:34 -0700541 self.assertEqual(sorted(tasks_with_default_utc_hour),
542 ['test1', 'test3'])