Exemplo n.º 1
0
    def test_pinger_picks_up_on_interval_change(self):
        interval = get_timeout(0.1)
        interval2 = get_timeout(0.3)

        self.p.ping_interval = timedelta(seconds=interval)

        with contextlib.ExitStack() as stack:
            ping = stack.enter_context(
                unittest.mock.patch(
                    "aioxmpp.ping.ping",
                    new=CoroutineMock(),
                ))

            self.p.start()

            run_coroutine(asyncio.sleep(interval / 2))

            self._require_task_running()
            ping.assert_called_once_with(self.cc,
                                         unittest.mock.sentinel.ping_address)
            ping.reset_mock()

            self.p.ping_interval = timedelta(seconds=interval2)

            import time
            run_coroutine(asyncio.sleep(interval2))
            self._require_task_running()
            print(time.monotonic(), "slept")
            ping.assert_called_once_with(
                self.cc,
                unittest.mock.sentinel.ping_address,
            )
            ping.reset_mock()
Exemplo n.º 2
0
    def test_pinger_skips_ping_emission_if_client_is_suspended(self):
        timeout = get_timeout(0.1)

        self.assertFalse(self.cc.suspended)

        self.p.ping_interval = timedelta(seconds=timeout)

        with contextlib.ExitStack() as stack:
            ping = stack.enter_context(
                unittest.mock.patch(
                    "aioxmpp.ping.ping",
                    new=CoroutineMock(),
                ))

            self.p.start()

            run_coroutine(asyncio.sleep(timeout / 2))

            for i in range(2):
                self._require_task_running()
                ping.assert_called_once_with(
                    self.cc, unittest.mock.sentinel.ping_address)
                ping.reset_mock()
                # we need to change the suspended flag here, because the next
                # sleep covers the next ping sending
                if i == 1:
                    self.cc.suspended = True
                run_coroutine(asyncio.sleep(timeout))

            for i in range(2):
                print(i)
                self._require_task_running()
                ping.assert_not_called()
                if i == 1:
                    self.cc.suspended = False
Exemplo n.º 3
0
    def test_pinger_uses_jitter_to_calculate_next(self):
        timeout = get_timeout(0.1)

        self.p.ping_interval = timedelta(seconds=timeout)
        self.jitter_mock.return_value = timeout * 2
        self.jitter_mock.side_effect = None

        with contextlib.ExitStack() as stack:
            ping = stack.enter_context(
                unittest.mock.patch(
                    "aioxmpp.ping.ping",
                    new=CoroutineMock(),
                ))

            self.p.start()

            run_coroutine(asyncio.sleep(timeout / 2))

            self._require_task_running()
            ping.assert_called_once_with(self.cc,
                                         unittest.mock.sentinel.ping_address)
            ping.reset_mock()

            run_coroutine(asyncio.sleep(timeout * 2))

            self._require_task_running()
            ping.assert_called_once_with(self.cc,
                                         unittest.mock.sentinel.ping_address)
            ping.reset_mock()
Exemplo n.º 4
0
    def test_pinger_cancels_futures_on_cancel(self):
        interval = get_timeout(0.1)

        futures = []

        def ping(*args, **kwargs):
            fut = asyncio.Future()
            futures.append(fut)
            return fut

        self.p.ping_interval = timedelta(seconds=interval)
        self.p.ping_timeout = timedelta(seconds=interval * 10)

        with contextlib.ExitStack() as stack:
            ping = stack.enter_context(
                unittest.mock.patch(
                    "aioxmpp.ping.ping",
                    new=unittest.mock.Mock(side_effect=ping, ),
                ))

            self.p.start()

            run_coroutine(asyncio.sleep(interval / 2))

            # we check that, at any time, at most four futures
            # (timeout/interval) are not cancelled
            for i in range(5):
                self._require_task_running()
                run_coroutine(asyncio.sleep(interval))

        self.p.stop()
        run_coroutine(asyncio.sleep(interval / 2))

        self.assertTrue(all(fut.done() for fut in futures))
