예제 #1
0
    def test_db(self, mock_get_database, mock_info, mock_ControlDaemon):
        midware = middleware.TurnstileMiddleware('app', {})

        db = midware.db

        self.assertEqual(db, 'database')
        mock_get_database.assert_called_once_with()
예제 #2
0
    def test_recheck_limits_exception(self, mock_Mapper, mock_limits_hydrate,
                                      mock_exception, mock_info,
                                      mock_ControlDaemon, mock_format_exc):
        limit_data = mock.Mock(
            **{
                'get_limits.side_effect': test_utils.TestException,
            })
        mock_ControlDaemon.return_value = mock.Mock(
            **{
                'get_limits.return_value': limit_data,
            })
        midware = middleware.TurnstileMiddleware('app', {})
        midware.limits = ['old_limit1', 'old_limit2']
        midware.limit_sum = 'old_sum'
        midware.mapper = 'old_mapper'
        midware._db = mock.Mock()

        midware.recheck_limits()

        mock_ControlDaemon.return_value.get_limits.assert_called_once_with()
        limit_data.get_limits.assert_called_once_with('old_sum')
        self.assertFalse(mock_limits_hydrate.called)
        self.assertFalse(mock_Mapper.called)
        for lim in mock_limits_hydrate.return_value:
            self.assertFalse(lim._route.called)
        self.assertEqual(midware.limits, ['old_limit1', 'old_limit2'])
        self.assertEqual(midware.limit_sum, 'old_sum')
        self.assertEqual(midware.mapper, 'old_mapper')
        mock_exception.assert_called_once_with("Could not load limits")
        mock_format_exc.assert_called_once_with()
        midware._db.assert_has_calls([
            mock.call.sadd('errors', 'Failed to load limits: <traceback>'),
            mock.call.publish('errors', 'Failed to load limits: <traceback>'),
        ])
예제 #3
0
    def test_recheck_limits_unchanged(self, mock_Mapper, mock_limits_hydrate,
                                      mock_exception, mock_info,
                                      mock_ControlDaemon, mock_format_exc):
        limit_data = mock.Mock(
            **{
                'get_limits.side_effect': control.NoChangeException,
            })
        mock_ControlDaemon.return_value = mock.Mock(
            **{
                'get_limits.return_value': limit_data,
            })
        midware = middleware.TurnstileMiddleware('app', {})
        midware.limits = ['old_limit1', 'old_limit2']
        midware.limit_sum = 'old_sum'
        midware.mapper = 'old_mapper'
        midware._db = mock.Mock()

        midware.recheck_limits()

        mock_ControlDaemon.return_value.get_limits.assert_called_once_with()
        limit_data.get_limits.assert_called_once_with('old_sum')
        self.assertFalse(mock_limits_hydrate.called)
        self.assertFalse(mock_Mapper.called)
        for lim in mock_limits_hydrate.return_value:
            self.assertFalse(lim._route.called)
        self.assertEqual(midware.limits, ['old_limit1', 'old_limit2'])
        self.assertEqual(midware.limit_sum, 'old_sum')
        self.assertEqual(midware.mapper, 'old_mapper')
        self.assertFalse(mock_exception.called)
        self.assertFalse(mock_format_exc.called)
        self.assertEqual(len(midware._db.method_calls), 0)
예제 #4
0
    def test_recheck_limits_basic(self, mock_Mapper, mock_limits_hydrate,
                                  mock_exception, mock_info,
                                  mock_ControlDaemon, mock_format_exc):
        limit_data = mock.Mock(**{
            'get_limits.return_value': ('new_sum', ['limit1', 'limit2']),
        })
        mock_ControlDaemon.return_value = mock.Mock(
            **{
                'get_limits.return_value': limit_data,
            })
        midware = middleware.TurnstileMiddleware('app', {})
        midware.limits = ['old_limit1', 'old_limit2']
        midware.limit_sum = 'old_sum'
        midware.mapper = 'old_mapper'
        midware._db = mock.Mock()

        midware.recheck_limits()

        mock_ControlDaemon.return_value.get_limits.assert_called_once_with()
        limit_data.get_limits.assert_called_once_with('old_sum')
        mock_limits_hydrate.assert_called_once_with(midware._db,
                                                    ['limit1', 'limit2'])
        mock_Mapper.assert_called_once_with(register=False)
        for lim in mock_limits_hydrate.return_value:
            lim._route.assert_called_once_with('mapper')
        self.assertEqual(midware.limits, mock_limits_hydrate.return_value)
        self.assertEqual(midware.limit_sum, 'new_sum')
        self.assertEqual(midware.mapper, 'mapper')
        self.assertFalse(mock_exception.called)
        self.assertFalse(mock_format_exc.called)
        self.assertEqual(len(midware._db.method_calls), 0)
