def setup_pidfile(self, pid=None, exit_code=None, tests_failed=None, use_second_read=False): contents = drone_manager.PidfileContents() if pid is not None: contents.process = drone_manager.Process('myhost', pid) contents.exit_status = exit_code contents.num_tests_failed = tests_failed self.mock_drone_manager.get_pidfile_contents.expect_call( self.pidfile_id, use_second_read=use_second_read).and_return(contents)
def setUp(self): self.god = mock.mock_god() self.god.stub_with(drones, 'AUTOTEST_INSTALL_DIR', self._DRONE_INSTALL_DIR) self.manager = drone_manager.DroneManager() self.god.stub_with(self.manager, '_results_dir', self._RESULTS_DIR) # we don't want this to ever actually get called self.god.stub_function(drones, 'get_drone') # we don't want the DroneManager to go messing with global config def do_nothing(): pass self.god.stub_with(self.manager, 'refresh_drone_configs', do_nothing) # set up some dummy drones self.mock_drone = MockDrone('mock_drone') self.manager._drones[self.mock_drone.name] = self.mock_drone self.results_drone = MockDrone('results_drone', 0, 10) self.manager._results_drone = self.results_drone self.mock_drone_process = drone_manager.Process(self.mock_drone.name, 0)
class PidfileRunMonitorTest(unittest.TestCase): execution_tag = 'test_tag' pid = 12345 process = drone_manager.Process('myhost', pid) num_tests_failed = 1 def setUp(self): self.god = mock.mock_god() self.mock_drone_manager = self.god.create_mock_class( drone_manager.DroneManager, 'drone_manager') self.god.stub_with(drone_manager, '_the_instance', self.mock_drone_manager) self.god.stub_with(pidfile_monitor, '_get_pidfile_timeout_secs', self._mock_get_pidfile_timeout_secs) self.pidfile_id = object() (self.mock_drone_manager.get_pidfile_id_from.expect_call( self.execution_tag, pidfile_name=drone_manager.AUTOSERV_PID_FILE).and_return( self.pidfile_id)) self.monitor = pidfile_monitor.PidfileRunMonitor() self.monitor.attach_to_existing_process(self.execution_tag) def tearDown(self): self.god.unstub_all() def _mock_get_pidfile_timeout_secs(self): return 300 def setup_pidfile(self, pid=None, exit_code=None, tests_failed=None, use_second_read=False): contents = drone_manager.PidfileContents() if pid is not None: contents.process = drone_manager.Process('myhost', pid) contents.exit_status = exit_code contents.num_tests_failed = tests_failed self.mock_drone_manager.get_pidfile_contents.expect_call( self.pidfile_id, use_second_read=use_second_read).and_return(contents) def set_not_yet_run(self): self.setup_pidfile() def set_empty_pidfile(self): self.setup_pidfile() def set_running(self, use_second_read=False): self.setup_pidfile(self.pid, use_second_read=use_second_read) def set_complete(self, error_code, use_second_read=False): self.setup_pidfile(self.pid, error_code, self.num_tests_failed, use_second_read=use_second_read) def _check_monitor(self, expected_pid, expected_exit_status, expected_num_tests_failed): if expected_pid is None: self.assertEquals(self.monitor._state.process, None) else: self.assertEquals(self.monitor._state.process.pid, expected_pid) self.assertEquals(self.monitor._state.exit_status, expected_exit_status) self.assertEquals(self.monitor._state.num_tests_failed, expected_num_tests_failed) self.god.check_playback() def _test_read_pidfile_helper(self, expected_pid, expected_exit_status, expected_num_tests_failed): self.monitor._read_pidfile() self._check_monitor(expected_pid, expected_exit_status, expected_num_tests_failed) def _get_expected_tests_failed(self, expected_exit_status): if expected_exit_status is None: expected_tests_failed = None else: expected_tests_failed = self.num_tests_failed return expected_tests_failed def test_read_pidfile(self): self.set_not_yet_run() self._test_read_pidfile_helper(None, None, None) self.set_empty_pidfile() self._test_read_pidfile_helper(None, None, None) self.set_running() self._test_read_pidfile_helper(self.pid, None, None) self.set_complete(123) self._test_read_pidfile_helper(self.pid, 123, self.num_tests_failed) def test_read_pidfile_error(self): self.mock_drone_manager.get_pidfile_contents.expect_call( self.pidfile_id, use_second_read=False).and_return( drone_manager.InvalidPidfile('error')) self.assertRaises(pidfile_monitor.PidfileRunMonitor._PidfileException, self.monitor._read_pidfile) self.god.check_playback() def setup_is_running(self, is_running): self.mock_drone_manager.is_process_running.expect_call( self.process).and_return(is_running) def _test_get_pidfile_info_helper(self, expected_pid, expected_exit_status, expected_num_tests_failed): self.monitor._get_pidfile_info() self._check_monitor(expected_pid, expected_exit_status, expected_num_tests_failed) def test_get_pidfile_info(self): """ normal cases for get_pidfile_info """ # running self.set_running() self.setup_is_running(True) self._test_get_pidfile_info_helper(self.pid, None, None) # exited during check self.set_running() self.setup_is_running(False) self.set_complete(123, use_second_read=True) # pidfile gets read again self._test_get_pidfile_info_helper(self.pid, 123, self.num_tests_failed) # completed self.set_complete(123) self._test_get_pidfile_info_helper(self.pid, 123, self.num_tests_failed) def test_get_pidfile_info_running_no_proc(self): """ pidfile shows process running, but no proc exists """ # running but no proc self.set_running() self.setup_is_running(False) self.set_running(use_second_read=True) self._test_get_pidfile_info_helper(self.pid, 1, 0) self.assertTrue(self.monitor.lost_process) def test_get_pidfile_info_not_yet_run(self): """ pidfile hasn't been written yet """ self.set_not_yet_run() self._test_get_pidfile_info_helper(None, None, None) def test_process_failed_to_write_pidfile(self): self.set_not_yet_run() self.monitor._start_time = ( time.time() - pidfile_monitor._get_pidfile_timeout_secs() - 1) self._test_get_pidfile_info_helper(None, 1, 0) self.assertTrue(self.monitor.lost_process)