Exemplo n.º 5
0
    def test_pinger_picks_up_on_timeout_change(self):
        interval = get_timeout(0.3)
        timeout = get_timeout(0.3)

        futures = []

        def ping_func(*args, **kwargs):
            fut = asyncio.Future()
            futures.append(fut)
            return fut

        self.p.ping_interval = timedelta(seconds=interval)
        self.p.ping_timeout = timedelta(seconds=interval * 10)

        with contextlib.ExitStack() as stack:
            ping = stack.enter_context(
                unittest.mock.patch(
                    "aioxmpp.ping.ping",
                    new=unittest.mock.Mock(side_effect=ping_func, ),
                ))

            self.p.start()

            run_coroutine(asyncio.sleep(interval / 2))

            self._require_task_running()
            ping.assert_called_once_with(self.cc,
                                         unittest.mock.sentinel.ping_address)
            ping.reset_mock()

            self.p.ping_timeout = timedelta(seconds=timeout)

            run_coroutine(asyncio.sleep(interval))
            self._require_task_running()

            self.assertEqual(len(futures), 2)

            run_coroutine(asyncio.sleep(interval))
            self._require_task_running()

            self.assertEqual(len(futures), 3)

            run_coroutine(asyncio.sleep(interval / 2))

        self.assertFalse(futures[0].done())
        self.assertTrue(futures[1].done())
        self.assertTrue(futures[2].done())
    def test_changing_soft_limit_may_emit_limit_immediately(self):
        dt = get_timeout(timedelta(seconds=0.1))

        self.am.notify_received()

        run_coroutine(asyncio.sleep((dt*1.1).total_seconds()))

        self.listener.on_deadtime_soft_limit_tripped.assert_not_called()
        self.am.deadtime_soft_limit = dt

        run_coroutine(asyncio.sleep(0))
        self.listener.on_deadtime_soft_limit_tripped.assert_called_once_with()
    def test_hard_timer_fires_even_without_any_reception(self):
        dt = get_timeout(timedelta(seconds=0.1))

        self.am.deadtime_hard_limit = dt

        run_coroutine(asyncio.sleep((dt * 0.9).total_seconds()))

        self.listener.on_deadtime_hard_limit_tripped.assert_not_called()

        run_coroutine(asyncio.sleep((dt * 0.2).total_seconds()))

        self.listener.on_deadtime_hard_limit_tripped.assert_called_once_with()
    def test_hard_limit_trips(self):
        dt = get_timeout(timedelta(seconds=0.1))

        self.am.deadtime_hard_limit = dt
        self.am.notify_received()

        run_coroutine(asyncio.sleep((dt * 0.9).total_seconds()))

        self.listener.on_deadtime_hard_limit_tripped.assert_not_called()

        run_coroutine(asyncio.sleep((dt * 0.2).total_seconds()))

        self.listener.on_deadtime_hard_limit_tripped.assert_called_once_with()
    def test_hard_limit_can_reemit_after_reception(self):
        dt = get_timeout(timedelta(seconds=0.1))

        self.am.deadtime_hard_limit = dt
        self.am.notify_received()

        run_coroutine(asyncio.sleep((dt*1.1).total_seconds()))

        self.listener.on_deadtime_hard_limit_tripped.assert_called_once_with()
        self.am.notify_received()
        self.listener.on_deadtime_hard_limit_tripped.reset_mock()

        run_coroutine(asyncio.sleep((dt*1.1).total_seconds()))
        self.listener.on_deadtime_hard_limit_tripped.assert_called_once_with()
Exemplo n.º 10
0
    def test_pinger_cancels_after_ping_timeout(self):
        interval = get_timeout(0.1)
        timeout = get_timeout(0.4)

        futures = []

        def ping_func(*args, **kwargs):
            fut = asyncio.Future()
            futures.append(fut)
            return fut

        self.p.ping_interval = timedelta(seconds=interval)
        self.p.ping_timeout = timedelta(seconds=timeout)

        with contextlib.ExitStack() as stack:
            ping = stack.enter_context(
                unittest.mock.patch(
                    "aioxmpp.ping.ping",
                    new=unittest.mock.Mock(side_effect=ping_func, ),
                ))

            self.p.start()

            run_coroutine(asyncio.sleep(interval / 2))

            # we check that, at any time, at most four futures
            # (timeout/interval) are not cancelled
            for i in range(10):
                self._require_task_running()
                ping.assert_called_once_with(
                    self.cc, unittest.mock.sentinel.ping_address)
                ping.reset_mock()
                self.assertLessEqual(
                    sum(not fut.done() for fut in futures),
                    4,
                )
                run_coroutine(asyncio.sleep(interval))
    def test_changing_soft_limit_recaluclates_timer(self):
        dt = get_timeout(timedelta(seconds=0.1))

        self.am.deadtime_soft_limit = dt
        self.am.notify_received()

        run_coroutine(asyncio.sleep((dt * 0.9).total_seconds()))

        self.listener.on_deadtime_soft_limit_tripped.assert_not_called()

        self.am.deadtime_soft_limit = dt*1.5

        run_coroutine(asyncio.sleep((dt * 0.5).total_seconds()))

        self.listener.on_deadtime_soft_limit_tripped.assert_not_called()

        run_coroutine(asyncio.sleep((dt * 0.2).total_seconds()))

        self.listener.on_deadtime_soft_limit_tripped.assert_called_once_with()
