From 7f9219b750a4834eb6d2cd0e8141eeecc7780c82 Mon Sep 17 00:00:00 2001 From: jkoelewijn Date: Mon, 30 Mar 2015 18:12:26 +0200 Subject: [PATCH] Add method isCanceled() to TripTimes. Add unit test for MODIFIED trip. --- .../routing/edgetype/Timetable.java | 2 + .../routing/trippattern/TripTimes.java | 12 +- .../stoptime/TimetableSnapshotSourceTest.java | 150 ++++++++++++++++++ 3 files changed, 161 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/routing/edgetype/Timetable.java b/src/main/java/org/opentripplanner/routing/edgetype/Timetable.java index 15370f11d68..f041e3cd3ca 100644 --- a/src/main/java/org/opentripplanner/routing/edgetype/Timetable.java +++ b/src/main/java/org/opentripplanner/routing/edgetype/Timetable.java @@ -151,6 +151,7 @@ public TripTimes getNextTrip(State s0, ServiceDay serviceDay, int stopIndex, boo // Hoping JVM JIT will distribute the loop over the if clauses as needed. // We could invert this and skip some service days based on schedule overlap as in RRRR. for (TripTimes tt : tripTimes) { + if (tt.isCanceled()) continue; if ( ! serviceDay.serviceRunning(tt.serviceCode)) continue; // TODO merge into call on next line if ( ! tt.tripAcceptable(s0, stopIndex)) continue; int adjustedTime = adjustTimeForTransfer(s0, currentStop, tt.trip, boarding, serviceDay, time); @@ -176,6 +177,7 @@ public TripTimes getNextTrip(State s0, ServiceDay serviceDay, int stopIndex, boo FrequencyEntry bestFreq = null; for (FrequencyEntry freq : frequencyEntries) { TripTimes tt = freq.tripTimes; + if (tt.isCanceled()) continue; if ( ! serviceDay.serviceRunning(tt.serviceCode)) continue; // TODO merge into call on next line if ( ! tt.tripAcceptable(s0, stopIndex)) continue; int adjustedTime = adjustTimeForTransfer(s0, currentStop, tt.trip, boarding, serviceDay, time); diff --git a/src/main/java/org/opentripplanner/routing/trippattern/TripTimes.java b/src/main/java/org/opentripplanner/routing/trippattern/TripTimes.java index a3aa74cffc4..b7b25539e13 100644 --- a/src/main/java/org/opentripplanner/routing/trippattern/TripTimes.java +++ b/src/main/java/org/opentripplanner/routing/trippattern/TripTimes.java @@ -21,7 +21,6 @@ the License, or (at your option) any later version. import com.google.common.hash.HashCode; import com.google.common.hash.HashFunction; import com.google.common.hash.Hasher; -import com.google.common.hash.Hashing; import org.onebusaway.gtfs.model.StopTime; import org.onebusaway.gtfs.model.Trip; import org.opentripplanner.common.MavenVersion; @@ -111,7 +110,7 @@ public class TripTimes implements Serializable, Comparable, Cloneable /** * Is this trip cancelled? */ - private boolean cancelled = false; + private boolean canceled = false; /** A Set of stop indexes that are marked as timepoints in the GTFS input. */ private final BitSet timepoints; @@ -264,6 +263,13 @@ public boolean isScheduled() { return departureTimes == null && arrivalTimes == null; } + /** + * @return true if this TripTimes is canceled + */ + public boolean isCanceled() { + return canceled; + } + /** Used in debugging / dumping times. */ public static String formatSeconds(int s) { int m = s / 60; @@ -323,7 +329,7 @@ public boolean tripAcceptable(State state0, int stopIndex) { /** Cancel this entire trip */ public void cancel() { - cancelled = true; + canceled = true; arrivalTimes = new int[getNumStops()]; Arrays.fill(arrivalTimes, UNAVAILABLE); departureTimes = arrivalTimes; diff --git a/src/test/java/org/opentripplanner/updater/stoptime/TimetableSnapshotSourceTest.java b/src/test/java/org/opentripplanner/updater/stoptime/TimetableSnapshotSourceTest.java index 3cb78364b94..26f348626f5 100644 --- a/src/test/java/org/opentripplanner/updater/stoptime/TimetableSnapshotSourceTest.java +++ b/src/test/java/org/opentripplanner/updater/stoptime/TimetableSnapshotSourceTest.java @@ -14,6 +14,7 @@ the License, or (at your option) any later version. package org.opentripplanner.updater.stoptime; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; @@ -283,6 +284,155 @@ public void testHandleAddedTrip() throws ParseException { assertEquals("Added trip should not be found in scheduled time table", -1, schedule.getTripIndex(addedTripId)); } + @Test + public void testHandleModifiedTrip() throws ParseException { + // TODO + + // GIVEN + + // Get service date of today because old dates will be purged after applying updates + ServiceDate serviceDate = new ServiceDate(Calendar.getInstance()); + + String modifiedTripId = "10.1"; + String modifiedTripAgency = "agency"; + + TripUpdate tripUpdate; + { + TripDescriptor.Builder tripDescriptorBuilder = TripDescriptor.newBuilder(); + + tripDescriptorBuilder.setTripId(modifiedTripId); + tripDescriptorBuilder.setScheduleRelationship(TripDescriptor.ScheduleRelationship.MODIFIED); + tripDescriptorBuilder.setStartDate(serviceDate.getAsString()); + + Calendar calendar = serviceDate.getAsCalendar(graph.getTimeZone()); + long midnightSecondsSinceEpoch = calendar.getTimeInMillis() / 1000; + + TripUpdate.Builder tripUpdateBuilder = TripUpdate.newBuilder(); + + tripUpdateBuilder.setTrip(tripDescriptorBuilder); + + { // Stop O + StopTimeUpdate.Builder stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder(); + stopTimeUpdateBuilder.setScheduleRelationship(StopTimeUpdate.ScheduleRelationship.SCHEDULED); + stopTimeUpdateBuilder.setStopId("O"); + stopTimeUpdateBuilder.setStopSequence(10); + + { // Arrival + StopTimeEvent.Builder arrivalBuilder = stopTimeUpdateBuilder.getArrivalBuilder(); + arrivalBuilder.setTime(midnightSecondsSinceEpoch + (12 * 3600) + (30 * 60)); + arrivalBuilder.setDelay(0); + } + + { // Departure + StopTimeEvent.Builder departureBuilder = stopTimeUpdateBuilder.getDepartureBuilder(); + departureBuilder.setTime(midnightSecondsSinceEpoch + (12 * 3600) + (30 * 60)); + departureBuilder.setDelay(0); + } + } + + { // Stop C + StopTimeUpdate.Builder stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder(); + stopTimeUpdateBuilder.setScheduleRelationship(StopTimeUpdate.ScheduleRelationship.ADDED); + stopTimeUpdateBuilder.setStopId("C"); + stopTimeUpdateBuilder.setStopSequence(30); + + { // Arrival + StopTimeEvent.Builder arrivalBuilder = stopTimeUpdateBuilder.getArrivalBuilder(); + arrivalBuilder.setTime(midnightSecondsSinceEpoch + (12 * 3600) + (40 * 60)); + arrivalBuilder.setDelay(0); + } + + { // Departure + StopTimeEvent.Builder departureBuilder = stopTimeUpdateBuilder.getDepartureBuilder(); + departureBuilder.setTime(midnightSecondsSinceEpoch + (12 * 3600) + (45 * 60)); + departureBuilder.setDelay(0); + } + } + + { // Stop D + StopTimeUpdate.Builder stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder(); + stopTimeUpdateBuilder.setScheduleRelationship(StopTimeUpdate.ScheduleRelationship.SKIPPED); + stopTimeUpdateBuilder.setStopId("D"); + stopTimeUpdateBuilder.setStopSequence(40); + + { // Arrival + StopTimeEvent.Builder arrivalBuilder = stopTimeUpdateBuilder.getArrivalBuilder(); + arrivalBuilder.setTime(midnightSecondsSinceEpoch + (12 * 3600) + (50 * 60)); + arrivalBuilder.setDelay(0); + } + + { // Departure + StopTimeEvent.Builder departureBuilder = stopTimeUpdateBuilder.getDepartureBuilder(); + departureBuilder.setTime(midnightSecondsSinceEpoch + (12 * 3600) + (51 * 60)); + departureBuilder.setDelay(0); + } + } + + { // Stop P + StopTimeUpdate.Builder stopTimeUpdateBuilder = tripUpdateBuilder.addStopTimeUpdateBuilder(); + stopTimeUpdateBuilder.setScheduleRelationship(StopTimeUpdate.ScheduleRelationship.SCHEDULED); + stopTimeUpdateBuilder.setStopId("P"); + stopTimeUpdateBuilder.setStopSequence(50); + + { // Arrival + StopTimeEvent.Builder arrivalBuilder = stopTimeUpdateBuilder.getArrivalBuilder(); + arrivalBuilder.setTime(midnightSecondsSinceEpoch + (12 * 3600) + (55 * 60)); + arrivalBuilder.setDelay(0); + } + + { // Departure + StopTimeEvent.Builder departureBuilder = stopTimeUpdateBuilder.getDepartureBuilder(); + departureBuilder.setTime(midnightSecondsSinceEpoch + (12 * 3600) + (55 * 60)); + departureBuilder.setDelay(0); + } + } + + tripUpdate = tripUpdateBuilder.build(); + } + + // WHEN + updater.applyTripUpdates(graph, fullDataset, Arrays.asList(tripUpdate), modifiedTripAgency); + + // THEN + TimetableSnapshot snapshot = updater.getTimetableSnapshot(); + + // Original trip pattern + { + AgencyAndId tripId = new AgencyAndId(modifiedTripAgency, modifiedTripId); + Trip trip = graph.index.tripForId.get(tripId); + TripPattern originalTripPattern = graph.index.patternForTrip.get(trip); + + Timetable originalTimetableForToday = snapshot.resolve(originalTripPattern, serviceDate); + Timetable originalTimetableScheduled = snapshot.resolve(originalTripPattern, null); + + assertNotSame(originalTimetableForToday, originalTimetableScheduled); + + int originalTripIndexScheduled = originalTimetableScheduled.getTripIndex(modifiedTripId); + assertTrue("Original trip should be found in scheduled time table", originalTripIndexScheduled > -1); + TripTimes originalTripTimesScheduled = originalTimetableScheduled.getTripTimes(originalTripIndexScheduled); + assertFalse("Original trip times should not be canceled in scheduled time table", originalTripTimesScheduled.isCanceled()); + + int originalTripIndexForToday = originalTimetableForToday.getTripIndex(modifiedTripId); + assertTrue("Original trip should be found in time table for service date", originalTripIndexForToday > -1); + TripTimes originalTripTimesForToday = originalTimetableForToday.getTripTimes(originalTripIndexForToday); + assertTrue("Original trip times should be canceled in time table for service date", originalTripTimesForToday.isCanceled()); + } + + // New trip pattern + { + TripPattern newTripPattern = snapshot.getLastAddedTripPattern(modifiedTripId, serviceDate); + assertNotNull("New trip pattern should be found", newTripPattern); + + Timetable newTimetableForToday = snapshot.resolve(newTripPattern, serviceDate); + Timetable newTimetableScheduled = snapshot.resolve(newTripPattern, null); + + assertNotSame(newTimetableForToday, newTimetableScheduled); + + assertTrue("New trip should be found in time table for service date", newTimetableForToday.getTripIndex(modifiedTripId) > -1); + assertEquals("New trip should not be found in scheduled time table", -1, newTimetableScheduled.getTripIndex(modifiedTripId)); + } + } + @Test public void testPurgeExpiredData() throws InvalidProtocolBufferException { AgencyAndId tripId = new AgencyAndId("agency", "1.1");