blob: c40b5cc2a9dcd9c88fc879cfc134b00cca2d0af4 [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 Wua5a29442017-10-11 11:03:02 -070025 self.dummy_run_count = 0
Xixuan Wu835dee22017-09-07 10:47:29 -070026
27 def run(self, **suite_kwargs):
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -070028 num = int(suite_kwargs.get('num', 0))
29 if num > self.success_num and num <= self.success_num + self.error_num:
Xixuan Wu835dee22017-09-07 10:47:29 -070030 raise ValueError('test')
31
Xixuan Wua5a29442017-10-11 11:03:02 -070032 def dummy_run(self):
33 self.dummy_run_count += 1
34
Xixuan Wu835dee22017-09-07 10:47:29 -070035
36class TaskExecutorTestCase(unittest.TestCase):
37
38 def setUp(self):
39 self.testbed = testbed.Testbed()
40 self.testbed.activate()
41 self.addCleanup(self.testbed.deactivate)
42
43 # root_path must be set the location of queue.yaml.
44 # Otherwise, only the 'default' queue will be available.
45 self.testbed.init_taskqueue_stub(
46 root_path=os.path.join(os.path.dirname(__file__)))
47 self.taskqueue_stub = self.testbed.get_stub(
48 testbed.TASKQUEUE_SERVICE_NAME)
49
50 def testPushTask(self):
51 suite_kwargs = {'suite': 'fake_suite'}
52 task_executor.push(task_executor.SUITES_QUEUE, **suite_kwargs)
53 tasks = self.taskqueue_stub.get_filtered_tasks()
54 self.assertEqual(len(tasks), 1)
55 self.assertEqual(suite_kwargs, tasks[0].extract_params())
56
Xixuan Wua5a29442017-10-11 11:03:02 -070057 def testBatchExecuteTaskWithGAETesting(self):
58 """Test task_executor execute tasks in batch in testing on GAE."""
59 suite_kwargs = {'suite': 'fake_suite'}
60 for i in range(task_executor.BATCH_SIZE):
61 suite_kwargs['num'] = i + 1
62 task_executor.push(task_executor.SUITES_QUEUE, **suite_kwargs)
63
64 with mock.patch('swarming_lib.SwarmingRunner',
65 return_value=FakeSwarmingLib()):
66 with mock.patch('global_config.GAE_TESTING', return_value=True):
Craig Bergstrom3212fb42018-04-17 19:24:15 -060067 task_processor = task_executor.TaskProcessor(task_executor.SUITES_QUEUE,
Xixuan Wu5d700dc2018-08-21 15:13:10 -070068 'invalidhostname',
69 'skylab_swarming_server')
Xixuan Wua5a29442017-10-11 11:03:02 -070070 task_processor.batch_execute()
71 self.assertEqual(task_executor.BATCH_SIZE,
72 task_processor.swarming.dummy_run_count)
73
Xixuan Wu835dee22017-09-07 10:47:29 -070074 def testBatchExecuteTaskSuccessfully(self):
75 """Test task_executor successfully execute tasks in batch."""
76 suite_kwargs = {'suite': 'fake_suite'}
77 extra_num = 10
78 for i in range(task_executor.BATCH_SIZE + extra_num):
79 suite_kwargs['num'] = i + 1
80 task_executor.push(task_executor.SUITES_QUEUE, **suite_kwargs)
81
82 # Before batch_execute
83 tasks = self.taskqueue_stub.get_filtered_tasks()
84 self.assertEqual(len(tasks), task_executor.BATCH_SIZE + extra_num)
85 with mock.patch('swarming_lib.SwarmingRunner',
86 return_value=FakeSwarmingLib()):
Craig Bergstrom3212fb42018-04-17 19:24:15 -060087 task_processor = task_executor.TaskProcessor(task_executor.SUITES_QUEUE,
Xixuan Wu5d700dc2018-08-21 15:13:10 -070088 'invalidhostname',
89 'skylab_swarming_server')
Xixuan Wu835dee22017-09-07 10:47:29 -070090 task_processor.batch_execute()
91 # After batch_execute succeeds, only extra_num tasks left.
92 tasks = self.taskqueue_stub.get_filtered_tasks()
93 self.assertEqual(len(tasks), extra_num)
94
95 def testBatchExecuteTaskFailedSwarmingTotally(self):
96 """Test task_executor fails at the beginning, and no tasks are deleted."""
97 suite_kwargs = {'suite': 'fake_suite'}
98 extra_num = 10
99 for i in range(task_executor.BATCH_SIZE + extra_num):
100 suite_kwargs['num'] = i + 1
101 task_executor.push(task_executor.SUITES_QUEUE, **suite_kwargs)
102
103 # Before batch_execute
104 tasks = self.taskqueue_stub.get_filtered_tasks()
105 self.assertEqual(len(tasks), task_executor.BATCH_SIZE + extra_num)
106 with mock.patch('swarming_lib.SwarmingRunner',
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -0700107 return_value=FakeSwarmingLib(0, error_num=len(tasks))):
Craig Bergstrom3212fb42018-04-17 19:24:15 -0600108 task_processor = task_executor.TaskProcessor(task_executor.SUITES_QUEUE,
Xixuan Wu5d700dc2018-08-21 15:13:10 -0700109 'invalidhostname',
110 'skylab_swarming_server')
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -0700111 task_processor.batch_execute()
112 # After batch_execute, no tasks are deleted from task queue, due
113 # to they're all failed to kick off.
Xixuan Wu835dee22017-09-07 10:47:29 -0700114 tasks = self.taskqueue_stub.get_filtered_tasks()
115 self.assertEqual(len(tasks), task_executor.BATCH_SIZE + extra_num)
116
117 def testBatchExecuteTaskFailedSwarmingPartially(self):
118 """Test task_executor fails halfway, and only executed tasks are deleted."""
119 suite_kwargs = {'suite': 'fake_suite'}
120 extra_num = 10
121 success_num = 50
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -0700122 error_num = 5
Xixuan Wu835dee22017-09-07 10:47:29 -0700123 for i in range(task_executor.BATCH_SIZE + extra_num):
124 suite_kwargs['num'] = i + 1
125 task_executor.push(task_executor.SUITES_QUEUE, **suite_kwargs)
126
127 # Before batch_execute
128 tasks = self.taskqueue_stub.get_filtered_tasks()
129 self.assertEqual(len(tasks), task_executor.BATCH_SIZE + extra_num)
130 with mock.patch('swarming_lib.SwarmingRunner',
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -0700131 return_value=FakeSwarmingLib(success_num, error_num)):
Craig Bergstrom3212fb42018-04-17 19:24:15 -0600132 task_processor = task_executor.TaskProcessor(task_executor.SUITES_QUEUE,
Xixuan Wu5d700dc2018-08-21 15:13:10 -0700133 'invalidhostname',
134 'skylab_swarming_server')
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -0700135 task_processor.batch_execute()
136 # After batch_execute, only failed suites and extra suites are
137 # kept in task queue.
Xixuan Wu835dee22017-09-07 10:47:29 -0700138 tasks = self.taskqueue_stub.get_filtered_tasks()
Xixuan Wu0a8d3ee2017-10-19 11:33:26 -0700139 self.assertEqual(len(tasks), error_num + extra_num)
Xixuan Wu835dee22017-09-07 10:47:29 -0700140
141 def testBatchExecuteTaskFailedLeasing(self):
142 """Test task_executor fails to lease task."""
143 suite_kwargs = {'suite': 'fake_suite'}
144 task_executor.push(task_executor.SUITES_QUEUE, **suite_kwargs)
145
146 with mock.patch('swarming_lib.SwarmingRunner',
147 return_value=FakeSwarmingLib(False)):
Craig Bergstrom3212fb42018-04-17 19:24:15 -0600148 task_processor = task_executor.TaskProcessor('nonExistentQueue',
Xixuan Wu5d700dc2018-08-21 15:13:10 -0700149 'invalidhostname',
150 'skylab_swarming_server')
Xixuan Wu835dee22017-09-07 10:47:29 -0700151 self.assertRaises(taskqueue.UnknownQueueError,
152 task_processor.batch_execute)
153 # After batch_execute fails, no tasks are deleted from task queue.
154 tasks = self.taskqueue_stub.get_filtered_tasks()
155 self.assertEqual(len(tasks), 1)
156
157
158if __name__ == '__main__':
159 unittest.main()