Exemplo n.º 12
0
    def test_pinger_emits_ping_every_ping_interval(self):
        timeout = get_timeout(0.1)

        self.p.ping_interval = timedelta(seconds=timeout)

        with contextlib.ExitStack() as stack:
            ping = stack.enter_context(
                unittest.mock.patch(
                    "aioxmpp.ping.ping",
                    new=CoroutineMock(),
                ))

            self.p.start()

            run_coroutine(asyncio.sleep(timeout / 2))

            for i in range(5):
                self._require_task_running()
                ping.assert_called_once_with(
                    self.cc, unittest.mock.sentinel.ping_address)
                ping.reset_mock()
                run_coroutine(asyncio.sleep(timeout))
Exemplo n.º 13
0
    def test_pinger_calls__interpret_result_for_finished_pings(self):
        interval = get_timeout(0.1)
        timeout = get_timeout(0.16)

        modes = [
            False,
            None,
            RuntimeError(),
        ]

        futures = []
        mode_i = 0

        def ping_func(*args, **kwargs):
            def make_fut():
                fut = asyncio.Future()
                futures.append(fut)
                return fut

            nonlocal mode_i

            mode = modes[mode_i]
            mode_i += 1

            fut = make_fut()
            if mode is None:
                fut.set_result(unittest.mock.sentinel.some_result)
            elif mode is False:
                pass
            else:
                fut.set_exception(mode)
            return fut

        self.p.ping_interval = timedelta(seconds=interval)
        self.p.ping_timeout = timedelta(seconds=timeout)

        with contextlib.ExitStack() as stack:
            ping = stack.enter_context(
                unittest.mock.patch(
                    "aioxmpp.ping.ping",
                    new=unittest.mock.Mock(side_effect=ping_func, ),
                ))

            _interpret_result = stack.enter_context(
                unittest.mock.patch.object(self.p, "_interpret_result"))

            self.p.start()

            logging.debug("test: sleeping for %s", interval / 2)
            run_coroutine(asyncio.sleep(interval / 2))
            # t_interval = 0.025 / 0.05, t_timeout = 0.025 / 0.08
            self.assertEqual(len(futures), 1)
            self.assertFalse(futures[0].done())

            logging.debug("test: sleeping for %s", interval * 0.6)
            run_coroutine(asyncio.sleep(interval * 0.6))
            # t_interval = 0.005 / 0.05, t_timeout = 0.055 / 0.08
            self.assertEqual(len(futures), 2)
            self.assertFalse(futures[0].done())
            self.assertTrue(futures[1].done())

            logging.debug("test: verifying")
            _interpret_result.assert_called_once_with(unittest.mock.ANY)
            _, (fut, ), _ = _interpret_result.mock_calls[0]
            self.assertEqual(fut.result(), futures[1].result())
            _interpret_result.reset_mock()

            logging.debug("test: sleeping for %s", interval * 0.6)
            run_coroutine(asyncio.sleep(interval * 0.6))
            # t_interval = 0.035 / 0.05, t_timeout = 0.085 / 0.08
            self.assertEqual(len(futures), 2)
            self.assertTrue(futures[0].done())
            self.assertTrue(futures[1].done())

            _interpret_result.assert_called_once_with(unittest.mock.ANY)
            _, (fut, ), _ = _interpret_result.mock_calls[0]
            self.assertEqual(len(futures), 2)
            self.assertTrue(futures[0].cancelled())
            self.assertTrue(futures[0].done())
            self.assertIsInstance(fut.exception(), asyncio.TimeoutError)
            _interpret_result.reset_mock()

            run_coroutine(asyncio.sleep(interval * 0.8))
            # t_interval = 0.025 / 0.05
            self.assertEqual(len(futures), 3)
            self.assertTrue(futures[2].done())

            _interpret_result.assert_called_once_with(unittest.mock.ANY)
            _, (fut, ), _ = _interpret_result.mock_calls[0]
            self.assertIs(fut.exception(), futures[2].exception())
            self.assertIsNotNone(fut.exception())
            _interpret_result.reset_mock()