def test_integration_http_teardown_killed(self, SignalerClass): """Ensure that the http teardown procedure closes correctly when abort kills the process.""" signaler = SignalerClass.return_value signaler.side_effect = lambda path, use_post_method: ( path == '/abortabortabort', None) clock = Mock(wraps=time) class TerminalStateStatusRunner(ThermosTaskRunner): """ Status is called each poll in the teardown procedure. We return kill after the 3rd poll to mimic a task that exits early. We want to ensure the shutdown procedure doesn't wait the full time if it doesn't need to. """ TIMES_CALLED = 0 @property def status(self): if (self.TIMES_CALLED >= 3): return StatusResult('Test task mock status', mesos_pb2.TASK_KILLED) self.TIMES_CALLED += 1 with self.yield_sleepy(TerminalStateStatusRunner, portmap={'health': 3141}, clock=clock, sleep=0, exit_code=0) as task_runner: graceful_shutdown_wait = Amount(1, Time.SECONDS) shutdown_wait = Amount(5, Time.SECONDS) http_task_runner = HttpLifecycleManager( task_runner, 3141, [('/quitquitquit', graceful_shutdown_wait), ('/abortabortabort', shutdown_wait)], clock=clock) http_task_runner.start() task_runner.forked.wait() http_task_runner.stop() http_teardown_poll_wait_call = call( HttpLifecycleManager.WAIT_POLL_INTERVAL.as_(Time.SECONDS)) assert clock.sleep.mock_calls.count( http_teardown_poll_wait_call) == 3 # Killed before 5 assert signaler.mock_calls == [ call('/quitquitquit', use_post_method=True), call('/abortabortabort', use_post_method=True) ]
def test_integration_http_teardown_escalate(self, SignalerClass): """Ensure that the http teardown process fully escalates when quit/abort both fail to kill.""" signaler = SignalerClass.return_value signaler.side_effect = lambda path, use_post_method: (True, None) clock = Mock(wraps=time) class KillCalledTaskRunner(ThermosTaskRunner): def __init__(self, *args, **kwargs): self._killed_called = False ThermosTaskRunner.__init__(self, *args, **kwargs) def kill_called(self): return self._killed_called def kill(self): self._killed_called = True @property def status(self): return None with self.yield_sleepy(KillCalledTaskRunner, portmap={'health': 3141}, clock=clock, sleep=0, exit_code=0) as task_runner: graceful_shutdown_wait = Amount(1, Time.SECONDS) shutdown_wait = Amount(5, Time.SECONDS) http_task_runner = HttpLifecycleManager( task_runner, 3141, [('/quitquitquit', graceful_shutdown_wait), ('/abortabortabort', shutdown_wait)], clock=clock) http_task_runner.start() task_runner.forked.wait() http_task_runner.stop() http_teardown_poll_wait_call = call( HttpLifecycleManager.WAIT_POLL_INTERVAL.as_(Time.SECONDS)) assert clock.sleep.mock_calls.count( http_teardown_poll_wait_call) == 6 assert signaler.mock_calls == [ call('/quitquitquit', use_post_method=True), call('/abortabortabort', use_post_method=True) ] assert task_runner.kill_called() is True
def test_integration_http_teardown_escalate(self, SignalerClass): """Ensure that the http teardown process fully escalates when quit/abort both fail to kill.""" signaler = SignalerClass.return_value signaler.side_effect = lambda path, use_post_method: (True, None) clock = Mock(wraps=time) class KillCalledTaskRunner(ThermosTaskRunner): def __init__(self, *args, **kwargs): self._killed_called = False ThermosTaskRunner.__init__(self, *args, **kwargs) def kill_called(self): return self._killed_called def kill(self): self._killed_called = True @property def status(self): return None with self.yield_sleepy( KillCalledTaskRunner, portmap={'health': 3141}, clock=clock, sleep=0, exit_code=0) as task_runner: graceful_shutdown_wait = Amount(1, Time.SECONDS) shutdown_wait = Amount(5, Time.SECONDS) http_task_runner = HttpLifecycleManager( task_runner, 3141, [('/quitquitquit', graceful_shutdown_wait), ('/abortabortabort', shutdown_wait)], clock=clock) http_task_runner.start() task_runner.forked.wait() http_task_runner.stop() http_teardown_poll_wait_call = call(HttpLifecycleManager.WAIT_POLL_INTERVAL.as_(Time.SECONDS)) assert clock.sleep.mock_calls.count(http_teardown_poll_wait_call) == 6 assert signaler.mock_calls == [ call('/quitquitquit', use_post_method=True), call('/abortabortabort', use_post_method=True)] assert task_runner.kill_called() == True
def test_integration_http_teardown_killed(self, SignalerClass): """Ensure that the http teardown procedure closes correctly when abort kills the process.""" signaler = SignalerClass.return_value signaler.side_effect = lambda path, use_post_method: (path == '/abortabortabort', None) clock = Mock(wraps=time) class TerminalStateStatusRunner(ThermosTaskRunner): """ Status is called each poll in the teardown procedure. We return kill after the 3rd poll to mimic a task that exits early. We want to ensure the shutdown procedure doesn't wait the full time if it doesn't need to. """ TIMES_CALLED = 0 @property def status(self): if (self.TIMES_CALLED >= 3): return StatusResult('Test task mock status', mesos_pb2.TASK_KILLED) self.TIMES_CALLED += 1 with self.yield_sleepy( TerminalStateStatusRunner, portmap={'health': 3141}, clock=clock, sleep=0, exit_code=0) as task_runner: graceful_shutdown_wait = Amount(1, Time.SECONDS) shutdown_wait = Amount(5, Time.SECONDS) http_task_runner = HttpLifecycleManager( task_runner, 3141, [('/quitquitquit', graceful_shutdown_wait), ('/abortabortabort', shutdown_wait)], clock=clock) http_task_runner.start() task_runner.forked.wait() http_task_runner.stop() http_teardown_poll_wait_call = call(HttpLifecycleManager.WAIT_POLL_INTERVAL.as_(Time.SECONDS)) assert clock.sleep.mock_calls.count(http_teardown_poll_wait_call) == 3 # Killed before 5 assert signaler.mock_calls == [ call('/quitquitquit', use_post_method=True), call('/abortabortabort', use_post_method=True)]