blob: b0a1e4d4292aa83d80edd1635bde3bc585ce2b9b [file] [log] [blame]
Xixuan Wu835dee22017-09-07 10:47:29 -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 task_executor unittests."""
6# pylint: disable=g-bad-import-order
7
8import mock
9import os
10import sys
11import unittest
12
13import task_executor
14
15from google.appengine.api import taskqueue
16from google.appengine.ext import testbed
17
18
19class FakeSwarmingLib(object):
20
Craig Bergstrom58263d32018-04-26 14:11:35 -060021 # pylint: disable=g-deprecated-member-used
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -070022 def __init__(self, success_num=sys.maxint, error_num=0):
Xixuan Wu835dee22017-09-07 10:47:29 -070023 self.success_num = success_num
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -070024 self.error_num = error_num
Xixuan Wua17e3282018-08-21 16:11:11 -070025 self.skylab_dummy_run_count = 0
26 self.afe_dummy_run_count = 0
Xixuan Wu835dee22017-09-07 10:47:29 -070027
28 def run(self, **suite_kwargs):
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -070029 num = int(suite_kwargs.get('num', 0))
30 if num > self.success_num and num <= self.success_num + self.error_num:
Xixuan Wu835dee22017-09-07 10:47:29 -070031 raise ValueError('test')
32
Xixuan Wua17e3282018-08-21 16:11:11 -070033 def dummy_run(self, is_skylab=False):
34 if is_skylab:
35 self.skylab_dummy_run_count += 1
36 else:
37 self.afe_dummy_run_count += 1
Xixuan Wua5a29442017-10-11 11:03:02 -070038
Xixuan Wu835dee22017-09-07 10:47:29 -070039
40class TaskExecutorTestCase(unittest.TestCase):
41
42 def setUp(self):
43 self.testbed = testbed.Testbed()
44 self.testbed.activate()
45 self.addCleanup(self.testbed.deactivate)
46
47 # root_path must be set the location of queue.yaml.
48 # Otherwise, only the 'default' queue will be available.
49 self.testbed.init_taskqueue_stub(
50 root_path=os.path.join(os.path.dirname(__file__)))
51 self.taskqueue_stub = self.testbed.get_stub(
52 testbed.TASKQUEUE_SERVICE_NAME)
53
54 def testPushTask(self):
55 suite_kwargs = {'suite': 'fake_suite'}
56 task_executor.push(task_executor.SUITES_QUEUE, **suite_kwargs)
57 tasks = self.taskqueue_stub.get_filtered_tasks()
58 self.assertEqual(len(tasks), 1)
59 self.assertEqual(suite_kwargs, tasks[0].extract_params())
60
Xixuan Wua5a29442017-10-11 11:03:02 -070061 def testBatchExecuteTaskWithGAETesting(self):
62 """Test task_executor execute tasks in batch in testing on GAE."""
63 suite_kwargs = {'suite': 'fake_suite'}
64 for i in range(task_executor.BATCH_SIZE):
65 suite_kwargs['num'] = i + 1
66 task_executor.push(task_executor.SUITES_QUEUE, **suite_kwargs)
67
68 with mock.patch('swarming_lib.SwarmingRunner',
69 return_value=FakeSwarmingLib()):
70 with mock.patch('global_config.GAE_TESTING', return_value=True):
Craig Bergstrom3212fb42018-04-17 19:24:15 -060071 task_processor = task_executor.TaskProcessor(task_executor.SUITES_QUEUE,
Xixuan Wu5d700dc2018-08-21 15:13:10 -070072 'invalidhostname',
73 'skylab_swarming_server')
Xixuan Wua5a29442017-10-11 11:03:02 -070074 task_processor.batch_execute()
75 self.assertEqual(task_executor.BATCH_SIZE,
Xixuan Wua17e3282018-08-21 16:11:11 -070076 task_processor.swarming.afe_dummy_run_count)
77 self.assertEqual(task_executor.BATCH_SIZE,
78 task_processor.swarming.skylab_dummy_run_count)
Xixuan Wua5a29442017-10-11 11:03:02 -070079
Xixuan Wu835dee22017-09-07 10:47:29 -070080 def testBatchExecuteTaskSuccessfully(self):
81 """Test task_executor successfully execute tasks in batch."""
82 suite_kwargs = {'suite': 'fake_suite'}
83 extra_num = 10
84 for i in range(task_executor.BATCH_SIZE + extra_num):
85 suite_kwargs['num'] = i + 1
86 task_executor.push(task_executor.SUITES_QUEUE, **suite_kwargs)
87
88 # Before batch_execute
89 tasks = self.taskqueue_stub.get_filtered_tasks()
90 self.assertEqual(len(tasks), task_executor.BATCH_SIZE + extra_num)
91 with mock.patch('swarming_lib.SwarmingRunner',
92 return_value=FakeSwarmingLib()):
Craig Bergstrom3212fb42018-04-17 19:24:15 -060093 task_processor = task_executor.TaskProcessor(task_executor.SUITES_QUEUE,
Xixuan Wu5d700dc2018-08-21 15:13:10 -070094 'invalidhostname',
95 'skylab_swarming_server')
Xixuan Wu835dee22017-09-07 10:47:29 -070096 task_processor.batch_execute()
97 # After batch_execute succeeds, only extra_num tasks left.
98 tasks = self.taskqueue_stub.get_filtered_tasks()
99 self.assertEqual(len(tasks), extra_num)
100
101 def testBatchExecuteTaskFailedSwarmingTotally(self):
102 """Test task_executor fails at the beginning, and no tasks are deleted."""
103 suite_kwargs = {'suite': 'fake_suite'}
104 extra_num = 10
105 for i in range(task_executor.BATCH_SIZE + extra_num):
106 suite_kwargs['num'] = i + 1
107 task_executor.push(task_executor.SUITES_QUEUE, **suite_kwargs)
108
109 # Before batch_execute
110 tasks = self.taskqueue_stub.get_filtered_tasks()
111 self.assertEqual(len(tasks), task_executor.BATCH_SIZE + extra_num)
112 with mock.patch('swarming_lib.SwarmingRunner',
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -0700113 return_value=FakeSwarmingLib(0, error_num=len(tasks))):
Craig Bergstrom3212fb42018-04-17 19:24:15 -0600114 task_processor = task_executor.TaskProcessor(task_executor.SUITES_QUEUE,
Xixuan Wu5d700dc2018-08-21 15:13:10 -0700115 'invalidhostname',
116 'skylab_swarming_server')
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -0700117 task_processor.batch_execute()
118 # After batch_execute, no tasks are deleted from task queue, due
119 # to they're all failed to kick off.
Xixuan Wu835dee22017-09-07 10:47:29 -0700120 tasks = self.taskqueue_stub.get_filtered_tasks()
121 self.assertEqual(len(tasks), task_executor.BATCH_SIZE + extra_num)
122
123 def testBatchExecuteTaskFailedSwarmingPartially(self):
124 """Test task_executor fails halfway, and only executed tasks are deleted."""
125 suite_kwargs = {'suite': 'fake_suite'}
126 extra_num = 10
127 success_num = 50
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -0700128 error_num = 5
Xixuan Wu835dee22017-09-07 10:47:29 -0700129 for i in range(task_executor.BATCH_SIZE + extra_num):
130 suite_kwargs['num'] = i + 1
131 task_executor.push(task_executor.SUITES_QUEUE, **suite_kwargs)
132
133 # Before batch_execute
134 tasks = self.taskqueue_stub.get_filtered_tasks()
135 self.assertEqual(len(tasks), task_executor.BATCH_SIZE + extra_num)
136 with mock.patch('swarming_lib.SwarmingRunner',
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -0700137 return_value=FakeSwarmingLib(success_num, error_num)):
Craig Bergstrom3212fb42018-04-17 19:24:15 -0600138 task_processor = task_executor.TaskProcessor(task_executor.SUITES_QUEUE,
Xixuan Wu5d700dc2018-08-21 15:13:10 -0700139 'invalidhostname',
140 'skylab_swarming_server')
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -0700141 task_processor.batch_execute()
142 # After batch_execute, only failed suites and extra suites are
143 # kept in task queue.
Xixuan Wu835dee22017-09-07 10:47:29 -0700144 tasks = self.taskqueue_stub.get_filtered_tasks()
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -0700145 self.assertEqual(len(tasks), error_num + extra_num)
Xixuan Wu835dee22017-09-07 10:47:29 -0700146
147 def testBatchExecuteTaskFailedLeasing(self):
148 """Test task_executor fails to lease task."""
149 suite_kwargs = {'suite': 'fake_suite'}
150 task_executor.push(task_executor.SUITES_QUEUE, **suite_kwargs)
151
152 with mock.patch('swarming_lib.SwarmingRunner',
153 return_value=FakeSwarmingLib(False)):
Craig Bergstrom3212fb42018-04-17 19:24:15 -0600154 task_processor = task_executor.TaskProcessor('nonExistentQueue',
Xixuan Wu5d700dc2018-08-21 15:13:10 -0700155 'invalidhostname',
156 'skylab_swarming_server')
Xixuan Wu835dee22017-09-07 10:47:29 -0700157 self.assertRaises(taskqueue.UnknownQueueError,
158 task_processor.batch_execute)
159 # After batch_execute fails, no tasks are deleted from task queue.
160 tasks = self.taskqueue_stub.get_filtered_tasks()
161 self.assertEqual(len(tasks), 1)
162
163
164if __name__ == '__main__':
165 unittest.main()