Beispiel #1
0
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
Beispiel #2
0
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():
        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="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=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) == 1
        assert db_trip_updates[0].status == "update"
        assert len(RealTimeUpdate.query.all()) == 2
        assert len(StopTimeUpdate.query.all()) == 3
Beispiel #3
0
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
Beispiel #4
0
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():
        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,
        )
        trip_update.stop_time_updates = []
        real_time_update = make_rt_update(raw_data=None, contributor_id=contributor.id)
        handle(builder, real_time_update, [trip_update])

        trip_update = TripUpdate(
            _create_db_vj(navitia_vj),
            status="none",
            effect=TripEffect.UNKNOWN_EFFECT.name,
            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"}, arr_status="none", dep_status="none", order=0),
            StopTimeUpdate({"id": "sa:2"}, arr_status="none", dep_status="none", order=1),
            StopTimeUpdate({"id": "sa:3"}, arrival_delay=timedelta(minutes=40), arr_status="update", order=2),
        ]
        res, _ = handle(builder, real_time_update, [trip_update])

        _check_cancellation_then_delay(res)
Beispiel #5
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
Beispiel #6
0
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
Beispiel #7
0
def test_find_stop():
    with app.app_context():
        vj = create_trip_update('70866ce8-0638-4fa1-8556-1ddfa22d09d3', 'vj1',
                                datetime.date(2015, 9, 8))
        st1 = StopTimeUpdate({'id': 'sa:1'}, None, None)
        vj.stop_time_updates.append(st1)
        st2 = StopTimeUpdate({'id': 'sa:2'}, None, None)
        vj.stop_time_updates.append(st2)
        st3 = StopTimeUpdate({'id': 'sa:3'}, None, None)
        vj.stop_time_updates.append(st3)

        assert vj.find_stop('sa:1') == st1
        assert vj.find_stop('sa:3') == st3
        assert vj.find_stop('sa:4') is None
Beispiel #8
0
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
Beispiel #9
0
def _make_stop_time_update(base_arrival, base_departure, last_departure, input_st, stop_point, order):
    dep, dep_status, dep_delay = _get_update_info_of_stop_event(
        base_departure, input_st.departure, input_st.departure_status, input_st.departure_delay
    )
    arr, arr_status, arr_delay = _get_update_info_of_stop_event(
        base_arrival, input_st.arrival, input_st.arrival_status, input_st.arrival_delay
    )

    # in case where arrival/departure time are None
    if arr is None:
        arr = dep if dep is not None else last_departure
    dep = dep if dep is not None else arr

    # in case where the previous departure time are greater than the current arrival
    if last_departure and last_departure > arr:
        arr_delay += last_departure - arr
        arr = last_departure

    # in the real world, the departure time must be greater or equal to the arrival time
    if arr > dep:
        dep_delay += arr - dep
        dep = arr

    return StopTimeUpdate(
        navitia_stop=stop_point,
        departure=dep,
        departure_delay=dep_delay,
        dep_status=dep_status,
        arrival=arr,
        arrival_delay=arr_delay,
        arr_status=arr_status,
        message=input_st.message,
        order=order,
    )
Beispiel #10
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(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")
Beispiel #11
0
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)
Beispiel #12
0
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
Beispiel #13
0
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)
Beispiel #14
0
def test_find_stop():
    with app.app_context():
        vj = create_trip_update("70866ce8-0638-4fa1-8556-1ddfa22d09d3", "vj1",
                                datetime.date(2015, 9, 8))
        st1 = StopTimeUpdate({"id": "sa:1"}, None, None, order=0)
        vj.stop_time_updates.append(st1)
        st2 = StopTimeUpdate({"id": "sa:2"}, None, None, order=1)
        vj.stop_time_updates.append(st2)
        st3 = StopTimeUpdate({"id": "sa:3"}, None, None, order=2)
        vj.stop_time_updates.append(st3)

        assert vj.find_stop("sa:1", 0) == st1
        assert vj.find_stop("sa:1") == st1
        assert vj.find_stop("sa:2", 1) == st2
        assert vj.find_stop("sa:3", 2) == st3
        assert vj.find_stop("sa:4") is None
