def test_cots_train_trip_removal(mock_navitia_fixture): """ test the import of cots_train_6113_trip_removal.json """ input_train_trip_removed = get_fixture_data( "cots_train_6113_trip_removal.json") with app.app_context(): contributor = model.Contributor( id=COTS_CONTRIBUTOR_ID, navitia_coverage=None, connector_type=ConnectorType.cots.value) wrap_build(KirinModelBuilder(contributor), input_train_trip_removed) trip_updates = TripUpdate.query.all() assert len(trip_updates) == 1 trip_up = trip_updates[0] assert trip_up.vj.navitia_trip_id == "trip:OCETGV-87686006-87751008-2:25768" assert trip_up.vj_id == trip_up.vj.id assert trip_up.status == "delete" # full trip removal : no stop_time to precise assert len(trip_up.stop_time_updates) == 0 # verify trip_update effect: assert trip_up.effect == "NO_SERVICE"
def post(self, id=None): if id is None: abort(400, message="Contributor's id is missing") contributor = (model.Contributor.query_existing().filter_by( id=id, connector_type=ConnectorType.piv.value).first()) if not contributor: abort(404, message="Contributor '{}' not found".format(id)) raw_json = _get_piv(flask.globals.request) wrap_build(KirinModelBuilder(contributor), raw_json) return {"message": "PIV feed processed"}, 200
def gtfs_poller(self, config): func_name = "gtfs_poller" contributor = ( model.Contributor.query_existing() .filter_by(id=config.get("contributor"), connector_type=ConnectorType.gtfs_rt.value) .first() ) logger = logging.LoggerAdapter(logging.getLogger(__name__), extra={"contributor": contributor.id}) lock_name = make_kirin_lock_name(func_name, contributor.id) with get_lock(logger, lock_name, app.config[str("REDIS_LOCK_TIMEOUT_POLLER")]) as locked: if not locked or not config.get("feed_url"): new_relic.ignore_transaction() return retrieval_interval = config.get("retrieval_interval", 10) if _is_last_call_too_recent(func_name, contributor.id, retrieval_interval): # do nothing if the last call is too recent new_relic.ignore_transaction() return logger.debug("polling of %s", config.get("feed_url")) # We do a HEAD request at the very beginning of polling and we compare it with the previous one to check if # the gtfs-rt is changed. # If the HEAD request or Redis get/set fail, we just ignore this part and do the polling anyway if not _is_newer(config): new_relic.ignore_transaction() manage_db_no_new(connector_type=ConnectorType.gtfs_rt.value, contributor_id=contributor.id) return try: response = _retrieve_gtfsrt(config) response.raise_for_status() except Exception as e: manage_db_error( data="", connector_type=ConnectorType.gtfs_rt.value, contributor_id=contributor.id, error="Http Error", is_reprocess_same_data_allowed=True, ) logger.debug(six.text_type(e)) return wrap_build(KirinModelBuilder(contributor), response.content) logger.info("%s for %s is finished", func_name, contributor.id)
def process_message(self, body, message): wrap_build(self.builder, body) # TODO: We might want to not acknowledge the message in case of error in # the processing. message.ack()
def post(self): raw_json = get_cots(flask.globals.request) wrap_build(self.builder, raw_json) return "OK", 200
def test_cots_train_delayed(mock_navitia_fixture): """ test the import of cots_train_96231_delayed.json """ input_train_delayed = get_fixture_data("cots_train_96231_delayed.json") with app.app_context(): contributor = model.Contributor( id=COTS_CONTRIBUTOR_ID, navitia_coverage=None, connector_type=ConnectorType.cots.value) wrap_build(KirinModelBuilder(contributor), input_train_delayed) trip_updates = TripUpdate.query.all() assert len(trip_updates) == 1 trip_up = trip_updates[0] assert trip_up.vj.navitia_trip_id == "trip:OCETrainTER-87212027-85000109-3:11859" assert trip_up.vj_id == trip_up.vj.id assert trip_up.status == "update" assert trip_up.effect == "SIGNIFICANT_DELAYS" # 5 stop times must have been created assert len(trip_up.stop_time_updates) == 6 # first impacted stop time should be 'gare de Sélestat' st = trip_up.stop_time_updates[1] assert st.id assert st.stop_id == "stop_point:OCE:SP:TrainTER-87214056" # the COTS data has no listeHoraireProjeteArrivee, so the status is 'none' assert st.arrival == datetime(2015, 9, 21, 15, 38, 0) assert st.arrival_delay == timedelta(minutes=0) assert st.arrival_status == "none" assert st.departure == datetime(2015, 9, 21, 15, 55, 0) assert st.departure_delay == timedelta(minutes=15) assert st.departure_status == "update" assert st.message == "Affluence exceptionnelle de voyageurs" # second impacted should be 'gare de Colmar' st = trip_up.stop_time_updates[2] assert st.id assert st.stop_id == "stop_point:OCE:SP:TrainTER-87182014" assert st.arrival == datetime(2015, 9, 21, 16, 6, 0) assert st.arrival_delay == timedelta(minutes=15) assert st.arrival_status == "update" assert st.departure == datetime(2015, 9, 21, 16, 8, 0) assert st.departure_delay == timedelta(minutes=15) assert st.departure_status == "update" assert st.message == "Affluence exceptionnelle de voyageurs" # last should be 'gare de Basel-SBB' st = trip_up.stop_time_updates[-1] assert st.id assert st.stop_id == "stop_point:OCE:SP:TrainTER-85000109" assert st.arrival == datetime(2015, 9, 21, 16, 54, 0) assert st.arrival_delay == timedelta(minutes=15) assert st.arrival_status == "update" # no departure since it's the last (thus the departure will be before the arrival) assert st.departure == datetime(2015, 9, 21, 16, 54, 0) assert st.departure_delay == timedelta(minutes=15) assert st.departure_status == "none" assert st.message == "Affluence exceptionnelle de voyageurs"
def test_get_action_on_trip_add(mock_navitia_fixture): """ Test the function _get_action_on_trip with different type of flux cots returns: 1. Fist trip add(AJOUTEE)-> FIRST_TIME_ADDED 2. Add followed by update (PERTURBEE) -> PREVIOUSLY_ADDED 3. Delete followed by add -> FIRST_TIME_ADDED """ with app.app_context(): # Test for the first add: should be FIRST_TIME_ADDED input_trip_add = get_fixture_data("cots_train_151515_added_trip.json") json_data = json.loads(input_trip_add) dict_version = model_maker.get_value(json_data, "nouvelleVersion") train_numbers = model_maker.get_value(dict_version, "numeroCourse") pdps = model_maker._retrieve_interesting_pdp( model_maker.get_value(dict_version, "listePointDeParcours")) action_on_trip = model_maker._get_action_on_trip( train_numbers, dict_version, pdps) assert action_on_trip == ActionOnTrip.FIRST_TIME_ADDED.name # Test for add followed by update should be PREVIOUSLY_ADDED contributor = model.Contributor( id=COTS_CONTRIBUTOR_ID, navitia_coverage=None, connector_type=ConnectorType.cots.value) builder = KirinModelBuilder(contributor) wrap_build(builder, input_trip_add) input_update_added_trip = get_fixture_data( "cots_train_151515_added_trip_with_delay.json") json_data = json.loads(input_update_added_trip) dict_version = model_maker.get_value(json_data, "nouvelleVersion") train_numbers = model_maker.get_value(dict_version, "numeroCourse") pdps = model_maker._retrieve_interesting_pdp( model_maker.get_value(dict_version, "listePointDeParcours")) action_on_trip = model_maker._get_action_on_trip( train_numbers, dict_version, pdps) assert action_on_trip == ActionOnTrip.PREVIOUSLY_ADDED.name # Clean database for further test clean_db() # Delete the recently added trip followed by add: should be FIRST_TIME_ADDED wrap_build(builder, input_trip_add) input_trip_delete = get_fixture_data( "cots_train_151515_deleted_trip_with_delay_and_stop_time_added.json" ) wrap_build(builder, input_trip_delete) input_added_trip = get_fixture_data( "cots_train_151515_added_trip.json") json_data = json.loads(input_added_trip) dict_version = model_maker.get_value(json_data, "nouvelleVersion") train_numbers = model_maker.get_value(dict_version, "numeroCourse") pdps = model_maker._retrieve_interesting_pdp( model_maker.get_value(dict_version, "listePointDeParcours")) action_on_trip = model_maker._get_action_on_trip( train_numbers, dict_version, pdps) assert action_on_trip == ActionOnTrip.FIRST_TIME_ADDED.name