Xixuan Wu | 303a519 | 2017-08-29 11:10:42 -0700 | [diff] [blame] | 1 | # 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.""" |
| 6 | |
| 7 | import datetime |
| 8 | import unittest |
| 9 | |
| 10 | import base_event |
| 11 | import config_reader |
| 12 | import datastore_client |
| 13 | import mock |
| 14 | import task |
Xixuan Wu | 51bb710 | 2019-03-18 14:51:44 -0700 | [diff] [blame] | 15 | import task_config_reader |
Xixuan Wu | 303a519 | 2017-08-29 11:10:42 -0700 | [diff] [blame] | 16 | import time_converter |
| 17 | |
| 18 | from google.appengine.ext import ndb |
| 19 | from google.appengine.ext import testbed |
| 20 | |
| 21 | |
| 22 | # pylint: disable=unused-argument |
| 23 | class FakeTask(object): |
| 24 | |
| 25 | def __init__(self, name, success, lc_branches='', lc_targets=''): |
| 26 | self.name = name |
| 27 | self.success = success |
| 28 | self.launch_control_branches = lc_branches.split(',') |
| 29 | self.launch_control_targets = lc_targets.split(',') |
Garry Wang | dce7757 | 2021-07-18 19:33:35 -0700 | [diff] [blame] | 30 | self.is_multi_dut_testing = False |
Xixuan Wu | 303a519 | 2017-08-29 11:10:42 -0700 | [diff] [blame] | 31 | |
Xinan Lin | 028f958 | 2019-12-11 10:55:33 -0800 | [diff] [blame] | 32 | def schedule(self, lc_builds, cros_builds, firmware_builds, |
| 33 | lab_config): |
Xixuan Wu | 303a519 | 2017-08-29 11:10:42 -0700 | [diff] [blame] | 34 | if not self.success: |
| 35 | raise task.SchedulingError('Failed to run task.') |
Xixuan Wu | 5451a66 | 2017-10-17 10:57:40 -0700 | [diff] [blame] | 36 | |
| 37 | return self.success |
Xinan Lin | 028f958 | 2019-12-11 10:55:33 -0800 | [diff] [blame] | 38 | |
| 39 | |
| 40 | class FakeBuildClient(object): |
| 41 | """Mock rest_client.BuildBucketBigqueryClient.""" |
| 42 | |
| 43 | def get_latest_passed_firmware_builds(self): |
| 44 | """Mock get_passed_firmware_builds.""" |
| 45 | return [ |
| 46 | ['cros', 'fake_board', ('gs://chromeos-image-archive/' |
| 47 | 'fake_board-release/R30-6182.0.0-rc2/' |
| 48 | 'fake_board')], |
| 49 | ['firmware', 'fake_board', ('gs://chromeos-image-archive/' |
| 50 | 'firmware-fake_board-12345.67.' |
| 51 | 'A-firmwarebranch/RFoo-1.0.0-b1e234567')], |
| 52 | ['firmware', 'foo_board', ('gs://chromeos-image-archive-foo/' |
| 53 | 'firmware-foo_board-12345.67.' |
| 54 | 'A-firmwarebranch/RFoo-1.0.0-b1e234567')], |
| 55 | ] |
| 56 | # pylint: enable=unused-argument |
Xixuan Wu | 303a519 | 2017-08-29 11:10:42 -0700 | [diff] [blame] | 57 | |
| 58 | |
| 59 | class BaseEventTestCase(unittest.TestCase): |
| 60 | |
| 61 | _KLASS = base_event.BaseEvent |
| 62 | |
| 63 | def setUp(self): |
Xixuan Wu | 51bb710 | 2019-03-18 14:51:44 -0700 | [diff] [blame] | 64 | super(BaseEventTestCase, self).setUp() |
Xixuan Wu | 303a519 | 2017-08-29 11:10:42 -0700 | [diff] [blame] | 65 | mock_utc_now = mock.patch('time_converter.utc_now') |
| 66 | self._mock_utc_now = mock_utc_now.start() |
| 67 | self.addCleanup(mock_utc_now.stop) |
| 68 | |
| 69 | self.testbed = testbed.Testbed() |
| 70 | self.testbed.activate() |
| 71 | self.addCleanup(self.testbed.deactivate) |
| 72 | self.testbed.init_datastore_v3_stub() |
| 73 | self.testbed.init_memcache_stub() |
| 74 | ndb.get_context().clear_cache() |
| 75 | |
| 76 | self.config = config_reader.ConfigReader(None) |
| 77 | |
| 78 | def testCreateEventWithAlwaysHandle(self): |
| 79 | """Create a base event with always_handle=True.""" |
| 80 | utc_now = datetime.datetime(2017, 8, 1, 4, tzinfo=time_converter.UTC_TZ) |
| 81 | event = self._KLASS( |
Xixuan Wu | 51bb710 | 2019-03-18 14:51:44 -0700 | [diff] [blame] | 82 | task_config_reader.EventSettings(True, None), utc_now, utc_now) |
Xixuan Wu | 303a519 | 2017-08-29 11:10:42 -0700 | [diff] [blame] | 83 | |
| 84 | self.assertEqual(event.target_exec_utc, utc_now) |
| 85 | self.assertEqual(event.last_exec_utc, utc_now) |
| 86 | self.assertTrue(event.always_handle) |
| 87 | self.assertTrue(event.should_handle) |
| 88 | |
| 89 | def testCreateEventWithoutAlwaysHandle(self): |
| 90 | """Create a base event with always_handle=False.""" |
| 91 | utc_now = datetime.datetime(2017, 8, 1, 4, tzinfo=time_converter.UTC_TZ) |
| 92 | event = self._KLASS( |
Xixuan Wu | 51bb710 | 2019-03-18 14:51:44 -0700 | [diff] [blame] | 93 | task_config_reader.EventSettings(False, None), utc_now, utc_now) |
Xixuan Wu | 303a519 | 2017-08-29 11:10:42 -0700 | [diff] [blame] | 94 | |
| 95 | self.assertEqual(event.target_exec_utc, utc_now) |
| 96 | self.assertEqual(event.last_exec_utc, utc_now) |
| 97 | self.assertFalse(event.always_handle) |
| 98 | self.assertFalse(event.should_handle) |
| 99 | |
| 100 | def testProcessTasks(self): |
| 101 | """Test process_tasks() for event.""" |
| 102 | utc_now = datetime.datetime(2017, 8, 1, 4, tzinfo=time_converter.UTC_TZ) |
| 103 | event = self._KLASS( |
Xixuan Wu | 51bb710 | 2019-03-18 14:51:44 -0700 | [diff] [blame] | 104 | task_config_reader.EventSettings(True, None), utc_now, utc_now) |
Xixuan Wu | 303a519 | 2017-08-29 11:10:42 -0700 | [diff] [blame] | 105 | task_list = [FakeTask('test1', True), FakeTask('test2', False)] |
| 106 | event.set_task_list(task_list) |
Garry Wang | dce7757 | 2021-07-18 19:33:35 -0700 | [diff] [blame] | 107 | finished_tasks = event.process_tasks(None, None, None, None, None) |
Xixuan Wu | 303a519 | 2017-08-29 11:10:42 -0700 | [diff] [blame] | 108 | self.assertEqual(len(finished_tasks), 1) |
| 109 | self.assertEqual(finished_tasks[0], 'test1') |
| 110 | |
| 111 | def testEventFinish(self): |
| 112 | """Test finish() for event.""" |
| 113 | utc_now = datetime.datetime(2017, 8, 1, 4, tzinfo=time_converter.UTC_TZ) |
| 114 | last_exec_utc = utc_now - datetime.timedelta(hours=1) |
| 115 | last_exec_client = datastore_client.LastExecutionRecordStore() |
| 116 | last_exec_client.set_last_execute_time(self._KLASS.KEYWORD, last_exec_utc) |
| 117 | event = self._KLASS( |
Xixuan Wu | 51bb710 | 2019-03-18 14:51:44 -0700 | [diff] [blame] | 118 | task_config_reader.EventSettings(True, None), last_exec_utc, utc_now) |
Xixuan Wu | 303a519 | 2017-08-29 11:10:42 -0700 | [diff] [blame] | 119 | |
| 120 | self.assertEqual( |
| 121 | last_exec_client.get_last_execute_time(self._KLASS.KEYWORD), |
| 122 | last_exec_utc) |
| 123 | |
| 124 | event.finish() |
| 125 | self.assertEqual( |
| 126 | last_exec_client.get_last_execute_time(self._KLASS.KEYWORD), |
| 127 | utc_now) |
| 128 | |
| 129 | def testPropertyLaunchControlBranchTargets(self): |
| 130 | """Test getter of property launch_control_branch_targets.""" |
| 131 | utc_now = datetime.datetime(2017, 8, 1, 4, tzinfo=time_converter.UTC_TZ) |
| 132 | event = self._KLASS( |
Xixuan Wu | 51bb710 | 2019-03-18 14:51:44 -0700 | [diff] [blame] | 133 | task_config_reader.EventSettings(True, None), utc_now, utc_now) |
Xixuan Wu | 303a519 | 2017-08-29 11:10:42 -0700 | [diff] [blame] | 134 | task_list = [FakeTask('test1', True, 'b1', 't1,t2'), |
| 135 | FakeTask('test2', True, 'b2', 't3,t4'), |
| 136 | FakeTask('test3', True, 'b1', 't5,t6')] |
| 137 | event.set_task_list(task_list) |
| 138 | self.assertEqual(event.launch_control_branch_targets, |
| 139 | {'b1': ['t1', 't2', 't5', 't6'], |
| 140 | 'b2': ['t3', 't4']}) |
Xixuan Wu | a5a2944 | 2017-10-11 11:03:02 -0700 | [diff] [blame] | 141 | |
| 142 | def testGAETestingForShouldHandle(self): |
| 143 | """Verify that testing on GAE staging will cause event to handle.""" |
| 144 | utc_now = datetime.datetime(2017, 8, 1, 4, tzinfo=time_converter.UTC_TZ) |
| 145 | with mock.patch('global_config.GAE_TESTING', return_value=True): |
| 146 | event = self._KLASS( |
Xixuan Wu | 51bb710 | 2019-03-18 14:51:44 -0700 | [diff] [blame] | 147 | task_config_reader.EventSettings(True, None), utc_now, utc_now) |
Xixuan Wu | a5a2944 | 2017-10-11 11:03:02 -0700 | [diff] [blame] | 148 | self.assertTrue(event.should_handle) |
Xinan Lin | 028f958 | 2019-12-11 10:55:33 -0800 | [diff] [blame] | 149 | |
| 150 | def testGetFirmwareBuilds(self): |
| 151 | """Test filter out invalid firmware build from BuildBucket.""" |
| 152 | utc_now = datetime.datetime(2017, 8, 1, 4, tzinfo=time_converter.UTC_TZ) |
| 153 | event = self._KLASS( |
| 154 | task_config_reader.EventSettings(True, None), utc_now, utc_now) |
| 155 | self.assertEqual(2, len(event.get_firmware_builds(FakeBuildClient()))) |