Skip to content

Commit 441bd5c

Browse files
committed
Refactor new tests to be module tests
1 parent 51d7550 commit 441bd5c

File tree

4 files changed

+197
-216
lines changed

4 files changed

+197
-216
lines changed

src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java

+18-3
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,14 @@ public TimetableSnapshot getTimetableSnapshot() {
208208
}
209209
}
210210

211+
public void commitTimetableSnapshot(boolean force) {
212+
if (siriSource != null) {
213+
siriSource.commitTimetableSnapshot(force);
214+
} else {
215+
gtfsSource.commitTimetableSnapshot(force);
216+
}
217+
}
218+
211219
public String getRealtimeTimetable(String tripId) {
212220
return getRealtimeTimetable(id(tripId), SERVICE_DATE);
213221
}
@@ -256,15 +264,22 @@ public UpdateResult applyEstimatedTimetable(List<EstimatedTimetableDeliveryStruc
256264
// GTFS-RT updates
257265

258266
public UpdateResult applyTripUpdate(GtfsRealtime.TripUpdate update) {
259-
return applyTripUpdates(List.of(update));
267+
return applyTripUpdates(List.of(update), false);
268+
}
269+
270+
public UpdateResult applyTripUpdate(GtfsRealtime.TripUpdate update, boolean differential) {
271+
return applyTripUpdates(List.of(update), differential);
260272
}
261273

262-
public UpdateResult applyTripUpdates(List<GtfsRealtime.TripUpdate> updates) {
274+
public UpdateResult applyTripUpdates(
275+
List<GtfsRealtime.TripUpdate> updates,
276+
boolean differential
277+
) {
263278
Objects.requireNonNull(gtfsSource, "Test environment is configured for SIRI only");
264279
return gtfsSource.applyTripUpdates(
265280
null,
266281
BackwardsDelayPropagationType.REQUIRED_NO_DATA,
267-
true,
282+
!differential,
268283
updates,
269284
getFeedId()
270285
);

src/test/java/org/opentripplanner/updater/trip/TimetableSnapshotSourceTest.java

-213
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@
22

33
import static com.google.transit.realtime.GtfsRealtime.TripDescriptor.ScheduleRelationship.ADDED;
44
import static com.google.transit.realtime.GtfsRealtime.TripDescriptor.ScheduleRelationship.CANCELED;
5-
import static com.google.transit.realtime.GtfsRealtime.TripDescriptor.ScheduleRelationship.DELETED;
65
import static com.google.transit.realtime.GtfsRealtime.TripDescriptor.ScheduleRelationship.SCHEDULED;
76
import static com.google.transit.realtime.GtfsRealtime.TripUpdate.StopTimeUpdate.ScheduleRelationship.SKIPPED;
87
import static org.junit.jupiter.api.Assertions.assertEquals;
98
import static org.junit.jupiter.api.Assertions.assertFalse;
109
import static org.junit.jupiter.api.Assertions.assertNotNull;
1110
import static org.junit.jupiter.api.Assertions.assertNotSame;
12-
import static org.junit.jupiter.api.Assertions.assertNull;
1311
import static org.junit.jupiter.api.Assertions.assertSame;
1412
import static org.junit.jupiter.api.Assertions.assertTrue;
1513
import static org.opentripplanner.updater.trip.BackwardsDelayPropagationType.REQUIRED_NO_DATA;
@@ -565,126 +563,6 @@ public void scheduledTripWithSkippedAndNoData() {
565563
assertTrue(newTripTimes.isNoDataStop(2));
566564
}
567565
}
568-
569-
/**
570-
* Test realtime system behavior under one very particular case from issue #5725.
571-
* When applying differential realtime updates, an update may cancel some stops on a trip. A
572-
* later update may then revert the trip back to its originally scheduled sequence of stops.
573-
* When this happens, we expect the trip to be associated with a new trip pattern (where some
574-
* stops have no pickup or dropoff) then dissociated from that new pattern and re-associated
575-
* with its originally scheduled pattern. Any trip times that were created in timetables under
576-
* the new stop-skipping trip pattern should also be removed.
577-
*/
578-
@Test
579-
public void scheduledTripWithPreviouslySkipped() {
580-
// Create update with a skipped stop at first
581-
String scheduledTripId = "1.1";
582-
583-
var skippedBuilder = new TripUpdateBuilder(
584-
scheduledTripId,
585-
SERVICE_DATE,
586-
SCHEDULED,
587-
transitModel.getTimeZone()
588-
)
589-
.addDelayedStopTime(1, 0)
590-
.addSkippedStop(2)
591-
.addDelayedStopTime(3, 90);
592-
593-
var tripUpdate = skippedBuilder.build();
594-
595-
var updater = defaultUpdater();
596-
597-
// apply the update with a skipped stop
598-
updater.applyTripUpdates(
599-
TRIP_MATCHER_NOOP,
600-
REQUIRED_NO_DATA,
601-
false,
602-
List.of(tripUpdate),
603-
feedId
604-
);
605-
606-
// Force a snapshot commit. This is done to mimic normal behaviour where a new update arrives
607-
// after the original snapshot has been committed
608-
updater.commitTimetableSnapshot(true);
609-
610-
// Create update to the same trip but now the skipped stop is no longer skipped
611-
var scheduledBuilder = new TripUpdateBuilder(
612-
scheduledTripId,
613-
SERVICE_DATE,
614-
SCHEDULED,
615-
transitModel.getTimeZone()
616-
)
617-
.addDelayedStopTime(1, 0)
618-
.addDelayedStopTime(2, 60, 80)
619-
.addDelayedStopTime(3, 90, 90);
620-
621-
tripUpdate = scheduledBuilder.build();
622-
623-
// apply the update with the previously skipped stop now scheduled
624-
updater.applyTripUpdates(
625-
TRIP_MATCHER_NOOP,
626-
REQUIRED_NO_DATA,
627-
false,
628-
List.of(tripUpdate),
629-
feedId
630-
);
631-
632-
// Check that the there is no longer a realtime added trip pattern for the trip and that the
633-
// stoptime updates have gone through
634-
var snapshot = updater.getTimetableSnapshot();
635-
{
636-
final TripPattern newTripPattern = snapshot.getRealtimeAddedTripPattern(
637-
new FeedScopedId(feedId, scheduledTripId),
638-
SERVICE_DATE
639-
);
640-
assertNull(newTripPattern);
641-
642-
final FeedScopedId tripId = new FeedScopedId(feedId, scheduledTripId);
643-
final Trip trip = transitModel.getTransitModelIndex().getTripForId().get(tripId);
644-
final TripPattern originalTripPattern = transitModel
645-
.getTransitModelIndex()
646-
.getPatternForTrip()
647-
.get(trip);
648-
649-
final Timetable originalTimetableForToday = snapshot.resolve(
650-
originalTripPattern,
651-
SERVICE_DATE
652-
);
653-
final Timetable originalTimetableScheduled = snapshot.resolve(originalTripPattern, null);
654-
655-
assertNotSame(originalTimetableForToday, originalTimetableScheduled);
656-
657-
final int originalTripIndexScheduled = originalTimetableScheduled.getTripIndex(tripId);
658-
assertTrue(
659-
originalTripIndexScheduled > -1,
660-
"Original trip should be found in scheduled time table"
661-
);
662-
final TripTimes originalTripTimesScheduled = originalTimetableScheduled.getTripTimes(
663-
originalTripIndexScheduled
664-
);
665-
assertFalse(
666-
originalTripTimesScheduled.isCanceledOrDeleted(),
667-
"Original trip times should not be canceled in scheduled time table"
668-
);
669-
assertEquals(RealTimeState.SCHEDULED, originalTripTimesScheduled.getRealTimeState());
670-
671-
final int originalTripIndexForToday = originalTimetableForToday.getTripIndex(tripId);
672-
assertTrue(
673-
originalTripIndexForToday > -1,
674-
"Original trip should be found in time table for service date"
675-
);
676-
final TripTimes originalTripTimesForToday = originalTimetableForToday.getTripTimes(
677-
originalTripIndexForToday
678-
);
679-
assertEquals(RealTimeState.UPDATED, originalTripTimesForToday.getRealTimeState());
680-
assertEquals(0, originalTripTimesForToday.getArrivalDelay(0));
681-
assertEquals(0, originalTripTimesForToday.getDepartureDelay(0));
682-
assertEquals(60, originalTripTimesForToday.getArrivalDelay(1));
683-
assertEquals(80, originalTripTimesForToday.getDepartureDelay(1));
684-
assertEquals(90, originalTripTimesForToday.getArrivalDelay(2));
685-
assertEquals(90, originalTripTimesForToday.getDepartureDelay(2));
686-
}
687-
}
688566
}
689567

690568
@Nested
@@ -900,97 +778,6 @@ public void repeatedlyAddedTripWithNewRoute() {
900778
assertSame(firstRoute, secondRoute);
901779
assertNotNull(transitModel.getTransitModelIndex().getRouteForId(firstRoute.getId()));
902780
}
903-
904-
static List<Arguments> cancelingAddedTripTestCases() {
905-
return List.of(
906-
// TODO we might want to change the behaviour so that only the trip without pattern is
907-
// persisted if the added trip is cancelled
908-
Arguments.of(CANCELED, RealTimeState.CANCELED),
909-
Arguments.of(DELETED, RealTimeState.DELETED)
910-
);
911-
}
912-
913-
/**
914-
* Test behavior of the realtime system in a case related to #5725 that is discussed at:
915-
* https://github.com/opentripplanner/OpenTripPlanner/pull/5726#discussion_r1521653840
916-
* When a trip is added by a realtime message, in the realtime data indexes a corresponding
917-
* trip pattern should be associated with the stops that trip visits. When a subsequent
918-
* realtime message cancels or deletes that trip, the pattern should continue to be present in
919-
* the realtime data indexes, and it should still contain the previously added trip, but that
920-
* trip should be marked as having canceled or deleted status. At no point should the trip
921-
* added by realtime data be present in the trip pattern for scheduled service.
922-
*/
923-
@ParameterizedTest
924-
@MethodSource("cancelingAddedTripTestCases")
925-
public void cancelingAddedTrip(
926-
ScheduleRelationship scheduleRelationship,
927-
RealTimeState expectedState
928-
) {
929-
var builder = new TripUpdateBuilder(
930-
addedTripId,
931-
SERVICE_DATE,
932-
ADDED,
933-
transitModel.getTimeZone()
934-
);
935-
936-
builder.addStopTime("A", 30).addStopTime("C", 40).addStopTime("E", 55);
937-
938-
var tripUpdate = builder.build();
939-
940-
var updater = defaultUpdater();
941-
942-
// WHEN
943-
updater.applyTripUpdates(
944-
TRIP_MATCHER_NOOP,
945-
REQUIRED_NO_DATA,
946-
FULL_DATASET,
947-
List.of(tripUpdate),
948-
feedId
949-
);
950-
951-
// THEN
952-
assertAddedTrip(SERVICE_DATE, this.addedTripId, updater, true);
953-
954-
var tripDescriptorBuilder = TripDescriptor.newBuilder();
955-
tripDescriptorBuilder.setTripId(addedTripId);
956-
tripDescriptorBuilder.setScheduleRelationship(scheduleRelationship);
957-
958-
tripDescriptorBuilder.setStartDate(ServiceDateUtils.asCompactString(SERVICE_DATE));
959-
tripUpdate = TripUpdate.newBuilder().setTrip(tripDescriptorBuilder).build();
960-
961-
// WHEN
962-
updater.applyTripUpdates(
963-
TRIP_MATCHER_NOOP,
964-
REQUIRED_NO_DATA,
965-
FULL_DATASET,
966-
List.of(tripUpdate),
967-
feedId
968-
);
969-
970-
// THEN
971-
var snapshot = updater.getTimetableSnapshot();
972-
var stopA = transitModel.getStopModel().getRegularStop(new FeedScopedId(feedId, "A"));
973-
// Get the trip pattern of the added trip which goes through stopA
974-
var patternsAtA = snapshot.getPatternsForStop(stopA);
975-
976-
assertNotNull(patternsAtA, "Added trip pattern should be found");
977-
var tripPattern = patternsAtA.stream().findFirst().get();
978-
979-
final Timetable forToday = snapshot.resolve(tripPattern, SERVICE_DATE);
980-
final Timetable schedule = snapshot.resolve(tripPattern, null);
981-
982-
assertNotSame(forToday, schedule);
983-
984-
final int forTodayAddedTripIndex = forToday.getTripIndex(addedTripId);
985-
assertTrue(
986-
forTodayAddedTripIndex > -1,
987-
"Added trip should be found in time table for the service date"
988-
);
989-
assertEquals(expectedState, forToday.getTripTimes(forTodayAddedTripIndex).getRealTimeState());
990-
991-
final int scheduleTripIndex = schedule.getTripIndex(addedTripId);
992-
assertEquals(-1, scheduleTripIndex, "Added trip should not be found in scheduled time table");
993-
}
994781
}
995782