Beispiel #15
0
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(_create_db_vj(navitia_vj),
                                 status="delete",
                                 contributor_id=COTS_CONTRIBUTOR_ID)
        trip_update.stop_time_updates = []
        real_time_update = make_rt_update(
            raw_data=None,
            connector_type=ConnectorType.cots.value,
            contributor_id=COTS_CONTRIBUTOR_ID)
        handle(real_time_update, [trip_update],
               contributor_id=COTS_CONTRIBUTOR_ID,
               is_new_complete=False)

        trip_update = TripUpdate(_create_db_vj(navitia_vj),
                                 status="update",
                                 contributor_id=COTS_CONTRIBUTOR_ID)
        real_time_update = make_rt_update(
            raw_data=None,
            connector_type=ConnectorType.cots.value,
            contributor_id=COTS_CONTRIBUTOR_ID)
        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],
                        COTS_CONTRIBUTOR_ID,
                        is_new_complete=False)

        _check_cancellation_then_delay(res)
Beispiel #16
0
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)
Beispiel #17
0
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
Beispiel #18
0
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(_create_db_vj(navitia_vj),
                                 status="update",
                                 contributor_id=COTS_CONTRIBUTOR_ID)
        real_time_update = make_rt_update(
            raw_data=None,
            connector_type=ConnectorType.cots.value,
            contributor_id=COTS_CONTRIBUTOR_ID)
        trip_update.stop_time_updates = [
            StopTimeUpdate({"id": "sa:1"},
                           departure_delay=timedelta(minutes=5),
                           dep_status="update")
        ]
        handle(real_time_update, [trip_update],
               contributor_id=COTS_CONTRIBUTOR_ID,
               is_new_complete=False)

        trip_update = TripUpdate(_create_db_vj(navitia_vj),
                                 status="update",
                                 contributor_id=COTS_CONTRIBUTOR_ID)
        real_time_update = make_rt_update(
            raw_data=None,
            connector_type=ConnectorType.cots.value,
            contributor_id=COTS_CONTRIBUTOR_ID)
        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],
                        contributor_id=COTS_CONTRIBUTOR_ID,
                        is_new_complete=False)

        _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
Beispiel #19
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
Beispiel #20
0
def test_simple_delay(navitia_vj):
    """Test on delay when there is nothing in the db"""
    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)
        st = StopTimeUpdate(
            {"id": "sa:1"},
            arrival_delay=timedelta(minutes=5),
            arr_status="update",
            departure_delay=timedelta(minutes=10),
            dep_status="update",
            order=0,
        )
        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].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:15")
        assert trip_update.stop_time_updates[1].arrival_delay == timedelta(minutes=10)
        assert trip_update.stop_time_updates[1].arrival_status == "update"
        assert trip_update.stop_time_updates[1].departure == _dt("9:20")
        assert trip_update.stop_time_updates[1].departure_delay == timedelta(minutes=10)
        assert trip_update.stop_time_updates[1].departure_status == "update"

        # 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].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:15")
        assert db_st_updates[1].departure == _dt("9:20")
        assert db_st_updates[1].trip_update_id == db_trip_updates[0].vj_id

        assert db_st_updates[2].stop_id == "sa:3"
Beispiel #21
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
Beispiel #22
0
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
Beispiel #23
0
def test_populate_pb_skipped_for_detour_stop_times_status():
    st_added_status = StopTimeUpdate({'id': 'id1'},
                                     dep_status='deleted_for_detour',
                                     arr_status='deleted_for_detour')
    pb_stop_time = gtfs_realtime_pb2.TripUpdate.StopTimeUpdate()

    fill_stop_times(pb_stop_time, st_added_status)

    assert pb_stop_time.departure.Extensions[
        kirin_pb2.stop_time_event_status] == kirin_pb2.DELETED_FOR_DETOUR
    assert pb_stop_time.arrival.Extensions[
        kirin_pb2.stop_time_event_status] == kirin_pb2.DELETED_FOR_DETOUR
