def add_line_of_cells_and_scan_lac(self): from ichnaea.tasks import cell_location_update, scan_lacs session = self.db_master_session big = 10000000 small = big / 10 keys = dict(radio=1, mcc=1, mnc=1, lac=1) measures = [ CellMeasure(lat=ctr + xd, lon=ctr + yd, cid=cell, **keys) for cell in range(0, 10) for ctr in [cell * big] for (xd, yd) in [(small, small), (small, -small), (-small, small), (-small, -small)] ] session.add_all(measures) cells = [ Cell(lat=ctr, lon=ctr, cid=cell, new_measures=4, total_measures=1, **keys) for cell in range(0, 10) for ctr in [cell * big] ] session.add_all(cells) session.commit() result = cell_location_update.delay(min_new=0, max_new=9999, batch=len(measures)) self.assertEqual(result.get(), (len(cells), 0)) scan_lacs.delay()
def add_line_of_cells_and_scan_lac(self): from ichnaea.tasks import cell_location_update, scan_lacs session = self.db_master_session big = 1.0 small = big / 10 keys = dict(radio=1, mcc=1, mnc=1, lac=1) measures = [ CellMeasure(lat=ctr + xd, lon=ctr + yd, cid=cell, **keys) for cell in range(10) for ctr in [cell * big] for (xd, yd) in [(small, small), (small, -small), (-small, small), (-small, -small)] ] session.add_all(measures) cells = [ Cell(lat=ctr, lon=ctr, cid=cell, new_measures=4, total_measures=1, **keys) for cell in range(10) for ctr in [cell * big] ] session.add_all(cells) session.commit() result = cell_location_update.delay(min_new=0, max_new=9999, batch=len(measures)) self.assertEqual(result.get(), (len(cells), 0)) scan_lacs.delay()
def test_cell_removal_updates_lac(self): from ichnaea.tasks import remove_cell, scan_lacs session = self.db_master_session keys = dict(radio=1, mcc=1, mnc=1, lac=1) # setup: build LAC as above self.add_line_of_cells_and_scan_lac() # confirm we got one lac = session.query(Cell).filter( Cell.lac == 1, Cell.cid == CELLID_LAC).first() self.assertEqual(lac.lat, 4.5) self.assertEqual(lac.lon, 4.5) self.assertEqual(lac.range, 723001) # Remove cells one by one checking that the LAC # changes shape along the way. steps = [ ((5.0, 5.0), 644242), ((5.5, 5.5), 565475), ((6.0, 6.0), 486721), ((6.5, 6.5), 408000), ((7.0, 7.0), 329334), ((7.5, 7.5), 250743), ((8.0, 8.0), 172249), ((8.5, 8.5), 93871), ((9.0, 9.0), 15630), ] for i in range(9): session.expire(lac) k = CellKey(cid=i, **keys) result = remove_cell.delay([k]) self.assertEqual(1, result.get()) result = scan_lacs.delay() self.assertEqual(1, result.get()) lac = session.query(Cell).filter( Cell.lac == 1, Cell.cid == CELLID_LAC).first() self.assertEqual(lac.lat, steps[i][0][0]) self.assertEqual(lac.lon, steps[i][0][1]) self.assertEqual(lac.range, steps[i][1]) # Remove final cell, check LAC is gone k = CellKey(cid=9, **keys) result = remove_cell.delay([k]) self.assertEqual(1, result.get()) result = scan_lacs.delay() self.assertEqual(0, result.get()) lac = session.query(Cell).filter( Cell.lac == 1, Cell.cid == CELLID_LAC).first() self.assertEqual(lac, None)
def test_cell_removal_updates_lac(self): from ichnaea.tasks import remove_cell, scan_lacs session = self.db_master_session keys = dict(radio=1, mcc=1, mnc=1, lac=1) # setup: build LAC as above self.add_line_of_cells_and_scan_lac() # confirm we got one lac = session.query(Cell).filter(Cell.lac == 1, Cell.cid == CELLID_LAC).first() self.assertEqual(lac.lat, 45000000) self.assertEqual(lac.lon, 45000000) self.assertEqual(lac.range, 723001) # Remove cells one by one checking that the LAC # changes shape along the way. steps = [ ((50000000, 50000000), 644242), ((55000000, 55000000), 565475), ((60000000, 60000000), 486721), ((65000000, 65000000), 408000), ((70000000, 70000000), 329334), ((75000000, 75000000), 250743), ((80000000, 80000000), 172249), ((85000000, 85000000), 93871), ((90000000, 90000000), 15630), ] for i in range(0, 9): session.expire(lac) k = CellKey(cid=i, **keys) result = remove_cell.delay([k]) self.assertEqual(1, result.get()) result = scan_lacs.delay() self.assertEqual(1, result.get()) lac = session.query(Cell).filter(Cell.lac == 1, Cell.cid == CELLID_LAC).first() self.assertEqual(lac.lat, steps[i][0][0]) self.assertEqual(lac.lon, steps[i][0][1]) self.assertEqual(lac.range, steps[i][1]) # Remove final cell, check LAC is gone k = CellKey(cid=9, **keys) result = remove_cell.delay([k]) self.assertEqual(1, result.get()) result = scan_lacs.delay() self.assertEqual(0, result.get()) lac = session.query(Cell).filter(Cell.lac == 1, Cell.cid == CELLID_LAC).first() self.assertEqual(lac, None)
def test_cell_lac_asymmetric(self): from ichnaea.tasks import cell_location_update, scan_lacs session = self.db_master_session big = 1000000 small = big / 10 keys = dict(radio=1, mcc=1, mnc=1, lac=1) measures = [ CellMeasure(lat=ctr + xd, lon=ctr + yd, cid=cell, **keys) for cell in range(0, 6) for ctr in [(2**cell) * big] for (xd, yd) in [(small, small), (small, -small), (-small, small), (-small, -small)] ] session.add_all(measures) cells = [ Cell(lat=ctr, lon=ctr, cid=cell, new_measures=4, total_measures=1, **keys) for cell in range(0, 6) for ctr in [(2**cell) * big] ] session.add_all(cells) session.commit() result = cell_location_update.delay(min_new=0, max_new=9999, batch=len(measures)) self.assertEqual(result.get(), (len(cells), 0)) scan_lacs.delay() lac = session.query(Cell).filter(Cell.lac == 1, Cell.cid == CELLID_LAC).first() # We produced a sequence of 0.02-degree-on-a-side # cell bounding boxes centered at # [0, 0.2, 0.4, 0.8, 1.6, 3.2] degrees. # So the lower-left corner is at (-0.01, -0.01) # and the upper-right corner is at (3.21, 3.21) # we should therefore see a LAC centroid at (1.05, 1.05) # with a range of 339.540m self.assertEqual(lac.lat, 10500000) self.assertEqual(lac.lon, 10500000) self.assertEqual(lac.range, 339540)
def test_cell_lac_asymmetric(self): from ichnaea.tasks import cell_location_update, scan_lacs session = self.db_master_session big = 0.1 small = big / 10 keys = dict(radio=1, mcc=1, mnc=1, lac=1) measures = [ CellMeasure(lat=ctr + xd, lon=ctr + yd, cid=cell, **keys) for cell in range(6) for ctr in [(2 ** cell) * big] for (xd, yd) in [(small, small), (small, -small), (-small, small), (-small, -small)] ] session.add_all(measures) cells = [ Cell(lat=ctr, lon=ctr, cid=cell, new_measures=4, total_measures=1, **keys) for cell in range(6) for ctr in [(2 ** cell) * big] ] session.add_all(cells) session.commit() result = cell_location_update.delay(min_new=0, max_new=9999, batch=len(measures)) self.assertEqual(result.get(), (len(cells), 0)) scan_lacs.delay() lac = session.query(Cell).filter( Cell.lac == 1, Cell.cid == CELLID_LAC).first() # We produced a sequence of 0.02-degree-on-a-side # cell bounding boxes centered at # [0, 0.2, 0.4, 0.8, 1.6, 3.2] degrees. # So the lower-left corner is at (-0.01, -0.01) # and the upper-right corner is at (3.21, 3.21) # we should therefore see a LAC centroid at (1.05, 1.05) # with a range of 339.540m self.assertEqual(lac.lat, 1.05) self.assertEqual(lac.lon, 1.05) self.assertEqual(lac.range, 339540)
def test_scan_lacs_race_with_cell_location_update(self): from ichnaea.tasks import cell_location_update, scan_lacs session = self.db_master_session # First batch of cell measurements for CID 1 keys = dict(radio=1, mcc=1, mnc=1, lac=1, cid=1) cell = Cell(new_measures=4, total_measures=1, **keys) measures = [ CellMeasure(lat=1.0, lon=1.0, **keys), CellMeasure(lat=1.0, lon=1.0, **keys), CellMeasure(lat=1.0, lon=1.0, **keys), CellMeasure(lat=1.0, lon=1.0, **keys), ] session.add(cell) session.add_all(measures) session.commit() # Periodic cell_location_update runs and updates CID 1 # to have a location, inserts LAC 1 with new_measures=1 # which will be picked up by the next scan_lac. result = cell_location_update.delay(min_new=1) self.assertEqual(result.get(), (1, 0)) # Second batch of cell measurements for CID 2 keys['cid'] = 2 cell = Cell(new_measures=4, total_measures=1, **keys) measures = [ CellMeasure(lat=1.0, lon=1.0, **keys), CellMeasure(lat=1.0, lon=1.0, **keys), CellMeasure(lat=1.0, lon=1.0, **keys), CellMeasure(lat=1.0, lon=1.0, **keys), ] session.add(cell) session.add_all(measures) session.commit() # Periodic LAC scan runs, picking up LAC 1; this could # accidentally pick up CID 2, but it should not since it # has not had its location updated yet. If there's no # exception here, CID 2 is properly ignored. scan_lacs.delay()