Skip to content

Commit

Permalink
Merge pull request #388 from conveyal/flex-unit-tests-refactor
Browse files Browse the repository at this point in the history
Flex unit test update
  • Loading branch information
Robin Beer authored Aug 10, 2023
2 parents 4806767 + 9332c41 commit 5b4eec6
Show file tree
Hide file tree
Showing 8 changed files with 316 additions and 27 deletions.
13 changes: 7 additions & 6 deletions src/main/java/com/conveyal/gtfs/loader/JdbcGtfsExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ public JdbcGtfsExporter(String feedId, String outFile, DataSource dataSource, bo
public Boolean exceptionInvolvesService(ScheduleException ex, String serviceId) {
return (
ex.addedService.contains(serviceId) ||
ex.removedService.contains(serviceId) ||
ex.customSchedule.contains(serviceId)
ex.removedService.contains(serviceId) ||
ex.customSchedule.contains(serviceId)
);
}

Expand Down Expand Up @@ -114,6 +114,7 @@ public FeedLoadResult exportTables() {
String whereRouteIsApproved = String.format("where %s.%s.status = 2", feedIdToExport, Table.ROUTES.name);
// Export each table in turn (by placing entry in zip output stream).
result.agency = export(Table.AGENCY, connection);
result.area = export(Table.AREA, connection);
result.bookingRules = export(Table.BOOKING_RULES, connection);
result.stopAreas = exportStopAreas();
if (fromEditor) {
Expand All @@ -135,11 +136,11 @@ public FeedLoadResult exportTables() {
GTFSFeed feed = new GTFSFeed();
// FIXME: The below table readers should probably just share a connection with the exporter.
JDBCTableReader<ScheduleException> exceptionsReader =
new JDBCTableReader(Table.SCHEDULE_EXCEPTIONS, dataSource, feedIdToExport + ".",
EntityPopulator.SCHEDULE_EXCEPTION);
new JDBCTableReader(Table.SCHEDULE_EXCEPTIONS, dataSource, feedIdToExport + ".",
EntityPopulator.SCHEDULE_EXCEPTION);
JDBCTableReader<Calendar> calendarsReader =
new JDBCTableReader(Table.CALENDAR, dataSource, feedIdToExport + ".",
EntityPopulator.CALENDAR);
new JDBCTableReader(Table.CALENDAR, dataSource, feedIdToExport + ".",
EntityPopulator.CALENDAR);
Iterable<Calendar> calendars = calendarsReader.getAll();
Iterable<ScheduleException> exceptionsIterator = exceptionsReader.getAll();
List<ScheduleException> exceptions = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1017,7 +1017,7 @@ private int updateStopTimesForPatternLocationOrPatternStopArea(
patternId,
stopSequence
);
LOG.info("{} stop_time flex service arrivals/departures updated", entitiesUpdated);
LOG.info("{} stop_time flex service start/end pickup drop off window updated.", entitiesUpdated);
return travelTime + dwellTime;
}

Expand Down
5 changes: 4 additions & 1 deletion src/main/java/com/conveyal/gtfs/loader/Table.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -777,7 +778,9 @@ public CsvReader getCsvReader(ZipFile zipFile, SQLErrorStorage sqlErrorStorage)
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
if (e.getName().endsWith(tableFileName)) {
// Include the file separator prefix to force the complete file name to be considered.
// This prevents stop_areas.txt from being loaded instead of areas.txt.
if (e.getName().endsWith(String.format("%s%s", File.separator, tableFileName))) {
entry = e;
if (sqlErrorStorage != null) sqlErrorStorage.storeError(NewGTFSError.forTable(this, TABLE_IN_SUBDIRECTORY));
break;
Expand Down
118 changes: 104 additions & 14 deletions src/test/java/com/conveyal/gtfs/GTFSFeedTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,46 +26,108 @@ public class GTFSFeedTest {

private static final Logger LOG = LoggerFactory.getLogger(GTFSFeedTest.class);
private static String simpleGtfsZipFileName;
private static String simpleFlexGtfsZipFileName;

@BeforeAll
public static void setUpClass() {
//executed only once, before the first test
simpleGtfsZipFileName = null;
simpleFlexGtfsZipFileName = null;
try {
simpleGtfsZipFileName = TestUtils.zipFolderFiles("fake-agency", true);
simpleFlexGtfsZipFileName = TestUtils.zipFolderFiles("fake-agency-with-flex", true);
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* Make sure a roundtrip of loading a GTFS zip file and then writing another zip file can be performed.
* Make sure a round-trip of loading a GTFS zip file and then writing another zip file can be performed.
*/
@Test
public void canDoRoundtripLoadAndWriteToZipFile() throws IOException {
// create a temp file for this test
File outZip = File.createTempFile("fake-agency-output", ".zip");

// delete file to make sure we can assert that this program created the file
outZip.delete();

GTFSFeed feed = GTFSFeed.fromFile(simpleGtfsZipFileName);
feed.toFile(outZip.getAbsolutePath());
feed.close();
assertThat(outZip.exists(), is(true));
FileTestCase[] fileTestCases = {
// agency.txt
new FileTestCase(
"agency.txt",
new TestUtils.DataExpectation[]{
new TestUtils.DataExpectation("agency_id", "1"),
new TestUtils.DataExpectation("agency_name", "Fake Transit")
}
),
new FileTestCase(
"calendar.txt",
new DataExpectation[]{
new DataExpectation("service_id", "04100312-8fe1-46a5-a9f2-556f39478f57"),
new DataExpectation("start_date", "20170915"),
new DataExpectation("end_date", "20170917")
}
),
new FileTestCase(
"routes.txt",
new DataExpectation[]{
new DataExpectation("agency_id", "1"),
new DataExpectation("route_id", "1"),
new DataExpectation("route_long_name", "Route 1")
}
),
new FileTestCase(
"shapes.txt",
new DataExpectation[]{
new DataExpectation("shape_id", "5820f377-f947-4728-ac29-ac0102cbc34e"),
new DataExpectation("shape_pt_lat", "37.0612132"),
new DataExpectation("shape_pt_lon", "-122.0074332")
}
),
new FileTestCase(
"stop_times.txt",
new DataExpectation[]{
new DataExpectation("trip_id", "a30277f8-e50a-4a85-9141-b1e0da9d429d"),
new DataExpectation("departure_time", "07:00:00"),
new DataExpectation("stop_id", "4u6g")
}
),
new FileTestCase(
"trips.txt",
new DataExpectation[]{
new DataExpectation("route_id", "1"),
new DataExpectation("trip_id", "a30277f8-e50a-4a85-9141-b1e0da9d429d"),
new DataExpectation("service_id", "04100312-8fe1-46a5-a9f2-556f39478f57")
}
)
};
loadAndWriteToZipFile(simpleGtfsZipFileName, fileTestCases);

// assert that rows of data were written to files within the zipfile
ZipFile zip = new ZipFile(outZip);
}

/**
* Make sure a round-trip of loading a GTFS flex zip file and then writing another zip file can be performed.
*/
@Test
void canDoRoundTripLoadAndWriteToFlexZipFile() throws IOException {
FileTestCase[] fileTestCases = {
// agency.txt
new FileTestCase(
"agency.txt",
new TestUtils.DataExpectation[]{
new TestUtils.DataExpectation("agency_id", "1"),
new TestUtils.DataExpectation("agency_name", "Fake Transit")
}
),
new FileTestCase(
"areas.txt",
new TestUtils.DataExpectation[]{
new TestUtils.DataExpectation("area_id", "1"),
new TestUtils.DataExpectation("area_name", "Area referencing a stop")
}
),
new FileTestCase(
"booking_rules.txt",
new TestUtils.DataExpectation[]{
new TestUtils.DataExpectation("booking_rule_id", "1"),
new TestUtils.DataExpectation("booking_type", "1"),
new TestUtils.DataExpectation("pickup_message", "This is a pickup message")
}
),
new FileTestCase(
"calendar.txt",
new DataExpectation[]{
Expand Down Expand Up @@ -98,6 +160,13 @@ public void canDoRoundtripLoadAndWriteToZipFile() throws IOException {
new DataExpectation("stop_id", "4u6g")
}
),
new FileTestCase(
"stop_areas.txt",
new DataExpectation[]{
new DataExpectation("area_id", "2"),
new DataExpectation("stop_id", "area-999")
}
),
new FileTestCase(
"trips.txt",
new DataExpectation[]{
Expand All @@ -107,6 +176,27 @@ public void canDoRoundtripLoadAndWriteToZipFile() throws IOException {
}
)
};
loadAndWriteToZipFile(simpleFlexGtfsZipFileName, fileTestCases);
}

/**
* Load feed and then write to zip file. Once complete, perform tests.
*/
void loadAndWriteToZipFile(String zipFileName, FileTestCase[] fileTestCases) throws IOException {
// create a temp file for this test
File outZip = File.createTempFile(zipFileName, ".zip");

// delete file to make sure we can assert that this program created the file
outZip.delete();

GTFSFeed feed = GTFSFeed.fromFile(zipFileName);
feed.toFile(outZip.getAbsolutePath());
feed.close();
assertThat(outZip.exists(), is(true));

// assert that rows of data were written to files within the zip file.
ZipFile zip = new ZipFile(outZip);

TestUtils.lookThroughFiles(fileTestCases, zip);
// Close the zip file so it can be deleted.
zip.close();
Expand Down
24 changes: 23 additions & 1 deletion src/test/java/com/conveyal/gtfs/GTFSTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1203,7 +1203,7 @@ private void assertThatPersistenceExpectationRecordWasFound(
/**
* Persistence expectations for use with the GTFS contained within the "fake-agency" resources folder.
*/
private PersistenceExpectation[] fakeAgencyPersistenceExpectations = new PersistenceExpectation[]{
private final PersistenceExpectation[] fakeAgencyPersistenceExpectations = new PersistenceExpectation[]{
new PersistenceExpectation(
"agency",
new RecordExpectation[]{
Expand All @@ -1212,6 +1212,21 @@ private void assertThatPersistenceExpectationRecordWasFound(
new RecordExpectation("agency_timezone", "America/Los_Angeles")
}
),
new PersistenceExpectation(
"areas",
new RecordExpectation[]{
new RecordExpectation("area_id", "area1"),
new RecordExpectation("area_name", "This is the area name")
}
),
new PersistenceExpectation(
"booking_rules",
new RecordExpectation[]{
new RecordExpectation("booking_rule_id", "1"),
new RecordExpectation("booking_type", "1"),
new RecordExpectation("pickup_message", "This is a pickup message")
}
),
new PersistenceExpectation(
"calendar",
new RecordExpectation[]{
Expand Down Expand Up @@ -1315,6 +1330,13 @@ private void assertThatPersistenceExpectationRecordWasFound(
new RecordExpectation("shape_dist_traveled", 0.0, 0.01)
}
),
new PersistenceExpectation(
"stop_areas",
new RecordExpectation[]{
new RecordExpectation("area_id", "area1"),
new RecordExpectation("stop_id", "123")
}
),
new PersistenceExpectation(
"trips",
new RecordExpectation[]{
Expand Down
8 changes: 4 additions & 4 deletions src/test/java/com/conveyal/gtfs/dto/PatternStopAreaDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ public PatternStopAreaDTO(
this.flex_default_zone_time = flexDefaultZoneTime;
}

public PatternStopAreaDTO(String pattern_id, String area_id, int stop_sequence) {
this.pattern_id = pattern_id;
this.area_id = area_id;
this.stop_sequence = stop_sequence;
public PatternStopAreaDTO(String patternId, String areaId, int stopSequence) {
this.pattern_id = patternId;
this.area_id = areaId;
this.stop_sequence = stopSequence;
}
}
9 changes: 9 additions & 0 deletions src/test/java/com/conveyal/gtfs/dto/StopTimeDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,13 @@ public StopTimeDTO(String stopId, Integer arrivalTime, Integer departureTime, In
departure_time = departureTime;
stop_sequence = stopSequence;
}

public static StopTimeDTO flexStopTime(String stopId, Integer startPickupDropOffWindow, Integer endPickupDropOffWindow, Integer stopSequence) {
StopTimeDTO stopTimeDTO = new StopTimeDTO();
stopTimeDTO.stop_id = stopId;
stopTimeDTO.start_pickup_drop_off_window = startPickupDropOffWindow;
stopTimeDTO.end_pickup_drop_off_window = endPickupDropOffWindow;
stopTimeDTO.stop_sequence = stopSequence;
return stopTimeDTO;
}
}
Loading

0 comments on commit 5b4eec6

Please sign in to comment.