/* This program is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package org.opentripplanner.routing.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectOutputStream;
import junit.framework.TestCase;
import org.junit.Test;
import org.opentripplanner.routing.edgetype.StreetEdge;
import org.opentripplanner.routing.edgetype.StreetTraversalPermission;
import org.opentripplanner.routing.error.GraphNotFoundException;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.vertextype.IntersectionVertex;
import org.opentripplanner.routing.vertextype.StreetVertex;
public class GraphServiceImplTest extends TestCase {
File basePath;
Graph emptyGraph;
Graph smallGraph;
byte[] emptyGraphData;
byte[] smallGraphData;
@Override
protected void setUp() throws IOException {
// Ensure a dummy disk location exists
basePath = new File("test_graphs");
if (!basePath.exists())
basePath.mkdir();
// Create an empty graph and it's serialized form
emptyGraph = new Graph();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
emptyGraph.save(new ObjectOutputStream(baos));
emptyGraphData = baos.toByteArray();
// Create a small graph with 2 vertices and one edge and it's serialized form
smallGraph = new Graph();
StreetVertex v1 = new IntersectionVertex(smallGraph, "v1", 0, 0);
StreetVertex v2 = new IntersectionVertex(smallGraph, "v2", 0, 0.1);
new StreetEdge(v1, v2, null, "v1v2", 11000, StreetTraversalPermission.PEDESTRIAN, false);
baos = new ByteArrayOutputStream();
smallGraph.save(new ObjectOutputStream(baos));
smallGraphData = baos.toByteArray();
}
@Override
protected void tearDown() throws FileNotFoundException {
deleteRecursive(basePath);
basePath = null;
}
public static boolean deleteRecursive(File path) throws FileNotFoundException {
if (!path.exists())
throw new FileNotFoundException(path.getAbsolutePath());
boolean ret = true;
if (path.isDirectory()) {
for (File f : path.listFiles()) {
ret = ret && deleteRecursive(f);
}
}
return ret && path.delete();
}
@Test
public final void testGraphServiceMemory() {
GraphServiceImpl graphService = new GraphServiceImpl();
graphService.registerGraph("A", new MemoryGraphSource("A", emptyGraph));
assertEquals(1, graphService.getRouterIds().size());
Graph graph = graphService.getGraph("A");
assertNotNull(graph);
assertEquals(emptyGraph, graph);
assertEquals("A", emptyGraph.routerId);
try {
graph = graphService.getGraph("inexistant");
assertTrue(false); // Should not be there
} catch (GraphNotFoundException e) {
}
graphService.setDefaultRouterId("A");
graph = graphService.getGraph();
assertEquals(emptyGraph, graph);
graphService.registerGraph("B", new MemoryGraphSource("B", smallGraph));
assertEquals(2, graphService.getRouterIds().size());
graph = graphService.getGraph("B");
assertNotNull(graph);
assertEquals(smallGraph, graph);
assertEquals("B", graph.routerId);
graphService.evictGraph("A");
assertEquals(1, graphService.getRouterIds().size());
try {
graph = graphService.getGraph("A");
assertTrue(false); // Should not be there
} catch (GraphNotFoundException e) {
}
try {
graph = graphService.getGraph();
assertTrue(false); // Should not be there
} catch (GraphNotFoundException e) {
}
graphService.evictAll();
assertEquals(0, graphService.getRouterIds().size());
}
@Test
public final void testGraphServiceFile() throws IOException {
// Create a GraphService and a GraphSourceFactory
GraphServiceImpl graphService = new GraphServiceImpl();
InputStreamGraphSource.FileFactory graphSourceFactory = new InputStreamGraphSource.FileFactory();
graphSourceFactory.basePath = basePath;
graphSourceFactory.save("A", new ByteArrayInputStream(emptyGraphData));
// Check if the graph has been saved
assertTrue(new File(new File(basePath, "A"), InputStreamGraphSource.GRAPH_FILENAME).canRead());
// Register this empty graph, reloading it from disk
boolean registered = graphService.registerGraph("A",
graphSourceFactory.createGraphSource("A"));
assertTrue(registered);
// Check if the loaded graph is the one we saved earlier
Graph graph = graphService.getGraph("A");
assertNotNull(graph);
assertEquals("A", graph.routerId);
assertEquals(0, graph.getVertices().size());
assertEquals(1, graphService.getRouterIds().size());
// Save A again, with more data this time
int verticesCount = smallGraph.getVertices().size();
int edgesCount = smallGraph.getEdges().size();
graphSourceFactory.save("A", new ByteArrayInputStream(smallGraphData));
// Force a reload, get again the graph
graphService.reloadGraphs(false);
graph = graphService.getGraph("A");
// Check if loaded graph is the one modified
assertEquals(verticesCount, graph.getVertices().size());
assertEquals(edgesCount, graph.getEdges().size());
// Remove the file from disk and reload
boolean deleted = new File(new File(basePath, "A"), InputStreamGraphSource.GRAPH_FILENAME)
.delete();
assertTrue(deleted);
graphService.reloadGraphs(false);
// Check that the graph have been evicted
assertEquals(0, graphService.getRouterIds().size());
// Register it manually
registered = graphService.registerGraph("A", graphSourceFactory.createGraphSource("A"));
// Check that it fails again (file still deleted)
assertFalse(registered);
assertEquals(0, graphService.getRouterIds().size());
// Re-save the graph file, register it again
graphSourceFactory.save("A", new ByteArrayInputStream(smallGraphData));
registered = graphService.registerGraph("A", graphSourceFactory.createGraphSource("A"));
// This time registering is OK
assertTrue(registered);
assertEquals(1, graphService.getRouterIds().size());
// Evict the graph, should be OK
boolean evicted = graphService.evictGraph("A");
assertTrue(evicted);
assertEquals(0, graphService.getRouterIds().size());
}
@Test
public final void testGraphServiceAutoscan() throws IOException {
// Check for no graphs
GraphServiceImpl graphService = new GraphServiceImpl(false);
GraphScanner graphScanner = new GraphScanner(graphService, true);
graphScanner.basePath = basePath;
graphScanner.startup();
assertEquals(0, graphService.getRouterIds().size());
System.out.println("------------------------------------------");
// Add a single default graph
InputStreamGraphSource.FileFactory graphSourceFactory = new InputStreamGraphSource.FileFactory();
graphSourceFactory.basePath = basePath;
graphSourceFactory.save("", new ByteArrayInputStream(smallGraphData));
// Check that the single graph is there
graphService = new GraphServiceImpl(false);
graphScanner = new GraphScanner(graphService, true);
graphScanner.basePath = basePath;
graphScanner.startup();
assertEquals(1, graphService.getRouterIds().size());
assertEquals("", graphService.getGraph().routerId);
assertEquals("", graphService.getGraph("").routerId);
System.out.println("------------------------------------------");
// Add another graph in a sub-directory
graphSourceFactory.save("A", new ByteArrayInputStream(smallGraphData));
graphService = new GraphServiceImpl(false);
graphScanner = new GraphScanner(graphService, true);
graphScanner.basePath = basePath;
graphScanner.startup();
assertEquals(2, graphService.getRouterIds().size());
assertEquals("", graphService.getGraph().routerId);
assertEquals("A", graphService.getGraph("A").routerId);
System.out.println("------------------------------------------");
// Remove default Graph
new File(basePath, InputStreamGraphSource.GRAPH_FILENAME).delete();
// Check that default is A this time
graphService = new GraphServiceImpl(false);
graphScanner = new GraphScanner(graphService, true);
graphScanner.basePath = basePath;
graphScanner.startup();
assertEquals(1, graphService.getRouterIds().size());
assertEquals("A", graphService.getGraph().routerId);
assertEquals("A", graphService.getGraph("A").routerId);
}
}