コード例 #1
0
ファイル: test_engine.py プロジェクト: Avatarchik/monitorrent
    def test_manual_execute_with_ids_ignored_while_in_execute(self):
        waiter = Event()

        long_execute_waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()
            long_execute_waiter.wait(1)
            self.assertTrue(long_execute_waiter.is_set)

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock
        clients_manager = ClientsManager({})
        engine_runner = EngineRunner(Logger(), self.trackers_manager, clients_manager, interval=1)
        engine_runner.execute(None)
        waiter.wait(0.3)
        waiter.clear()
        ids = [1, 2, 3]
        engine_runner.execute(ids)
        long_execute_waiter.set()
        waiter.wait(0.3)
        self.assertTrue(waiter.is_set)
        engine_runner.stop()
        engine_runner.join(1)
        self.assertFalse(engine_runner.is_alive())

        execute_mock.assert_called_once_with(ANY, None)
コード例 #2
0
 def create_runner(self, logger=None, interval=0.1):
     self.settings_manager = Mock()
     self.clients_manager = ClientsManager({})
     self.notifier_manager = NotifierManager(self.settings_manager, {})
     self.engine_runner = EngineRunner(
         Logger() if logger is None else logger,
         self.settings_manager,
         self.trackers_manager,
         self.clients_manager,
         self.notifier_manager,
         interval=interval)
