def test_cancellation_then_delay_in_2_updates(navitia_vj): """ same as test_cancellation_then_delay, but with a clear db and in 2 updates """ with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='delete') trip_update.stop_time_updates = [] real_time_update = RealTimeUpdate(raw_data=None, connector='ire', contributor='realtime.ire') handle(real_time_update, [trip_update], 'kisio-digital') trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') real_time_update = RealTimeUpdate(raw_data=None, connector='ire', contributor='realtime.ire') trip_update.stop_time_updates = [ StopTimeUpdate({'id': 'sa:3'}, arrival_delay=timedelta(minutes=40), arr_status='update', order=2), ] res, _ = handle(real_time_update, [trip_update], 'kisio-digital') _check_cancellation_then_delay(res)
def test_cancellation_then_delay(navitia_vj): """ we have a cancelled vj in the db, and we receive an update on the 3rd stoptime, at the end we have a delayed vj sa:1 sa:2 sa:3 VJ navitia 8:10 9:05-9:10 10:05 VJ in db - update kirin 8:10 9:05-9:10 10:45* """ with app.app_context(): vju = create_trip_update('70866ce8-0638-4fa1-8556-1ddfa22d09d3', 'vehicle_journey:1', datetime.date(2015, 9, 8), [], status='delete') rtu = RealTimeUpdate(None, 'ire') rtu.id = '10866ce8-0638-4fa1-8556-1ddfa22d09d3' rtu.trip_updates.append(vju) db.session.add(rtu) db.session.commit() with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') real_time_update = RealTimeUpdate(raw_data=None, connector='ire') trip_update.stop_time_updates = [ StopTimeUpdate({'id': 'sa:3'}, arrival_delay=timedelta(minutes=40), arr_status='update'), ] res = handle(real_time_update, [trip_update], 'kisio-digital') _check_cancellation_then_delay(res)
def setup_database(): """ we create two realtime_updates with the same vj but for different date and return a vj for navitia """ with app.app_context(): vju = create_trip_update('70866ce8-0638-4fa1-8556-1ddfa22d09d3', 'vehicle_journey:1', datetime.date(2015, 9, 8), [ {'id': 'sa:1', 'departure': _dt("8:15"), 'arrival': None, 'departure_status': 'update', 'arrival_status': 'none'}, {'id': 'sa:2', 'departure': _dt("9:10"), 'arrival': _dt("9:05"), 'departure_status': 'none', 'arrival_status': 'none'}, {'id': 'sa:3', 'departure': None, 'arrival': _dt("10:05"), 'departure_status': 'none', 'arrival_status': 'none'}, ]) rtu = RealTimeUpdate(None, 'ire') rtu.id = '10866ce8-0638-4fa1-8556-1ddfa22d09d3' rtu.trip_updates.append(vju) db.session.add(rtu) vju = create_trip_update('70866ce8-0638-4fa1-8556-1ddfa22d09d4', 'vehicle_journey:1', datetime.date(2015, 9, 7), [ {'id': 'sa:1', 'departure': _dt("8:35", day=7), 'arrival': None, 'departure_status': 'update', 'arrival_status': 'none'}, {'id': 'sa:2', 'departure': _dt("9:40", day=7), 'arrival': _dt("9:35", day=7), 'departure_status': 'update', 'arrival_status': 'update'}, {'id': 'sa:3', 'departure': None, 'arrival': _dt("10:35", day=7), 'departure_status': 'none', 'arrival_status': 'update'}, ]) rtu = RealTimeUpdate(None, 'ire') rtu.id = '20866ce8-0638-4fa1-8556-1ddfa22d09d3' rtu.trip_updates.append(vju) db.session.add(rtu) db.session.commit()
def create_real_time_update(id, contributor, connector, vj_id, trip_id, circulation_date): rtu = RealTimeUpdate('', connector) rtu.id = id trip_update = create_trip_update(vj_id, trip_id, circulation_date) trip_update.contributor = contributor rtu.trip_updates.append(trip_update)
def purge_rt_update(self, config): func_name = "purge_rt_update" connector = config["connector"] logger = logging.LoggerAdapter(logging.getLogger(__name__), extra={"connector": connector}) logger.debug("purge realtime update for %s", connector) lock_name = make_kirin_lock_name(func_name, connector) with get_lock(logger, lock_name, app.config[str("REDIS_LOCK_TIMEOUT_PURGE")]) as locked: if not locked: logger.warning("%s for %s is already in progress", func_name, connector) return until = datetime.date.today() - datetime.timedelta( days=int(config["nb_days_to_keep"])) logger.info("purge realtime update for {} until {}".format( connector, until)) # TODO: we want to purge on "contributor" later, not "connector". RealTimeUpdate.remove_by_connectors_until(connectors=[connector], until=until) logger.info("%s for %s is finished", func_name, connector)
def test_delays_then_cancellation_in_2_updates(navitia_vj): """ Same test as above, but with nothing in the db, and with 2 updates """ with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') real_time_update = RealTimeUpdate(raw_data=None, connector='ire') trip_update.stop_time_updates = [ StopTimeUpdate({'id': 'sa:1'}, departure_delay=timedelta(minutes=5), dep_status='update'), ] handle(real_time_update, [trip_update], 'kisio-digital') trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='delete') real_time_update = RealTimeUpdate(raw_data=None, connector='ire') res = handle(real_time_update, [trip_update], 'kisio-digital') assert len(res.trip_updates) == 1 trip_update = res.trip_updates[0] assert trip_update.status == 'delete' assert len(trip_update.stop_time_updates) == 0 assert len(trip_update.real_time_updates) == 2
def test_gtfs_model_builder(basic_gtfs_rt_data): """ test the model builder with a simple gtfs-rt we have realtime data on only 2 stops, so the model builder should only have 2 stops (even if the VJ have 4 stops) """ with app.app_context(): data = '' rt_update = RealTimeUpdate(data, connector='gtfs-rt') trip_updates = gtfs_rt.KirinModelBuilder(dumb_nav_wrapper()).build(rt_update, basic_gtfs_rt_data) # we associate the trip_update manually for sqlalchemy to make the links rt_update.trip_updates = trip_updates db.session.add(rt_update) db.session.commit() assert len(trip_updates) == 1 assert len(trip_updates[0].stop_time_updates) == 2 second_stop = trip_updates[0].stop_time_updates[0] assert second_stop.stop_id == 'StopR2' assert second_stop.arrival_status == 'update' assert second_stop.arrival_delay == timedelta(minutes=1) assert second_stop.departure_delay is None assert second_stop.departure_status == 'none' assert second_stop.message is None fourth_stop = trip_updates[0].stop_time_updates[1] assert fourth_stop.stop_id == 'StopR4' assert fourth_stop.arrival_status == 'update' assert fourth_stop.arrival_delay == timedelta(minutes=3) assert fourth_stop.departure_delay is None assert fourth_stop.departure_status == 'none' assert fourth_stop.message is None
def purge_rt(nb_day_to_keep, connector): """ purge table real_time_update and associate_realtimeupdate_tripupdate for given connector with nb_day_to_keep of history """ logger = logging.getLogger(__name__) until = datetime.date.today() - datetime.timedelta(days=int(nb_day_to_keep)) logger.info("purge table real_time_update for %s until %s", connector, until) RealTimeUpdate.remove_by_connectors_until(connectors=[connector], until=until) db.session.commit()
def set_rtu_status_ko(rtu: RealTimeUpdate, error: str, is_reprocess_same_data_allowed: bool) -> None: """ Set RealTimeUpdate's status to KO, handling all in one except commit and logs :param rtu: RealTimeUpdate object to amend :param error: error message to associate to RTU :param is_reprocess_same_data_allowed: If the same input is provided next time, should we reprocess it (hoping a happier ending) """ if is_reprocess_same_data_allowed: allow_reprocess_same_data(rtu.contributor_id) rtu.status = "KO" rtu.error = error
def test_handle_new_trip_out_of_order(navitia_vj): """ We have one vj with only one stop time updated, but it's not the first so we have to reorder the stop times in the resulting trip_update """ with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') st = StopTimeUpdate({'id': 'sa:2'}, departure_delay=timedelta(minutes=40), dep_status='update', arrival_delay=timedelta(minutes=44), arr_status='update') real_time_update = RealTimeUpdate(raw_data=None, connector='ire') trip_update.stop_time_updates.append(st) res = handle(real_time_update, [trip_update], 'kisio-digital') assert len(res.trip_updates) == 1 trip_update = res.trip_updates[0] assert len(trip_update.stop_time_updates) == 3 assert trip_update.stop_time_updates[0].stop_id == 'sa:1' assert trip_update.stop_time_updates[0].departure == _dt("8:10") assert trip_update.stop_time_updates[0].arrival == _dt("8:10") assert trip_update.stop_time_updates[1].stop_id == 'sa:2' assert trip_update.stop_time_updates[1].departure == _dt("9:50") assert trip_update.stop_time_updates[1].arrival == _dt("9:49") assert trip_update.stop_time_updates[2].stop_id == 'sa:3' assert trip_update.stop_time_updates[2].departure == _dt("10:05") assert trip_update.stop_time_updates[2].arrival == _dt("10:05")
def _delete_real_time_update_rows(contributor: Contributor) -> Dict: with new_relic.agent.FunctionTrace( "{}:_delete_real_time_update_rows".format(contributor.id)): until = datetime.date.today() - datetime.timedelta( days=int(contributor.nb_days_to_keep_rt_update)) return RealTimeUpdate.remove_by_contributors_until( contributors=[contributor.id], until=until)
def poke_updated_at(rtu: RealTimeUpdate) -> None: """ just update the updated_at of the RealTimeUpdate object provided """ if rtu: rtu.updated_at = datetime.utcnow() # just to poke updated_at model.db.session.commit()
def test_manage_consistency(navitia_vj): """ we receive an update for a vj already in the database sa:1 sa:2 sa:3 VJ navitia 08:10 09:05-09:10 10:05 update kirin - *10:15-09:20* - expected result 08:10-08:10 10:15-10:15 11:10-11:10 """ with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') st = StopTimeUpdate({'id': 'sa:2'}, arrival_delay=timedelta(minutes=70), dep_status='update', departure_delay=timedelta(minutes=10), arr_status='update', order=1) st.arrival_status = st.departure_status = 'update' real_time_update = RealTimeUpdate(raw_data=None, connector='ire', contributor='realtime.ire') real_time_update.id = '30866ce8-0638-4fa1-8556-1ddfa22d09d3' trip_update.stop_time_updates.append(st) res, _ = handle(real_time_update, [trip_update], 'kisio-digital') assert len(res.trip_updates) == 1 trip_update = res.trip_updates[0] assert trip_update.status == 'update' assert len(trip_update.real_time_updates) == 1 assert len(trip_update.stop_time_updates) == 3 stu_map = {stu.stop_id: stu for stu in trip_update.stop_time_updates} assert 'sa:1' in stu_map assert stu_map['sa:1'].arrival == _dt("8:10") assert stu_map['sa:1'].departure == _dt("8:10") assert 'sa:2' in stu_map assert stu_map['sa:2'].arrival == _dt("10:15") assert stu_map['sa:2'].departure == _dt("10:15") assert 'sa:3' in stu_map assert stu_map['sa:3'].arrival == _dt("11:10") assert stu_map['sa:3'].departure == _dt("11:10")
def test_populate_pb_with_full_dataset(): """ VJ cancelation """ navitia_vj = { 'trip': { 'id': 'vehicle_journey:1' }, 'stop_times': [{ 'arrival_time': datetime.time(8, 10), 'stop_point': { 'stop_area': { 'timezone': 'UTC' } } }] } with app.app_context(): trip_update = TripUpdate() vj = VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)) trip_update.vj = vj trip_update.status = 'delete' trip_update.message = 'Message Test' real_time_update = RealTimeUpdate(raw_data=None, connector='ire', contributor='realtime.ire') trip_update.contributor = 'kisio-digital' trip_update.company_id = 'keolis' trip_update.effect = 'DETOUR' real_time_update.trip_updates.append(trip_update) db.session.add(real_time_update) db.session.commit() feed_entity = convert_to_gtfsrt( real_time_update.trip_updates, gtfs_realtime_pb2.FeedHeader.FULL_DATASET) assert feed_entity.header.incrementality == gtfs_realtime_pb2.FeedHeader.FULL_DATASET assert feed_entity.header.gtfs_realtime_version == '1' pb_trip_update = feed_entity.entity[0].trip_update assert pb_trip_update.trip.trip_id == 'vehicle_journey:1' assert pb_trip_update.trip.start_date == '20150908' assert pb_trip_update.HasExtension(kirin_pb2.trip_message) == True assert pb_trip_update.Extensions[ kirin_pb2.trip_message] == 'Message Test' assert pb_trip_update.trip.schedule_relationship == gtfs_realtime_pb2.TripDescriptor.CANCELED assert pb_trip_update.trip.HasExtension(kirin_pb2.contributor) == True assert pb_trip_update.trip.Extensions[ kirin_pb2.contributor] == 'kisio-digital' assert pb_trip_update.trip.Extensions[kirin_pb2.company_id] == 'keolis' assert pb_trip_update.Extensions[ kirin_pb2.effect] == gtfs_realtime_pb2.Alert.DETOUR assert len(feed_entity.entity[0].trip_update.stop_time_update) == 0
def test_handle_basic(): with pytest.raises(TypeError): handle(None) #a RealTimeUpdate without any TripUpdate doesn't do anything with app.app_context(): real_time_update = RealTimeUpdate(raw_data=None, connector='ire') res = handle(real_time_update, [], 'kisio-digital') assert res == real_time_update
def test_populate_pb_with_cancelation(): """ VJ cancelation """ navitia_vj = { 'trip': { 'id': 'vehicle_journey:1' }, 'stop_times': [{ 'utc_arrival_time': datetime.time(8, 10), 'stop_point': { 'stop_area': { 'timezone': 'UTC' } } }] } with app.app_context(): trip_update = TripUpdate() vj = VehicleJourney( navitia_vj, utc.localize(datetime.datetime(2015, 9, 8, 7, 10, 0)), utc.localize(datetime.datetime(2015, 9, 8, 11, 5, 0))) trip_update.vj = vj trip_update.status = 'delete' trip_update.message = 'Message Test' real_time_update = RealTimeUpdate(raw_data=None, connector='cots', contributor='realtime.cots') trip_update.contributor = 'kisio-digital' trip_update.company_id = 'sncf' trip_update.effect = 'REDUCED_SERVICE' real_time_update.trip_updates.append(trip_update) db.session.add(real_time_update) db.session.commit() feed_entity = convert_to_gtfsrt(real_time_update.trip_updates) assert feed_entity.header.incrementality == gtfs_realtime_pb2.FeedHeader.DIFFERENTIAL assert feed_entity.header.gtfs_realtime_version == '1' pb_trip_update = feed_entity.entity[0].trip_update assert pb_trip_update.trip.trip_id == 'vehicle_journey:1' assert pb_trip_update.trip.start_date == '20150908' assert pb_trip_update.HasExtension(kirin_pb2.trip_message) == True assert pb_trip_update.Extensions[ kirin_pb2.trip_message] == 'Message Test' assert pb_trip_update.trip.schedule_relationship == gtfs_realtime_pb2.TripDescriptor.CANCELED assert pb_trip_update.trip.HasExtension(kirin_pb2.contributor) == True assert pb_trip_update.trip.Extensions[ kirin_pb2.contributor] == 'kisio-digital' assert pb_trip_update.trip.Extensions[kirin_pb2.company_id] == 'sncf' assert pb_trip_update.Extensions[ kirin_pb2.effect] == gtfs_realtime_pb2.Alert.REDUCED_SERVICE assert len(feed_entity.entity[0].trip_update.stop_time_update) == 0
def test_populate_pb_with_one_stop_time(): """ an easy one: we have one vj with only one stop time updated fill protobuf from trip_update Verify protobuf """ navitia_vj = { 'trip': { 'id': 'vehicle_journey:1' }, 'stop_times': [{ 'arrival_time': None, 'departure_time': datetime.time(8, 10), 'stop_point': { 'id': 'sa:1' } }, { 'arrival_time': datetime.time(9, 10), 'departure_time': None, 'stop_point': { 'id': 'sa:2' } }] } with app.app_context(): trip_update = TripUpdate() vj = VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)) trip_update.vj = vj st = StopTimeUpdate({'id': 'sa:1'}, departure=_dt("8:15"), arrival=None) real_time_update = RealTimeUpdate(raw_data=None, connector='ire') real_time_update.trip_updates.append(trip_update) trip_update.stop_time_updates.append(st) db.session.add(real_time_update) db.session.commit() feed_entity = convert_to_gtfsrt(real_time_update.trip_updates) assert feed_entity.header.incrementality == gtfs_realtime_pb2.FeedHeader.DIFFERENTIAL assert feed_entity.header.gtfs_realtime_version == '1' pb_trip_update = feed_entity.entity[0].trip_update assert pb_trip_update.trip.trip_id == 'vehicle_journey:1' assert pb_trip_update.trip.start_date == '20150908' assert pb_trip_update.trip.schedule_relationship == gtfs_realtime_pb2.TripDescriptor.SCHEDULED pb_stop_time = feed_entity.entity[0].trip_update.stop_time_update[0] assert pb_stop_time.arrival.time == 0 assert pb_stop_time.departure.time == to_posix_time(_dt("8:15")) assert pb_stop_time.stop_id == 'sa:1' assert pb_trip_update.HasExtension(kirin_pb2.trip_message) == False assert pb_trip_update.trip.HasExtension(kirin_pb2.contributor) == False
def test_multiple_delays_in_2_updates(navitia_vj): """ same test as test_multiple_delays, but with nothing in the db and with 2 trip updates """ with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') real_time_update = RealTimeUpdate(raw_data=None, connector='ire', contributor='realtime.ire') trip_update.stop_time_updates = [ StopTimeUpdate({'id': 'sa:1'}, departure_delay=timedelta(minutes=5), dep_status='update'), ] handle(real_time_update, [trip_update], 'kisio-digital') trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') real_time_update = RealTimeUpdate(raw_data=None, connector='ire', contributor='realtime.ire') trip_update.stop_time_updates = [ StopTimeUpdate({'id': 'sa:1'}, departure_delay=timedelta(minutes=10), dep_status='update'), StopTimeUpdate({'id': 'sa:2'}, arrival_delay=timedelta(minutes=2), arr_status='update'), ] res, _ = handle(real_time_update, [trip_update], 'kisio-digital') _check_multiples_delay(res) # we also check that there is what we want in the db db_trip_updates = res.query.from_self(TripUpdate).all() assert len(db_trip_updates) == 1 assert db_trip_updates[0].status == 'update' assert len(RealTimeUpdate.query.all()) == 2 assert len(StopTimeUpdate.query.all()) == 3
def test_manage_consistency(navitia_vj): """ we receive an update for a vj already in the database sa:1 sa:2 sa:3 VJ navitia 08:10 09:05-09:10 10:05 update kirin - *10:15-09:20* - expected result 08:10-08:10 10:15-10:15 11:10-11:10 """ with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') st = StopTimeUpdate({'id': 'sa:2'}, arrival_delay=timedelta(minutes=70), dep_status='update', departure_delay=timedelta(minutes=10), arr_status='update') st.arrival_status = st.departure_status = 'update' real_time_update = RealTimeUpdate(raw_data=None, connector='ire') real_time_update.id = '30866ce8-0638-4fa1-8556-1ddfa22d09d3' trip_update.stop_time_updates.append(st) res = handle(real_time_update, [trip_update], 'kisio-digital') assert len(res.trip_updates) == 1 trip_update = res.trip_updates[0] assert trip_update.status == 'update' assert len(trip_update.real_time_updates) == 1 assert len(trip_update.stop_time_updates) == 3 stu_map = {stu.stop_id: stu for stu in trip_update.stop_time_updates} assert 'sa:1' in stu_map assert stu_map['sa:1'].arrival == _dt("8:10") assert stu_map['sa:1'].departure == _dt("8:10") assert 'sa:2' in stu_map assert stu_map['sa:2'].arrival == _dt("10:15") assert stu_map['sa:2'].departure == _dt("10:15") assert 'sa:3' in stu_map assert stu_map['sa:3'].arrival == _dt("11:10") assert stu_map['sa:3'].departure == _dt("11:10")
def test_delays_then_cancellation(setup_database, navitia_vj): """ We have a delay on the first st of a vj in the db and we receive a cancellation on this vj, we should have a cancelled vj in the end sa:1 sa:2 sa:3 VJ navitia 8:10 9:05-9:10 10:05 VJ in db 8:15* 9:05-9:10 10:05 update kirin - """ with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='delete') real_time_update = RealTimeUpdate(raw_data=None, connector='ire') res = handle(real_time_update, [trip_update], 'kisio-digital') assert len(res.trip_updates) == 1 trip_update = res.trip_updates[0] assert trip_update.status == 'delete' assert len(trip_update.stop_time_updates) == 0 assert len(trip_update.real_time_updates) == 2
def test_multiple_delays(setup_database, navitia_vj): """ We receive a delay on the first and second stoptimes of a vj, and there was already some delay on the first st of this vj sa:1 sa:2 sa:3 VJ navitia 8:10 9:05-9:10 10:05 VJ in db 8:15* 9:05-9:10 10:05 update kirin 8:20* *9:07-9:10 10:05 """ with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') real_time_update = RealTimeUpdate(raw_data=None, connector='ire', contributor='realtime.ire') trip_update.stop_time_updates = [ # Note: the delay is based of the navitia's vj StopTimeUpdate({'id': 'sa:1'}, departure_delay=timedelta(minutes=10), dep_status='update'), StopTimeUpdate({'id': 'sa:2'}, arrival_delay=timedelta(minutes=2), arr_status='update'), ] res, _ = handle(real_time_update, [trip_update], 'kisio-digital') _check_multiples_delay(res) # we also check that there is what we want in the db db_trip_updates = res.query.from_self(TripUpdate).all() assert len(db_trip_updates) == 2 for tu in db_trip_updates: assert tu.status == 'update' assert len( RealTimeUpdate.query.all()) == 3 # 2 already in db, one new update assert len(StopTimeUpdate.query.all()) == 6 # 3 st * 2 vj in the db
def test_populate_pb_with_cancelation(): """ VJ cancelation """ navitia_vj = {'trip': {'id': 'vehicle_journey:1'}} with app.app_context(): trip_update = TripUpdate() vj = VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)) trip_update.vj = vj trip_update.status = 'delete' trip_update.message = 'Message Test' real_time_update = RealTimeUpdate(raw_data=None, connector='ire') trip_update.contributor = 'kisio-digital' real_time_update.trip_updates.append(trip_update) db.session.add(real_time_update) db.session.commit() feed_entity = convert_to_gtfsrt(real_time_update.trip_updates) assert feed_entity.header.incrementality == gtfs_realtime_pb2.FeedHeader.DIFFERENTIAL assert feed_entity.header.gtfs_realtime_version == '1' pb_trip_update = feed_entity.entity[0].trip_update assert pb_trip_update.trip.trip_id == 'vehicle_journey:1' assert pb_trip_update.trip.start_date == '20150908' assert pb_trip_update.HasExtension(kirin_pb2.trip_message) == True assert pb_trip_update.Extensions[ kirin_pb2.trip_message] == 'Message Test' assert pb_trip_update.trip.schedule_relationship == gtfs_realtime_pb2.TripDescriptor.CANCELED assert pb_trip_update.trip.HasExtension(kirin_pb2.contributor) == True assert pb_trip_update.trip.Extensions[ kirin_pb2.contributor] == 'kisio-digital' assert len(feed_entity.entity[0].trip_update.stop_time_update) == 0
def callback(body, message): task = task_pb2.Task() try: # `body` is of unicode type, but we need str type for # `ParseFromString()` to work. It seems to work. # Maybe kombu estimate that, without any information, # the body should be something as json, and thus a # unicode string. On the c++ side, I didn't manage to # find a way to give a content-type or something like # that. body = str(body) task.ParseFromString(body) except DecodeError as e: log.warn('invalid protobuf: {}'.format(str(e))) return log.info('getting a request: {}'.format(task)) if task.action != task_pb2.LOAD_REALTIME or not task.load_realtime: return feed = convert_to_gtfsrt(RealTimeUpdate.all(task.load_realtime.contributors)) with self._get_producer() as producer: producer.publish(feed.SerializeToString(), routing_key=task.load_realtime.queue_name)
def test_find_activate(): with app.app_context(): create_real_time_update('70866ce8-0638-4fa1-8556-1ddfa22d09d3', 'C1', 'ire', '70866ce8-0638-4fa1-8556-1ddfa22d09d3', 'vj1', datetime.date(2015, 9, 8)) create_real_time_update('70866ce8-0638-4fa1-8556-1ddfa22d09d4', 'C1', 'ire', '70866ce8-0638-4fa1-8556-1ddfa22d09d4', 'vj2', datetime.date(2015, 9, 10)) create_real_time_update('70866ce8-0638-4fa1-8556-1ddfa22d09d5', 'C1', 'ire', '70866ce8-0638-4fa1-8556-1ddfa22d09d5', 'vj3', datetime.date(2015, 9, 12)) create_real_time_update('70866ce8-0638-4fa1-8556-1ddfa22d09d6', 'C2', 'ire', '70866ce8-0638-4fa1-8556-1ddfa22d09d6', 'vj4', datetime.date(2015, 9, 12)) db.session.commit() """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date 20150906 | | | """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 6)) assert len(rtu) == 3 assert rtu[0].id == '70866ce8-0638-4fa1-8556-1ddfa22d09d3' assert rtu[1].id == '70866ce8-0638-4fa1-8556-1ddfa22d09d4' assert rtu[2].id == '70866ce8-0638-4fa1-8556-1ddfa22d09d5' """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date 20150908 | | """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 8)) assert len(rtu) == 3 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date | 20150909 | | """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 9)) assert len(rtu) == 2 assert rtu[0].id == '70866ce8-0638-4fa1-8556-1ddfa22d09d4' assert rtu[1].id == '70866ce8-0638-4fa1-8556-1ddfa22d09d5' """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date | 20150910 | """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 10)) assert len(rtu) == 2 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date | | 20150911 | """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 11)) assert len(rtu) == 1 assert rtu[0].id == '70866ce8-0638-4fa1-8556-1ddfa22d09d5' """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date | | 20150912 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 12)) assert len(rtu) == 1 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date | | | 20150913 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 13)) assert len(rtu) == 0 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |---------| | | | 20150905 20150906 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 05), datetime.date(2015, 9, 06)) assert len(rtu) == 0 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |--------------------| | | 20150905 20150908 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 05), datetime.date(2015, 9, 8)) assert len(rtu) == 1 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |-------------------------| | | 20150905 20150909 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 05), datetime.date(2015, 9, 9)) assert len(rtu) == 1 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |----------------------------------------------------| | 20150905 20150910 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 05), datetime.date(2015, 9, 10)) assert len(rtu) == 2 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |----------------------------------------------------------------| | 20150905 20150911 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 05), datetime.date(2015, 9, 11)) assert len(rtu) == 2 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |----------------------------------------------------------------------------| 20150905 20150912 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 05), datetime.date(2015, 9, 12)) assert len(rtu) == 3 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |--------------------------------------------------------------------------------------| 20150905 20150914 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 05), datetime.date(2015, 9, 14)) assert len(rtu) == 3 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |------------------------------------------------------------------| 20150908 20150914 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 8), datetime.date(2015, 9, 14)) assert len(rtu) == 3 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |----------------------------------------------------------------| 20150909 20150914 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 9), datetime.date(2015, 9, 14)) assert len(rtu) == 2 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |-----------------------------------| 20150910 20150914 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 10), datetime.date(2015, 9, 14)) assert len(rtu) == 2 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |--------------------------------| 20150911 20150914 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 11), datetime.date(2015, 9, 14)) assert len(rtu) == 1 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |-----------| 20150912 20150914 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 12), datetime.date(2015, 9, 14)) assert len(rtu) == 1 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request interval date |---------| 20150913 20150914 """ rtu = RealTimeUpdate.all(['C1'], datetime.date(2015, 9, 13), datetime.date(2015, 9, 14)) assert len(rtu) == 0 rtu = RealTimeUpdate.all(['C2'], datetime.date(2015, 9, 6)) assert len(rtu) == 1 rtu = RealTimeUpdate.all(['C2'], datetime.date(2015, 9, 12)) assert len(rtu) == 1 rtu = RealTimeUpdate.all(['C1', 'C2'], datetime.date(2015, 9, 12)) assert len(rtu) == 2
def test_populate_pb_for_added_trip(): """ For an added trip we don't call navitia to get a vj instead we create and initialize one vj only with 'id' Fill protobuf from trip_update Verify protobuf """ navitia_vj = make_navitia_empty_vj('vehicle_journey:1') with app.app_context(): trip_update = TripUpdate() vj = VehicleJourney( navitia_vj, utc_since_dt=utc.localize(datetime.datetime(2015, 9, 8, 5, 10, 0)), utc_until_dt=utc.localize(datetime.datetime(2015, 9, 8, 8, 10, 0)), vj_start_dt=utc.localize(datetime.datetime(2015, 9, 8, 5, 10, 0))) trip_update.vj = vj trip_update.status = 'add' trip_update.effect = 'ADDITIONAL_SERVICE' trip_update.physical_mode_id = 'physical_mode:LongDistanceTrain' real_time_update = RealTimeUpdate(raw_data=None, connector='cots', contributor='realtime.cots') real_time_update.trip_updates.append(trip_update) st = StopTimeUpdate({'id': 'sa:1'}, departure=_dt("8:15"), departure_delay=timedelta(minutes=5), arrival=None, arr_status='none', dep_status='add') trip_update.stop_time_updates.append(st) st = StopTimeUpdate({'id': 'sa:2'}, departure=_dt("8:21"), departure_delay=timedelta(minutes=-40), arrival=_dt("8:20"), arrival_delay=timedelta(minutes=-40), message="bob's on the track", arr_status='add', dep_status='none') trip_update.stop_time_updates.append(st) db.session.add(real_time_update) db.session.commit() feed_entity = convert_to_gtfsrt(real_time_update.trip_updates) assert feed_entity.header.incrementality == gtfs_realtime_pb2.FeedHeader.DIFFERENTIAL assert feed_entity.header.gtfs_realtime_version, '1' assert len(feed_entity.entity) == 1 pb_trip_update = feed_entity.entity[0].trip_update assert pb_trip_update.trip.trip_id == 'OCE:SN:vehicle_journey:1' assert pb_trip_update.trip.start_date == '20150908' assert pb_trip_update.HasExtension(kirin_pb2.trip_message) is False assert pb_trip_update.trip.HasExtension(kirin_pb2.contributor) is False assert pb_trip_update.trip.HasExtension(kirin_pb2.company_id) is False assert pb_trip_update.HasExtension(kirin_pb2.effect) is True assert pb_trip_update.Extensions[ kirin_pb2.effect] == gtfs_realtime_pb2.Alert.ADDITIONAL_SERVICE assert pb_trip_update.vehicle.Extensions[ kirin_pb2.physical_mode_id] == 'physical_mode:LongDistanceTrain' assert len(pb_trip_update.stop_time_update) == 2 pb_stop_time = pb_trip_update.stop_time_update[0] assert pb_stop_time.stop_id == 'sa:1' assert pb_stop_time.arrival.time == 0 assert pb_stop_time.arrival.delay == 0 assert pb_stop_time.departure.time == to_posix_time(_dt("8:15")) assert pb_stop_time.departure.delay == 5 * 60 assert pb_stop_time.Extensions[kirin_pb2.stoptime_message] == "" assert pb_stop_time.arrival.Extensions[ kirin_pb2.stop_time_event_status] == kirin_pb2.SCHEDULED assert pb_stop_time.departure.Extensions[ kirin_pb2.stop_time_event_status] == kirin_pb2.ADDED pb_stop_time = pb_trip_update.stop_time_update[1] assert pb_stop_time.stop_id == 'sa:2' assert pb_stop_time.arrival.time == to_posix_time(_dt("8:20")) assert pb_stop_time.arrival.delay == -40 * 60 assert pb_stop_time.departure.time == to_posix_time(_dt("8:21")) assert pb_stop_time.departure.delay == -40 * 60 assert pb_stop_time.Extensions[ kirin_pb2.stoptime_message] == "bob's on the track" assert pb_stop_time.arrival.Extensions[ kirin_pb2.stop_time_event_status] == kirin_pb2.ADDED assert pb_stop_time.departure.Extensions[ kirin_pb2.stop_time_event_status] == kirin_pb2.SCHEDULED
def setup_database(): """ we create two realtime_updates with the same vj but for different date and return a vj for navitia """ with app.app_context(): vju = create_trip_update('70866ce8-0638-4fa1-8556-1ddfa22d09d3', 'vehicle_journey:1', datetime.date(2015, 9, 8), [ { 'id': 'sa:1', 'departure': _dt("8:15"), 'arrival': None, 'departure_status': 'update', 'arrival_status': 'none' }, { 'id': 'sa:2', 'departure': _dt("9:10"), 'arrival': _dt("9:05"), 'departure_status': 'none', 'arrival_status': 'none' }, { 'id': 'sa:3', 'departure': None, 'arrival': _dt("10:05"), 'departure_status': 'none', 'arrival_status': 'none' }, ]) rtu = RealTimeUpdate(None, 'ire') rtu.id = '10866ce8-0638-4fa1-8556-1ddfa22d09d3' rtu.trip_updates.append(vju) db.session.add(rtu) vju = create_trip_update('70866ce8-0638-4fa1-8556-1ddfa22d09d4', 'vehicle_journey:1', datetime.date(2015, 9, 7), [ { 'id': 'sa:1', 'departure': _dt("8:35", day=7), 'arrival': None, 'departure_status': 'update', 'arrival_status': 'none' }, { 'id': 'sa:2', 'departure': _dt("9:40", day=7), 'arrival': _dt("9:35", day=7), 'departure_status': 'update', 'arrival_status': 'update' }, { 'id': 'sa:3', 'departure': None, 'arrival': _dt("10:35", day=7), 'departure_status': 'none', 'arrival_status': 'update' }, ]) rtu = RealTimeUpdate(None, 'ire') rtu.id = '20866ce8-0638-4fa1-8556-1ddfa22d09d3' rtu.trip_updates.append(vju) db.session.add(rtu) db.session.commit()
def test_simple_delay(navitia_vj): """Test on delay when there is nothing in the db""" with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') st = StopTimeUpdate({'id': 'sa:1'}, departure_delay=timedelta(minutes=10), dep_status='update', arrival_delay=timedelta(minutes=5), arr_status='update') real_time_update = RealTimeUpdate(raw_data=None, connector='ire') trip_update.stop_time_updates.append(st) res = handle(real_time_update, [trip_update], 'kisio-digital') assert len(res.trip_updates) == 1 trip_update = res.trip_updates[0] assert trip_update.status == 'update' assert len(trip_update.stop_time_updates) == 3 assert trip_update.stop_time_updates[0].stop_id == 'sa:1' assert trip_update.stop_time_updates[0].arrival == _dt( '8:20') # departure assert trip_update.stop_time_updates[0].arrival_delay == timedelta( minutes=5) assert trip_update.stop_time_updates[0].arrival_status == 'update' assert trip_update.stop_time_updates[0].departure == _dt( '8:20') # 8:10 + 10mn assert trip_update.stop_time_updates[0].departure_delay == timedelta( minutes=10) assert trip_update.stop_time_updates[0].departure_status == 'update' assert trip_update.stop_time_updates[1].stop_id == 'sa:2' assert trip_update.stop_time_updates[1].arrival == _dt('9:05') assert trip_update.stop_time_updates[1].arrival_delay == timedelta(0) assert trip_update.stop_time_updates[1].arrival_status == 'none' assert trip_update.stop_time_updates[1].departure == _dt('9:10') assert trip_update.stop_time_updates[1].departure_delay == timedelta(0) assert trip_update.stop_time_updates[1].departure_status == 'none' # testing that RealTimeUpdate is persisted in db db_trip_updates = real_time_update.query.from_self(TripUpdate).all() assert len(db_trip_updates) == 1 assert db_trip_updates[0].status == 'update' db_st_updates = real_time_update.query.from_self( StopTimeUpdate).order_by('stop_id').all() assert len(db_st_updates) == 3 assert db_st_updates[0].stop_id == 'sa:1' assert db_st_updates[0].arrival == _dt('8:20') # departure assert db_st_updates[0].arrival_delay == timedelta(minutes=5) assert db_st_updates[0].arrival_status == 'update' assert db_st_updates[0].departure == _dt('8:20') # 8:10 + 10mn assert db_st_updates[0].departure_delay == timedelta(minutes=10) assert db_st_updates[0].departure_status == 'update' assert db_st_updates[1].stop_id == 'sa:2' assert db_st_updates[1].arrival == _dt('9:05') assert db_st_updates[1].departure == _dt('9:10') assert db_st_updates[1].trip_update_id == db_trip_updates[0].vj_id assert db_st_updates[2].stop_id == 'sa:3'
def test_handle_update_vj(setup_database, navitia_vj): """ this time we receive an update for a vj already in the database sa:1 sa:2 sa:3 VJ navitia 8:10 9:05-9:10 10:05 VJ in db 8:15* 9:05-9:10 10:05 update kirin - *9:15-9:20* - """ with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') st = StopTimeUpdate({'id': 'sa:2'}, arrival_delay=timedelta(minutes=10), dep_status='update', departure_delay=timedelta(minutes=10), arr_status='update') st.arrival_status = st.departure_status = 'update' real_time_update = RealTimeUpdate(raw_data=None, connector='ire') real_time_update.id = '30866ce8-0638-4fa1-8556-1ddfa22d09d3' trip_update.stop_time_updates.append(st) res = handle(real_time_update, [trip_update], 'kisio-digital') assert len(res.trip_updates) == 1 trip_update = res.trip_updates[0] assert trip_update.status == 'update' assert len(trip_update.real_time_updates) == 2 assert len(trip_update.stop_time_updates) == 3 stu_map = {stu.stop_id: stu for stu in trip_update.stop_time_updates} assert 'sa:1' in stu_map assert stu_map['sa:1'].arrival == _dt("8:15") assert stu_map['sa:1'].departure == _dt("8:15") assert 'sa:2' in stu_map assert stu_map['sa:2'].arrival == _dt("9:15") assert stu_map['sa:2'].departure == _dt("9:20") assert 'sa:3' in stu_map assert stu_map['sa:3'].arrival == _dt("10:05") assert stu_map['sa:3'].departure == _dt("10:05") # testing that RealTimeUpdate is persisted in db db_trip_updates = TripUpdate.query.join(VehicleJourney).order_by( 'circulation_date').all() assert len(db_trip_updates) == 2 assert real_time_update.query.from_self( TripUpdate).all()[0].status == 'update' st_updates = real_time_update.query.from_self(StopTimeUpdate).order_by( 'stop_id').all() assert len(st_updates) == 6 # testing that trip update on 2015/09/07 is remaining correctly stored in db assert len(db_trip_updates[0].stop_time_updates) == 3 db_stu_map = { stu.stop_id: stu for stu in db_trip_updates[0].stop_time_updates } assert 'sa:1' in db_stu_map assert db_stu_map['sa:1'].arrival is None assert db_stu_map['sa:1'].departure == _dt("8:35", day=7) assert 'sa:2' in db_stu_map assert db_stu_map['sa:2'].arrival == _dt("9:35", day=7) assert db_stu_map['sa:2'].departure == _dt("9:40", day=7) assert 'sa:3' in db_stu_map assert db_stu_map['sa:3'].arrival == _dt("10:35", day=7) assert db_stu_map['sa:3'].departure is None # testing that trip update on 2015/09/08 is correctly merged and stored in db assert len(db_trip_updates[1].stop_time_updates) == 3 db_stu_map = { stu.stop_id: stu for stu in db_trip_updates[1].stop_time_updates } assert 'sa:1' in db_stu_map assert db_stu_map['sa:1'].arrival == _dt("8:15") assert db_stu_map['sa:1'].departure == _dt("8:15") assert 'sa:2' in db_stu_map assert db_stu_map['sa:2'].arrival == _dt("9:15") assert db_stu_map['sa:2'].departure == _dt("9:20") assert 'sa:3' in db_stu_map assert db_stu_map['sa:3'].arrival == _dt("10:05") assert db_stu_map['sa:3'].departure == _dt("10:05")
def test_past_midnight(): """ integration of a past midnight """ navitia_vj = { 'trip': { 'id': 'vehicle_journey:1' }, 'stop_times': [ { 'arrival_time': datetime.time(22, 10), 'departure_time': datetime.time(22, 15), 'stop_point': { 'id': 'sa:1', 'stop_area': { 'timezone': 'UTC' } } }, # arrive at sa:2 at 23:10 and leave the day after { 'arrival_time': datetime.time(23, 10), 'departure_time': datetime.time(2, 15), 'stop_point': { 'id': 'sa:2', 'stop_area': { 'timezone': 'UTC' } } }, { 'arrival_time': datetime.time(3, 20), 'departure_time': datetime.time(3, 25), 'stop_point': { 'id': 'sa:3', 'stop_area': { 'timezone': 'UTC' } } } ] } with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') st = StopTimeUpdate({'id': 'sa:2'}, departure_delay=timedelta(minutes=31), dep_status='update') real_time_update = RealTimeUpdate(raw_data=None, connector='ire') trip_update.stop_time_updates.append(st) res = handle(real_time_update, [trip_update], 'kisio-digital') assert len(res.trip_updates) == 1 trip_update = res.trip_updates[0] assert trip_update.status == 'update' assert len(trip_update.stop_time_updates) == 3 assert trip_update.stop_time_updates[0].stop_id == 'sa:1' assert trip_update.stop_time_updates[0].arrival == _dt("22:10") assert trip_update.stop_time_updates[0].departure == _dt("22:15") assert trip_update.stop_time_updates[1].stop_id == 'sa:2' assert trip_update.stop_time_updates[1].arrival == _dt("23:10") assert trip_update.stop_time_updates[1].arrival_delay == timedelta(0) assert trip_update.stop_time_updates[1].departure == _dt("2:46", day=9) assert trip_update.stop_time_updates[1].departure_delay == timedelta( minutes=31) assert trip_update.stop_time_updates[2].stop_id == 'sa:3' assert trip_update.stop_time_updates[2].arrival == _dt("3:20", day=9) assert trip_update.stop_time_updates[2].arrival_delay == timedelta(0) assert trip_update.stop_time_updates[2].departure == _dt("3:25", day=9) assert trip_update.stop_time_updates[2].departure_delay == timedelta(0)
def test_handle_new_vj(): """an easy one: we have one vj with only one stop time updated""" navitia_vj = { 'trip': { 'id': 'vehicle_journey:1' }, 'stop_times': [{ 'arrival_time': None, 'departure_time': datetime.time(8, 10), 'stop_point': { 'id': 'sa:1', 'stop_area': { 'timezone': 'UTC' } } }, { 'arrival_time': datetime.time(9, 10), 'departure_time': None, 'stop_point': { 'id': 'sa:2', 'stop_area': { 'timezone': 'UTC' } } }] } with app.app_context(): trip_update = TripUpdate(VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)), status='update') st = StopTimeUpdate({'id': 'sa:1'}, departure_delay=timedelta(minutes=5), dep_status='update') real_time_update = RealTimeUpdate(raw_data=None, connector='ire') trip_update.stop_time_updates.append(st) res = handle(real_time_update, [trip_update], 'kisio-digital') assert len(res.trip_updates) == 1 trip_update = res.trip_updates[0] assert trip_update.status == 'update' assert len(trip_update.stop_time_updates) == 2 assert trip_update.stop_time_updates[0].stop_id == 'sa:1' assert trip_update.stop_time_updates[0].departure == _dt("8:15") assert trip_update.stop_time_updates[0].arrival == _dt("8:15") assert trip_update.stop_time_updates[1].stop_id == 'sa:2' assert trip_update.stop_time_updates[1].departure == _dt("9:10") assert trip_update.stop_time_updates[1].arrival == _dt("9:10") # testing that RealTimeUpdate is persisted in db db_trip_updates = real_time_update.query.from_self(TripUpdate).all() assert len(db_trip_updates) == 1 assert db_trip_updates[0].status == 'update' db_st_updates = real_time_update.query.from_self( StopTimeUpdate).order_by('stop_id').all() assert len(db_st_updates) == 2 assert db_st_updates[0].stop_id == 'sa:1' assert db_st_updates[0].departure == _dt("8:15") assert db_st_updates[0].arrival == _dt("8:15") assert db_st_updates[0].trip_update_id == db_trip_updates[0].vj_id assert db_st_updates[1].stop_id == 'sa:2' assert db_st_updates[1].departure == _dt("9:10") assert db_st_updates[1].arrival == _dt("9:10") assert db_st_updates[1].trip_update_id == db_trip_updates[0].vj_id
def test_populate_pb_with_deleted_stop_time(): """ test protobuf for partial delete nav vj sa:1 * ---- * sa:2 * ---- * sa:3 * ---- * sa:4 we stop the vj from going to sa:3 and sa:4 sa:1 * ---- * sa:2 And we delay sa:1 of 5 minutes Note: in the message sent sa:2 departure will be removed as well as sa:3 departures/arrival and sa:4' arrival """ #we add another impacted stop time to the Model from datetime import time navitia_vj = { 'trip': { 'id': 'vehicle_journey:1' }, 'stop_times': [{ 'arrival_time': None, 'departure_time': time(8, 11), 'stop_point': { 'id': 'sa:1', 'stop_area': { 'timezone': 'Europe/Paris' } } }, { 'arrival_time': time(9, 10), 'departure_time': time(9, 11), 'stop_point': { 'id': 'sa:2', 'stop_area': { 'timezone': 'Europe/Paris' } } }, { 'arrival_time': time(10, 10), 'departure_time': time(10, 11), 'stop_point': { 'id': 'sa:3', 'stop_area': { 'timezone': 'Europe/Paris' } } }, { 'arrival_time': time(11, 10), 'departure_time': None, 'stop_point': { 'id': 'sa:4', 'stop_area': { 'timezone': 'Europe/Paris' } } }] } with app.app_context(): trip_update = TripUpdate() vj = VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)) trip_update.vj = vj real_time_update = RealTimeUpdate(raw_data=None, connector='ire', contributor='realtime.ire') real_time_update.trip_updates.append(trip_update) st = StopTimeUpdate({'id': 'sa:1'}, departure=_dt("8:15"), departure_delay=timedelta(minutes=5), arrival=None) trip_update.stop_time_updates.append(st) st = StopTimeUpdate( {'id': 'sa:2'}, arrival=_dt("9:10"), departure=_dt("9:11"), dep_status='delete', # we delete the departure message="bob's on the track") real_time_update.trip_updates[0].stop_time_updates.append(st) st = StopTimeUpdate( {'id': 'sa:3'}, # Note: we still send the departure/arrival for coherence arrival=_dt("10:10"), dep_status='delete', # we delete both departure and arrival departure=_dt("10:11"), arr_status='delete', message="bob's on the track") real_time_update.trip_updates[0].stop_time_updates.append(st) st = StopTimeUpdate( {'id': 'sa:4'}, arrival=_dt("11:10"), arr_status='delete', # we delete only the arrival departure=_dt("11:11"), message="bob's on the track") real_time_update.trip_updates[0].stop_time_updates.append(st) db.session.add(real_time_update) db.session.commit() feed_entity = convert_to_gtfsrt(real_time_update.trip_updates) assert feed_entity.header.incrementality == gtfs_realtime_pb2.FeedHeader.DIFFERENTIAL assert feed_entity.header.gtfs_realtime_version, '1' assert len(feed_entity.entity) == 1 pb_trip_update = feed_entity.entity[0].trip_update assert pb_trip_update.trip.trip_id == 'vehicle_journey:1' assert pb_trip_update.trip.start_date == '20150908' assert pb_trip_update.HasExtension(kirin_pb2.trip_message) is False assert pb_trip_update.trip.HasExtension(kirin_pb2.contributor) is False assert pb_trip_update.trip.schedule_relationship == gtfs_realtime_pb2.TripDescriptor.SCHEDULED assert len(pb_trip_update.stop_time_update) == 4 pb_stop_time = pb_trip_update.stop_time_update[0] assert pb_stop_time.stop_id == 'sa:1' assert pb_stop_time.arrival.time == 0 assert pb_stop_time.arrival.delay == 0 assert pb_stop_time.departure.time == to_posix_time(_dt("8:15")) assert pb_stop_time.departure.delay == 5 * 60 assert pb_stop_time.Extensions[kirin_pb2.stoptime_message] == "" pb_stop_time = pb_trip_update.stop_time_update[1] assert pb_stop_time.stop_id == 'sa:2' assert pb_stop_time.arrival.time == to_posix_time(_dt("9:10")) assert pb_stop_time.arrival.delay == 0 # the arrival at the stop is still scheduled, but the departure is skipped assert pb_stop_time.arrival.Extensions[kirin_pb2.stop_time_event_relationship] == \ gtfs_realtime_pb2.TripUpdate.StopTimeUpdate.SCHEDULED assert pb_stop_time.departure.time == to_posix_time(_dt("9:11")) assert pb_stop_time.departure.delay == 0 assert pb_stop_time.departure.Extensions[kirin_pb2.stop_time_event_relationship] == \ gtfs_realtime_pb2.TripUpdate.StopTimeUpdate.SKIPPED assert pb_stop_time.Extensions[ kirin_pb2.stoptime_message] == "bob's on the track" pb_stop_time = pb_trip_update.stop_time_update[2] assert pb_stop_time.stop_id == 'sa:3' # both departure and arrival are SKIPPED assert pb_stop_time.arrival.time == to_posix_time(_dt("10:10")) assert pb_stop_time.arrival.delay == 0 assert pb_stop_time.arrival.Extensions[kirin_pb2.stop_time_event_relationship] == \ gtfs_realtime_pb2.TripUpdate.StopTimeUpdate.SKIPPED assert pb_stop_time.departure.time == to_posix_time(_dt("10:11")) assert pb_stop_time.departure.delay == 0 assert pb_stop_time.departure.Extensions[kirin_pb2.stop_time_event_relationship] == \ gtfs_realtime_pb2.TripUpdate.StopTimeUpdate.SKIPPED assert pb_stop_time.Extensions[ kirin_pb2.stoptime_message] == "bob's on the track" pb_stop_time = pb_trip_update.stop_time_update[3] assert pb_stop_time.stop_id == 'sa:4' # only the arrival is skipped, the departure does not exists as it's the last stop assert pb_stop_time.arrival.time == to_posix_time(_dt("11:10")) assert pb_stop_time.arrival.delay == 0 assert pb_stop_time.arrival.Extensions[kirin_pb2.stop_time_event_relationship] == \ gtfs_realtime_pb2.TripUpdate.StopTimeUpdate.SKIPPED assert pb_stop_time.departure.time == to_posix_time(_dt("11:11")) assert pb_stop_time.departure.delay == 0 assert pb_stop_time.departure.Extensions[kirin_pb2.stop_time_event_relationship] == \ gtfs_realtime_pb2.TripUpdate.StopTimeUpdate.SCHEDULED assert pb_stop_time.Extensions[ kirin_pb2.stoptime_message] == "bob's on the track"
def test_populate_pb_with_two_stop_time(): """ an easy one: we have one vj with only one stop time updated fill protobuf from trip_update Verify protobuf """ #we add another impacted stop time to the Model navitia_vj = { 'trip': { 'id': 'vehicle_journey:1' }, 'stop_times': [{ 'arrival_time': None, 'departure_time': datetime.time(8, 10), 'stop_point': { 'id': 'sa:1', 'stop_area': { 'timezone': 'Europe/Paris' } } }, { 'arrival_time': datetime.time(9, 10), 'departure_time': None, 'stop_point': { 'id': 'sa:2', 'stop_area': { 'timezone': 'Europe/Paris' } } }] } with app.app_context(): trip_update = TripUpdate() vj = VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)) trip_update.vj = vj real_time_update = RealTimeUpdate(raw_data=None, connector='ire', contributor='realtime.ire') real_time_update.trip_updates.append(trip_update) st = StopTimeUpdate({'id': 'sa:1'}, departure=_dt("8:15"), departure_delay=timedelta(minutes=5), arrival=None) trip_update.stop_time_updates.append(st) st = StopTimeUpdate({'id': 'sa:2'}, departure=_dt("8:21"), departure_delay=timedelta(minutes=-40), arrival=_dt("8:20"), arrival_delay=timedelta(minutes=-40), message="bob's on the track") real_time_update.trip_updates[0].stop_time_updates.append(st) db.session.add(real_time_update) db.session.commit() feed_entity = convert_to_gtfsrt(real_time_update.trip_updates) assert feed_entity.header.incrementality == gtfs_realtime_pb2.FeedHeader.DIFFERENTIAL assert feed_entity.header.gtfs_realtime_version, '1' assert len(feed_entity.entity) == 1 pb_trip_update = feed_entity.entity[0].trip_update assert pb_trip_update.trip.trip_id == 'vehicle_journey:1' assert pb_trip_update.trip.start_date == '20150908' assert pb_trip_update.HasExtension(kirin_pb2.trip_message) is False assert pb_trip_update.trip.HasExtension(kirin_pb2.contributor) is False assert pb_trip_update.trip.schedule_relationship == gtfs_realtime_pb2.TripDescriptor.SCHEDULED assert len(pb_trip_update.stop_time_update) == 2 pb_stop_time = pb_trip_update.stop_time_update[0] assert pb_stop_time.stop_id == 'sa:1' assert pb_stop_time.arrival.time == 0 assert pb_stop_time.arrival.delay == 0 assert pb_stop_time.departure.time == to_posix_time(_dt("8:15")) assert pb_stop_time.departure.delay == 5 * 60 assert pb_stop_time.Extensions[kirin_pb2.stoptime_message] == "" pb_stop_time = pb_trip_update.stop_time_update[1] assert pb_stop_time.stop_id == 'sa:2' assert pb_stop_time.arrival.time == to_posix_time(_dt("8:20")) assert pb_stop_time.arrival.delay == -40 * 60 assert pb_stop_time.departure.time == to_posix_time(_dt("8:21")) assert pb_stop_time.departure.delay == -40 * 60 assert pb_stop_time.Extensions[ kirin_pb2.stoptime_message] == "bob's on the track"
def test_handle_update_vj(setup_database, navitia_vj): """ this time we receive an update for a vj already in the database """ with app.app_context(): trip_update = TripUpdate() vj = VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)) trip_update.status = 'update' trip_update.vj = vj st = StopTimeUpdate({'id': 'sa:2'}, departure=_dt("9:20"), arrival=_dt("9:15")) st.arrival_status = st.departure_status = 'update' real_time_update = RealTimeUpdate(raw_data=None, connector='ire') real_time_update.id = '30866ce8-0638-4fa1-8556-1ddfa22d09d3' trip_update.stop_time_updates.append(st) res = handle(real_time_update, [trip_update]) assert len(res.trip_updates) == 1 trip_update = res.trip_updates[0] assert trip_update.status == 'update' assert len(trip_update.real_time_updates) == 2 assert len(trip_update.stop_time_updates) == 3 stu_map = {stu.stop_id: stu for stu in trip_update.stop_time_updates} assert 'sa:1' in stu_map assert stu_map['sa:1'].arrival == None assert stu_map['sa:1'].departure == _dt("8:15") assert 'sa:2' in stu_map assert stu_map['sa:2'].arrival == _dt("9:15") assert stu_map['sa:2'].departure == _dt("9:20") assert 'sa:3' in stu_map assert stu_map['sa:3'].arrival == _dt("10:05") assert stu_map['sa:3'].departure == None # testing that RealTimeUpdate is persisted in db db_trip_updates = TripUpdate.query.join(VehicleJourney).order_by('circulation_date').all() assert len(db_trip_updates) == 2 assert real_time_update.query.from_self(TripUpdate).all()[0].status == 'update' st_updates = real_time_update.query.from_self(StopTimeUpdate).order_by('stop_id').all() assert len(st_updates) == 6 # testing that trip update on 2015/09/07 is remaining correctly stored in db assert len(db_trip_updates[0].stop_time_updates) == 3 db_stu_map = {stu.stop_id: stu for stu in db_trip_updates[0].stop_time_updates} assert 'sa:1' in db_stu_map assert db_stu_map['sa:1'].arrival == None assert db_stu_map['sa:1'].departure == _dt("8:35", day=7) assert 'sa:2' in db_stu_map assert db_stu_map['sa:2'].arrival == _dt("9:35", day=7) assert db_stu_map['sa:2'].departure == _dt("9:40", day=7) assert 'sa:3' in db_stu_map assert db_stu_map['sa:3'].arrival == _dt("10:35", day=7) assert db_stu_map['sa:3'].departure == None # testing that trip update on 2015/09/08 is correctly merged and stored in db assert len(db_trip_updates[1].stop_time_updates) == 3 db_stu_map = {stu.stop_id: stu for stu in db_trip_updates[1].stop_time_updates} assert 'sa:1' in db_stu_map assert db_stu_map['sa:1'].arrival == None assert db_stu_map['sa:1'].departure == _dt("8:15") assert 'sa:2' in db_stu_map assert db_stu_map['sa:2'].arrival == _dt("9:15") assert db_stu_map['sa:2'].departure == _dt("9:20") assert 'sa:3' in db_stu_map assert db_stu_map['sa:3'].arrival == _dt("10:05") assert db_stu_map['sa:3'].departure == None