996783
@Nonnull

src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java

+70
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.opentripplanner.updater.trip.moduletests.cancellation;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertNotNull;
45
import static org.junit.jupiter.api.Assertions.assertNotSame;
56
import static org.junit.jupiter.api.Assertions.assertTrue;
67

@@ -58,4 +59,73 @@ public void cancelledTrip(ScheduleRelationship relationship, RealTimeState state
5859
assertEquals(state, tripTimes.getRealTimeState());
5960
assertTrue(tripTimes.isCanceledOrDeleted());
6061
}
62+
63+
/**
64+
* Test behavior of the realtime system in a case related to #5725 that is discussed at:
65+
* https://github.com/opentripplanner/OpenTripPlanner/pull/5726#discussion_r1521653840
66+
* When a trip is added by a realtime message, in the realtime data indexes a corresponding
67+
* trip pattern should be associated with the stops that trip visits. When a subsequent
68+
* realtime message cancels or deletes that trip, the pattern should continue to be present in
69+
* the realtime data indexes, and it should still contain the previously added trip, but that
70+
* trip should be marked as having canceled or deleted status. At no point should the trip
71+
* added by realtime data be present in the trip pattern for scheduled service.
72+
*/
73+
@ParameterizedTest
74+
@MethodSource("cases")
75+
public void cancelingAddedTrip(ScheduleRelationship relationship, RealTimeState state) {
76+
var env = RealtimeTestEnvironment.gtfs();
77+
var addedTripId = "added-trip";
78+
// First add ADDED trip
79+
var update = new TripUpdateBuilder(
80+
addedTripId,
81+
RealtimeTestEnvironment.SERVICE_DATE,
82+
ScheduleRelationship.ADDED,
83+
env.timeZone
84+
)
85+
.addStopTime(env.stopA1.getId().getId(), 30)
86+
.addStopTime(env.stopB1.getId().getId(), 40)
87+
.addStopTime(env.stopC1.getId().getId(), 55)
88+
.build();
89+
90+
var result = env.applyTripUpdate(update, true);
91+
92+
assertEquals(1, result.successful());
93+
94+
env.commitTimetableSnapshot(true);
95+
96+
// Cancel or delete the added trip
97+
update =
98+
new TripUpdateBuilder(
99+
addedTripId,
100+
RealtimeTestEnvironment.SERVICE_DATE,
101+
relationship,
102+
env.timeZone
103+
)
104+
.build();
105+
result = env.applyTripUpdate(update, true);
106+
107+
assertEquals(1, result.successful());
108+
109+
final TimetableSnapshot snapshot = env.getTimetableSnapshot();
110+
// Get the trip pattern of the added trip which goes through stopA
111+
var patternsAtA = snapshot.getPatternsForStop(env.stopA1);
112+
113+
assertNotNull(patternsAtA, "Added trip pattern should be found");
114+
var tripPattern = patternsAtA.stream().findFirst().get();
115+
116+
final Timetable forToday = snapshot.resolve(tripPattern, RealtimeTestEnvironment.SERVICE_DATE);
117+
final Timetable schedule = snapshot.resolve(tripPattern, null);
118+
119+
assertNotSame(forToday, schedule);
120+
121+
final int forTodayAddedTripIndex = forToday.getTripIndex(addedTripId);
122+
assertTrue(
123+
forTodayAddedTripIndex > -1,
124+
"Added trip should be found in time table for the service date"
125+
);
126+
assertEquals(state, forToday.getTripTimes(forTodayAddedTripIndex).getRealTimeState());
127+
128+
final int scheduleTripIndex = schedule.getTripIndex(addedTripId);
129+
assertEquals(-1, scheduleTripIndex, "Added trip should not be found in scheduled time table");
130+
}
61131
}

0 commit comments

Comments
 (0)