Beispiel #24
0
def test_populate_pb_deleted_stop_times_status():
    st_added_status = StopTimeUpdate({"id": "id1"},
                                     dep_status="delete",
                                     arr_status="delete")
    pb_stop_time = gtfs_realtime_pb2.TripUpdate.StopTimeUpdate()

    fill_stop_times(pb_stop_time, st_added_status)

    assert pb_stop_time.departure.Extensions[
        kirin_pb2.stop_time_event_status] == kirin_pb2.DELETED
    assert pb_stop_time.arrival.Extensions[
        kirin_pb2.stop_time_event_status] == kirin_pb2.DELETED
Beispiel #25
0
def test_populate_pb_no_status_stop_times_status():
    st_no_status = StopTimeUpdate({'id': 'id1'},
                                  dep_status='none',
                                  arr_status='none')
    pb_stop_time = gtfs_realtime_pb2.TripUpdate.StopTimeUpdate()

    fill_stop_times(pb_stop_time, st_no_status)

    assert pb_stop_time.departure.Extensions[
        kirin_pb2.stop_time_event_status] == kirin_pb2.SCHEDULED
    assert pb_stop_time.arrival.Extensions[
        kirin_pb2.stop_time_event_status] == kirin_pb2.SCHEDULED
Beispiel #26
0
def test_populate_pb_added_for_detour_stop_times_status():
    st_added_status = StopTimeUpdate({"id": "id1"},
                                     dep_status="added_for_detour",
                                     arr_status="added_for_detour")
    pb_stop_time = gtfs_realtime_pb2.TripUpdate.StopTimeUpdate()

    fill_stop_times(pb_stop_time, st_added_status)

    assert pb_stop_time.departure.Extensions[
        kirin_pb2.stop_time_event_status] == kirin_pb2.ADDED_FOR_DETOUR
    assert pb_stop_time.arrival.Extensions[
        kirin_pb2.stop_time_event_status] == kirin_pb2.ADDED_FOR_DETOUR
