Пример #1
0
    def test_polling_with_duplicate_car_ids(self):
        def mock_get_response(url, timeout=999):
            return {
                '1': CAR_1_INSIDE_GEOFENCE_RESPONSE,
                '2': CAR_2_INSIDE_SECOND_GEOFENCE_RESPONSE,
            }[re.search(r'-?\d+$', url).group()]

        with mock.patch('monitor.alert') as mock_alert:
            with mock.patch('requests.get',
                            side_effect=mock_get_response) as mock_get:
                geofence_monitor.start([
                    '1-2',
                    '1',
                    '2',
                    'http://test.com',
                    '--car_status_url=http://test.com/carStatus/%s',
                    '--max_query_qps=2.0',
                    '--poll_period_s=10',
                    '--min_poll_padding_period_s=0',
                ])

                monitor.poll_timer.mock_tick(1.0)
                mock_get.assert_has_calls([
                    mock.call('http://test.com/carStatus/1', timeout=10),
                    mock.call('http://test.com/carStatus/2', timeout=10),
                ])
                # Assert that it's only making two requests.
                self.assertEqual(mock_get.call_count, 2)

            mock_alert.assert_not_called()
Пример #2
0
    def test_polling_request_throttling(self):
        request_times = []

        def mock_get_response(url, timeout=999):
            request_times.append(time.time())
            time.sleep(0.1)
            return {
                '1': CAR_1_INSIDE_GEOFENCE_RESPONSE,
                '2': CAR_2_INSIDE_SECOND_GEOFENCE_RESPONSE,
            }[re.search(r'-?\d+$', url).group()]

        with mock.patch('requests.get',
                        side_effect=mock_get_response) as mock_get:
            geofence_monitor.start([
                '1-2',
                'http://test.com',
                '--car_status_url=http://test.com/carStatus/%s',
                '--max_query_qps=2.0',
                '--poll_period_s=10',
                '--min_poll_padding_period_s=0',
            ])

            monitor.poll_timer.mock_tick(1.0)
            mock_get.assert_has_calls([
                mock.call('http://test.com/carStatus/1', timeout=10),
                mock.call('http://test.com/carStatus/2', timeout=10),
            ])
            self.assertEqual(mock_get.call_count, 2)

        self.assertTrue(request_times[1] - request_times[0] >= 0.5)
Пример #3
0
    def test_polling_some_inside_some_outside_their_geofences(self):
        def mock_get_response(url, timeout=999):
            return {
                '1': CAR_1_INSIDE_GEOFENCE_RESPONSE,
                '2': CAR_2_INSIDE_SECOND_GEOFENCE_RESPONSE,
                '3': CAR_3_OUTSIDE_ITS_GEOFENCES_RESPONSE,
            }[re.search(r'-?\d+$', url).group()]

        with mock.patch('monitor.alert') as mock_alert:
            with mock.patch('requests.get',
                            side_effect=mock_get_response) as mock_get:
                geofence_monitor.start([
                    '1-3',
                    'http://test.com',
                    '--car_status_url=http://test.com/carStatus/%s',
                    '--google_maps_api_key=1234567890',
                    '--max_query_qps=2.0',
                    '--poll_period_s=10',
                    '--min_poll_padding_period_s=0',
                ])

                monitor.poll_timer.mock_tick(1.0)
                mock_get.assert_has_calls([
                    mock.call('http://test.com/carStatus/1', timeout=10),
                    mock.call('http://test.com/carStatus/2', timeout=10),
                    mock.call('http://test.com/carStatus/3', timeout=10),
                ])
                self.assertEqual(mock_get.call_count, 3)

            mock_alert.assert_called_once_with(
                'Cars outside of geofences', 'geofence_monitor_geofence', {
                    'car_coords': [(3, [-73.98, 40.76])],
                    'google_maps_api_key': '1234567890'
                })
Пример #4
0
    def test_parse_args_defaults(self):
        geofence_monitor.start(['1', 'http://test.com'])

        self.assertEqual(monitor.args.car_ids, [1])
        self.assertEqual(
            monitor.args.car_status_url,
            'http://skurt-interview-api.herokuapp.com/carStatus/%s')
        self.assertEqual(monitor.args.query_delay_s, 1.0)
