def check_db_john_trip_removal(): with app.app_context(): assert len(RealTimeUpdate.query.all()) >= 1 assert len(TripUpdate.query.all()) >= 2 assert len(StopTimeUpdate.query.all()) >= 0 db_trip1_removal = TripUpdate.find_by_dated_vj( 'trip:OCETGV-87686006-87751008-2:25768', datetime(2015, 9, 21, 10, 37, tzinfo=utc)) assert db_trip1_removal assert db_trip1_removal.vj.navitia_trip_id == 'trip:OCETGV-87686006-87751008-2:25768' assert db_trip1_removal.vj.get_start_timestamp() == datetime( 2015, 9, 21, 10, 37, tzinfo=utc) assert db_trip1_removal.vj_id == db_trip1_removal.vj.id assert db_trip1_removal.status == 'delete' # full trip removal : no stop_time to precise assert len(db_trip1_removal.stop_time_updates) == 0 db_trip2_removal = TripUpdate.find_by_dated_vj( 'trip:OCETrainTER-87212027-85000109-3:11859', datetime(2015, 9, 21, 15, 21, tzinfo=utc)) assert db_trip2_removal assert db_trip2_removal.vj.navitia_trip_id == 'trip:OCETrainTER-87212027-85000109-3:11859' assert db_trip2_removal.vj.get_start_timestamp() == datetime( 2015, 9, 21, 15, 21, tzinfo=utc) assert db_trip2_removal.vj_id == db_trip2_removal.vj.id assert db_trip2_removal.status == 'delete' # full trip removal : no stop_time to precise assert len(db_trip2_removal.stop_time_updates) == 0
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(): contributor = model.Contributor( id=GTFS_CONTRIBUTOR_ID, navitia_coverage=None, connector_type=ConnectorType.gtfs_rt.value ) builder = kirin.poller_workers.gtfs_rt.KirinModelBuilder(contributor) trip_update = TripUpdate(_create_db_vj(navitia_vj), status="update", contributor_id=contributor.id) real_time_update = make_rt_update(raw_data=None, contributor_id=contributor.id) 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(builder, real_time_update, [trip_update]) _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 check_db_ire_JOHN_trip_removal(): with app.app_context(): assert len(RealTimeUpdate.query.all()) >= 1 assert len(TripUpdate.query.all()) >= 2 assert len(StopTimeUpdate.query.all()) >= 0 db_trip1_removal = TripUpdate.find_by_dated_vj('trip:OCETGV-87686006-87751008-2:25768', datetime.date(2015, 9, 21)) assert db_trip1_removal assert db_trip1_removal.vj.navitia_trip_id == 'trip:OCETGV-87686006-87751008-2:25768' assert db_trip1_removal.vj.circulation_date == datetime.date(2015, 9, 21) assert db_trip1_removal.vj_id == db_trip1_removal.vj.id assert db_trip1_removal.status == 'delete' # full trip removal : no stop_time to precise assert len(db_trip1_removal.stop_time_updates) == 0 db_trip2_removal = TripUpdate.find_by_dated_vj('trip:OCETrainTER-87212027-85000109-3:11859', datetime.date(2015, 9, 21)) assert db_trip2_removal assert db_trip2_removal.vj.navitia_trip_id == 'trip:OCETrainTER-87212027-85000109-3:11859' assert db_trip2_removal.vj.circulation_date == datetime.date(2015, 9, 21) assert db_trip2_removal.vj_id == db_trip2_removal.vj.id assert db_trip2_removal.status == 'delete' # full trip removal : no stop_time to precise assert len(db_trip2_removal.stop_time_updates) == 0
def test_populate_pb_with_full_dataset(): """ 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, 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 len(feed_entity.entity[0].trip_update.stop_time_update) == 0
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() vj = VehicleJourney(navitia_vj, datetime.date(2015, 9, 8)) trip_update.vj = vj st = StopTimeUpdate({'id': 'sa:2'}, departure=_dt("9:50"), arrival=_dt("9:49")) real_time_update = RealTimeUpdate(raw_data=None, connector='ire') 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 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 == None 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 == None assert trip_update.stop_time_updates[2].arrival == _dt("10:05")
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(): contributor = model.Contributor( id=GTFS_CONTRIBUTOR_ID, navitia_coverage=None, connector_type=ConnectorType.gtfs_rt.value ) builder = kirin.poller_workers.gtfs_rt.KirinModelBuilder(contributor) trip_update = TripUpdate(_create_db_vj(navitia_vj), status="update", contributor_id=contributor.id) real_time_update = make_rt_update(raw_data=None, contributor_id=contributor.id) trip_update.stop_time_updates = [ StopTimeUpdate({"id": "sa:1"}, departure_delay=timedelta(minutes=5), dep_status="update") ] handle(builder, real_time_update, [trip_update]) trip_update = TripUpdate( _create_db_vj(navitia_vj), status="delete", effect=TripEffect.NO_SERVICE.name, contributor_id=contributor.id, ) real_time_update = make_rt_update(raw_data=None, contributor_id=contributor.id) res, _ = handle(builder, real_time_update, [trip_update]) assert len(res.trip_updates) == 1 trip_update = res.trip_updates[0] assert trip_update.status == "delete" assert len(trip_update.stop_time_updates) == 3 for stu in trip_update.stop_time_updates: assert stu.arrival_status == "delete" assert stu.departure_status == "delete" assert len(trip_update.real_time_updates) == 2
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 create_trip_update(id, trip_id, circulation_date, stops, status='update'): trip_update = TripUpdate( VehicleJourney( { 'trip': { 'id': trip_id }, 'stop_times': [{ 'arrival_time': datetime.time(8, 10), 'stop_point': { 'stop_area': { 'timezone': 'UTC' } } }] }, circulation_date), status) trip_update.id = id for stop in stops: st = StopTimeUpdate({'id': stop['id']}, stop['departure'], stop['arrival']) st.arrival_status = stop['arrival_status'] st.departure_status = stop['departure_status'] trip_update.stop_time_updates.append(st) db.session.add(trip_update) return trip_update
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 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') 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') 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_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') 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 create_trip_update( id, trip_id, circulation_date, stops, status="update", contributor_id=GTFS_CONTRIBUTOR_ID ): trip_update = TripUpdate( VehicleJourney( { "trip": {"id": trip_id}, "stop_times": [ {"utc_arrival_time": datetime.time(8, 10), "stop_point": {"stop_area": {"timezone": "UTC"}}} ], }, datetime.datetime.combine(circulation_date, datetime.time(7, 10)), datetime.datetime.combine(circulation_date, datetime.time(9, 10)), ), contributor_id, status, ) trip_update.id = id for stop in stops: st = StopTimeUpdate({"id": stop["id"]}, stop["departure"], stop["arrival"]) st.arrival_status = stop["arrival_status"] st.departure_status = stop["departure_status"] trip_update.stop_time_updates.append(st) db.session.add(trip_update) return trip_update
def test_populate_pb_with_cancelation(): """ VJ cancelation """ navitia_vj = {'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' real_time_update = RealTimeUpdate(raw_data=None, connector='ire') 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) 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.CANCELED assert len(feed_entity.entity[0].trip_update.stop_time_update) == 0
def check_db_john_trip_removal(): with app.app_context(): assert len(RealTimeUpdate.query.all()) >= 1 assert len(TripUpdate.query.all()) >= 2 assert len(StopTimeUpdate.query.all()) >= 0 db_trip1_removal = TripUpdate.find_by_dated_vj( "trip:OCETGV-87686006-87751008-2:25768", datetime(2015, 9, 21, 13, 37) ) assert db_trip1_removal assert db_trip1_removal.vj.navitia_trip_id == "trip:OCETGV-87686006-87751008-2:25768" assert db_trip1_removal.vj.start_timestamp == datetime(2015, 9, 21, 13, 37) assert db_trip1_removal.vj_id == db_trip1_removal.vj.id assert db_trip1_removal.status == "delete" assert db_trip1_removal.effect == "NO_SERVICE" # full trip removal : no stop_time to precise assert len(db_trip1_removal.stop_time_updates) == 0 db_trip2_removal = TripUpdate.find_by_dated_vj( "trip:OCETrainTER-87212027-85000109-3:11859", datetime(2015, 9, 21, 15, 21) ) assert db_trip2_removal assert db_trip2_removal.vj.navitia_trip_id == "trip:OCETrainTER-87212027-85000109-3:11859" assert db_trip2_removal.vj.start_timestamp == datetime(2015, 9, 21, 15, 21) assert db_trip2_removal.vj_id == db_trip2_removal.vj.id assert db_trip2_removal.status == "delete" assert db_trip2_removal.effect == "NO_SERVICE" # full trip removal : no stop_time to precise assert len(db_trip2_removal.stop_time_updates) == 0
def create_trip_update(vj_id, trip_id, circulation_date): trip_update = TripUpdate() vj = VehicleJourney( { 'trip': { 'id': trip_id }, 'stop_times': [{ 'utc_arrival_time': datetime.time(8, 0), 'stop_point': { 'stop_area': { 'timezone': 'UTC' } } }] }, utc.localize( datetime.datetime.combine(circulation_date, datetime.time(7, 0))), utc.localize( datetime.datetime.combine(circulation_date, datetime.time(9, 0)))) vj.id = vj_id trip_update.vj = vj db.session.add(vj) db.session.add(trip_update) return trip_update
def create_trip_update(vj_id, trip_id, circulation_date): trip_update = TripUpdate() vj = VehicleJourney({'trip': {'id': trip_id}}, circulation_date) vj.id = vj_id trip_update.vj = vj db.session.add(vj) db.session.add(trip_update) return trip_update
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'}}, {'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) st = StopTimeUpdate({'id': 'sa:2'}, departure=_dt("8:21"), arrival=_dt("8:20"), 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) == False assert pb_trip_update.trip.HasExtension(kirin_pb2.contributor) == 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.departure.time == to_posix_time(_dt("8:15")) 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.departure.time == to_posix_time(_dt("8:21")) assert pb_stop_time.Extensions[kirin_pb2.stoptime_message] == "bob's on the track"
def test_find_by_vj(setup_database): with app.app_context(): assert TripUpdate.find_by_dated_vj("vehicle_journey:1", datetime.datetime(2015, 9, 9, 8, 0)) is None row = TripUpdate.find_by_dated_vj("vehicle_journey:1", datetime.datetime(2015, 9, 8, 8, 0)) assert row is not None assert row.vj_id == "70866ce8-0638-4fa1-8556-1ddfa22d09d3" row = TripUpdate.find_by_dated_vj("vehicle_journey:2", datetime.datetime(2015, 9, 8, 8, 0)) assert row is not None assert row.vj_id == "70866ce8-0638-4fa1-8556-1ddfa22d09d4"
def test_find_by_vj(setup_database): with app.app_context(): assert TripUpdate.find_by_dated_vj('vehicle_journey:1', datetime.date(2015, 9, 9)) is None row = TripUpdate.find_by_dated_vj('vehicle_journey:1', datetime.date(2015, 9, 8)) assert row is not None assert row.vj_id == '70866ce8-0638-4fa1-8556-1ddfa22d09d3' row = TripUpdate.find_by_dated_vj('vehicle_journey:2', datetime.date(2015, 9, 8)) assert row is not None assert row.vj_id == '70866ce8-0638-4fa1-8556-1ddfa22d09d4'
def create_trip_update(id, trip_id, circulation_date, stops, status='update'): trip_update = TripUpdate(VehicleJourney({'trip': {'id': trip_id}}, circulation_date), status) trip_update.id = id for stop in stops: st = StopTimeUpdate({'id': stop['id']}, stop['departure'], stop['arrival']) st.arrival_status = stop['arrival_status'] st.departure_status = stop['departure_status'] trip_update.stop_time_updates.append(st) db.session.add(trip_update) return trip_update
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 create_trip_update(vj_id, trip_id, circulation_date): trip_update = TripUpdate() vj = VehicleJourney({'trip': {'id': trip_id}, 'stop_times': [ {'arrival_time': datetime.time(8, 0), 'stop_point': {'stop_area': {'timezone': 'UTC'}}} ]}, circulation_date) vj.id = vj_id trip_update.vj = vj db.session.add(vj) db.session.add(trip_update) return trip_update
def create_trip_update(id, trip_id, circulation_date, stops, status='update'): trip_update = TripUpdate( VehicleJourney({'trip': { 'id': trip_id }}, circulation_date), status) trip_update.id = id for stop in stops: st = StopTimeUpdate({'id': stop['id']}, stop['departure'], stop['arrival']) st.arrival_status = stop['arrival_status'] st.departure_status = stop['departure_status'] trip_update.stop_time_updates.append(st) db.session.add(trip_update) return trip_update
def _delete_trip_update_rows(contributor: Contributor) -> Dict: with new_relic.agent.FunctionTrace("{}:_delete_trip_update_rows".format( contributor.id)): until = datetime.date.today() - datetime.timedelta( days=int(contributor.nb_days_to_keep_trip_update)) return TripUpdate.remove_by_contributors_until( contributors=[contributor.id], until=until)
def purge_trip_update(self, config): func_name = 'purge_trip_update' contributor = config['contributor'] logger = logging.LoggerAdapter(logging.getLogger(__name__), extra={'contributor': contributor}) logger.debug('purge trip update for %s', contributor) lock_name = make_kirin_lock_name(func_name, contributor) with get_lock(logger, lock_name, app.config['REDIS_LOCK_TIMEOUT_PURGE']) as locked: if not locked: logger.warning('%s for %s is already in progress', func_name, contributor) return until = datetime.date.today() - datetime.timedelta(days=int(config['nb_days_to_keep'])) logger.info('purge trip update for {} until {}'.format(contributor, until)) TripUpdate.remove_by_contributors_and_period(contributors=[contributor], start_date=None, end_date=until) logger.info('%s for %s is finished', func_name, contributor)
def test_past_midnight(): """ integration of a past midnight """ navitia_vj = { "trip": {"id": "vehicle_journey:1"}, "stop_times": [ { "utc_arrival_time": datetime.time(22, 10), "utc_departure_time": datetime.time(22, 15), "stop_point": {"id": "sa:1"}, }, # arrive at sa:2 at 23:10 and leave the day after { "utc_arrival_time": datetime.time(23, 10), "utc_departure_time": datetime.time(2, 15), "stop_point": {"id": "sa:2", "stop_area": {"timezone": "UTC"}}, }, { "utc_arrival_time": datetime.time(3, 20), "utc_departure_time": datetime.time(3, 25), "stop_point": {"id": "sa:3", "stop_area": {"timezone": "UTC"}}, }, ], } with app.app_context(): contributor = model.Contributor( id=GTFS_CONTRIBUTOR_ID, navitia_coverage=None, connector_type=ConnectorType.gtfs_rt.value ) builder = kirin.poller_workers.gtfs_rt.KirinModelBuilder(contributor) vj = VehicleJourney( navitia_vj, datetime.datetime(2015, 9, 8, 21, 15, 0), datetime.datetime(2015, 9, 9, 4, 20, 0) ) trip_update = TripUpdate(vj, status="update", contributor_id=contributor.id) st = StopTimeUpdate({"id": "sa:2"}, departure_delay=timedelta(minutes=31), dep_status="update", order=1) real_time_update = make_rt_update(raw_data=None, contributor_id=contributor.id) trip_update.stop_time_updates.append(st) res, _ = handle(builder, 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.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:51", day=9) assert trip_update.stop_time_updates[2].arrival_delay == timedelta(minutes=31) assert trip_update.stop_time_updates[2].departure == _dt("3:56", day=9) assert trip_update.stop_time_updates[2].departure_delay == timedelta(minutes=31)
def handle(builder, real_time_update, trip_updates): """ Receive a RealTimeUpdate with at least one TripUpdate filled with the data received by the connector. Each TripUpdate is associated with the base-schedule VehicleJourney, complete/merge realtime is done using builder Then persist in db, publish for Navitia Returns real_time_update and the log_dict """ if not real_time_update: raise TypeError() id_timestamp_tuples = [(tu.vj.navitia_trip_id, tu.vj.start_timestamp) for tu in trip_updates] old_trip_updates = TripUpdate.find_by_dated_vjs(id_timestamp_tuples) for trip_update in trip_updates: # find if there is already a row in db old = next( (tu for tu in old_trip_updates if tu.vj.navitia_trip_id == trip_update.vj.navitia_trip_id and tu.vj.start_timestamp == trip_update.vj.start_timestamp), None, ) # merge the base schedule, the current realtime, and the new realtime current_trip_update = builder.merge_trip_updates( trip_update.vj.navitia_vj, old, trip_update) # manage and adjust consistency if possible if current_trip_update is not None and check_consistency( current_trip_update): # we have to link the current_vj_update with the new real_time_update # this link is done quite late to avoid too soon persistence of trip_update by sqlalchemy current_trip_update.real_time_updates.append(real_time_update) db_commit(real_time_update) feed = convert_to_gtfsrt(real_time_update.trip_updates, gtfs_realtime_pb2.FeedHeader.DIFFERENTIAL) feed_str = feed.SerializeToString() publish(feed_str, builder.contributor.id) data_time = datetime.datetime.utcfromtimestamp(feed.header.timestamp) log_dict = { "contributor": builder.contributor.id, "timestamp": data_time, "output_trip_update_count": len(feed.entity), "output_feed_size": sys.getsizeof(feed_str), } # After merging trip_updates information of connector realtime, navitia and kirin database, if there is no new # information destined to navitia, update real_time_update with status = 'KO' and a proper error message. if not real_time_update.trip_updates and real_time_update.status == "pending": msg = "No new information destined for navitia on {}".format( real_time_update.contributor_id) set_rtu_status_ko(real_time_update, msg, is_reprocess_same_data_allowed=False) logging.getLogger(__name__).warning("RealTimeUpdate id={}: {}".format( real_time_update.id, msg), extra=log_dict) db_commit(real_time_update) return real_time_update, log_dict
def handle(real_time_update, trip_updates, contributor): """ receive a RealTimeUpdate with at least one TripUpdate filled with the data received by the connector. each TripUpdate is associated with the VehicleJourney returned by jormugandr """ if not real_time_update: raise TypeError() for trip_update in trip_updates: # find if there already a row in db old = TripUpdate.find_by_dated_vj(trip_update.vj.navitia_trip_id, trip_update.vj.circulation_date) # merge the theoric, the current realtime, and the new realtime current_trip_update = merge(trip_update.vj.navitia_vj, old, trip_update) # manage and adjust consistency if possible if manage_consistency(current_trip_update): # we have to link the current_vj_update with the new real_time_update # this link is done quite late to avoid too soon persistence of trip_update by sqlalchemy current_trip_update.real_time_updates.append(real_time_update) persist(real_time_update) feed = convert_to_gtfsrt(real_time_update.trip_updates) publish(feed, contributor) return real_time_update
def check_db_ire_96231_normal(): with app.app_context(): assert len(RealTimeUpdate.query.all()) >= 1 assert len(TripUpdate.query.all()) >= 1 assert len(StopTimeUpdate.query.all()) >= 6 db_trip_delayed = TripUpdate.find_by_dated_vj( 'trip:OCETrainTER-87212027-85000109-3:11859', datetime.datetime(2015, 9, 21, 15, 21, tzinfo=utc)) assert db_trip_delayed assert db_trip_delayed.vj.navitia_trip_id == 'trip:OCETrainTER-87212027-85000109-3:11859' assert db_trip_delayed.vj.get_start_timestamp() == datetime.datetime( 2015, 9, 21, 15, 21, tzinfo=utc) assert db_trip_delayed.vj_id == db_trip_delayed.vj.id assert db_trip_delayed.status == 'update' # 6 stop times must have been created assert len(db_trip_delayed.stop_time_updates) == 6 # the first stop (in Strasbourg) is not in the IRE, only on navitia's base schedule # no delay then, only base schedule # Navitia's time are in local, so departure 17h21 in paris is 15h21 in UTC first_st = db_trip_delayed.stop_time_updates[0] assert first_st.stop_id == 'stop_point:OCE:SP:TrainTER-87212027' assert first_st.arrival == datetime.datetime(2015, 9, 21, 15, 21) assert first_st.arrival_status == 'none' assert first_st.arrival_delay == timedelta(0) assert first_st.departure == datetime.datetime(2015, 9, 21, 15, 21) assert first_st.departure_delay == timedelta(0) assert first_st.departure_status == 'none' assert first_st.message is None #the departure time has been updated with a delay at 0 second_st = db_trip_delayed.stop_time_updates[1] assert second_st.stop_id == 'stop_point:OCE:SP:TrainTER-87214056' assert second_st.arrival == datetime.datetime(2015, 9, 21, 15, 38) assert second_st.arrival_status == 'none' assert second_st.arrival_delay == timedelta(0) assert second_st.departure == datetime.datetime(2015, 9, 21, 15, 40) assert second_st.departure_delay == timedelta(minutes=0) assert second_st.departure_status == 'update' assert second_st.message == 'Affluence exceptionnelle de voyageurs' # last stop is gare de Basel-SBB, the arrival is also updated with a delay at 0 last_st = db_trip_delayed.stop_time_updates[-1] assert last_st.stop_id == 'stop_point:OCE:SP:TrainTER-85000109' assert last_st.arrival == datetime.datetime(2015, 9, 21, 16, 39) assert last_st.arrival_status == 'update' assert last_st.arrival_delay == timedelta(minutes=0) #The departure should be the same has the theroric one #except that it's not the case, we have messed with it when the vj was delayed, but we didn't put it back #like it was when the train catch up is delay try: assert last_st.departure == datetime.datetime(2015, 9, 21, 16, 39) assert last_st.departure_delay == timedelta(minutes=0) assert last_st.departure_status == 'none' assert last_st.message == 'Affluence exceptionnelle de voyageurs' except AssertionError: pass # xfail: we don't change back the departure :( assert db_trip_delayed.contributor == 'realtime.ire'
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(_create_db_vj(navitia_vj), status="delete", contributor_id=COTS_CONTRIBUTOR_ID) real_time_update = make_rt_update( raw_data=None, connector_type=ConnectorType.cots.value, contributor_id=COTS_CONTRIBUTOR_ID) res, _ = handle(real_time_update, [trip_update], contributor_id=COTS_CONTRIBUTOR_ID, is_new_complete=False) 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_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(): contributor = model.Contributor( id=GTFS_CONTRIBUTOR_ID, navitia_coverage=None, connector_type=ConnectorType.gtfs_rt.value ) builder = kirin.poller_workers.gtfs_rt.KirinModelBuilder(contributor) trip_update = TripUpdate( _create_db_vj(navitia_vj), status="delete", effect=TripEffect.NO_SERVICE.name, contributor_id=contributor.id, ) real_time_update = make_rt_update(raw_data=None, contributor_id=contributor.id) res, _ = handle(builder, real_time_update, [trip_update]) assert len(res.trip_updates) == 1 trip_update = res.trip_updates[0] assert trip_update.status == "delete" assert len(trip_update.stop_time_updates) == 3 for stu in trip_update.stop_time_updates: assert stu.arrival_status == "delete" assert stu.departure_status == "delete" assert len(trip_update.real_time_updates) == 2
def create_trip_update(vj_id, trip_id, circulation_date, contributor_id=COTS_CONTRIBUTOR_ID): vj = VehicleJourney( { "trip": { "id": trip_id }, "stop_times": [{ "utc_arrival_time": datetime.time(8, 0), "stop_point": { "stop_area": { "timezone": "UTC" } } }], }, datetime.datetime.combine(circulation_date, datetime.time(7, 0)), datetime.datetime.combine(circulation_date, datetime.time(9, 0)), ) vj.id = vj_id trip_update = TripUpdate(vj=vj, contributor_id=contributor_id) db.session.add(vj) db.session.add(trip_update) return trip_update
def handle(real_time_update, trip_updates, contributor, is_new_complete=False): """ receive a RealTimeUpdate with at least one TripUpdate filled with the data received by the connector. each TripUpdate is associated with the VehicleJourney returned by jormugandr Returns real_time_update and the log_dict """ if not real_time_update: raise TypeError() id_timestamp_tuples = [(tu.vj.navitia_trip_id, tu.vj.get_start_timestamp()) for tu in trip_updates] old_trip_updates = TripUpdate.find_by_dated_vjs(id_timestamp_tuples) for trip_update in trip_updates: # find if there is already a row in db old = next((tu for tu in old_trip_updates if tu.vj.navitia_trip_id == trip_update.vj.navitia_trip_id and tu.vj.get_start_timestamp() == trip_update.vj.get_start_timestamp()), None) # merge the base schedule, the current realtime, and the new realtime current_trip_update = merge(trip_update.vj.navitia_vj, old, trip_update, is_new_complete=is_new_complete) # manage and adjust consistency if possible if current_trip_update and manage_consistency(current_trip_update): # we have to link the current_vj_update with the new real_time_update # this link is done quite late to avoid too soon persistence of trip_update by sqlalchemy current_trip_update.real_time_updates.append(real_time_update) persist(real_time_update) feed = convert_to_gtfsrt(real_time_update.trip_updates) feed_str = feed.SerializeToString() publish(feed_str, contributor) data_time = datetime.datetime.utcfromtimestamp(feed.header.timestamp) log_dict = {'contributor': contributor, 'timestamp': data_time, 'trip_update_count': len(feed.entity), 'size': len(feed_str)} return real_time_update, log_dict
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 handle(real_time_update, trip_updates): """ receive a RealTimeUpdate with at least one TripUpdate filled with the data received by the connector. each TripUpdate is associated with the VehicleJourney returned by jormugandr """ if not real_time_update: raise TypeError() for trip_update in trip_updates: #find if there already a row in db old = TripUpdate.find_by_dated_vj(trip_update.vj.navitia_id, trip_update.vj.circulation_date) #merge the theoric, the current realtime, and the new relatime current_trip_update = merge(trip_update, old) # we have to link the current_vj_update with the new real_time_update # this link is done quite late to avoid too soon persistence of trip_update by sqlalchemy current_trip_update.real_time_updates.append(real_time_update) persist(real_time_update) feed = convert_to_gtfsrt([real_time_update]) publish(feed, real_time_update) return real_time_update
def check_db_ire_96231_delayed(motif_externe_is_null=False): with app.app_context(): assert len(RealTimeUpdate.query.all()) >= 1 assert len(TripUpdate.query.all()) >= 1 assert len(StopTimeUpdate.query.all()) >= 6 db_trip_delayed = TripUpdate.find_by_dated_vj( 'trip:OCETrainTER-87212027-85000109-3:11859', datetime.datetime(2015, 9, 21, 15, 21, tzinfo=utc)) assert db_trip_delayed assert db_trip_delayed.vj.navitia_trip_id == 'trip:OCETrainTER-87212027-85000109-3:11859' assert db_trip_delayed.vj.get_start_timestamp() == datetime.datetime( 2015, 9, 21, 15, 21, tzinfo=utc) assert db_trip_delayed.vj_id == db_trip_delayed.vj.id assert db_trip_delayed.status == 'update' # 6 stop times must have been created assert len(db_trip_delayed.stop_time_updates) == 6 # the first stop (in Strasbourg) is not in the IRE, only on navitia's base schedule # no delay then, only base schedule # Navitia's time are in local, so departure 17h21 in paris is 15h21 in UTC first_st = db_trip_delayed.stop_time_updates[0] assert first_st.stop_id == 'stop_point:OCE:SP:TrainTER-87212027' assert first_st.arrival == datetime.datetime(2015, 9, 21, 15, 21) assert first_st.arrival_status == 'none' assert first_st.arrival_delay == timedelta(0) assert first_st.departure == datetime.datetime(2015, 9, 21, 15, 21) assert first_st.departure_delay == timedelta(0) assert first_st.departure_status == 'none' assert first_st.message is None second_st = db_trip_delayed.stop_time_updates[1] assert second_st.stop_id == 'stop_point:OCE:SP:TrainTER-87214056' assert second_st.arrival == datetime.datetime(2015, 9, 21, 15, 38) assert second_st.arrival_status == 'none' assert second_st.arrival_delay == timedelta(0) assert second_st.departure == datetime.datetime(2015, 9, 21, 15, 55) assert second_st.departure_delay == timedelta(minutes=15) assert second_st.departure_status == 'update' if motif_externe_is_null: assert second_st.message is None else: assert second_st.message == 'Affluence exceptionnelle de voyageurs' # last stop is gare de Basel-SBB, delay's only at the arrival last_st = db_trip_delayed.stop_time_updates[-1] assert last_st.stop_id == 'stop_point:OCE:SP:TrainTER-85000109' assert last_st.arrival == datetime.datetime(2015, 9, 21, 16, 54) assert last_st.arrival_status == 'update' assert last_st.arrival_delay == timedelta(minutes=15) #The departure is consistent with arrival assert last_st.departure == datetime.datetime(2015, 9, 21, 16, 54) assert last_st.departure_delay == timedelta(minutes=15) assert last_st.departure_status == 'none' if motif_externe_is_null: assert second_st.message is None else: assert second_st.message == 'Affluence exceptionnelle de voyageurs' assert db_trip_delayed.contributor == 'realtime.ire'
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_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_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": [ { "utc_arrival_time": None, "utc_departure_time": datetime.time(8, 10), "stop_point": {"id": "sa:1", "stop_area": {"timezone": "UTC"}}, }, { "utc_arrival_time": datetime.time(9, 10), "utc_departure_time": None, "stop_point": {"id": "sa:2", "stop_area": {"timezone": "UTC"}}, }, ], } with app.app_context(): contributor = model.Contributor( id=GTFS_CONTRIBUTOR_ID, navitia_coverage=None, connector_type=ConnectorType.gtfs_rt.value ) builder = kirin.poller_workers.gtfs_rt.KirinModelBuilder(contributor) trip_update = TripUpdate(_create_db_vj(navitia_vj), contributor_id=contributor.id, status="update") st = StopTimeUpdate({"id": "sa:1"}, departure_delay=timedelta(minutes=5), dep_status="update") real_time_update = make_rt_update(raw_data=None, contributor_id=contributor.id) trip_update.stop_time_updates.append(st) res, _ = handle(builder, 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.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:15") assert trip_update.stop_time_updates[1].arrival == _dt("9:15") # 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:15") assert db_st_updates[1].arrival == _dt("9:15") assert db_st_updates[1].trip_update_id == db_trip_updates[0].vj_id
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') 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') 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 test_handle_new_vj(): """an easy one: we have one vj with only one stop time updated""" navitia_vj = {'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 trip_update.status = 'update' st = StopTimeUpdate({'id': 'sa:1'}, departure=_dt("8:15"), arrival=None) real_time_update = RealTimeUpdate(raw_data=None, connector='ire') 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.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 == None assert trip_update.stop_time_updates[1].stop_id == 'sa:2' assert trip_update.stop_time_updates[1].departure == None 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 == None 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 == None assert db_st_updates[1].arrival == _dt("9:10") assert db_st_updates[1].trip_update_id == db_trip_updates[0].vj_id
def check_db_ire_96231_delayed(): with app.app_context(): assert len(RealTimeUpdate.query.all()) >= 1 assert len(TripUpdate.query.all()) >= 1 assert len(StopTimeUpdate.query.all()) >= 6 db_trip_delayed = TripUpdate.find_by_dated_vj('trip:OCETrainTER-87212027-85000109-3:11859', datetime.date(2015, 9, 21)) assert db_trip_delayed assert db_trip_delayed.vj.navitia_trip_id == 'trip:OCETrainTER-87212027-85000109-3:11859' assert db_trip_delayed.vj.circulation_date == datetime.date(2015, 9, 21) assert db_trip_delayed.vj_id == db_trip_delayed.vj.id assert db_trip_delayed.status == 'update' # 6 stop times must have been created assert len(db_trip_delayed.stop_time_updates) == 6 # the first stop (in Strasbourg) is not in the IRE, only on navitia's base schedule # no delay then, only base schedule # Navitia's time are in local, so departure 17h21 in paris is 15h21 in UTC first_st = db_trip_delayed.stop_time_updates[0] assert first_st.stop_id == 'stop_point:OCE:SP:TrainTER-87212027' assert first_st.arrival == datetime.datetime(2015, 9, 21, 15, 21) assert first_st.arrival_status == 'none' assert first_st.arrival_delay == timedelta(0) assert first_st.departure == datetime.datetime(2015, 9, 21, 15, 21) assert first_st.departure_delay == timedelta(0) assert first_st.departure_status == 'none' assert first_st.message is None second_st = db_trip_delayed.stop_time_updates[1] assert second_st.stop_id == 'stop_point:OCE:SP:TrainTER-87214056' assert second_st.arrival == datetime.datetime(2015, 9, 21, 15, 38) assert second_st.arrival_status == 'none' assert second_st.arrival_delay == timedelta(0) assert second_st.departure == datetime.datetime(2015, 9, 21, 15, 55) assert second_st.departure_delay == timedelta(minutes=15) assert second_st.departure_status == 'update' assert second_st.message == 'Affluence exceptionnelle de voyageurs' # last stop is gare de Basel-SBB, delay's only at the arrival last_st = db_trip_delayed.stop_time_updates[-1] assert last_st.stop_id == 'stop_point:OCE:SP:TrainTER-85000109' assert last_st.arrival == datetime.datetime(2015, 9, 21, 16, 54) assert last_st.arrival_status == 'update' assert last_st.arrival_delay == timedelta(minutes=15) #The departure is consistent with arrival assert last_st.departure == datetime.datetime(2015, 9, 21, 16, 54) assert last_st.departure_delay == timedelta(minutes=15) assert last_st.departure_status == 'none' assert last_st.message == 'Affluence exceptionnelle de voyageurs' assert db_trip_delayed.contributor == 'realtime.ire'
def check_db_ire_96231_trip_removal(): with app.app_context(): assert len(RealTimeUpdate.query.all()) >= 1 assert len(TripUpdate.query.all()) >= 1 assert len(StopTimeUpdate.query.all()) >= 0 db_trip_removal = TripUpdate.find_by_dated_vj('vehicle_journey:OCETrainTER-87212027-85000109-3:11859', datetime.date(2015, 9, 21)) assert db_trip_removal assert db_trip_removal.vj.navitia_id == 'vehicle_journey:OCETrainTER-87212027-85000109-3:11859' assert db_trip_removal.vj.circulation_date == datetime.date(2015, 9, 21) assert db_trip_removal.vj_id == db_trip_removal.vj.id assert db_trip_removal.status == 'delete' # full trip removal : no stop_time to precise assert len(db_trip_removal.stop_time_updates) == 0
def check_db_ire_6113_trip_removal(): with app.app_context(): assert len(RealTimeUpdate.query.all()) >= 1 assert len(TripUpdate.query.all()) >= 1 assert len(StopTimeUpdate.query.all()) >= 0 db_trip_removal = TripUpdate.find_by_dated_vj('vehicle_journey:OCETGV-87686006-87751008-2:25768', datetime.date(2015, 10, 6)) assert db_trip_removal assert db_trip_removal.vj.navitia_id == 'vehicle_journey:OCETGV-87686006-87751008-2:25768' assert db_trip_removal.vj.circulation_date == datetime.date(2015, 10, 6) assert db_trip_removal.vj_id == db_trip_removal.vj.id assert db_trip_removal.status == 'delete' # full trip removal : no stop_time to precise assert len(db_trip_removal.stop_time_updates) == 0
def check_db_ire_96231_delayed(): with app.app_context(): assert len(RealTimeUpdate.query.all()) >= 1 assert len(TripUpdate.query.all()) >= 1 assert len(StopTimeUpdate.query.all()) >= 6 db_trip_delayed = TripUpdate.find_by_dated_vj('vehicle_journey:OCETrainTER-87212027-85000109-3:11859', datetime.date(2015, 9, 21)) assert db_trip_delayed assert db_trip_delayed.vj.navitia_id == 'vehicle_journey:OCETrainTER-87212027-85000109-3:11859' assert db_trip_delayed.vj.circulation_date == datetime.date(2015, 9, 21) assert db_trip_delayed.vj_id == db_trip_delayed.vj.id assert db_trip_delayed.status == 'update' # 6 stop times must have been created assert len(db_trip_delayed.stop_time_updates) == 6
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 = {'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) 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'
def check_db_ire_6114_trip_removal(): with app.app_context(): assert len(RealTimeUpdate.query.all()) >= 1 assert len(TripUpdate.query.all()) >= 1 assert len(StopTimeUpdate.query.all()) >= 0 db_trip_removal = TripUpdate.find_by_dated_vj('trip:OCETGV-87686006-87751008-2:25768-2', datetime.date(2015, 10, 6)) assert db_trip_removal assert db_trip_removal.vj.navitia_trip_id == 'trip:OCETGV-87686006-87751008-2:25768-2' assert db_trip_removal.vj.circulation_date == datetime.date(2015, 10, 6) assert db_trip_removal.vj_id == db_trip_removal.vj.id assert db_trip_removal.status == 'delete' print db_trip_removal.message assert db_trip_removal.message == u'Accident à un Passage à Niveau' # full trip removal : no stop_time to precise assert len(db_trip_removal.stop_time_updates) == 0
def callback(body, message): try: 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 begin_date = None end_date = None if hasattr(task.load_realtime, "begin_date"): if task.load_realtime.begin_date: begin_date = str_to_date(task.load_realtime.begin_date) if hasattr(task.load_realtime, "end_date"): if task.load_realtime.end_date: end_date = str_to_date(task.load_realtime.end_date) feed = convert_to_gtfsrt(TripUpdate.find_by_contributor_period(task.load_realtime.contributors, begin_date, end_date), gtfs_realtime_pb2.FeedHeader.FULL_DATASET) with self._get_producer() as producer: log.info('Publishing full feed...') producer.publish(feed.SerializeToString(), routing_key=task.load_realtime.queue_name) log.info('Full feed published.') finally: db.session.remove()
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
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 = TripUpdate.find_by_contributor_period(['C1'], datetime.date(2015, 9, 6)) assert len(rtu) == 3 assert rtu[0].vj_id == '70866ce8-0638-4fa1-8556-1ddfa22d09d3' assert rtu[1].vj_id == '70866ce8-0638-4fa1-8556-1ddfa22d09d4' assert rtu[2].vj_id == '70866ce8-0638-4fa1-8556-1ddfa22d09d5' """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date 20150908 | | """ rtu = TripUpdate.find_by_contributor_period(['C1'], datetime.date(2015, 9, 8)) assert len(rtu) == 3 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date | 20150909 | | """ rtu = TripUpdate.find_by_contributor_period(['C1'], datetime.date(2015, 9, 9)) assert len(rtu) == 2 assert rtu[0].vj_id == '70866ce8-0638-4fa1-8556-1ddfa22d09d4' assert rtu[1].vj_id == '70866ce8-0638-4fa1-8556-1ddfa22d09d5' """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date | 20150910 | """ rtu = TripUpdate.find_by_contributor_period(['C1'], datetime.date(2015, 9, 10)) assert len(rtu) == 2 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date | | 20150911 | """ rtu = TripUpdate.find_by_contributor_period(['C1'], datetime.date(2015, 9, 11)) assert len(rtu) == 1 assert rtu[0].vj_id == '70866ce8-0638-4fa1-8556-1ddfa22d09d5' """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date | | 20150912 """ rtu = TripUpdate.find_by_contributor_period(['C1'], datetime.date(2015, 9, 12)) assert len(rtu) == 1 """ contributor C1 VehicleJourney vj1 Circulation date 20150908 20150910 20150912 | | | request date | | | 20150913 """ rtu = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['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 = TripUpdate.find_by_contributor_period(['C1'], datetime.date(2015, 9, 13), datetime.date(2015, 9, 14)) assert len(rtu) == 0 rtu = TripUpdate.find_by_contributor_period(['C2'], datetime.date(2015, 9, 6)) assert len(rtu) == 1 rtu = TripUpdate.find_by_contributor_period(['C2'], datetime.date(2015, 9, 12)) assert len(rtu) == 1 rtu = TripUpdate.find_by_contributor_period(['C1', 'C2'], datetime.date(2015, 9, 12)) assert len(rtu) == 2