예제 #5
0
    def test_init_remote(self, mock_info, mock_RemoteControlDaemon,
                         mock_ControlDaemon, mock_find_entrypoint):
        midware = middleware.TurnstileMiddleware('app', {
            'control.remote': 'yes',
        })

        self.assertEqual(midware.app, 'app')
        self.assertEqual(midware.limits, [])
        self.assertEqual(midware.limit_sum, None)
        self.assertEqual(midware.mapper, None)
        self.assertIsInstance(midware.mapper_lock,
                              eventlet.semaphore.Semaphore)
        self.assertEqual(
            midware.conf._config, {
                None: dict(status='413 Request Entity Too Large'),
                'control': dict(remote='yes'),
            })
        self.assertEqual(midware._db, None)
        self.assertEqual(midware.preprocessors, [])
        self.assertEqual(midware.postprocessors, [])
        self.assertEqual(midware.formatter, midware.format_delay)
        self.assertFalse(mock_ControlDaemon.called)
        mock_RemoteControlDaemon.assert_has_calls([
            mock.call(midware, midware.conf),
            mock.call().start(),
        ])
        mock_info.assert_called_once_with("Turnstile middleware initialized")
예제 #6
0
    def test_init_formatter(self, mock_info, mock_RemoteControlDaemon,
                            mock_ControlDaemon, mock_find_entrypoint):
        fake_formatter = mock_find_entrypoint.return_value
        midware = middleware.TurnstileMiddleware('app',
                                                 dict(formatter='formatter'))

        self.assertEqual(midware.app, 'app')
        self.assertEqual(midware.limits, [])
        self.assertEqual(midware.limit_sum, None)
        self.assertEqual(midware.mapper, None)
        self.assertIsInstance(midware.mapper_lock,
                              eventlet.semaphore.Semaphore)
        self.assertEqual(
            midware.conf._config, {
                None: {
                    'status': '413 Request Entity Too Large',
                    'formatter': 'formatter',
                },
            })
        self.assertEqual(midware._db, None)
        self.assertEqual(midware.preprocessors, [])
        self.assertEqual(midware.postprocessors, [])
        mock_find_entrypoint.assert_called_once_with('turnstile.formatter',
                                                     'formatter',
                                                     required=True)
        self.assertFalse(mock_RemoteControlDaemon.called)
        mock_ControlDaemon.assert_has_calls([
            mock.call(midware, midware.conf),
            mock.call().start(),
        ])
        mock_info.assert_called_once_with("Turnstile middleware initialized")
        midware.formatter('delay', 'limit', 'bucket', 'environ', 'start')
        fake_formatter.assert_called_once_with('413 Request Entity Too Large',
                                               'delay', 'limit', 'bucket',
                                               'environ', 'start')
예제 #7
0
    def test_db_cached(self, mock_get_database, mock_info, mock_ControlDaemon):
        midware = middleware.TurnstileMiddleware('app', {})
        midware._db = 'cached'

        db = midware.db

        self.assertEqual(db, 'cached')
        self.assertFalse(mock_get_database.called)
