def add_reports(self, num=1, blue_factor=0, cell_factor=1, wifi_factor=2, api_key='test', email=None, ip=None, nickname=None, blue_key=None, cell_mcc=None, wifi_key=None, lat=None): reports = [] for i in range(num): pos = CellFactory.build() report = { 'timestamp': time.time() * 1000.0, 'position': {}, 'bluetoothBeacons': [], 'cellTowers': [], 'wifiAccessPoints': [], } report['position']['latitude'] = lat or pos.lat report['position']['longitude'] = pos.lon report['position']['accuracy'] = 17 + i blues = WifiFactory.build_batch(blue_factor, lat=pos.lat, lon=pos.lon) for blue in blues: blue_data = { 'macAddress': blue_key or blue.key, 'signalStrength': -100 + i, } report['bluetoothBeacons'].append(blue_data) cells = CellFactory.build_batch(cell_factor, lat=pos.lat, lon=pos.lon) for cell in cells: cell_data = { 'radioType': cell.radio.name, 'mobileCountryCode': cell_mcc or cell.mcc, 'mobileNetworkCode': cell.mnc, 'locationAreaCode': cell.lac, 'cellId': cell.cid, 'primaryScramblingCode': cell.psc, 'signalStrength': -110 + i, } report['cellTowers'].append(cell_data) wifis = WifiFactory.build_batch(wifi_factor, lat=pos.lat, lon=pos.lon) for wifi in wifis: wifi_data = { 'macAddress': wifi_key or wifi.key, 'signalStrength': -90 + i, } report['wifiAccessPoints'].append(wifi_data) reports.append(report) queue_reports.delay(reports=reports, api_key=api_key, email=email, ip=ip, nickname=nickname).get() return reports
def test_no_call_made_when_not_allowed_for_apikey(self): cells = CellFactory.build_batch(2) wifis = WifiFactory.build_batch(2) self.provider.api_key.allow_fallback = False query = self.model_query(cells=cells, wifis=wifis) self.check_should_locate(query, False)
def add_reports(self, number=3, api_key='test', email=None): reports = [] for i in range(number): report = { 'timestamp': time.time() * 1000.0, 'position': {}, 'cellTowers': [], 'wifiAccessPoints': [], } cell = CellFactory.build() report['position']['latitude'] = cell.lat report['position']['longitude'] = cell.lon report['position']['accuracy'] = 17 + i cell_data = { 'radioType': cell.radio.name, 'mobileCountryCode': cell.mcc, 'mobileNetworkCode': cell.mnc, 'locationAreaCode': cell.lac, 'cellId': cell.cid, 'primaryScramblingCode': cell.psc, 'signalStrength': -110 + i, } report['cellTowers'].append(cell_data) wifis = WifiFactory.build_batch(2, lat=cell.lat, lon=cell.lon) for wifi in wifis: wifi_data = { 'macAddress': wifi.key, 'signalStrength': -90 + i, } report['wifiAccessPoints'].append(wifi_data) reports.append(report) queue_reports.delay(reports=reports, api_key=api_key, email=email).get() return reports
def test_fallback_used_when_geoip_also_present(self): cells = CellFactory.build_batch(2, radio=Radio.wcdma) wifis = WifiFactory.build_batch(3) api_key = ApiKey.getkey(self.session, 'test') api_key.allow_fallback = True self.session.flush() with requests_mock.Mocker() as mock: response_location = { 'location': { 'lat': 1.0, 'lng': 1.0, }, 'accuracy': 100, } mock.register_uri( 'POST', requests_mock.ANY, json=response_location) query = self.model_query(cells=cells, wifis=wifis) res = self._call(body=query, ip=self.test_ip) send_json = mock.request_history[0].json() self.assertEqual(len(send_json['cellTowers']), 2) self.assertEqual(len(send_json['wifiAccessPoints']), 3) self.check_model_response(res, None, lat=1.0, lon=1.0, accuracy=100) self.check_stats( timer=[self.metric_url], counter=[self.metric + '.api_key.test', self.metric + '.fallback_hit', self.metric_url + '.200', self.metric + '.api_log.test.fallback_hit'], )
def test_wifi_not_found(self): wifis = WifiFactory.build_batch(2) res = self.app.post_json( '%s?key=test' % self.url, { "wifiAccessPoints": [ {"macAddress": wifis[0].key}, {"macAddress": wifis[1].key}, ]}, status=404) self.assertEqual(res.content_type, 'application/json') self.assertEqual( res.json, {"error": { "errors": [{ "domain": "geolocation", "reason": "notFound", "message": "Not found", }], "code": 404, "message": "Not found" }} ) # Make sure to get two counters, a timer, and no traceback self.check_stats( counter=[self.metric + '.api_key.test', self.metric + '.api_log.test.wifi_miss', self.metric_url + '.404'], timer=[self.metric_url]) self.check_raven(total=0)
def test_should_not_provide_location_if_non_geoip_location_found(self): wifis = WifiFactory.build_batch(2) internal_pos = Position( source=DataSource.Internal, lat=1.0, lon=1.0, accuracy=1.0) query = self.model_query(wifis=wifis) self.check_should_locate(query, False, location=internal_pos)
def test_database_error(self): london = self.geoip_data['London'] self.session.execute(text('drop table wifi;')) self.session.execute(text('drop table cell;')) cell = CellFactory.build() wifis = WifiFactory.build_batch(2) res = self.app.post_json( '/v1/geolocate?key=test', { 'cellTowers': [{ 'radioType': cell.radio.name, 'mobileCountryCode': cell.mcc, 'mobileNetworkCode': cell.mnc, 'locationAreaCode': cell.lac, 'cellId': cell.cid}, ], 'wifiAccessPoints': [ {'macAddress': wifis[0].key}, {'macAddress': wifis[1].key}, ]}, extra_environ={'HTTP_X_FORWARDED_FOR': london['ip']}, status=200) self.assertEqual(res.content_type, 'application/json') self.assertEqual(res.json, {'location': {'lat': london['latitude'], 'lng': london['longitude']}, 'accuracy': london['accuracy']}) self.check_stats( timer=['request.v1.geolocate'], counter=[ 'request.v1.geolocate.200', 'geolocate.geoip_hit', ]) self.check_raven([('ProgrammingError', 2)])
def test_wifi_not_found(self): wifis = WifiFactory.build_batch(2) res = self.app.post_json( '%s?key=test' % self.url, { 'wifiAccessPoints': [ {'macAddress': wifis[0].key}, {'macAddress': wifis[1].key}, ]}, status=404) self.assertEqual(res.content_type, 'application/json') self.assertEqual( res.json, {'error': { 'errors': [{ 'domain': 'geolocation', 'reason': 'notFound', 'message': 'Not found', }], 'code': 404, 'message': 'Not found' }} ) # Make sure to get two counters, a timer, and no traceback self.check_stats( counter=[self.metric + '.api_key.test', self.metric + '.api_log.test.wifi_miss', self.metric_url + '.404'], timer=[self.metric_url])
def add_reports(self, number=3, api_key='test', email=None): reports = [] for i in range(number): report = { 'timestamp': time.time() * 1000.0, 'position': {}, 'cellTowers': [], 'wifiAccessPoints': [], } cell = CellFactory.build() report['position']['latitude'] = cell.lat report['position']['longitude'] = cell.lon report['position']['accuracy'] = 17 + i cell_data = { 'radioType': cell.radio.name, 'mobileCountryCode': cell.mcc, 'mobileNetworkCode': cell.mnc, 'locationAreaCode': cell.lac, 'cellId': cell.cid, 'primaryScramblingCode': cell.psc, 'signalStrength': -110 + i, } report['cellTowers'].append(cell_data) wifis = WifiFactory.build_batch(2, lat=cell.lat, lon=cell.lon) for wifi in wifis: wifi_data = { 'macAddress': wifi.key, 'signalStrength': -90 + i, } report['wifiAccessPoints'].append(wifi_data) reports.append(report) queue_reports.delay( reports=reports, api_key=api_key, email=email).get() return reports
def setUp(self): super(TestFallbackProvider, self).setUp() self.provider.api_key.allow_fallback = True self.response_location = { 'location': { 'lat': 51.5366, 'lng': 0.03989, }, 'accuracy': 1500, 'fallback': 'lacf', } self.cells = [] for cell in CellFactory.build_batch(2): self.cells.append({ 'radio': cell.radio, 'mcc': cell.mcc, 'mnc': cell.mnc, 'lac': cell.lac, 'cid': cell.cid, 'signal': -70, }) self.cells[0]['ta'] = 1 self.wifis = [] for wifi in WifiFactory.build_batch(2): self.wifis.append({ 'key': wifi.key, 'signal': -77, }) self.wifis[0]['channel'] = 6 self.wifis[0]['frequency'] = 2437 self.wifis[0]['snr'] = 13
def test_geoip_fallback(self): london = self.geoip_data['London'] wifis = WifiFactory.build_batch(4) res = self.app.post_json( '%s?key=test' % self.url, { "wifiAccessPoints": [ { "macAddress": wifis[0].key }, { "macAddress": wifis[1].key }, { "macAddress": wifis[2].key }, { "macAddress": wifis[3].key }, ] }, extra_environ={'HTTP_X_FORWARDED_FOR': london['ip']}, status=200) self.assertEqual(res.content_type, 'application/json') self.assertEqual( res.json, { "location": { "lat": london['latitude'], "lng": london['longitude'] }, "accuracy": london['accuracy'] })
def test_should_provide_location_if_only_geoip_location_found(self): london = self.london_model wifis = WifiFactory.build_batch(2) geoip_pos = Position( source=DataSource.GeoIP, lat=london.lat, lon=london.lon, accuracy=london.range) query = self.model_query(wifis=wifis, geoip=london.ip) self.check_should_locate(query, True, location=geoip_pos)
def test_wifi(self): wifis = WifiFactory.build_batch(2) query = self.model_query(wifis=wifis) res = self._call( body=query, ip='127.0.0.1', status=404) self.check_response(res, 'not_found') self.check_db_calls(rw=0, ro=0) self.check_stats( counter=[self.metric + '.miss'])
def test_batches(self): batch = 110 wifis = WifiFactory.build_batch(batch) items = [{'lat': wifi.lat, 'lon': wifi.lon, 'wifi': [{'key': wifi.key}]} for wifi in wifis] # add a bad one, this will just be skipped items.append({'lat': 10.0, 'lon': 10.0, 'whatever': 'xx'}) self._post(items) self._assert_queue_size(batch)
def test_wifi_not_found(self): wifis = WifiFactory.build_batch(2) query = self.model_query(wifis=wifis) res = self._call(body=query, status=self.not_found.code) self.check_response(res, 'not_found') self.check_stats( counter=[self.metric + '.api_key.test', self.metric + '.api_log.test.wifi_miss', self.metric_url + '.' + str(self.not_found.code)], timer=[self.metric_url])
def test_database_error(self): london = self.geoip_data['London'] session = self.session stmt = text("drop table wifi;") session.execute(stmt) stmt = text("drop table cell;") session.execute(stmt) cell = CellFactory.build() wifis = WifiFactory.build_batch(2) res = self.app.post_json( '/v1/geolocate?key=test', { "cellTowers": [ { "radioType": cell.radio.name, "mobileCountryCode": cell.mcc, "mobileNetworkCode": cell.mnc, "locationAreaCode": cell.lac, "cellId": cell.cid }, ], "wifiAccessPoints": [ { "macAddress": wifis[0].key }, { "macAddress": wifis[1].key }, ] }, extra_environ={'HTTP_X_FORWARDED_FOR': london['ip']}, status=200) self.assertEqual(res.content_type, 'application/json') self.assertEqual( res.json, { "location": { "lat": london['latitude'], "lng": london['longitude'] }, "accuracy": london['accuracy'] }) self.check_stats(timer=['request.v1.geolocate'], counter=[ 'request.v1.geolocate.200', 'geolocate.geoip_hit', ]) self.check_raven([('ProgrammingError', 2)])
def test_batches(self): batch = 110 wifis = WifiFactory.build_batch(batch) items = [{ 'position': { 'latitude': wifi.lat, 'longitude': wifi.lon}, 'wifiAccessPoints': [ {'macAddress': wifi.key}, ]} for wifi in wifis] # add a bad one, this will just be skipped items.append({'latitude': 10.0, 'longitude': 10.0, 'whatever': 'xx'}) self._post(items) self._assert_queue_size(batch)
def test_geoip_fallback(self): london = self.geoip_data['London'] wifis = WifiFactory.build_batch(4) res = self.app.post_json( '%s?key=test' % self.url, {"wifiAccessPoints": [ {"macAddress": wifis[0].key}, {"macAddress": wifis[1].key}, {"macAddress": wifis[2].key}, {"macAddress": wifis[3].key}, ]}, extra_environ={'HTTP_X_FORWARDED_FOR': london['ip']}, status=200) self.assertEqual(res.content_type, 'application/json') self.assertEqual(res.json, {"location": {"lat": london['latitude'], "lng": london['longitude']}, "accuracy": london['accuracy']})
def test_wifi_not_found(self): wifis = WifiFactory.build_batch(2) res = self.app.post_json( '%s?key=test' % self.url, { 'wifiAccessPoints': [ {'macAddress': wifis[0].key}, {'macAddress': wifis[1].key}, ]}, status=404) self.assertEqual(res.content_type, 'application/json') self.assertEqual(res.json, LocationNotFound.json_body()) # Make sure to get two counters, a timer, and no traceback self.check_stats( counter=[self.metric + '.api_key.test', self.metric + '.api_log.test.wifi_miss', (self.metric_url + '.404', 1)], timer=[self.metric_url])
def test_wifi(self): wifis = WifiFactory.build_batch(2) wifi_query = [] wifi_keys = [] for wifi in wifis: wifi_keys.append(wifi.key) wifi_query.append({ 'key': wifi.key, 'signal': -85, 'channel': 11, }) query = Query(wifi=wifi_query) self.assertEqual(len(query.wifi), 2) for wifi in query.wifi: self.assertEqual(wifi['signal'], -85) self.assertEqual(wifi['channel'], 11) self.assertTrue(wifi['key'] in wifi_keys)
def test_dont_cache_when_wifi_keys_present(self): cell = CellFactory.build() wifis = WifiFactory.build_batch(2) mock_redis_client = self._mock_redis_client() mock_redis_client.get.return_value = json.dumps(self.fallback_location) with requests_mock.Mocker() as mock_request: mock_request.register_uri( 'POST', requests_mock.ANY, json=self.fallback_location) with mock.patch.object(self.provider, 'redis_client', mock_redis_client): query = self.model_query(cells=[cell], wifis=wifis) location = self.provider.locate(query) self.check_model_location(location, self.fallback_model) self.assertFalse(mock_redis_client.get.called) self.assertFalse(mock_redis_client.set.called)
def test_database_error(self, db_errors=0): for tablename in ('wifi', 'cell', 'cell_area', 'ocid_cell', 'ocid_cell_area'): self.session.execute(text('drop table %s;' % tablename)) cells = CellFactory.build_batch(2) wifis = WifiFactory.build_batch(2) query = self.model_query(cells=cells, wifis=wifis) res = self._call(body=query, ip=self.test_ip) self.check_response(res, 'ok') self.check_stats( timer=[self.metric_url], counter=[ self.metric_url + '.200', self.metric + '.geoip_hit', ], ) self.check_raven([('ProgrammingError', db_errors)])
def test_wifi_not_found(self): wifis = WifiFactory.build_batch(2) res = self.app.post_json('%s?key=test' % self.url, { "wifiAccessPoints": [ { "macAddress": wifis[0].key }, { "macAddress": wifis[1].key }, ] }, status=404) self.assertEqual(res.content_type, 'application/json') self.assertEqual( res.json, { "error": { "errors": [{ "domain": "geolocation", "reason": "notFound", "message": "Not found", }], "code": 404, "message": "Not found" } }) # Make sure to get two counters, a timer, and no traceback self.check_stats(counter=[ self.metric + '.api_key.test', self.metric + '.api_log.test.wifi_miss', self.metric_url + '.404' ], timer=[self.metric_url]) self.check_raven(total=0)
def test_should_provide_location_if_only_empty_location_found(self): wifis = WifiFactory.build_batch(2) query = self.model_query(wifis=wifis) self.check_should_locate(query, True)