Beispiel #27
0
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     10:15-10:15

    > propagating 10 min from sa:2 departure to sa:3, not needing correction for consistency
    """
    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)
        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 = make_rt_update(raw_data=None, contributor_id=contributor.id)
        real_time_update.id = "30866ce8-0638-4fa1-8556-1ddfa22d09d3"
        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.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("10:15")
        assert stu_map["sa:3"].departure == _dt("10:15")
Beispiel #28
0
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(_create_db_vj(navitia_vj),
                                 status="update",
                                 contributor_id=COTS_CONTRIBUTOR_ID)
        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 = make_rt_update(
            raw_data=None,
            connector_type=ConnectorType.cots.value,
            contributor_id=COTS_CONTRIBUTOR_ID)
        real_time_update.id = "30866ce8-0638-4fa1-8556-1ddfa22d09d3"
        trip_update.stop_time_updates.append(st)
        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 == "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")
Beispiel #29
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():
        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
Beispiel #30
0
def create_trip_update(vj_id, trip_id, circulation_date, 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)
    # Add 3 StopTimeUpdate
    st1 = StopTimeUpdate({"id": "sa:1"}, None, None, order=0)
    trip_update.stop_time_updates.append(st1)
    st2 = StopTimeUpdate({"id": "sa:2"}, None, None, order=1)
    trip_update.stop_time_updates.append(st2)
    st3 = StopTimeUpdate({"id": "sa:3"}, None, None, order=2)
    trip_update.stop_time_updates.append(st3)

    db.session.add(vj)
    db.session.add(trip_update)
    return trip_update
Beispiel #31
0
def test_update_stoptime():
    with app.app_context():
        st = StopTimeUpdate({'id': 'foo'},
                 departure_delay=datetime.timedelta(minutes=10), arrival_delay=datetime.timedelta(minutes=10),
                 dep_status='update', arr_status='update')

        st.update_arrival(time=None, status=None, delay=datetime.timedelta(minutes=0))
        assert st.arrival_delay == datetime.timedelta(minutes=0)

        st.update_departure(time=None, status=None, delay=datetime.timedelta(minutes=0))
        assert st.departure_delay == datetime.timedelta(minutes=0)
Beispiel #32
0
def merge(navitia_vj, db_trip_update, new_trip_update):
    """
    We need to merge the info from 3 sources:
        * the navitia base schedule
        * the trip update already in the bd (potentially not existent)
        * the incoming trip update

    The result is either the db_trip_update if it exists, or the new_trip_update (it is updated as a side
    effect)

    The mechanism is quite simple:
        * the result trip status is the new_trip_update's status
            (ie in the db the trip was cancelled, and a new update is only an update, the trip update is
            not cancelled anymore, only updated)

        * for each navitia's stop_time and for departure|arrival:
            - if there is an update on this stoptime (in new_trip_update):
                we compute the new datetime based on the new information and the navitia's base schedule
            - else if there is the stoptime in the db:
                we keep this db stoptime
            - else we keep the navitia's base schedule

    Note that the results is either 'db_trip_update' or 'new_trip_update'. Side effects on this object are
    thus wanted because of database persistency (update or creation of new objects)


    ** Important Note **:
    we DO NOT HANDLE changes in navitia's schedule for the moment
    it will need to be handled, but it will be done after
    """
    res = db_trip_update if db_trip_update else new_trip_update
    res_stoptime_updates = []

    res.status = new_trip_update.status
    if new_trip_update.message:
        res.message = new_trip_update.message
    res.contributor = new_trip_update.contributor

    if res.status == 'delete':
        # for trip cancellation, we delete all stoptimes update
        res.stop_time_updates = []
        return res

    last_nav_dep = None
    circulation_date = new_trip_update.vj.circulation_date
    for navitia_stop in navitia_vj.get('stop_times', []):
        stop_id = navitia_stop.get('stop_point', {}).get('id')
        new_st = new_trip_update.find_stop(stop_id)
        db_st = db_trip_update.find_stop(stop_id) if db_trip_update else None

        # TODO handle forbidden pickup/dropoff (in those case set departure/arrival at None)
        nav_departure_time = navitia_stop.get('departure_time')
        nav_arrival_time = navitia_stop.get('arrival_time')
        timezone = _get_timezone(navitia_stop)

        arrival = departure = None
        if nav_arrival_time:
            if last_nav_dep and last_nav_dep > nav_arrival_time:
                # last departure is after arrival, it's a past-midnight
                circulation_date += timedelta(days=1)
            arrival = _get_datetime(circulation_date, nav_arrival_time, timezone)
        if nav_departure_time:
            if nav_arrival_time and nav_arrival_time > nav_departure_time:
                # departure is before arrival, it's a past-midnight
                circulation_date += timedelta(days=1)
            departure = _get_datetime(circulation_date, nav_departure_time, timezone)

        if new_st:
            res_st = db_st or StopTimeUpdate(navitia_stop['stop_point'])
            # we have an update on the stop time, we consider it
            if new_st.departure_status == 'update':
                dep = departure + new_st.departure_delay if departure else None
                res_st.update_departure(time=dep, status='update', delay=new_st.departure_delay)
            elif db_st:
                # we have no update on the departure for this st, we take it from the db (if it exists)
                res_st.update_departure(time=db_st.departure,
                                        status=db_st.departure_status,
                                        delay=db_st.departure_delay)
            else:
                # we store the base's schedule
                res_st.update_departure(time=departure, status='none', delay=None)

            if new_st.arrival_status == 'update':
                arr = arrival + new_st.arrival_delay if arrival else None
                res_st.update_arrival(time=arr, status='update', delay=new_st.arrival_delay)
            elif db_st:
                res_st.update_arrival(time=db_st.arrival,
                                      status=db_st.arrival_status,
                                      delay=db_st.arrival_delay)
            else:
                # we store the base's schedule
                res_st.update_arrival(time=arrival, status='none', delay=None)

            res_st.message = new_st.message
            # we might need to update the st's order
            res_st.order = len(res_stoptime_updates)
            res_stoptime_updates.append(res_st)
        elif db_st:
            db_st.order = len(res_stoptime_updates)
            res_stoptime_updates.append(db_st)
        else:
            # nothing in db and in new trip update, we take the base schedule
            new_st = StopTimeUpdate(navitia_stop['stop_point'], departure=departure, arrival=arrival)
            new_st.order = len(res_stoptime_updates)
            res_stoptime_updates.append(new_st)

        last_nav_dep = nav_departure_time

    res.stop_time_updates = res_stoptime_updates

    return res