Пример #5
0
    def test_polling_triggering_both_alerts(self):
        def mock_get_response(url, timeout=999):
            if url[-2:] == '-2':
                raise requests.exceptions.Timeout('Request timed out')

            return {
                '-1': CAR_NEGATIVE_1_404_RESPONSE,
                '0': CAR_0_NO_COORDINATES_RESPONSE,
                '1': CAR_1_INSIDE_GEOFENCE_RESPONSE,
                '2': CAR_2_INSIDE_SECOND_GEOFENCE_RESPONSE,
                '3': CAR_3_OUTSIDE_ITS_GEOFENCES_RESPONSE,
            }[re.search(r'-?\d+$', url).group()]

        with mock.patch('monitor.alert') as mock_alert:
            with mock.patch('requests.get',
                            side_effect=mock_get_response) as mock_get:
                geofence_monitor.start([
                    '-2',
                    '-1',
                    '0-3',
                    'http://test.com',
                    '--car_status_url=http://test.com/carStatus/%s',
                    '--google_maps_api_key=1234567890',
                    '--max_query_qps=2.0',
                    '--poll_period_s=10',
                    '--min_poll_padding_period_s=0',
                ])

                monitor.poll_timer.mock_tick(1.0)
                mock_get.assert_has_calls([
                    mock.call('http://test.com/carStatus/-2', timeout=10),
                    mock.call('http://test.com/carStatus/-1', timeout=10),
                    mock.call('http://test.com/carStatus/0', timeout=10),
                    mock.call('http://test.com/carStatus/1', timeout=10),
                    mock.call('http://test.com/carStatus/2', timeout=10),
                    mock.call('http://test.com/carStatus/3', timeout=10),
                ])
                self.assertEqual(mock_get.call_count, 6)

            mock_alert.assert_has_calls([
                mock.call(
                    'Cars outside of geofences', 'geofence_monitor_geofence', {
                        'car_coords': [(3, [-73.98, 40.76])],
                        'google_maps_api_key': '1234567890'
                    }),
                mock.call(
                    'Geofence monitor errors', 'geofence_monitor_errors', {
                        'car_errors': [(-2, 'FETCH_TIMED_OUT'),
                                       (-1, 'INVALID_FETCH_RESPONSE'),
                                       (0, 'NO_CAR_COORDS')]
                    }),
            ],
                                        any_order=True)