예제 #8
0
    def test_init_enable(self, mock_info, mock_RemoteControlDaemon,
                         mock_ControlDaemon, mock_find_entrypoint):
        entrypoints = {
            'turnstile.preprocessor': {
                'ep1': 'preproc1',
                'ep3': 'preproc3',
                'ep4': 'preproc4',
                'ep6': 'preproc6',
            },
            'turnstile.postprocessor': {
                'ep2': 'postproc2',
                'ep4': 'postproc4',
                'ep6': 'postproc6',
            },
        }

        mock_find_entrypoint.side_effect = \
            lambda x, y, compat=True: entrypoints[x].get(y)

        midware = middleware.TurnstileMiddleware(
            'app', {
                'enable': 'ep1 ep2 ep3 ep4 ep5 ep6',
            })

        self.assertEqual(midware.app, 'app')
        self.assertEqual(midware.limits, [])
        self.assertEqual(midware.limit_sum, None)
        self.assertEqual(midware.mapper, None)
        self.assertIsInstance(midware.mapper_lock,
                              eventlet.semaphore.Semaphore)
        self.assertEqual(
            midware.conf._config, {
                None:
                dict(status='413 Request Entity Too Large',
                     enable='ep1 ep2 ep3 ep4 ep5 ep6'),
            })
        self.assertEqual(midware._db, None)
        self.assertEqual(midware.preprocessors, [
            'preproc1',
            'preproc3',
            'preproc4',
            'preproc6',
        ])
        self.assertEqual(midware.postprocessors, [
            'postproc6',
            'postproc4',
            'postproc2',
        ])
        self.assertEqual(midware.formatter, midware.format_delay)
        self.assertFalse(mock_RemoteControlDaemon.called)
        mock_ControlDaemon.assert_has_calls([
            mock.call(midware, midware.conf),
            mock.call().start(),
        ])
        mock_info.assert_called_once_with("Turnstile middleware initialized")
예제 #9
0
    def test_format_delay(self, mock_HeadersDict, mock_info,
                          mock_ControlDaemon):
        midware = middleware.TurnstileMiddleware('app', {})
        limit = mock.Mock(**{
            'format.return_value': ('limit status', 'limit entity'),
        })
        start_response = mock.Mock()

        result = midware.format_delay(10.1, limit, 'bucket', 'environ',
                                      start_response)

        self.assertEqual(result, 'limit entity')
        mock_HeadersDict.assert_called_once_with([('Retry-After', '11')])
        limit.format.assert_called_once_with('413 Request Entity Too Large',
                                             mock_HeadersDict.return_value,
                                             'environ', 'bucket', 10.1)
        start_response.assert_called_once_with('limit status', 'header items')
예제 #10
0
    def test_call_basic(self, mock_format_delay, mock_recheck_limits,
                        mock_info, mock_ControlDaemon):
        app = mock.Mock(return_value='app response')
        midware = middleware.TurnstileMiddleware(app, {})
        midware.mapper = mock.Mock()
        environ = {}

        result = midware(environ, 'start_response')

        self.assertEqual(result, 'app response')
        mock_recheck_limits.assert_called_once_with()
        midware.mapper.routematch.assert_called_once_with(environ=environ)
        self.assertFalse(mock_format_delay.called)
        app.assert_called_once_with(environ, 'start_response')
        self.assertEqual(environ, {
            'turnstile.conf': midware.conf,
        })
예제 #11
0
    def test_call_delay(self, mock_format_delay, mock_recheck_limits,
                        mock_info, mock_ControlDaemon):
        app = mock.Mock(return_value='app response')
        midware = middleware.TurnstileMiddleware(app, {})
        midware.mapper = mock.Mock()
        midware.preprocessors = [mock.Mock(), mock.Mock()]
        midware.postprocessors = [mock.Mock(), mock.Mock()]
        environ = {
            'turnstile.delay': [
                (30, 'limit1', 'bucket1'),
                (20, 'limit2', 'bucket2'),
                (60, 'limit3', 'bucket3'),
                (10, 'limit4', 'bucket4'),
            ],
        }

        result = midware(environ, 'start_response')

        self.assertEqual(result, 'formatted delay')
        mock_recheck_limits.assert_called_once_with()
        for proc in midware.preprocessors:
            proc.assert_called_once_with(midware, environ)
        midware.mapper.routematch.assert_called_once_with(environ=environ)
        mock_format_delay.assert_called_once_with(60, 'limit3', 'bucket3',
                                                  environ, 'start_response')
        for proc in midware.postprocessors:
            self.assertFalse(proc.called)
        self.assertFalse(app.called)
        self.assertEqual(
            environ, {
                'turnstile.delay': [
                    (30, 'limit1', 'bucket1'),
                    (20, 'limit2', 'bucket2'),
                    (60, 'limit3', 'bucket3'),
                    (10, 'limit4', 'bucket4'),
                ],
                'turnstile.conf':
                midware.conf,
            })