def test_create_vehicle(entity_key, entity_type, is_assigned, expect_vehicle, train_id, expected_vehicle_id): trip = gtfs.TripDescriptor(trip_id=TRIP_ID) mta_ext = trip.Extensions[trip._extensions_by_number[ gtfs.MTA_EXTENSION_ID]] if train_id is not None: mta_ext.train_id = train_id if is_assigned is not None: mta_ext.is_assigned = is_assigned entity_key_to_entity = {entity_key: entity_type(trip=trip)} message = gtfs.FeedMessage( header=gtfs.FeedHeader(gtfs_realtime_version="2.0"), entity=[gtfs.FeedEntity(id="1", **entity_key_to_entity)], ) expected_vehicle = parse.Vehicle(id=expected_vehicle_id, trip_id=TRIP_ID) parser = SubwayTripsParser() parser.load_content(message.SerializeToString()) actual_vehicles = list(parser.get_vehicles()) if expect_vehicle: assert [expected_vehicle] == actual_vehicles else: if entity_type is gtfs.VehiclePosition: assert [parse.Vehicle(id=None, trip_id=TRIP_ID)] == actual_vehicles else: assert [] == actual_vehicles
def test_vehicle__set_stop_simple_case( db_session, current_update, trip_for_vehicle, stop_1_3, provide_stop_id, provide_stop_sequence, ): vehicle = parse.Vehicle( id="vehicle_id", trip_id="trip_id", current_stop_id=stop_1_3.id if provide_stop_id else None, current_stop_sequence=3 if provide_stop_sequence else None, ) importdriver.run_import(current_update.pk, ParserForTesting([vehicle])) persisted_vehicle = db_session.query(models.Vehicle).all()[0] if not provide_stop_id and not provide_stop_sequence: assert persisted_vehicle.current_stop is None assert persisted_vehicle.current_stop_sequence is None else: assert persisted_vehicle.current_stop == stop_1_3 assert persisted_vehicle.current_stop_sequence == 3
def test_vehicle__move_between_trips_attached( db_session, add_model, system_1, route_1_1, previous_update, current_update, trip_for_vehicle, stop_1_3, ): vehicle = add_model( models.Vehicle( id="vehicle_id", system=system_1, source=previous_update, trip=trip_for_vehicle, )) importdriver.run_import( current_update.pk, ParserForTesting([ parse.Trip(id="trip_id_2", route_id=route_1_1.id), parse.Vehicle(id="vehicle_id", trip_id="trip_id_2"), ]), ) db_session.refresh(trip_for_vehicle) new_trip = (db_session.query( models.Trip).filter(models.Trip.id == "trip_id_2").one_or_none()) assert trip_for_vehicle.vehicle is None assert new_trip.vehicle == vehicle
def test_vehicle__merged_vehicle_edge_case( db_session, previous_update, current_update, trip_for_vehicle, stop_1_3, ): vehicle_1 = parse.Vehicle(id=None, trip_id="trip_id") vehicle_2 = parse.Vehicle(id="vehicle_id", trip_id=None) vehicle_3 = parse.Vehicle(id="vehicle_id", trip_id="trip_id") importdriver.run_import(previous_update.pk, ParserForTesting([vehicle_1, vehicle_2])) db_session.refresh(trip_for_vehicle) result = importdriver.run_import(current_update.pk, ParserForTesting([vehicle_3])) verify_stats(result, (0, 0, 2))
def test_vehicle__duplicate_trip_ids( db_session, current_update, trip_for_vehicle, stop_1_3, ): vehicle = parse.Vehicle(id=None, trip_id="trip_id") result = importdriver.run_import(current_update.pk, ParserForTesting([vehicle, vehicle])) verify_stats(result, (1, 0, 0))
def test_vehicle__no_vehicle_id( db_session, current_update, trip_for_vehicle, stop_1_3, vehicle_id, ): vehicle = parse.Vehicle(id=vehicle_id, trip_id="trip_id") importdriver.run_import(current_update.pk, ParserForTesting([vehicle])) persisted_vehicle = db_session.query(models.Vehicle).all()[0] db_session.refresh(trip_for_vehicle) assert trip_for_vehicle.vehicle == persisted_vehicle assert persisted_vehicle.trip == trip_for_vehicle
new_agency = parse.Agency(id="agency", name="New Agency", timezone="", url="") new_alert = parse.Alert(id="alert", cause=parse.Alert.Cause.DEMONSTRATION, effect=parse.Alert.Effect.DETOUR) new_route = parse.Route(id="route", type=parse.Route.Type.RAIL, description="new_route") new_stop = parse.Stop(id="route", name="new stop", latitude=0, longitude=0, type=parse.Stop.Type.STATION) new_vehicle = parse.Vehicle(id="vehicle", label="new vehicle", current_status=parse.Vehicle.Status.STOPPED_AT) @pytest.mark.parametrize( "entity_type,previous,current,expected_counts", [ [models.Alert, [], [new_alert], (1, 0, 0)], [ models.Alert, [ models.Alert( id="alert", cause=models.Alert.Cause.DEMONSTRATION, effect=models.Alert.Effect.DETOUR, )
def build_test_parse_vehicle_params(gtfs): for data in [ [ # Basic case 1 gtfs.TripUpdate( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), ), gtfs.VehiclePosition( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), current_stop_sequence=6, ), parse.Vehicle(id=VEHICLE_ID, trip_id=TRIP_ID, current_stop_sequence=6), ], [ # Basic case 2 gtfs.TripUpdate(trip=gtfs.TripDescriptor(trip_id=TRIP_ID),), gtfs.VehiclePosition( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), current_stop_sequence=6, ), parse.Vehicle(id=VEHICLE_ID, trip_id=TRIP_ID, current_stop_sequence=6), ], [ # Basic case 3 gtfs.TripUpdate( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), ), gtfs.VehiclePosition( vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), current_stop_sequence=6 ), parse.Vehicle(id=VEHICLE_ID, trip_id=TRIP_ID, current_stop_sequence=6), ], [ # Basic case 4 gtfs.TripUpdate( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), ), gtfs.VehiclePosition( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), current_stop_sequence=6 ), parse.Vehicle(id=VEHICLE_ID, trip_id=TRIP_ID, current_stop_sequence=6), ], [ # Basic case 5 gtfs.TripUpdate(trip=gtfs.TripDescriptor(trip_id=TRIP_ID),), gtfs.VehiclePosition( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), current_stop_sequence=6 ), parse.Vehicle(id=None, trip_id=TRIP_ID, current_stop_sequence=6), ], [ # Valid vehicle descriptor but no vehicle position gtfs.TripUpdate( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), ), None, parse.Vehicle(id=VEHICLE_ID, trip_id=TRIP_ID), ], [ # Invalid vehicle descriptor and no vehicle position gtfs.TripUpdate( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor(label=VEHICLE_ID), ), None, parse.Vehicle(trip_id=TRIP_ID, label=VEHICLE_ID), ], [ # No vehicle descriptor and no vehicle position gtfs.TripUpdate(trip=gtfs.TripDescriptor(trip_id=TRIP_ID),), None, None, ], [ # No trip update but vehicle position has trip descriptor None, gtfs.VehiclePosition( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), ), parse.Vehicle(id=VEHICLE_ID, trip_id=TRIP_ID), ], [ # No trip update and no trip descriptor None, gtfs.VehiclePosition(vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID)), parse.Vehicle(id=VEHICLE_ID), ], [ # Ensure trip data doesn't overwrite vehicle data gtfs.TripUpdate( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), ), gtfs.VehiclePosition( vehicle=gtfs.VehicleDescriptor( id=VEHICLE_ID, label=LABEL, license_plate=LICENCE_PLACE ) ), parse.Vehicle( id=VEHICLE_ID, trip_id=TRIP_ID, label=LABEL, license_plate=LICENCE_PLACE ), ], [ # Ensure vehicle data doesn't overwrite trip data gtfs.TripUpdate( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor( id=VEHICLE_ID, label=LABEL, license_plate=LICENCE_PLACE ), ), gtfs.VehiclePosition(vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID)), parse.Vehicle( id=VEHICLE_ID, trip_id=TRIP_ID, label=LABEL, license_plate=LICENCE_PLACE ), ], [ # Inconsistent trip <-> vehicle pairing gtfs.TripUpdate( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), ), gtfs.VehiclePosition( trip=gtfs.TripDescriptor(trip_id=TRIP_ID_2), vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), ), None, ], [ # Inconsistent trip <-> vehicle pairing gtfs.TripUpdate( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), ), gtfs.VehiclePosition( trip=gtfs.TripDescriptor(trip_id=TRIP_ID), vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID_2), ), None, ], [ # All data copied None, gtfs.VehiclePosition( vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), position=gtfs.Position( latitude=1.0, longitude=2.0, bearing=3.0, odometer=4.0, speed=5.0, ), current_stop_sequence=6, stop_id="7", current_status=VEHICLE_STOP_STATUS.value, congestion_level=CONGESTION_LEVEL.value, occupancy_status=OCCUPANCY_STATUS.value, ), parse.Vehicle( id=VEHICLE_ID, latitude=1.0, longitude=2.0, bearing=3.0, odometer=4.0, speed=5.0, current_stop_sequence=6, current_stop_id="7", current_status=VEHICLE_STOP_STATUS, congestion_level=CONGESTION_LEVEL, occupancy_status=OCCUPANCY_STATUS, ), ], [ # Some data not copied None, gtfs.VehiclePosition( vehicle=gtfs.VehicleDescriptor(id=VEHICLE_ID), position=gtfs.Position(latitude=1.0, longitude=2.0,), current_stop_sequence=6, stop_id="7", occupancy_status=OCCUPANCY_STATUS.value, ), parse.Vehicle( id=VEHICLE_ID, latitude=1.0, longitude=2.0, current_stop_sequence=6, current_stop_id="7", occupancy_status=OCCUPANCY_STATUS, ), ], [None, None, None], # No data at all ]: # Note: this is to ensure no duplicate test cases. If the input trip or # vehicle is None, all entity_location cases are the same. yield data + ["same"] if data[0] is not None and data[1] is not None: yield data + ["trip_first"] yield data + ["vehicle_first"]