Exemplo n.º 1
0
def test_http_lifecycle_wrapper_without_lifecycle():
  mti_without_lifecycle = MesosTaskInstance()
  mti_without_http_lifecycle = MesosTaskInstance(lifecycle=LifecycleConfig())

  runner_mock = mock.create_autospec(ThermosTaskRunner)
  assert HttpLifecycleManager.wrap(runner_mock, mti_without_lifecycle, {}) is runner_mock
  assert HttpLifecycleManager.wrap(runner_mock, mti_without_http_lifecycle, {}) is runner_mock
Exemplo n.º 2
0
def make_mocks(mesos_task_instance, portmap):
    # wrap it once health is available and validate the constructor is called as expected
    runner_mock = mock.create_autospec(ThermosTaskRunner)
    with mock.patch.object(HttpLifecycleManager, '__init__',
                           return_value=None) as wrapper_init:
        runner_wrapper = HttpLifecycleManager.wrap(runner_mock,
                                                   mesos_task_instance,
                                                   portmap)
        yield runner_mock, runner_wrapper, wrapper_init
Exemplo n.º 3
0
  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
Exemplo n.º 4
0
  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)]
Exemplo n.º 5
0
def test_http_lifecycle_wraps_start_and_stop():
  mti = MesosTaskInstance(lifecycle=LifecycleConfig(http=HttpLifecycleConfig()))
  runner_mock = mock.create_autospec(ThermosTaskRunner)
  with mock.patch.object(HttpLifecycleManager, '_terminate_http', return_value=None) as http_mock:
    runner_wrapper = HttpLifecycleManager.wrap(runner_mock, mti, {'health': 31337})

    # ensure that start and stop are properly wrapped
    runner_wrapper.start(23.3)
    assert runner_mock.start.mock_calls == [mock.call(timeout=23.3)]

    # ensure that http teardown called when stopped
    runner_wrapper.stop(32.2)
    assert http_mock.mock_calls == [mock.call()]
    assert runner_mock.stop.mock_calls == [mock.call(timeout=32.2)]
    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
Exemplo n.º 8
0
def make_mocks(mesos_task_instance, portmap):
  # wrap it once health is available and validate the constructor is called as expected
  runner_mock = mock.create_autospec(ThermosTaskRunner)
  with mock.patch.object(HttpLifecycleManager, '__init__', return_value=None) as wrapper_init:
    runner_wrapper = HttpLifecycleManager.wrap(runner_mock, mesos_task_instance, portmap)
    yield runner_mock, runner_wrapper, wrapper_init