コード例 #3
0
    def test_exeption_in_finally_execute(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock
        clients_manager = ClientsManager({})
        logger = Logger()
        logger.finished = Mock(side_effect=Exception("Failed to save"))
        engine_runner = EngineRunner(logger,
                                     self.trackers_manager,
                                     clients_manager,
                                     interval=0.1)
        waiter.wait(1)
        self.assertTrue(waiter.is_set)
        self.assertTrue(engine_runner.is_alive())

        engine_runner.stop()
        engine_runner.join(1)
        self.assertFalse(engine_runner.is_alive())

        self.assertEqual(1, execute_mock.call_count)
コード例 #4
0
    def test_update_interval_during_execute(self, test_interval):
        waiter = Event()
        scope = self.Bunch()
        scope.first_execute = True

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            engine_runner.interval = test_interval
            if scope.first_execute:
                scope.start = time()
                scope.first_execute = False
            else:
                scope.end = time()
                waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock
        clients_manager = ClientsManager({})
        engine_runner = EngineRunner(Logger(),
                                     self.trackers_manager,
                                     clients_manager,
                                     interval=0.1)
        waiter.wait(2)
        self.assertTrue(waiter.is_set)
        engine_runner.stop()
        engine_runner.join(1)
        self.assertFalse(engine_runner.is_alive())

        self.assertEqual(2, execute_mock.call_count)

        # noinspection PyUnresolvedReferences
        delta = scope.end - scope.start

        self.assertLessEqual(abs(delta - test_interval), 0.02)
コード例 #5
0
    def test_stop_after_multiple_execute(self, value):
        waiter = Event()
        scope = self.Bunch()
        scope.execute_count = 0

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            scope.execute_count += 1
            if scope.execute_count < value:
                return
            waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock
        clients_manager = ClientsManager({})
        engine_runner = EngineRunner(Logger(),
                                     self.trackers_manager,
                                     clients_manager,
                                     interval=0.1)
        waiter.wait(2)
        self.assertTrue(waiter.is_set)
        engine_runner.stop()
        engine_runner.join(1)
        self.assertFalse(engine_runner.is_alive())

        self.assertEqual(value, execute_mock.call_count)
コード例 #6
0
ファイル: test_engine.py プロジェクト: Avatarchik/monitorrent
    def test_update_interval_during_execute(self, test_interval):
        waiter = Event()
        scope = self.Bunch()
        scope.first_execute = True

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            engine_runner.interval = test_interval
            if scope.first_execute:
                scope.start = time()
                scope.first_execute = False
            else:
                scope.end = time()
                waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock
        clients_manager = ClientsManager({})
        engine_runner = EngineRunner(Logger(), self.trackers_manager, clients_manager, interval=0.1)
        waiter.wait(2)
        self.assertTrue(waiter.is_set)
        engine_runner.stop()
        engine_runner.join(1)
        self.assertFalse(engine_runner.is_alive())

        self.assertEqual(2, execute_mock.call_count)

        # noinspection PyUnresolvedReferences
        delta = scope.end - scope.start

        self.assertLessEqual(abs(delta - test_interval), 0.02)
コード例 #7
0
    def test_stop_bofore_execute(self):
        execute_mock = MagicMock()
        self.trackers_manager.execute = execute_mock
        clients_manager = ClientsManager({})
        engine_runner = EngineRunner(Logger(),
                                     self.trackers_manager,
                                     clients_manager,
                                     interval=0.1)
        engine_runner.stop()
        engine_runner.join(1)
        self.assertFalse(engine_runner.is_alive())

        execute_mock.assert_not_called()
コード例 #8
0
ファイル: test_engine.py プロジェクト: Avatarchik/monitorrent
    def test_stop_bofore_execute(self):        
        execute_mock = MagicMock()
        self.trackers_manager.execute = execute_mock
        clients_manager = ClientsManager({})
        engine_runner = EngineRunner(Logger(), self.trackers_manager, clients_manager, interval=0.1)
        engine_runner.stop()
        engine_runner.join(1)
        self.assertFalse(engine_runner.is_alive())

        execute_mock.assert_not_called()
コード例 #9
0
    def test_manual_execute(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock
        clients_manager = ClientsManager({})
        engine_runner = EngineRunner(Logger(),
                                     self.trackers_manager,
                                     clients_manager,
                                     interval=1)
        engine_runner.execute(None)
        waiter.wait(0.3)
        self.assertTrue(waiter.is_set)
        engine_runner.stop()
        engine_runner.join(1)
        self.assertFalse(engine_runner.is_alive())

        self.assertEqual(1, execute_mock.call_count)
コード例 #10
0
ファイル: test_engine.py プロジェクト: Avatarchik/monitorrent
    def test_manual_execute(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock
        clients_manager = ClientsManager({})
        engine_runner = EngineRunner(Logger(), self.trackers_manager, clients_manager, interval=1)
        engine_runner.execute(None)
        waiter.wait(0.3)
        self.assertTrue(waiter.is_set)
        engine_runner.stop()
        engine_runner.join(1)
        self.assertFalse(engine_runner.is_alive())

        self.assertEqual(1, execute_mock.call_count)
コード例 #11
0
    def test_manual_execute_with_ids(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock
        clients_manager = ClientsManager({})
        engine_runner = EngineRunner(Logger(),
                                     self.trackers_manager,
                                     clients_manager,
                                     interval=10)
        ids = [1, 2, 3]
        engine_runner.execute(ids)
        waiter.wait(0.3)
        self.assertTrue(waiter.is_set)
        engine_runner.stop()
        engine_runner.join(1)
        self.assertFalse(engine_runner.is_alive())

        execute_mock.assert_called_once_with(ANY, ids)
コード例 #12
0
ファイル: test_engine.py プロジェクト: Avatarchik/monitorrent
    def test_exeption_in_finally_execute(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock
        clients_manager = ClientsManager({})
        logger = Logger()
        logger.finished = Mock(side_effect=Exception("Failed to save"))
        engine_runner = EngineRunner(logger, self.trackers_manager, clients_manager, interval=0.1)
        waiter.wait(1)
        self.assertTrue(waiter.is_set)
        self.assertTrue(engine_runner.is_alive())

        engine_runner.stop()
        engine_runner.join(1)
        self.assertFalse(engine_runner.is_alive())

        self.assertEqual(1, execute_mock.call_count)
コード例 #13
0
ファイル: test_engine.py プロジェクト: Avatarchik/monitorrent
    def test_stop_after_multiple_execute(self, value):
        waiter = Event()
        scope = self.Bunch()
        scope.execute_count = 0

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            scope.execute_count += 1
            if scope.execute_count < value:
                return
            waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock
        clients_manager = ClientsManager({})
        engine_runner = EngineRunner(Logger(), self.trackers_manager, clients_manager, interval=0.1)
        waiter.wait(2)
        self.assertTrue(waiter.is_set)
        engine_runner.stop()
        engine_runner.join(1)
        self.assertFalse(engine_runner.is_alive())

        self.assertEqual(value, execute_mock.call_count)
コード例 #14
0
ファイル: test_engine.py プロジェクト: werwolfby/monitorrent
 def create_runner(self, logger=None, interval=0.1):
     self.clients_manager = ClientsManager({})
     self.engine_runner = EngineRunner(Logger() if logger is None else logger,
                                       self.trackers_manager,
                                       self.clients_manager,
                                       interval=interval)
コード例 #15
0
ファイル: test_engine.py プロジェクト: werwolfby/monitorrent
class EngineRunnerTest(TestCase, WithEngineRunnerTest):
    class Bunch(object):
        pass

    def setUp(self):
        super(EngineRunnerTest, self).setUp()
        self.create_trackers_manager()


    def create_runner(self, logger=None, interval=0.1):
        self.clients_manager = ClientsManager({})
        self.engine_runner = EngineRunner(Logger() if logger is None else logger,
                                          self.trackers_manager,
                                          self.clients_manager,
                                          interval=interval)

    def test_stop_bofore_execute(self):
        execute_mock = MagicMock()
        self.trackers_manager.execute = execute_mock

        self.create_runner()
        self.stop_runner()

        execute_mock.assert_not_called()

    def test_stop_after_execute(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock

        self.create_runner()
        waiter.wait(1)
        self.assertTrue(waiter.is_set)

        self.stop_runner()
        self.assertEqual(1, execute_mock.call_count)

    @data(2, 5, 10)
    def test_stop_after_multiple_execute(self, value):
        waiter = Event()
        scope = self.Bunch()
        scope.execute_count = 0

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            scope.execute_count += 1
            if scope.execute_count < value:
                return
            waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock

        self.create_runner()
        waiter.wait(2)
        self.assertTrue(waiter.is_set)

        self.stop_runner()

        self.assertEqual(value, execute_mock.call_count)

    @data(0.1, 0.3, 0.5, 0.6)
    def test_update_interval_during_execute(self, test_interval):
        waiter = Event()
        scope = self.Bunch()
        scope.first_execute = True

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            self.engine_runner.interval = test_interval
            if scope.first_execute:
                scope.start = time()
                scope.first_execute = False
            else:
                scope.end = time()
                waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock

        self.create_runner()
        waiter.wait(2)
        self.assertTrue(waiter.is_set)

        self.stop_runner()

        self.assertEqual(2, execute_mock.call_count)

        # noinspection PyUnresolvedReferences
        delta = scope.end - scope.start

        self.assertLessEqual(abs(delta - test_interval), 0.02)

    def test_manual_execute(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock

        self.create_runner(interval=1)
        self.engine_runner.execute(None)
        waiter.wait(0.3)
        self.assertTrue(waiter.is_set)

        self.stop_runner()

        self.assertEqual(1, execute_mock.call_count)

    def test_exeption_in_execute(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()
            raise Exception('Some error')

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock

        self.create_runner()
        waiter.wait(1)
        self.assertTrue(waiter.is_set)

        self.stop_runner()

        self.assertEqual(1, execute_mock.call_count)

    def test_exeption_in_finally_execute(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock

        logger = Logger()
        logger.finished = Mock(side_effect=Exception("Failed to save"))

        self.create_runner(logger=logger)
        waiter.wait(1)
        self.assertTrue(waiter.is_set)
        self.assertTrue(self.engine_runner.is_alive())

        self.stop_runner()

        self.assertEqual(1, execute_mock.call_count)

    def test_manual_execute_with_ids(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock

        self.create_runner(interval=10)
        ids = [1, 2, 3]
        self.engine_runner.execute(ids)
        waiter.wait(0.3)
        self.assertTrue(waiter.is_set)

        self.stop_runner()

        execute_mock.assert_called_once_with(ANY, ids)

    def test_manual_execute_with_ids_ignored_while_in_execute(self):
        waiter = Event()

        long_execute_waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()
            long_execute_waiter.wait(1)
            self.assertTrue(long_execute_waiter.is_set)

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock

        self.create_runner(interval=1)
        self.engine_runner.execute(None)
        waiter.wait(0.3)
        waiter.clear()
        ids = [1, 2, 3]
        self.engine_runner.execute(ids)
        long_execute_waiter.set()
        waiter.wait(0.3)
        self.assertTrue(waiter.is_set)

        self.stop_runner()

        execute_mock.assert_called_once_with(ANY, None)

    def test_manual_execute_shouldnt_reset_timeout_for_whole_execute(self):
        executed = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            executed.set()

        execute_mock = Mock(side_effect=execute)
        self.trackers_manager.execute = execute_mock

        # start
        self.create_runner(interval=1)

        sleep(0.5)
        # start manual
        self.engine_runner.execute([1, 2, 3])
        executed.wait(0.3)
        executed.clear()

        sleep(0.5)
        executed.wait(0.3)

        self.assertTrue(executed.is_set)
        self.stop_runner()

        self.assertEqual(2, execute_mock.call_count)

    @data(10, 200, 3600, 7200)
    @patch('monitorrent.engine.timer')
    def test_interval_set_should_update_timer(self, expected_value, create_timer_mock):
        # arrange
        cancel_mock = Mock()
        create_timer_mock.return_value = cancel_mock
        self.create_runner()

        # act
        self.engine_runner.interval = expected_value
        self.stop_runner()

        # assert
        self.assertEqual(2, create_timer_mock.call_count)
        self.assertEqual(2, cancel_mock.call_count)
コード例 #16
0
class EngineRunnerTest(TestCase, WithEngineRunnerTest):
    class Bunch(object):
        pass

    def setUp(self):
        super(EngineRunnerTest, self).setUp()
        self.create_trackers_manager()

    def create_runner(self, logger=None, interval=0.1):
        self.settings_manager = Mock()
        self.clients_manager = ClientsManager({})
        self.notifier_manager = NotifierManager(self.settings_manager, {})
        self.engine_runner = EngineRunner(
            Logger() if logger is None else logger,
            self.settings_manager,
            self.trackers_manager,
            self.clients_manager,
            self.notifier_manager,
            interval=interval)

    def test_stop_bofore_execute(self):
        execute_mock = MagicMock()

        mock_tracker = Mock()
        mock_tracker.get_topics = Mock(return_value=[Topic()])
        mock_tracker.execute = execute_mock
        self.trackers_manager.trackers = {'mock.tracker': mock_tracker}

        self.create_runner()
        self.stop_runner()

        execute_mock.assert_not_called()

    def test_stop_after_execute(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)

        mock_tracker = Mock()
        mock_tracker.get_topics = Mock(return_value=[Topic()])
        mock_tracker.execute = execute_mock
        self.trackers_manager.trackers = {'mock.tracker': mock_tracker}

        self.create_runner()
        waiter.wait(1)
        self.assertTrue(waiter.is_set)

        self.stop_runner()
        self.assertEqual(1, execute_mock.call_count)

    @data(2, 5, 10)
    def test_stop_after_multiple_execute(self, value):
        waiter = Event()
        scope = self.Bunch()
        scope.execute_count = 0

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            scope.execute_count += 1
            if scope.execute_count < value:
                return
            waiter.set()

        execute_mock = Mock(side_effect=execute)

        mock_tracker = Mock()
        mock_tracker.get_topics = Mock(return_value=[Topic()])
        mock_tracker.execute = execute_mock
        self.trackers_manager.trackers = {'mock.tracker': mock_tracker}

        self.create_runner()
        waiter.wait(2)
        self.assertTrue(waiter.is_set)

        self.stop_runner()

        self.assertEqual(value, execute_mock.call_count)

    @data(0.1, 0.3, 0.5, 0.6)
    def test_update_interval_during_execute(self, test_interval):
        waiter = Event()
        scope = self.Bunch()
        scope.first_execute = True

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            self.engine_runner.interval = test_interval
            if scope.first_execute:
                scope.start = time()
                scope.first_execute = False
            else:
                scope.end = time()
                waiter.set()

        execute_mock = Mock(side_effect=execute)

        mock_tracker = Mock()
        mock_tracker.get_topics = Mock(return_value=[Topic()])
        mock_tracker.execute = execute_mock
        self.trackers_manager.trackers = {'mock.tracker': mock_tracker}

        self.create_runner()
        waiter.wait(2)
        self.assertTrue(waiter.is_set)

        self.stop_runner()

        self.assertEqual(2, execute_mock.call_count)

        # noinspection PyUnresolvedReferences
        delta = scope.end - scope.start

        self.assertLessEqual(abs(delta - test_interval), 0.027)

    def test_manual_execute(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)

        mock_tracker = Mock()
        mock_tracker.get_topics = Mock(return_value=[Topic()])
        mock_tracker.execute = execute_mock
        self.trackers_manager.trackers = {'mock.tracker': mock_tracker}

        self.create_runner(interval=1)
        self.engine_runner.execute(None)
        waiter.wait(0.3)
        self.assertTrue(waiter.is_set)

        self.stop_runner()

        self.assertEqual(1, execute_mock.call_count)

    def test_exeption_in_execute(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()
            raise Exception('Some error')

        execute_mock = Mock(side_effect=execute)

        mock_tracker = Mock()
        mock_tracker.get_topics = execute_mock
        self.trackers_manager.trackers = {'mock.tracker': mock_tracker}

        self.create_runner()
        self.assertTrue(waiter.wait(1))

        self.stop_runner()

        self.assertEqual(1, execute_mock.call_count)

    def test_exeption_in_finally_execute(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)

        mock_tracker = Mock()
        mock_tracker.get_topics = Mock(return_value=[Topic()])
        mock_tracker.execute = execute_mock
        self.trackers_manager.trackers = {'mock.tracker': mock_tracker}

        logger = Logger()
        logger.finished = Mock(side_effect=Exception("Failed to save"))

        self.create_runner(logger=logger)
        self.assertTrue(waiter.wait(1))
        self.assertTrue(self.engine_runner.is_alive())

        self.stop_runner()

        self.assertEqual(1, execute_mock.call_count)

    def test_manual_execute_with_ids(self):
        waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()

        execute_mock = Mock(side_effect=execute)

        topics = [Topic()]

        mock_tracker = Mock()
        mock_tracker.get_topics = Mock(return_value=topics)
        mock_tracker.execute = execute_mock
        self.trackers_manager.trackers = {'mock.tracker': mock_tracker}

        self.create_runner(interval=10)
        ids = [1, 2, 3]
        self.engine_runner.execute(ids)
        self.assertTrue(waiter.wait(0.3))

        self.stop_runner()

        execute_mock.assert_called_once_with(topics, ANY)

    def test_manual_execute_with_ids_ignored_while_in_execute(self):
        waiter = Event()

        long_execute_waiter = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            waiter.set()
            long_execute_waiter.wait(1)
            self.assertTrue(long_execute_waiter.is_set)

        execute_mock = Mock(side_effect=execute)

        topics = [Topic()]

        mock_tracker = Mock()
        mock_tracker.get_topics = Mock(return_value=topics)
        mock_tracker.execute = execute_mock
        self.trackers_manager.trackers = {'mock.tracker': mock_tracker}

        self.create_runner(interval=1)
        self.engine_runner.execute(None)
        waiter.wait(0.3)
        waiter.clear()
        ids = [1, 2, 3]
        self.engine_runner.execute(ids)
        long_execute_waiter.set()
        waiter.wait(0.3)
        self.assertTrue(waiter.is_set)

        self.stop_runner()

        execute_mock.assert_called_once_with(topics, ANY)

    def test_manual_execute_shouldnt_reset_timeout_for_whole_execute(self):
        executed = Event()

        # noinspection PyUnusedLocal
        def execute(*args, **kwargs):
            executed.set()

        execute_mock = Mock(side_effect=execute)

        mock_tracker = Mock()
        mock_tracker.get_topics = Mock(return_value=[Topic()])
        mock_tracker.execute = execute_mock
        self.trackers_manager.trackers = {'mock.tracker': mock_tracker}

        # start
        self.create_runner(interval=1)

        sleep(0.5)
        # start manual
        self.engine_runner.execute([1, 2, 3])
        executed.wait(0.3)
        executed.clear()

        sleep(0.5)
        executed.wait(0.3)

        self.assertTrue(executed.is_set)
        self.stop_runner()

        self.assertEqual(2, execute_mock.call_count)

    @data(10, 200, 3600, 7200)
    @patch('monitorrent.engine.timer')
    def test_interval_set_should_update_timer(self, expected_value,
                                              create_timer_mock):
        # arrange
        cancel_mock = Mock()
        create_timer_mock.return_value = cancel_mock
        self.create_runner()

        # act
        self.engine_runner.interval = expected_value
        self.stop_runner()

        # assert
        self.assertEqual(2, create_timer_mock.call_count)
        self.assertEqual(2, cancel_mock.call_count)