5 from autotest_lib
.frontend
import setup_django_environment
6 from autotest_lib
.client
.common_lib
.test_utils
import mock
7 from autotest_lib
.frontend
.afe
import frontend_test_utils
, models
as afe_models
8 from autotest_lib
.frontend
.afe
import model_attributes
as afe_model_attributes
9 from autotest_lib
.frontend
.shared
import rest_client
10 from autotest_lib
.frontend
.planner
import models
, execution_engine
, support
11 from autotest_lib
.frontend
.planner
import model_attributes
14 class MockObject(object):
16 Empty mock object class, so that setattr() works on all names
21 class MockAfeRest(object):
23 execution_info
= MockObject()
24 queue_entries_request
= MockObject()
27 class MockRestJobs(object):
28 def __init__(self
, total_results
):
29 self
.total_results
= total_results
32 class MockExecutionInfo(object):
36 class MockQueueEntriesRequest(object):
37 queue_entries
= object()
40 class MockExecutionEngine(execution_engine
.ExecutionEngine
):
41 _planner_rpc
= MockObject()
45 _afe_rest
= MockAfeRest()
46 _label_name
= object()
50 def __init__(self
, *args
, **kwargs
):
54 class MockTestPlanController(support
.TestPlanController
):
55 def __init__(self
, *args
, **kwargs
):
56 super(MockTestPlanController
, self
).__init
__(machine
=None,
60 class ExecutionEngineTest(unittest
.TestCase
,
61 frontend_test_utils
.FrontendTestMixin
):
63 self
._frontend
_common
_setup
()
64 self
.engine
= MockExecutionEngine()
68 self
._frontend
_common
_teardown
()
71 def _setup_test_initialize_plan(self
):
72 self
.god
.stub_function(self
.engine
._planner
_rpc
, 'run')
73 self
.god
.stub_function(self
.engine
._afe
_rest
.jobs
, 'get')
74 self
.god
.stub_function(self
.engine
, '_wait_for_initialization')
77 def test_initialize_plan_new_plan(self
):
78 self
._setup
_test
_initialize
_plan
()
79 self
.god
.stub_function(self
.engine
, '_launch_set_atomic_group_job')
81 self
.engine
._planner
_rpc
.run
.expect_call(
82 'get_plan', id=self
.engine
._plan
_id
).and_return(
84 self
.engine
._afe
_rest
.jobs
.get
.expect_call(
85 name
='plan_set_atomic_group').and_return(MockRestJobs(None))
86 self
.engine
._launch
_set
_atomic
_group
_job
.expect_call(
87 'plan_set_atomic_group')
88 self
.engine
._wait
_for
_initialization
.expect_call()
90 self
.engine
._initialize
_plan
()
91 self
.god
.check_playback
94 def test_initialize_plan_existing(self
):
95 self
._setup
_test
_initialize
_plan
()
97 self
.engine
._planner
_rpc
.run
.expect_call(
98 'get_plan', id=self
.engine
._plan
_id
).and_return(
100 self
.engine
._afe
_rest
.jobs
.get
.expect_call(
101 name
='plan_set_atomic_group').and_return(MockRestJobs(object()))
102 self
.engine
._wait
_for
_initialization
.expect_call()
104 self
.engine
._initialize
_plan
()
105 self
.god
.check_playback
108 def _setup_test_launch_atomic_group_job(self
, name
):
109 DUMMY_CONTROL
= '%(server)r %(label_name)r %(plan_id)r'
110 DUMMY_EXECUTION_INFO
= MockExecutionInfo()
111 DUMMY_QUEUE_ENTRIES_REQUEST
= MockQueueEntriesRequest()
113 self
.god
.stub_function(self
.engine
._planner
_rpc
, 'run')
114 self
.god
.stub_function(self
.engine
._afe
_rest
.execution_info
, 'get')
115 self
.god
.stub_function(
116 self
.engine
._afe
_rest
.queue_entries_request
, 'get')
118 self
.engine
._planner
_rpc
.run
.expect_call(
119 'get_hosts', plan_id
=self
.engine
._plan
_id
).and_return(
121 self
.engine
._planner
_rpc
.run
.expect_call(
122 'get_atomic_group_control_file').and_return(DUMMY_CONTROL
)
123 self
.engine
._afe
_rest
.execution_info
.get
.expect_call().and_return(
124 DUMMY_EXECUTION_INFO
)
125 self
.engine
._afe
_rest
.queue_entries_request
.get
.expect_call(
126 hosts
=self
.hosts
).and_return(DUMMY_QUEUE_ENTRIES_REQUEST
)
128 control_file
= DUMMY_CONTROL
% dict(server
=self
.engine
._server
,
129 label_name
=self
.engine
._label
_name
,
130 plan_id
=self
.engine
._plan
_id
)
131 DUMMY_EXECUTION_INFO
.execution_info
= {
132 'control_file': control_file
,
133 'cleanup_before_job': afe_model_attributes
.RebootBefore
.NEVER
,
134 'cleanup_after_job': afe_model_attributes
.RebootAfter
.NEVER
,
136 'machines_per_execution': len(self
.hosts
)}
138 job_req
= {'name': name
,
139 'owner': self
.engine
._owner
,
140 'execution_info': DUMMY_EXECUTION_INFO
.execution_info
,
141 'queue_entries': DUMMY_QUEUE_ENTRIES_REQUEST
.queue_entries
}
146 def test_launch_atomic_group_job(self
):
147 job_req
= self
._setup
_test
_launch
_atomic
_group
_job
('atomic_group_job')
148 self
.god
.stub_function(self
.engine
._afe
_rest
.jobs
, 'post')
150 self
.engine
._afe
_rest
.jobs
.post
.expect_call(job_req
)
152 self
.engine
._launch
_set
_atomic
_group
_job
('atomic_group_job')
153 self
.god
.check_playback()
156 def _setup_mock_controller(self
, controller_options
):
157 mock_controller
= MockTestPlanController()
158 for key
, value
in controller_options
.iteritems():
159 setattr(mock_controller
, key
, value
)
160 self
.god
.stub_with(support
, 'TestPlanController',
161 lambda *args
, **kwargs
: mock_controller
)
162 return mock_controller
165 def _test_process_finished_runs_helper(self
, status
, should_block
=False,
166 controller_options
={}):
167 Status
= model_attributes
.TestRunStatus
168 TEST_RUN_ID
= object()
169 TKO_TEST_ID
= object()
172 mock_controller
= self
._setup
_mock
_controller
(controller_options
)
174 self
.god
.stub_function(self
.engine
._planner
_rpc
, 'run')
175 self
.god
.stub_function(self
.engine
, '_run_execute_after')
177 test_run
= {'id': TEST_RUN_ID
,
178 'host': {'host': self
.hosts
[0].hostname
,
180 'test_job': {'test_config': {'alias': 'test_alias'}},
181 'tko_test': TKO_TEST_ID
,
184 self
.engine
._planner
_rpc
.run
.expect_call(
186 plan__id
=self
.engine
._plan
_id
,
187 status__in
=(Status
.PASSED
, Status
.FAILED
),
188 finalized
=False).and_return([test_run
])
189 self
.engine
._run
_execute
_after
.expect_call(
190 mock_controller
, tko_test_id
=TKO_TEST_ID
,
191 success
=(status
== Status
.PASSED
))
193 self
.engine
._planner
_rpc
.run
.expect_call('modify_host', id=HOST_ID
,
195 self
.engine
._planner
_rpc
.run
.expect_call('modify_test_run',
196 id=TEST_RUN_ID
, finalized
=True)
198 self
.engine
._process
_finished
_runs
()
200 self
.god
.check_playback()
203 def test_process_finished_runs_pass(self
):
204 self
._test
_process
_finished
_runs
_helper
(
205 model_attributes
.TestRunStatus
.PASSED
)
208 def test_process_finished_runs_fail(self
):
209 self
._test
_process
_finished
_runs
_helper
(
210 model_attributes
.TestRunStatus
.FAILED
, should_block
=True)
213 def test_process_finished_runs_fail_unblock(self
):
214 self
._test
_process
_finished
_runs
_helper
(
215 model_attributes
.TestRunStatus
.FAILED
, should_block
=False,
216 controller_options
={'_unblock': True})
219 def _test_schedule_new_runs_helper(self
, complete
=False, should_skip
=False,
220 controller_options
={}):
221 TEST_CONFIG_ID
= object()
223 self
.god
.stub_function(self
.engine
._planner
_rpc
, 'run')
224 self
.god
.stub_function(self
.engine
, '_run_execute_before')
226 result
= {'complete': complete
,
227 'next_configs': [{'next_test_config_id': TEST_CONFIG_ID
,
228 'host': self
.hosts
[0].hostname
,
229 'next_test_config_alias': object()}]}
231 mock_controller
= self
._setup
_mock
_controller
(controller_options
)
233 self
.engine
._planner
_rpc
.run
.expect_call(
234 'get_next_test_configs',
235 plan_id
=self
.engine
._plan
_id
).and_return(result
)
238 self
.engine
._run
_execute
_before
.expect_call(mock_controller
)
241 self
.engine
._planner
_rpc
.run
.expect_call(
242 'skip_test', test_config_id
=TEST_CONFIG_ID
,
243 hostname
=self
.hosts
[0].hostname
)
245 self
.god
.stub_function(self
.engine
, '_run_job')
246 self
.engine
._run
_job
.expect_call(
247 hostname
=self
.hosts
[0].hostname
,
248 test_config_id
=TEST_CONFIG_ID
,
249 cleanup_before_job
=mock_controller
._reboot
_before
,
250 cleanup_after_job
=mock_controller
._reboot
_after
,
251 run_verify
=mock_controller
._run
_verify
)
253 self
.engine
._schedule
_new
_runs
()
255 self
.god
.check_playback()
258 def test_schedule_new_runs(self
):
259 self
._test
_schedule
_new
_runs
_helper
()
262 def test_schedule_new_runs_complete(self
):
263 self
._test
_schedule
_new
_runs
_helper
(complete
=True)
266 def test_schedule_new_runs_skip(self
):
267 self
._test
_schedule
_new
_runs
_helper
(should_skip
=True,
268 controller_options
={'_skip': True})
271 def test_run_global_support(self
):
272 self
._ran
_global
_support
= False
274 def test_global_support(controller):
275 controller._ran_global_support = True
278 DUMMY_PLAN
= {'support': support
}
280 self
.god
.stub_function(self
.engine
._planner
_rpc
, 'run')
282 self
.engine
._planner
_rpc
.run
.expect_call(
283 'get_plan', id=self
.engine
._plan
_id
).and_return(DUMMY_PLAN
)
285 self
.engine
._run
_global
_support
(controller
=self
,
286 function_name
='test_global_support')
288 self
.assertTrue(self
._ran
_global
_support
)
289 self
.god
.check_playback()
292 if __name__
== '__main__':