Пример #6
0
    def test_parse_args_with_overlapping_car_id_ranges(self):
        geofence_monitor.start([
            '5-10',
            '1-7',
            '3',
            'http://test.com',
            '--car_status_url=http://test.com/carStatus/%s',
            '--max_query_qps=2.0',
        ])

        self.assertEqual(monitor.args.car_ids, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
        self.assertEqual(monitor.args.car_status_url,
                         'http://test.com/carStatus/%s')
        self.assertEqual(monitor.args.query_delay_s, 0.5)
Пример #7
0
    def test_parse_args_with_complex_args(self):
        geofence_monitor.start([
            '1-11',
            '13',
            '15-16',
            'http://test.com',
            '--car_status_url=http://test.com/carStatus/%s',
            '--max_query_qps=2.0',
        ])

        self.assertEqual(monitor.args.car_ids,
                         [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 16])
        self.assertEqual(monitor.args.car_status_url,
                         'http://test.com/carStatus/%s')
        self.assertEqual(monitor.args.query_delay_s, 0.5)
Пример #8
0
    def test_polling_one_inside_its_second_geofence(self):
        with mock.patch('monitor.alert') as mock_alert:
            with mock.patch('requests.get',
                            return_value=CAR_2_INSIDE_SECOND_GEOFENCE_RESPONSE
                            ) as mock_get:
                geofence_monitor.start([
                    '2',
                    'http://test.com',
                    '--car_status_url=http://test.com/carStatus/%s',
                    '--max_query_qps=2.0',
                    '--poll_period_s=10',
                    '--min_poll_padding_period_s=0',
                ])

                monitor.poll_timer.mock_tick(1.0)
                mock_get.assert_called_once_with('http://test.com/carStatus/2',
                                                 timeout=10)

            mock_alert.assert_not_called()
Пример #9
0
    def test_polling_one_car_with_no_coordinates(self):
        with mock.patch('monitor.alert') as mock_alert:
            with mock.patch(
                    'requests.get',
                    return_value=CAR_0_NO_COORDINATES_RESPONSE) as mock_get:
                geofence_monitor.start([
                    '0',
                    'http://test.com',
                    '--car_status_url=http://test.com/carStatus/%s',
                    '--max_query_qps=2.0',
                    '--poll_period_s=10',
                    '--min_poll_padding_period_s=0',
                ])

                monitor.poll_timer.mock_tick(1.0)
                mock_get.assert_called_once_with('http://test.com/carStatus/0',
                                                 timeout=10)

            mock_alert.assert_called_once_with(
                'Geofence monitor errors', 'geofence_monitor_errors',
                {'car_errors': [(0, 'NO_CAR_COORDS')]})
Пример #10
0
    def test_polling_one_car_with_404_response(self):
        with mock.patch('monitor.alert') as mock_alert:
            with mock.patch(
                    'requests.get',
                    return_value=CAR_NEGATIVE_1_404_RESPONSE) as mock_get:
                geofence_monitor.start([
                    '-1',
                    'http://test.com',
                    '--car_status_url=http://test.com/carStatus/%s',
                    '--max_query_qps=2.0',
                    '--poll_period_s=10',
                    '--min_poll_padding_period_s=0',
                ])

                monitor.poll_timer.mock_tick(1.0)
                mock_get.assert_called_once_with(
                    'http://test.com/carStatus/-1', timeout=10)

            mock_alert.assert_called_once_with(
                'Geofence monitor errors', 'geofence_monitor_errors',
                {'car_errors': [(-1, 'INVALID_FETCH_RESPONSE')]})
Пример #11
0
    def test_polling_one_car_that_times_out(self):
        def time_out(url, timeout=999):
            raise requests.exceptions.Timeout('Request timed out')

        with mock.patch('monitor.alert') as mock_alert:
            with mock.patch('requests.get', side_effect=time_out) as mock_get:
                geofence_monitor.start([
                    '-2',
                    'http://test.com',
                    '--car_status_url=http://test.com/carStatus/%s',
                    '--max_query_qps=2.0',
                    '--poll_period_s=10',
                    '--min_poll_padding_period_s=0',
                ])

                monitor.poll_timer.mock_tick(1.0)
                mock_get.assert_called_once_with(
                    'http://test.com/carStatus/-2', timeout=10)

            mock_alert.assert_called_once_with(
                'Geofence monitor errors', 'geofence_monitor_errors',
                {'car_errors': [(-2, 'FETCH_TIMED_OUT')]})
Пример #12
0
    def test_polling_one_outside_its_geofences(self):
        with mock.patch('monitor.alert') as mock_alert:
            with mock.patch('requests.get',
                            return_value=CAR_3_OUTSIDE_ITS_GEOFENCES_RESPONSE
                            ) as mock_get:
                geofence_monitor.start([
                    '3',
                    'http://test.com',
                    '--car_status_url=http://test.com/carStatus/%s',
                    '--google_maps_api_key=1234567890',
                    '--max_query_qps=2.0',
                    '--poll_period_s=10',
                    '--min_poll_padding_period_s=0',
                ])

                monitor.poll_timer.mock_tick(1.0)
                mock_get.assert_called_once_with('http://test.com/carStatus/3',
                                                 timeout=10)

            mock_alert.assert_called_once_with(
                'Cars outside of geofences', 'geofence_monitor_geofence', {
                    'car_coords': [(3, [-73.98, 40.76])],
                    'google_maps_api_key': '1234567890'
                })
Пример #13
0
 def test_parse_args_without_car_ids(self):
     with self.assertRaises(SystemExit) as e:
         geofence_monitor.start([])
     self.assertEqual(e.exception.code, 2)