/* 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 com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.MissingNode; import com.fasterxml.jackson.databind.node.ObjectNode; import junit.framework.TestCase; import org.junit.Test; import org.opentripplanner.graph_builder.module.EmbedConfig; 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.services.GraphService; import org.opentripplanner.routing.vertextype.IntersectionVertex; import org.opentripplanner.routing.vertextype.StreetVertex; import java.io.*; public class GraphServiceTest 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() { GraphService graphService = new GraphService(); graphService.registerGraph("A", new MemoryGraphSource("A", emptyGraph)); assertEquals(1, graphService.getRouterIds().size()); Graph graph = graphService.getRouter("A").graph; assertNotNull(graph); assertEquals(emptyGraph, graph); assertEquals("A", emptyGraph.routerId); try { graph = graphService.getRouter("inexistant").graph; assertTrue(false); // Should not be there } catch (GraphNotFoundException e) { } graphService.setDefaultRouterId("A"); graph = graphService.getRouter().graph; assertEquals(emptyGraph, graph); graphService.registerGraph("B", new MemoryGraphSource("B", smallGraph)); assertEquals(2, graphService.getRouterIds().size()); graph = graphService.getRouter("B").graph; assertNotNull(graph); assertEquals(smallGraph, graph); assertEquals("B", graph.routerId); graphService.evictRouter("A"); assertEquals(1, graphService.getRouterIds().size()); try { graph = graphService.getRouter("A").graph; assertTrue(false); // Should not be there } catch (GraphNotFoundException e) { } try { graph = graphService.getRouter().graph; 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 GraphService graphService = new GraphService(); InputStreamGraphSource.FileFactory graphSourceFactory = new InputStreamGraphSource.FileFactory(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.getRouter("A").graph; 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, true); graph = graphService.getRouter("A").graph; // 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, true); // 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.evictRouter("A"); assertTrue(evicted); assertEquals(0, graphService.getRouterIds().size()); } @Test public final void testGraphServiceAutoscan() throws IOException { // Check for no graphs GraphService graphService = new GraphService(false); GraphScanner graphScanner = new GraphScanner(graphService, basePath, true); graphScanner.startup(); assertEquals(0, graphService.getRouterIds().size()); System.out.println("------------------------------------------"); // Add a single default graph InputStreamGraphSource.FileFactory graphSourceFactory = new InputStreamGraphSource.FileFactory(basePath); graphSourceFactory.save("", new ByteArrayInputStream(smallGraphData)); // Check that the single graph is there graphService = new GraphService(false); graphScanner = new GraphScanner(graphService, basePath, true); graphScanner.startup(); assertEquals(1, graphService.getRouterIds().size()); assertEquals("", graphService.getRouter().graph.routerId); assertEquals("", graphService.getRouter("").graph.routerId); System.out.println("------------------------------------------"); // Add another graph in a sub-directory graphSourceFactory.save("A", new ByteArrayInputStream(smallGraphData)); graphService = new GraphService(false); graphScanner = new GraphScanner(graphService, basePath, true); graphScanner.startup(); assertEquals(2, graphService.getRouterIds().size()); assertEquals("", graphService.getRouter().graph.routerId); assertEquals("A", graphService.getRouter("A").graph.routerId); System.out.println("------------------------------------------"); // Remove default Graph new File(basePath, InputStreamGraphSource.GRAPH_FILENAME).delete(); // Check that default is A this time graphService = new GraphService(false); graphScanner = new GraphScanner(graphService, basePath, true); graphScanner.startup(); assertEquals(1, graphService.getRouterIds().size()); assertEquals("A", graphService.getRouter().graph.routerId); assertEquals("A", graphService.getRouter("A").graph.routerId); } @Test public final void testGraphServiceMemoryRouterConfig () throws IOException { ObjectMapper mapper = new ObjectMapper(); JsonNode buildConfig = MissingNode.getInstance(); ObjectNode routerConfig = mapper.createObjectNode(); routerConfig.put("timeout", 8); EmbedConfig embedConfig = new EmbedConfig(buildConfig, routerConfig); embedConfig.buildGraph(emptyGraph, null); GraphService graphService = new GraphService(); graphService.registerGraph("A", new MemoryGraphSource("A", emptyGraph)); assertEquals(1, graphService.getRouterIds().size()); Graph graph = graphService.getRouter("A").graph; assertNotNull(graph); assertEquals(emptyGraph, graph); assertEquals("A", emptyGraph.routerId); JsonNode graphRouterConfig = mapper.readTree(graph.routerConfig); assertEquals(graphRouterConfig, routerConfig); assertEquals(graphRouterConfig.get("timeout"), routerConfig.get("timeout")); } }