def test_heartbeat_continue_cleaning_no_worker(self, mock_continue, mock_handler): kwargs = { 'agent_url': 'http://127.0.0.1:9999/bar' } self.node.clean_step = { 'priority': 10, 'interface': 'deploy', 'step': 'foo', 'reboot_requested': False } mock_continue.side_effect = exception.NoFreeConductorWorker() for state in (states.CLEANWAIT, states.CLEANING): self.node.provision_state = state self.node.save() with task_manager.acquire( self.context, self.node.uuid, shared=True) as task: self.passthru.heartbeat(task, **kwargs) mock_continue.assert_called_once_with(mock.ANY, task, **kwargs) self.assertFalse(mock_handler.called) mock_handler.reset_mock() mock_continue.reset_mock()
def test_power_state_error_handler_no_worker(self, log_mock): exc = exception.NoFreeConductorWorker() conductor_utils.power_state_error_handler(exc, self.node, 'newstate') self.node.save.assert_called_once_with() self.assertEqual('newstate', self.node.power_state) self.assertEqual(states.NOSTATE, self.node.target_power_state) self.assertIn('No free conductor workers', self.node.last_error) self.assertTrue(log_mock.warning.called)
def test_provision_error_handler_no_worker(self, log_mock): exc = exception.NoFreeConductorWorker() conductor_utils.provisioning_error_handler(exc, self.node, 'state-one', 'state-two') self.node.save.assert_called_once_with() self.assertEqual('state-one', self.node.provision_state) self.assertEqual('state-two', self.node.target_provision_state) self.assertIn('No free conductor workers', self.node.last_error) self.assertTrue(log_mock.warning.called)
def _spawn_worker(self, func, *args, **kwargs): """Create a greenthread to run func(*args, **kwargs). Spawns a greenthread if there are free slots in pool, otherwise raises exception. Execution control returns immediately to the caller. :returns: GreenThread object. :raises: NoFreeConductorWorker if worker pool is currently full. """ if self._worker_pool.free(): return self._worker_pool.spawn(func, *args, **kwargs) else: raise exception.NoFreeConductorWorker()
def _spawn_worker(self, func, *args, **kwargs): """Create a greenthread to run func(*args, **kwargs). Spawns a greenthread if there are free slots in pool, otherwise raises exception. Execution control returns immediately to the caller. :returns: Future object. :raises: NoFreeConductorWorker if worker pool is currently full. """ try: return self._executor.submit(func, *args, **kwargs) except futurist.RejectedSubmission: raise exception.NoFreeConductorWorker()
def test_change_node_power_state_worker_pool_full(self): # Test change_node_power_state including integration with # conductor.utils.node_power_action and lower. initial_state = states.POWER_OFF n = utils.get_test_node(driver='fake', power_state=initial_state) db_node = self.dbapi.create_node(n) self.service.start() with mock.patch.object(self.service, '_spawn_worker') \ as spawn_mock: spawn_mock.side_effect = exception.NoFreeConductorWorker() self.assertRaises(exception.NoFreeConductorWorker, self.service.change_node_power_state, self.context, db_node.uuid, states.POWER_ON) spawn_mock.assert_called_once_with(mock.ANY, mock.ANY, mock.ANY, mock.ANY) db_node.refresh(self.context) self.assertEqual(initial_state, db_node.power_state) self.assertIsNone(db_node.target_power_state) self.assertIsNone(db_node.last_error) # Verify the picked reservation has been cleared due to full pool. self.assertIsNone(db_node.reservation)
def test_spawn_cleaning_error_handler_no_worker(self, log_mock): exc = exception.NoFreeConductorWorker() conductor_utils.spawn_cleaning_error_handler(exc, self.node) self.node.save.assert_called_once_with() self.assertIn('No free conductor workers', self.node.last_error) self.assertTrue(log_mock.warning.called)