def test_chef_poking(self, mocker): """ Test interval-based chef poking. """ test_interval = 3 kitchen = DumplingKitchen( dumpling_queue=mocker.Mock(), chef_poke_interval=test_interval, ) mocker.patch.object(kitchen, '_put_dumpling_on_queue') # _poke_chefs() runs in an infinite loop which we need to break out of. # We do that by setting a side effect on the mocked call to sleep() # which will raise a RuntimeError. This doesn't interfere with being # able to determine the value passed to sleep(). mock_sleep = mocker.patch( 'netdumplings.dumplingkitchen.sleep', side_effect=RuntimeError ) # Set up two valid chefs. One of them returns a dumpling when poked and # and the other one doesn't. mock_chef_with_interval_dumpling = mocker.Mock() mock_chef_with_no_interval_dumpling = mocker.Mock() dumpling_interval_handler = ( mock_chef_with_interval_dumpling.interval_handler ) no_dumpling_interval_handler = ( mock_chef_with_no_interval_dumpling.interval_handler ) dumpling_interval_handler.return_value = 'dumpling' no_dumpling_interval_handler.return_value = None kitchen._chefs = [ mock_chef_with_interval_dumpling, mock_chef_with_no_interval_dumpling, ] # Run once through the poker infinite loop. with pytest.raises(RuntimeError): kitchen._poke_chefs(test_interval) # Check that we were asked to sleep by the test interval. mock_sleep.assert_called_once_with(test_interval) # Check that the two interval handlers were invoked, and that the one # that returned a dumpling resulted in that dumpling being sent. dumpling_interval_handler.assert_called_once_with( interval=test_interval ) no_dumpling_interval_handler.assert_called_once_with( interval=test_interval ) kitchen._put_dumpling_on_queue.assert_called_once_with( mock_chef_with_interval_dumpling, 'dumpling', DumplingDriver.interval, )
def test_chef_poking(self, mocker): """ Test interval-based chef poking. """ test_interval = 3 kitchen = DumplingKitchen( dumpling_queue=mocker.Mock(), chef_poke_interval=test_interval, ) mocker.patch.object(kitchen, '_put_dumpling_on_queue') # _poke_chefs() runs in an infinite loop which we need to break out of. # We do that by setting a side effect on the mocked call to sleep() # which will raise a RuntimeError. This doesn't interfere with being # able to determine the value passed to sleep(). mock_sleep = mocker.patch('netdumplings.dumplingkitchen.sleep', side_effect=RuntimeError) # Set up two valid chefs. One of them returns a dumpling when poked and # and the other one doesn't. mock_chef_with_interval_dumpling = mocker.Mock() mock_chef_with_no_interval_dumpling = mocker.Mock() dumpling_interval_handler = ( mock_chef_with_interval_dumpling.interval_handler) no_dumpling_interval_handler = ( mock_chef_with_no_interval_dumpling.interval_handler) dumpling_interval_handler.return_value = 'dumpling' no_dumpling_interval_handler.return_value = None kitchen._chefs = [ mock_chef_with_interval_dumpling, mock_chef_with_no_interval_dumpling, ] # Run once through the poker infinite loop. with pytest.raises(RuntimeError): kitchen._poke_chefs(test_interval) # Check that we were asked to sleep by the test interval. mock_sleep.assert_called_once_with(test_interval) # Check that the two interval handlers were invoked, and that the one # that returned a dumpling resulted in that dumpling being sent. dumpling_interval_handler.assert_called_once_with( interval=test_interval) no_dumpling_interval_handler.assert_called_once_with( interval=test_interval) kitchen._put_dumpling_on_queue.assert_called_once_with( mock_chef_with_interval_dumpling, 'dumpling', DumplingDriver.interval, )
def test_chef_poking_with_broken_handler(self, mocker): """ Test interval-based chef poking where one of the handlers raises an exception, which should result in an exception-level log entry being created but the processing being otherwise unaffected. """ test_interval = 3 kitchen = DumplingKitchen( dumpling_queue=mocker.Mock(), chef_poke_interval=test_interval, ) mocker.patch.object(kitchen, '_put_dumpling_on_queue') mocker.patch.object(kitchen, '_logger') mocker.patch( 'netdumplings.dumplingkitchen.sleep', side_effect=RuntimeError ) # Set up one valid chefs which returns an interval dumpling, and one # chef which raises an exception in its interval handler. # and the other one doesn't. mock_chef_with_interval_dumpling = mocker.Mock() mock_chef_with_interval_error = mocker.Mock() dumpling_interval_handler = ( mock_chef_with_interval_dumpling.interval_handler ) error_interval_handler = ( mock_chef_with_interval_error.interval_handler ) dumpling_interval_handler.return_value = 'dumpling' error_interval_handler.side_effect = KeyError kitchen._chefs = [ mock_chef_with_interval_dumpling, mock_chef_with_interval_error, ] # Run once through the poker infinite loop. with pytest.raises(RuntimeError): kitchen._poke_chefs(test_interval) # Check that the valid dumpling was sent, and that we logged an # exception for the other chef. kitchen._put_dumpling_on_queue.assert_called_once_with( mock_chef_with_interval_dumpling, 'dumpling', DumplingDriver.interval, ) kitchen._logger.exception.assert_called_once()
def test_chef_poking_with_broken_handler(self, mocker): """ Test interval-based chef poking where one of the handlers raises an exception, which should result in an exception-level log entry being created but the processing being otherwise unaffected. """ test_interval = 3 kitchen = DumplingKitchen( dumpling_queue=mocker.Mock(), chef_poke_interval=test_interval, ) mocker.patch.object(kitchen, '_put_dumpling_on_queue') mocker.patch.object(kitchen, '_logger') mocker.patch('netdumplings.dumplingkitchen.sleep', side_effect=RuntimeError) # Set up one valid chefs which returns an interval dumpling, and one # chef which raises an exception in its interval handler. # and the other one doesn't. mock_chef_with_interval_dumpling = mocker.Mock() mock_chef_with_interval_error = mocker.Mock() dumpling_interval_handler = ( mock_chef_with_interval_dumpling.interval_handler) error_interval_handler = ( mock_chef_with_interval_error.interval_handler) dumpling_interval_handler.return_value = 'dumpling' error_interval_handler.side_effect = KeyError kitchen._chefs = [ mock_chef_with_interval_dumpling, mock_chef_with_interval_error, ] # Run once through the poker infinite loop. with pytest.raises(RuntimeError): kitchen._poke_chefs(test_interval) # Check that the valid dumpling was sent, and that we logged an # exception for the other chef. kitchen._put_dumpling_on_queue.assert_called_once_with( mock_chef_with_interval_dumpling, 'dumpling', DumplingDriver.interval, ) kitchen._logger.exception.assert_called_once()