diff --git a/docs/api.rst b/docs/api.rst index 9f254c2..3ed7802 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,218 +1,273 @@ Graph traversal API =================== Terminology ----------- This API uses the following notions: - **Node**: a node in the `Software Heritage graph `_, represented by a `persistent identifier `_ (abbreviated as *SWH PID*, or simply *PID*). - **Node type**: the 3-letter specifier from the node PID (``cnt``, ``dir``, ``rel``, ``rev``, ``snp``), or ``*`` for all node types. - **Edge type**: a comma-separated list of ``src:dst`` strings where ``src`` and ``dst`` are node types, or ``*`` for all edge types. Examples ~~~~~~~~ - ``swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2`` the PID of a node of type content containing the full text of the GPL3 license. - ``swh:1:rev:f39d7d78b70e0f39facb1e4fab77ad3df5c52a35`` the PID of a node of type revision corresponding to the commit in Linux that merged the 'x86/urgent' branch on 31 December 2017. - ``"dir:dir,dir:cnt"`` node types allowing edges from directories to directories nodes, or directories to contents nodes. - ``"rev:rev,dir:*"`` node types allowing edges from revisions to revisions nodes, or from directories nodes. - ``"*:rel"`` node types allowing all edges to releases. +Timings +~~~~~~~ + +When configured to do so (see the server's README), the server can provide +timings metadata in addition to the result: + +- ``traversal``: time in seconds to do the actual graph traversal. +- ``pid2node``: time in seconds to convert input PID to node id. +- ``node2pid``: time in seconds to convert output node ids to PIDs. + Leaves ------ .. http:get:: /graph/leaves/:src Performs a graph traversal and returns the leaves of the subgraph rooted at the specified source node. :param string src: source node specified as a SWH PID :query string edges: edges types the traversal can follow; default to ``"*"`` :query string direction: direction in which graph edges will be followed; can be either ``forward`` or ``backward``, default to ``forward`` :statuscode 200: success :statuscode 400: invalid query string provided :statuscode 404: starting node cannot be found .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json - [ - "swh:1:cnt:669ac7c32292798644b21dbb5a0dc657125f444d", - "swh:1:cnt:da4cb28febe66172a9fdf1a235525ae6c00cde1d", - ... - ] + { + "result": [ + "swh:1:cnt:669ac7c32292798644b21dbb5a0dc657125f444d", + "swh:1:cnt:da4cb28febe66172a9fdf1a235525ae6c00cde1d", + ... + ], + "meta": { + "timings": { + "traversal": 0.002942681, + "pid2node": 0.000178051, + "node2pid": 0.000956569 + } + } + } Neighbors --------- .. http:get:: /graph/neighbors/:src Returns node direct neighbors (linked with exactly one edge) in the graph. :param string src: source node specified as a SWH PID :query string edges: edges types allowed to be listed as neighbors; default to ``"*"`` :query string direction: direction in which graph edges will be followed; can be either ``forward`` or ``backward``, default to ``forward`` :statuscode 200: success :statuscode 400: invalid query string provided :statuscode 404: starting node cannot be found .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json - [ - "swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2", - "swh:1:dir:d198bc9d7a6bcf6db04f476d29314f157507d505", - ... - ] + { + "result": [ + "swh:1:cnt:94a9ed024d3859793618152ea559a168bbcbb5e2", + "swh:1:dir:d198bc9d7a6bcf6db04f476d29314f157507d505", + ... + ], + "meta": { + "timings": { + "traversal": 0.002942681, + "pid2node": 0.000178051, + "node2pid": 0.000956569 + } + } + } Walk ---- .. http:get:: /graph/walk/:src/:dst Performs a graph traversal and returns the first found path from source to destination (final destination node included). :param string src: starting node specified as a SWH PID :param string dst: destination node, either as a node PID or a node type. The traversal will stop at the first node encountered matching the desired destination. :query string edges: edges types the traversal can follow; default to ``"*"`` :query string traversal: traversal algorithm; can be either ``dfs`` or ``bfs``, default to ``dfs`` :query string direction: direction in which graph edges will be followed; can be either ``forward`` or ``backward``, default to ``forward`` :statuscode 200: success :statuscode 400: invalid query string provided :statuscode 404: starting node cannot be found .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json - [ - "swh:1:rev:f39d7d78b70e0f39facb1e4fab77ad3df5c52a35", - "swh:1:rev:52c90f2d32bfa7d6eccd66a56c44ace1f78fbadd", - "swh:1:rev:cea92e843e40452c08ba313abc39f59efbb4c29c", - "swh:1:rev:8d517bdfb57154b8a11d7f1682ecc0f79abf8e02", - ... - ] + { + "result": [ + "swh:1:rev:f39d7d78b70e0f39facb1e4fab77ad3df5c52a35", + "swh:1:rev:52c90f2d32bfa7d6eccd66a56c44ace1f78fbadd", + "swh:1:rev:cea92e843e40452c08ba313abc39f59efbb4c29c", + "swh:1:rev:8d517bdfb57154b8a11d7f1682ecc0f79abf8e02", + ... + ], + "meta": { + "timings": { + "traversal": 0.002942681, + "pid2node": 0.000178051, + "node2pid": 0.000956569 + } + } + } Visit ----- .. http:get:: /graph/visit/nodes/:src .. http:get:: /graph/visit/paths/:src Performs a graph traversal and returns explored nodes or paths (in the order of the traversal). :param string src: starting node specified as a SWH PID :query string edges: edges types the traversal can follow; default to ``"*"`` :query string direction: direction in which graph edges will be followed; can be either ``forward`` or ``backward``, default to ``forward`` :statuscode 200: success :statuscode 400: invalid query string provided :statuscode 404: starting node cannot be found .. sourcecode:: http GET /graph/visit/nodes/ HTTP/1.1 200 OK Content-Type: application/json - [ - "swh:1:rev:f39d7d78b70e0f39facb1e4fab77ad3df5c52a35", - "swh:1:rev:52c90f2d32bfa7d6eccd66a56c44ace1f78fbadd", - ... - "swh:1:rev:a31e58e129f73ab5b04016330b13ed51fde7a961", - ... - ] + { + "result": [ + "swh:1:rev:f39d7d78b70e0f39facb1e4fab77ad3df5c52a35", + "swh:1:rev:52c90f2d32bfa7d6eccd66a56c44ace1f78fbadd", + ... + "swh:1:rev:a31e58e129f73ab5b04016330b13ed51fde7a961", + ... + ], + "meta": { + "timings": { + "traversal": 0.002942681, + "pid2node": 0.000178051, + "node2pid": 0.000956569 + } + } + } .. sourcecode:: http GET /graph/visit/paths/ HTTP/1.1 200 OK Content-Type: application/json - [ - [ - "swh:1:rev:f39d7d78b70e0f39facb1e4fab77ad3df5c52a35", - "swh:1:rev:52c90f2d32bfa7d6eccd66a56c44ace1f78fbadd", - ... - ], - [ - "swh:1:rev:f39d7d78b70e0f39facb1e4fab77ad3df5c52a35", - "swh:1:rev:a31e58e129f73ab5b04016330b13ed51fde7a961", + { + "result": [ + [ + "swh:1:rev:f39d7d78b70e0f39facb1e4fab77ad3df5c52a35", + "swh:1:rev:52c90f2d32bfa7d6eccd66a56c44ace1f78fbadd", + ... + ], + [ + "swh:1:rev:f39d7d78b70e0f39facb1e4fab77ad3df5c52a35", + "swh:1:rev:a31e58e129f73ab5b04016330b13ed51fde7a961", + ... + ], ... ], - ... - ] + "meta": { + "timings" : { + "traversal": 0.002942681, + "pid2node": 0.000178051, + "node2pid": 0.000956569 + } + } + } Stats ----- .. http:get:: /graph/stats Returns statistics on the compressed graph. :statuscode 200: success .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { "counts": { "nodes": 16222788, "edges": 9907464 }, "ratios": { "compression": 0.367, "bits_per_node": 5.846, "bits_per_edge": 9.573, "avg_locality": 270.369 }, "indegree": { "min": 0, "max": 12382, "avg": 0.6107127825377487 }, "outdegree": { "min": 0, "max": 1, "avg": 0.6107127825377487 } } diff --git a/java/server/README.md b/java/server/README.md index 0323461..5e2a41c 100644 --- a/java/server/README.md +++ b/java/server/README.md @@ -1,48 +1,50 @@ Graph service - Server side =========================== Server side Java REST API. Build ----- ```bash $ mvn compile assembly:single ``` Start REST API -------------- ```bash $ java -cp target/swh-graph-0.0.1-jar-with-dependencies.jar \ org.softwareheritage.graph.App \ ``` -Default port is 5009. +Default port is 5009 (use the `--port` option to change port number). If you +need timings metadata send back to the client in addition to the result, use the +`--timings` flag. Tests ----- Unit tests rely on test data that are already available in the Git repository (under `src/test/dataset/`). You generally only need to run them using Maven: ```bash $ mvn test ``` In case you want to regenerate the test data: ```bash # Graph compression $ cd src/test/dataset $ ./generate_graph.sh $ cd ../../../ $ mvn compile assembly:single # Dump mapping files $ java -cp target/swh-graph-0.0.1-jar-with-dependencies.jar \ org.softwareheritage.graph.backend.Setup \ src/test/dataset/example.nodes.csv.gz \ src/test/dataset/output/example ``` diff --git a/java/server/src/main/java/org/softwareheritage/graph/App.java b/java/server/src/main/java/org/softwareheritage/graph/App.java index 4a3d896..a191203 100644 --- a/java/server/src/main/java/org/softwareheritage/graph/App.java +++ b/java/server/src/main/java/org/softwareheritage/graph/App.java @@ -1,169 +1,199 @@ package org.softwareheritage.graph; import java.io.IOException; +import java.util.HashMap; import java.util.List; import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.martiansoftware.jsap.FlaggedOption; import com.martiansoftware.jsap.JSAP; import com.martiansoftware.jsap.JSAPException; import com.martiansoftware.jsap.JSAPResult; import com.martiansoftware.jsap.Parameter; import com.martiansoftware.jsap.SimpleJSAP; +import com.martiansoftware.jsap.Switch; import com.martiansoftware.jsap.UnflaggedOption; import io.javalin.Javalin; import io.javalin.http.Context; import io.javalin.plugin.json.JavalinJackson; import org.softwareheritage.graph.Endpoint; import org.softwareheritage.graph.Graph; import org.softwareheritage.graph.SwhId; import org.softwareheritage.graph.algo.Stats; /** * Web framework of the swh-graph server REST API. * * @author Thibault Allançon * @version 0.0.1 * @since 0.0.1 */ public class App { /** * Main entrypoint. * * @param args command line arguments */ public static void main(String[] args) throws IOException, JSAPException { SimpleJSAP jsap = new SimpleJSAP( App.class.getName(), "Server to load and query a compressed graph representation of Software Heritage archive.", new Parameter[] { new FlaggedOption("port", JSAP.INTEGER_PARSER, "5009", JSAP.NOT_REQUIRED, 'p', "port", "Binding port of the server."), new UnflaggedOption("graphPath", JSAP.STRING_PARSER, JSAP.NO_DEFAULT, JSAP.REQUIRED, JSAP.NOT_GREEDY, "The basename of the compressed graph."), + new Switch("timings", 't', "timings", "Show timings in API result metadata."), } ); JSAPResult config = jsap.parse(args); if (jsap.messagePrinted()) { System.exit(1); } String graphPath = config.getString("graphPath"); int port = config.getInt("port"); + boolean showTimings = config.getBoolean("timings"); - startServer(graphPath, port); + startServer(graphPath, port, showTimings); } /** * Loads compressed graph and starts the web server to query it. * * @param graphPath basename of the compressed graph * @param port binding port of the server + * @param showTimings true if timings should be in results metadata, false otherwise */ - private static void startServer(String graphPath, int port) throws IOException { + private static void startServer(String graphPath, int port, boolean showTimings) throws IOException { Graph graph = new Graph(graphPath); Stats stats = new Stats(graphPath); // Clean up on exit Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { try { graph.cleanUp(); } catch (IOException e) { System.out.println("Could not clean up graph on exit: " + e); } } }); // Configure Jackson JSON to use snake case naming style ObjectMapper objectMapper = JavalinJackson.getObjectMapper(); objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); JavalinJackson.configure(objectMapper); Javalin app = Javalin.create().start(port); app.before("/stats/*", ctx -> { checkQueryStrings(ctx, ""); }); app.before("/leaves/*", ctx -> { checkQueryStrings(ctx, "direction|edges"); }); app.before("/neighbors/*", ctx -> { checkQueryStrings(ctx, "direction|edges"); }); app.before("/visit/*", ctx -> { checkQueryStrings(ctx, "direction|edges"); }); app.before("/walk/*", ctx -> { checkQueryStrings(ctx, "direction|edges|traversal"); }); app.get("/stats/", ctx -> { ctx.json(stats); }); // Graph traversal endpoints // By default the traversal is a forward DFS using all edges app.get("/leaves/:src", ctx -> { SwhId src = new SwhId(ctx.pathParam("src")); String direction = ctx.queryParam("direction", "forward"); String edgesFmt = ctx.queryParam("edges", "*"); Endpoint endpoint = new Endpoint(graph, direction, edgesFmt); - ctx.json(endpoint.leaves(src)); + Endpoint.Output output = endpoint.leaves(src); + ctx.json(formatEndpointOutput(output, showTimings)); }); app.get("/neighbors/:src", ctx -> { SwhId src = new SwhId(ctx.pathParam("src")); String direction = ctx.queryParam("direction", "forward"); String edgesFmt = ctx.queryParam("edges", "*"); Endpoint endpoint = new Endpoint(graph, direction, edgesFmt); - ctx.json(endpoint.neighbors(src)); + Endpoint.Output output = endpoint.neighbors(src); + ctx.json(formatEndpointOutput(output, showTimings)); }); app.get("/visit/nodes/:src", ctx -> { SwhId src = new SwhId(ctx.pathParam("src")); String direction = ctx.queryParam("direction", "forward"); String edgesFmt = ctx.queryParam("edges", "*"); Endpoint endpoint = new Endpoint(graph, direction, edgesFmt); - ctx.json(endpoint.visitNodes(src)); + Endpoint.Output output = endpoint.visitNodes(src); + ctx.json(formatEndpointOutput(output, showTimings)); }); app.get("/visit/paths/:src", ctx -> { SwhId src = new SwhId(ctx.pathParam("src")); String direction = ctx.queryParam("direction", "forward"); String edgesFmt = ctx.queryParam("edges", "*"); Endpoint endpoint = new Endpoint(graph, direction, edgesFmt); - ctx.json(endpoint.visitPaths(src)); + Endpoint.Output output = endpoint.visitPaths(src); + ctx.json(formatEndpointOutput(output, showTimings)); }); app.get("/walk/:src/:dst", ctx -> { SwhId src = new SwhId(ctx.pathParam("src")); String dstFmt = ctx.pathParam("dst"); String direction = ctx.queryParam("direction", "forward"); String edgesFmt = ctx.queryParam("edges", "*"); String algorithm = ctx.queryParam("traversal", "dfs"); Endpoint endpoint = new Endpoint(graph, direction, edgesFmt); - ctx.json(endpoint.walk(src, dstFmt, algorithm)); + Endpoint.Output output = endpoint.walk(src, dstFmt, algorithm); + ctx.json(formatEndpointOutput(output, showTimings)); }); app.exception(IllegalArgumentException.class, (e, ctx) -> { ctx.status(400); ctx.result(e.getMessage()); }); } /** * Checks query strings names provided to the REST API. * * @param ctx Javalin HTTP request context * @param allowedFmt a regular expression describing allowed query strings names * @throws IllegalArgumentException unknown query string provided */ private static void checkQueryStrings(Context ctx, String allowedFmt) { Map> queryParamMap = ctx.queryParamMap(); for (String key : queryParamMap.keySet()) { if (!key.matches(allowedFmt)) { throw new IllegalArgumentException("Unknown query string: " + key); } } } + + /** + * Formats endpoint result into final JSON for the REST API. + *

+ * Removes unwanted information if necessary, such as timings (to prevent use of side channels + * attacks). + * + * @param output endpoint operation output which needs formatting + * @param showTimings true if timings should be in results metadata, false otherwise + * @return final Object with desired JSON format + */ + private static Object formatEndpointOutput(Endpoint.Output output, boolean showTimings) { + if (showTimings) { + return output; + } else { + Map outputNoTimings = new HashMap<>(); + outputNoTimings.put("result", output.result); + return outputNoTimings; + } + } } diff --git a/java/server/src/main/java/org/softwareheritage/graph/Endpoint.java b/java/server/src/main/java/org/softwareheritage/graph/Endpoint.java index 03bbf1b..1827da3 100644 --- a/java/server/src/main/java/org/softwareheritage/graph/Endpoint.java +++ b/java/server/src/main/java/org/softwareheritage/graph/Endpoint.java @@ -1,217 +1,281 @@ package org.softwareheritage.graph; import java.util.ArrayList; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.softwareheritage.graph.Graph; import org.softwareheritage.graph.SwhId; import org.softwareheritage.graph.SwhPath; import org.softwareheritage.graph.algo.Traversal; import org.softwareheritage.graph.utils.Timing; /** * REST API endpoints wrapper functions. *

* Graph operations are segmented between high-level class (this one) and the low-level class * ({@link Traversal}). The {@link Endpoint} class creates wrappers for each endpoints by performing * all the input/output node ids conversions and logging timings. * * @author Thibault Allançon * @version 0.0.1 * @since 0.0.1 * @see org.softwareheritage.graph.algo.Traversal */ public class Endpoint { + /** + * Wrapper class to return both the endpoint result and metadata (such as timings). + */ + public class Output { + /** The result content itself */ + public T result; + /** Various metadata about the result */ + public Meta meta; + + public Output() { + this.result = null; + this.meta = new Meta(); + } + + /** + * Endpoint result metadata. + */ + public class Meta { + /** Operations timings */ + public Timings timings; + + public Meta() { + this.timings = new Timings(); + } + + /** + * Wrapper class for JSON output format. + */ + public class Timings { + /** Time in seconds to do the traversal */ + public float traversal; + /** Time in seconds to convert input SWH PID to node id */ + public float pid2node; + /** Time in seconds to convert output node ids to SWH PIDs */ + public float node2pid; + } + } + } + /** Graph where traversal endpoint is performed */ Graph graph; /** Internal traversal API */ Traversal traversal; - /** Timings logger */ - private static final Logger logger = LoggerFactory.getLogger(Endpoint.class); - /** * Constructor. * * @param graph the graph used for traversal endpoint * @param direction a string (either "forward" or "backward") specifying edge orientation * @param edgesFmt a formatted string describing allowed edges */ public Endpoint(Graph graph, String direction, String edgesFmt) { this.graph = graph; this.traversal = new Traversal(graph, direction, edgesFmt); } /** * Converts a list of (internal) long node ids to a list of corresponding (external) SWH PIDs. * * @param nodeIds the list of long node ids * @return a list of corresponding SWH PIDs */ private ArrayList convertNodesToSwhIds(ArrayList nodeIds) { - long startTime = Timing.start(); ArrayList swhIds = new ArrayList<>(); for (long nodeId : nodeIds) { swhIds.add(graph.getSwhId(nodeId)); } - float duration = Timing.stop(startTime); - logger.debug("convertNodesToSwhIds() took {} s.", duration); return swhIds; } /** * Converts a list of (internal) long node ids to the corresponding {@link SwhPath}. * * @param nodeIds the list of long node ids * @return the corresponding {@link SwhPath} * @see org.softwareheritage.graph.SwhPath */ private SwhPath convertNodesToSwhPath(ArrayList nodeIds) { - long startTime = Timing.start(); SwhPath path = new SwhPath(); for (long nodeId : nodeIds) { path.add(graph.getSwhId(nodeId)); } - float duration = Timing.stop(startTime); - logger.debug("convertNodesToSwhPath() took {} s.", duration); return path; } /** * Converts a list of paths made of (internal) long node ids to one made of {@link SwhPath}-s. * * @param pathsNodeId the list of paths with long node ids * @return a list of corresponding {@link SwhPath} * @see org.softwareheritage.graph.SwhPath */ private ArrayList convertPathsToSwhIds(ArrayList> pathsNodeId) { - long startTime = Timing.start(); ArrayList paths = new ArrayList<>(); for (ArrayList path : pathsNodeId) { paths.add(convertNodesToSwhPath(path)); } - float duration = Timing.stop(startTime); - logger.debug("convertPathsToSwhIds() took {} s.", duration); return paths; } /** * Leaves endpoint wrapper. * * @param src source node of endpoint call specified as a {@link SwhId} - * @return the resulting list of {@link SwhId} from endpoint call + * @return the resulting list of {@link SwhId} from endpoint call and operation metadata * @see org.softwareheritage.graph.SwhId * @see org.softwareheritage.graph.algo.Traversal#leaves(long) */ - public ArrayList leaves(SwhId src) { + public Output leaves(SwhId src) { + Output> output = new Output<>(); + long startTime; + + startTime = Timing.start(); long srcNodeId = graph.getNodeId(src); + output.meta.timings.pid2node = Timing.stop(startTime); - long startTime = Timing.start(); + startTime = Timing.start(); ArrayList nodeIds = traversal.leaves(srcNodeId); - float duration = Timing.stop(startTime); - logger.debug("leaves({}) took {} s.", src, duration); + output.meta.timings.traversal = Timing.stop(startTime); + + startTime = Timing.start(); + output.result = convertNodesToSwhIds(nodeIds); + output.meta.timings.node2pid = Timing.stop(startTime); - return convertNodesToSwhIds(nodeIds); + return output; } /** * Neighbors endpoint wrapper. * * @param src source node of endpoint call specified as a {@link SwhId} - * @return the resulting list of {@link SwhId} from endpoint call + * @return the resulting list of {@link SwhId} from endpoint call and operation metadata * @see org.softwareheritage.graph.SwhId * @see org.softwareheritage.graph.algo.Traversal#neighbors(long) */ - public ArrayList neighbors(SwhId src) { + public Output neighbors(SwhId src) { + Output> output = new Output<>(); + long startTime; + + startTime = Timing.start(); long srcNodeId = graph.getNodeId(src); + output.meta.timings.pid2node = Timing.stop(startTime); - long startTime = Timing.start(); + startTime = Timing.start(); ArrayList nodeIds = traversal.neighbors(srcNodeId); - float duration = Timing.stop(startTime); - logger.debug("neighbors({}) took {} s.", src, duration); + output.meta.timings.traversal = Timing.stop(startTime); - return convertNodesToSwhIds(nodeIds); + startTime = Timing.start(); + output.result = convertNodesToSwhIds(nodeIds); + output.meta.timings.node2pid = Timing.stop(startTime); + + return output; } /** * Walk endpoint wrapper. * * @param src source node of endpoint call specified as a {@link SwhId} * @param dstFmt destination formatted string as described in the API * @param algorithm traversal algorithm used in endpoint call (either "dfs" or "bfs") - * @return the resulting {@link SwhPath} from endpoint call + * @return the resulting {@link SwhPath} from endpoint call and operation metadata * @see org.softwareheritage.graph.SwhId * @see org.softwareheritage.graph.SwhPath * @see org.softwareheritage.graph.algo.Traversal#walk */ - public SwhPath walk(SwhId src, String dstFmt, String algorithm) { + public Output walk(SwhId src, String dstFmt, String algorithm) { + Output output = new Output<>(); + long startTime; + + startTime = Timing.start(); long srcNodeId = graph.getNodeId(src); + output.meta.timings.pid2node = Timing.stop(startTime); + ArrayList nodeIds = new ArrayList(); // Destination is either a SWH ID or a node type try { SwhId dstSwhId = new SwhId(dstFmt); long dstNodeId = graph.getNodeId(dstSwhId); - long startTime = Timing.start(); + startTime = Timing.start(); nodeIds = traversal.walk(srcNodeId, dstNodeId, algorithm); - float duration = Timing.stop(startTime); - logger.debug("walk({}) took {} s.", src, duration); + output.meta.timings.traversal = Timing.stop(startTime); } catch (IllegalArgumentException ignored1) { try { Node.Type dstType = Node.Type.fromStr(dstFmt); - long startTime = Timing.start(); + startTime = Timing.start(); nodeIds = traversal.walk(srcNodeId, dstType, algorithm); - float duration = Timing.stop(startTime); - logger.debug("walk({}) took {} s.", src, duration); + output.meta.timings.traversal = Timing.stop(startTime); } catch (IllegalArgumentException ignored2) { } } - return convertNodesToSwhPath(nodeIds); + startTime = Timing.start(); + output.result = convertNodesToSwhPath(nodeIds); + output.meta.timings.node2pid = Timing.stop(startTime); + + return output; } /** * VisitNodes endpoint wrapper. * * @param src source node of endpoint call specified as a {@link SwhId} - * @return the resulting list of {@link SwhId} from endpoint call + * @return the resulting list of {@link SwhId} from endpoint call and operation metadata * @see org.softwareheritage.graph.SwhId * @see org.softwareheritage.graph.algo.Traversal#visitNodes(long) */ - public ArrayList visitNodes(SwhId src) { + public Output visitNodes(SwhId src) { + Output> output = new Output<>(); + long startTime; + + startTime = Timing.start(); long srcNodeId = graph.getNodeId(src); + output.meta.timings.pid2node = Timing.stop(startTime); - long startTime = Timing.start(); + startTime = Timing.start(); ArrayList nodeIds = traversal.visitNodes(srcNodeId); - float duration = Timing.stop(startTime); - logger.debug("visitNodes({}) took {} s.", src, duration); + output.meta.timings.traversal = Timing.stop(startTime); + + startTime = Timing.start(); + output.result = convertNodesToSwhIds(nodeIds); + output.meta.timings.node2pid = Timing.stop(startTime); - return convertNodesToSwhIds(nodeIds); + return output; } /** * VisitPaths endpoint wrapper. * * @param src source node of endpoint call specified as a {@link SwhId} - * @return the resulting list of {@link SwhPath} from endpoint call + * @return the resulting list of {@link SwhPath} from endpoint call and operation metadata * @see org.softwareheritage.graph.SwhId * @see org.softwareheritage.graph.SwhPath * @see org.softwareheritage.graph.algo.Traversal#visitPaths(long) */ - public ArrayList visitPaths(SwhId src) { + public Output visitPaths(SwhId src) { + Output> output = new Output<>(); + long startTime; + + startTime = Timing.start(); long srcNodeId = graph.getNodeId(src); + output.meta.timings.pid2node = Timing.stop(startTime); - long startTime = Timing.start(); + startTime = Timing.start(); ArrayList> paths = traversal.visitPaths(srcNodeId); - float duration = Timing.stop(startTime); - logger.debug("visitPaths({}) took {} s.", src, duration); + output.meta.timings.traversal = Timing.stop(startTime); + + startTime = Timing.start(); + output.result = convertPathsToSwhIds(paths); + output.meta.timings.node2pid = Timing.stop(startTime); - return convertPathsToSwhIds(paths); + return output; } } diff --git a/java/server/src/test/java/org/softwareheritage/graph/LeavesTest.java b/java/server/src/test/java/org/softwareheritage/graph/LeavesTest.java index 46e8797..d75e8c9 100644 --- a/java/server/src/test/java/org/softwareheritage/graph/LeavesTest.java +++ b/java/server/src/test/java/org/softwareheritage/graph/LeavesTest.java @@ -1,101 +1,103 @@ package org.softwareheritage.graph; import java.util.ArrayList; import org.junit.Test; import org.softwareheritage.graph.Endpoint; import org.softwareheritage.graph.Graph; import org.softwareheritage.graph.GraphTest; import org.softwareheritage.graph.SwhId; +// Avoid warnings concerning Endpoint.Output.result manual cast +@SuppressWarnings("unchecked") public class LeavesTest extends GraphTest { @Test public void forwardFromSnp() { Graph graph = getGraph(); SwhId src = new SwhId("swh:1:snp:0000000000000000000000000000000000000020"); Endpoint endpoint = new Endpoint(graph, "forward", "*"); ArrayList expectedLeaves = new ArrayList<>(); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000001")); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000004")); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000005")); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000007")); - GraphTest.assertEqualsAnyOrder(expectedLeaves, endpoint.leaves(src)); + GraphTest.assertEqualsAnyOrder(expectedLeaves, (ArrayList) endpoint.leaves(src).result); } @Test public void forwardFromRel() { Graph graph = getGraph(); SwhId src = new SwhId("swh:1:rel:0000000000000000000000000000000000000019"); Endpoint endpoint = new Endpoint(graph, "forward", "*"); ArrayList expectedLeaves = new ArrayList<>(); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000015")); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000014")); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000001")); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000004")); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000005")); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000007")); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000011")); - GraphTest.assertEqualsAnyOrder(expectedLeaves, endpoint.leaves(src)); + GraphTest.assertEqualsAnyOrder(expectedLeaves, (ArrayList) endpoint.leaves(src).result); } @Test public void backwardFromLeaf() { Graph graph = getGraph(); Endpoint endpoint = new Endpoint(graph, "backward", "*"); SwhId src1 = new SwhId("swh:1:cnt:0000000000000000000000000000000000000015"); ArrayList expectedLeaves1 = new ArrayList<>(); expectedLeaves1.add(new SwhId("swh:1:rel:0000000000000000000000000000000000000019")); - GraphTest.assertEqualsAnyOrder(expectedLeaves1, endpoint.leaves(src1)); + GraphTest.assertEqualsAnyOrder(expectedLeaves1, (ArrayList) endpoint.leaves(src1).result); SwhId src2 = new SwhId("swh:1:cnt:0000000000000000000000000000000000000004"); ArrayList expectedLeaves2 = new ArrayList<>(); expectedLeaves2.add(new SwhId("swh:1:ori:0000000000000000000000000000000000000021")); expectedLeaves2.add(new SwhId("swh:1:rel:0000000000000000000000000000000000000019")); - GraphTest.assertEqualsAnyOrder(expectedLeaves2, endpoint.leaves(src2)); + GraphTest.assertEqualsAnyOrder(expectedLeaves2, (ArrayList) endpoint.leaves(src2).result); } @Test public void forwardRevToRevOnly() { Graph graph = getGraph(); SwhId src = new SwhId("swh:1:rev:0000000000000000000000000000000000000018"); Endpoint endpoint = new Endpoint(graph, "forward", "rev:rev"); ArrayList expectedLeaves = new ArrayList<>(); expectedLeaves.add(new SwhId("swh:1:rev:0000000000000000000000000000000000000003")); - GraphTest.assertEqualsAnyOrder(expectedLeaves, endpoint.leaves(src)); + GraphTest.assertEqualsAnyOrder(expectedLeaves, (ArrayList) endpoint.leaves(src).result); } @Test public void forwardDirToAll() { Graph graph = getGraph(); SwhId src = new SwhId("swh:1:dir:0000000000000000000000000000000000000008"); Endpoint endpoint = new Endpoint(graph, "forward", "dir:*"); ArrayList expectedLeaves = new ArrayList<>(); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000004")); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000005")); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000001")); expectedLeaves.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000007")); - GraphTest.assertEqualsAnyOrder(expectedLeaves, endpoint.leaves(src)); + GraphTest.assertEqualsAnyOrder(expectedLeaves, (ArrayList) endpoint.leaves(src).result); } @Test public void backwardCntToDirDirToDir() { Graph graph = getGraph(); SwhId src = new SwhId("swh:1:cnt:0000000000000000000000000000000000000005"); Endpoint endpoint = new Endpoint(graph, "backward", "cnt:dir,dir:dir"); ArrayList expectedLeaves = new ArrayList<>(); expectedLeaves.add(new SwhId("swh:1:dir:0000000000000000000000000000000000000012")); - GraphTest.assertEqualsAnyOrder(expectedLeaves, endpoint.leaves(src)); + GraphTest.assertEqualsAnyOrder(expectedLeaves, (ArrayList) endpoint.leaves(src).result); } } diff --git a/java/server/src/test/java/org/softwareheritage/graph/NeighborsTest.java b/java/server/src/test/java/org/softwareheritage/graph/NeighborsTest.java index 25b524f..4f55956 100644 --- a/java/server/src/test/java/org/softwareheritage/graph/NeighborsTest.java +++ b/java/server/src/test/java/org/softwareheritage/graph/NeighborsTest.java @@ -1,127 +1,129 @@ package org.softwareheritage.graph; import java.util.ArrayList; import org.junit.Test; import org.softwareheritage.graph.Endpoint; import org.softwareheritage.graph.Graph; import org.softwareheritage.graph.GraphTest; import org.softwareheritage.graph.SwhId; +// Avoid warnings concerning Endpoint.Output.result manual cast +@SuppressWarnings("unchecked") public class NeighborsTest extends GraphTest { @Test public void zeroNeighbor() { Graph graph = getGraph(); ArrayList expectedNodes = new ArrayList<>(); SwhId src1 = new SwhId("swh:1:ori:0000000000000000000000000000000000000021"); Endpoint endpoint1 = new Endpoint(graph, "backward", "*"); - GraphTest.assertEqualsAnyOrder(expectedNodes, endpoint1.neighbors(src1)); + GraphTest.assertEqualsAnyOrder(expectedNodes, (ArrayList) endpoint1.neighbors(src1).result); SwhId src2 = new SwhId("swh:1:cnt:0000000000000000000000000000000000000004"); Endpoint endpoint2 = new Endpoint(graph, "forward", "*"); - GraphTest.assertEqualsAnyOrder(expectedNodes, endpoint2.neighbors(src2)); + GraphTest.assertEqualsAnyOrder(expectedNodes, (ArrayList) endpoint2.neighbors(src2).result); SwhId src3 = new SwhId("swh:1:cnt:0000000000000000000000000000000000000015"); Endpoint endpoint3 = new Endpoint(graph, "forward", "*"); - GraphTest.assertEqualsAnyOrder(expectedNodes, endpoint3.neighbors(src3)); + GraphTest.assertEqualsAnyOrder(expectedNodes, (ArrayList) endpoint3.neighbors(src3).result); SwhId src4 = new SwhId("swh:1:rel:0000000000000000000000000000000000000019"); Endpoint endpoint4 = new Endpoint(graph, "backward", "*"); - GraphTest.assertEqualsAnyOrder(expectedNodes, endpoint4.neighbors(src4)); + GraphTest.assertEqualsAnyOrder(expectedNodes, (ArrayList) endpoint4.neighbors(src4).result); SwhId src5 = new SwhId("swh:1:dir:0000000000000000000000000000000000000008"); Endpoint endpoint5 = new Endpoint(graph, "forward", "snp:*,rev:*,rel:*"); - GraphTest.assertEqualsAnyOrder(expectedNodes, endpoint5.neighbors(src5)); + GraphTest.assertEqualsAnyOrder(expectedNodes, (ArrayList) endpoint5.neighbors(src5).result); } @Test public void oneNeighbor() { Graph graph = getGraph(); SwhId src1 = new SwhId("swh:1:rev:0000000000000000000000000000000000000003"); Endpoint endpoint1 = new Endpoint(graph, "forward", "*"); ArrayList expectedNodes1 = new ArrayList<>(); expectedNodes1.add(new SwhId("swh:1:dir:0000000000000000000000000000000000000002")); - GraphTest.assertEqualsAnyOrder(expectedNodes1, endpoint1.neighbors(src1)); + GraphTest.assertEqualsAnyOrder(expectedNodes1, (ArrayList) endpoint1.neighbors(src1).result); SwhId src2 = new SwhId("swh:1:dir:0000000000000000000000000000000000000017"); Endpoint endpoint2 = new Endpoint(graph, "forward", "dir:cnt"); ArrayList expectedNodes2 = new ArrayList<>(); expectedNodes2.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000014")); - GraphTest.assertEqualsAnyOrder(expectedNodes2, endpoint2.neighbors(src2)); + GraphTest.assertEqualsAnyOrder(expectedNodes2, (ArrayList) endpoint2.neighbors(src2).result); SwhId src3 = new SwhId("swh:1:dir:0000000000000000000000000000000000000012"); Endpoint endpoint3 = new Endpoint(graph, "backward", "*"); ArrayList expectedNodes3 = new ArrayList<>(); expectedNodes3.add(new SwhId("swh:1:rev:0000000000000000000000000000000000000013")); - GraphTest.assertEqualsAnyOrder(expectedNodes3, endpoint3.neighbors(src3)); + GraphTest.assertEqualsAnyOrder(expectedNodes3, (ArrayList) endpoint3.neighbors(src3).result); SwhId src4 = new SwhId("swh:1:rev:0000000000000000000000000000000000000009"); Endpoint endpoint4 = new Endpoint(graph, "backward", "rev:rev"); ArrayList expectedNodes4 = new ArrayList<>(); expectedNodes4.add(new SwhId("swh:1:rev:0000000000000000000000000000000000000013")); - GraphTest.assertEqualsAnyOrder(expectedNodes4, endpoint4.neighbors(src4)); + GraphTest.assertEqualsAnyOrder(expectedNodes4, (ArrayList) endpoint4.neighbors(src4).result); SwhId src5 = new SwhId("swh:1:snp:0000000000000000000000000000000000000020"); Endpoint endpoint5 = new Endpoint(graph, "backward", "*"); ArrayList expectedNodes5 = new ArrayList<>(); expectedNodes5.add(new SwhId("swh:1:ori:0000000000000000000000000000000000000021")); - GraphTest.assertEqualsAnyOrder(expectedNodes5, endpoint5.neighbors(src5)); + GraphTest.assertEqualsAnyOrder(expectedNodes5, (ArrayList) endpoint5.neighbors(src5).result); } @Test public void twoNeighbors() { Graph graph = getGraph(); SwhId src1 = new SwhId("swh:1:snp:0000000000000000000000000000000000000020"); Endpoint endpoint1 = new Endpoint(graph, "forward", "*"); ArrayList expectedNodes1 = new ArrayList<>(); expectedNodes1.add(new SwhId("swh:1:rel:0000000000000000000000000000000000000010")); expectedNodes1.add(new SwhId("swh:1:rev:0000000000000000000000000000000000000009")); - GraphTest.assertEqualsAnyOrder(expectedNodes1, endpoint1.neighbors(src1)); + GraphTest.assertEqualsAnyOrder(expectedNodes1, (ArrayList) endpoint1.neighbors(src1).result); SwhId src2 = new SwhId("swh:1:dir:0000000000000000000000000000000000000008"); Endpoint endpoint2 = new Endpoint(graph, "forward", "dir:cnt"); ArrayList expectedNodes2 = new ArrayList<>(); expectedNodes2.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000001")); expectedNodes2.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000007")); - GraphTest.assertEqualsAnyOrder(expectedNodes2, endpoint2.neighbors(src2)); + GraphTest.assertEqualsAnyOrder(expectedNodes2, (ArrayList) endpoint2.neighbors(src2).result); SwhId src3 = new SwhId("swh:1:cnt:0000000000000000000000000000000000000001"); Endpoint endpoint3 = new Endpoint(graph, "backward", "*"); ArrayList expectedNodes3 = new ArrayList<>(); expectedNodes3.add(new SwhId("swh:1:dir:0000000000000000000000000000000000000008")); expectedNodes3.add(new SwhId("swh:1:dir:0000000000000000000000000000000000000002")); - GraphTest.assertEqualsAnyOrder(expectedNodes3, endpoint3.neighbors(src3)); + GraphTest.assertEqualsAnyOrder(expectedNodes3, (ArrayList) endpoint3.neighbors(src3).result); SwhId src4 = new SwhId("swh:1:rev:0000000000000000000000000000000000000009"); Endpoint endpoint4 = new Endpoint(graph, "backward", "rev:snp,rev:rel"); ArrayList expectedNodes4 = new ArrayList<>(); expectedNodes4.add(new SwhId("swh:1:snp:0000000000000000000000000000000000000020")); expectedNodes4.add(new SwhId("swh:1:rel:0000000000000000000000000000000000000010")); - GraphTest.assertEqualsAnyOrder(expectedNodes4, endpoint4.neighbors(src4)); + GraphTest.assertEqualsAnyOrder(expectedNodes4, (ArrayList) endpoint4.neighbors(src4).result); } @Test public void threeNeighbors() { Graph graph = getGraph(); SwhId src1 = new SwhId("swh:1:dir:0000000000000000000000000000000000000008"); Endpoint endpoint1 = new Endpoint(graph, "forward", "*"); ArrayList expectedNodes1 = new ArrayList<>(); expectedNodes1.add(new SwhId("swh:1:dir:0000000000000000000000000000000000000006")); expectedNodes1.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000001")); expectedNodes1.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000007")); - GraphTest.assertEqualsAnyOrder(expectedNodes1, endpoint1.neighbors(src1)); + GraphTest.assertEqualsAnyOrder(expectedNodes1, (ArrayList) endpoint1.neighbors(src1).result); SwhId src2 = new SwhId("swh:1:rev:0000000000000000000000000000000000000009"); Endpoint endpoint2 = new Endpoint(graph, "backward", "*"); ArrayList expectedNodes2 = new ArrayList<>(); expectedNodes2.add(new SwhId("swh:1:snp:0000000000000000000000000000000000000020")); expectedNodes2.add(new SwhId("swh:1:rel:0000000000000000000000000000000000000010")); expectedNodes2.add(new SwhId("swh:1:rev:0000000000000000000000000000000000000013")); - GraphTest.assertEqualsAnyOrder(expectedNodes2, endpoint2.neighbors(src2)); + GraphTest.assertEqualsAnyOrder(expectedNodes2, (ArrayList) endpoint2.neighbors(src2).result); } } diff --git a/java/server/src/test/java/org/softwareheritage/graph/VisitTest.java b/java/server/src/test/java/org/softwareheritage/graph/VisitTest.java index dbc2ff3..6ddbdbe 100644 --- a/java/server/src/test/java/org/softwareheritage/graph/VisitTest.java +++ b/java/server/src/test/java/org/softwareheritage/graph/VisitTest.java @@ -1,533 +1,535 @@ package org.softwareheritage.graph; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; import org.junit.Test; import org.softwareheritage.graph.Endpoint; import org.softwareheritage.graph.Graph; import org.softwareheritage.graph.GraphTest; import org.softwareheritage.graph.SwhId; import org.softwareheritage.graph.SwhPath; +// Avoid warnings concerning Endpoint.Output.result manual cast +@SuppressWarnings("unchecked") public class VisitTest extends GraphTest { private void assertSameNodesFromPaths(ArrayList paths, ArrayList nodes) { Set expectedNodes = new HashSet(); for (SwhPath path : paths) { for (SwhId node : path.getPath()) { expectedNodes.add(node); } } GraphTest.assertEqualsAnyOrder(expectedNodes, nodes); } @Test public void forwardFromRoot() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:ori:0000000000000000000000000000000000000021"); Endpoint endpoint = new Endpoint(graph, "forward", "*"); - ArrayList paths = endpoint.visitPaths(swhId); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList paths = (ArrayList) endpoint.visitPaths(swhId).result; + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedPaths = new ArrayList(); expectedPaths.add( new SwhPath( "swh:1:ori:0000000000000000000000000000000000000021", "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:cnt:0000000000000000000000000000000000000007" )); expectedPaths.add( new SwhPath( "swh:1:ori:0000000000000000000000000000000000000021", "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:cnt:0000000000000000000000000000000000000001" )); expectedPaths.add( new SwhPath( "swh:1:ori:0000000000000000000000000000000000000021", "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000004" )); expectedPaths.add( new SwhPath( "swh:1:ori:0000000000000000000000000000000000000021", "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000005" )); expectedPaths.add( new SwhPath( "swh:1:ori:0000000000000000000000000000000000000021", "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rev:0000000000000000000000000000000000000003", "swh:1:dir:0000000000000000000000000000000000000002", "swh:1:cnt:0000000000000000000000000000000000000001" )); expectedPaths.add( new SwhPath( "swh:1:ori:0000000000000000000000000000000000000021", "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rel:0000000000000000000000000000000000000010", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:cnt:0000000000000000000000000000000000000007" )); expectedPaths.add( new SwhPath( "swh:1:ori:0000000000000000000000000000000000000021", "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rel:0000000000000000000000000000000000000010", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:cnt:0000000000000000000000000000000000000001" )); expectedPaths.add( new SwhPath( "swh:1:ori:0000000000000000000000000000000000000021", "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rel:0000000000000000000000000000000000000010", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000004" )); expectedPaths.add( new SwhPath( "swh:1:ori:0000000000000000000000000000000000000021", "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rel:0000000000000000000000000000000000000010", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000005" )); expectedPaths.add( new SwhPath( "swh:1:ori:0000000000000000000000000000000000000021", "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rel:0000000000000000000000000000000000000010", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rev:0000000000000000000000000000000000000003", "swh:1:dir:0000000000000000000000000000000000000002", "swh:1:cnt:0000000000000000000000000000000000000001" )); GraphTest.assertEqualsAnyOrder(expectedPaths, paths); assertSameNodesFromPaths(expectedPaths, nodes); } @Test public void forwardFromMiddle() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:dir:0000000000000000000000000000000000000012"); Endpoint endpoint = new Endpoint(graph, "forward", "*"); - ArrayList paths = endpoint.visitPaths(swhId); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList paths = (ArrayList) endpoint.visitPaths(swhId).result; + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedPaths = new ArrayList(); expectedPaths.add( new SwhPath( "swh:1:dir:0000000000000000000000000000000000000012", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:cnt:0000000000000000000000000000000000000007" )); expectedPaths.add( new SwhPath( "swh:1:dir:0000000000000000000000000000000000000012", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:cnt:0000000000000000000000000000000000000001" )); expectedPaths.add( new SwhPath( "swh:1:dir:0000000000000000000000000000000000000012", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000004" )); expectedPaths.add( new SwhPath( "swh:1:dir:0000000000000000000000000000000000000012", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000005" )); expectedPaths.add( new SwhPath( "swh:1:dir:0000000000000000000000000000000000000012", "swh:1:cnt:0000000000000000000000000000000000000011" )); GraphTest.assertEqualsAnyOrder(expectedPaths, paths); assertSameNodesFromPaths(expectedPaths, nodes); } @Test public void forwardFromLeaf() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:cnt:0000000000000000000000000000000000000004"); Endpoint endpoint = new Endpoint(graph, "forward", "*"); - ArrayList paths = endpoint.visitPaths(swhId); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList paths = (ArrayList) endpoint.visitPaths(swhId).result; + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedPaths = new ArrayList(); expectedPaths.add( new SwhPath( "swh:1:cnt:0000000000000000000000000000000000000004" )); GraphTest.assertEqualsAnyOrder(expectedPaths, paths); assertSameNodesFromPaths(expectedPaths, nodes); } @Test public void backwardFromRoot() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:ori:0000000000000000000000000000000000000021"); Endpoint endpoint = new Endpoint(graph, "backward", "*"); - ArrayList paths = endpoint.visitPaths(swhId); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList paths = (ArrayList) endpoint.visitPaths(swhId).result; + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedPaths = new ArrayList(); expectedPaths.add( new SwhPath( "swh:1:ori:0000000000000000000000000000000000000021" )); GraphTest.assertEqualsAnyOrder(expectedPaths, paths); assertSameNodesFromPaths(expectedPaths, nodes); } @Test public void backwardFromMiddle() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:dir:0000000000000000000000000000000000000012"); Endpoint endpoint = new Endpoint(graph, "backward", "*"); - ArrayList paths = endpoint.visitPaths(swhId); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList paths = (ArrayList) endpoint.visitPaths(swhId).result; + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedPaths = new ArrayList(); expectedPaths.add( new SwhPath( "swh:1:dir:0000000000000000000000000000000000000012", "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:rev:0000000000000000000000000000000000000018", "swh:1:rel:0000000000000000000000000000000000000019" )); GraphTest.assertEqualsAnyOrder(expectedPaths, paths); assertSameNodesFromPaths(expectedPaths, nodes); } @Test public void backwardFromLeaf() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:cnt:0000000000000000000000000000000000000004"); Endpoint endpoint = new Endpoint(graph, "backward", "*"); - ArrayList paths = endpoint.visitPaths(swhId); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList paths = (ArrayList) endpoint.visitPaths(swhId).result; + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedPaths = new ArrayList(); expectedPaths.add( new SwhPath( "swh:1:cnt:0000000000000000000000000000000000000004", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000012", "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:rev:0000000000000000000000000000000000000018", "swh:1:rel:0000000000000000000000000000000000000019" )); expectedPaths.add( new SwhPath( "swh:1:cnt:0000000000000000000000000000000000000004", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:rev:0000000000000000000000000000000000000018", "swh:1:rel:0000000000000000000000000000000000000019" )); expectedPaths.add( new SwhPath( "swh:1:cnt:0000000000000000000000000000000000000004", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:ori:0000000000000000000000000000000000000021" )); expectedPaths.add( new SwhPath( "swh:1:cnt:0000000000000000000000000000000000000004", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rel:0000000000000000000000000000000000000010", "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:ori:0000000000000000000000000000000000000021" )); GraphTest.assertEqualsAnyOrder(expectedPaths, paths); assertSameNodesFromPaths(expectedPaths, nodes); } @Test public void forwardSnpToRev() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:snp:0000000000000000000000000000000000000020"); Endpoint endpoint = new Endpoint(graph, "forward", "snp:rev"); - ArrayList paths = endpoint.visitPaths(swhId); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList paths = (ArrayList) endpoint.visitPaths(swhId).result; + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedPaths = new ArrayList(); expectedPaths.add( new SwhPath( "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rev:0000000000000000000000000000000000000009" )); GraphTest.assertEqualsAnyOrder(expectedPaths, paths); assertSameNodesFromPaths(expectedPaths, nodes); } @Test public void forwardRelToRevRevToRev() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:rel:0000000000000000000000000000000000000010"); Endpoint endpoint = new Endpoint(graph, "forward", "rel:rev,rev:rev"); - ArrayList paths = endpoint.visitPaths(swhId); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList paths = (ArrayList) endpoint.visitPaths(swhId).result; + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedPaths = new ArrayList(); expectedPaths.add( new SwhPath( "swh:1:rel:0000000000000000000000000000000000000010", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rev:0000000000000000000000000000000000000003" )); GraphTest.assertEqualsAnyOrder(expectedPaths, paths); assertSameNodesFromPaths(expectedPaths, nodes); } @Test public void forwardRevToAllDirToAll() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:rev:0000000000000000000000000000000000000013"); Endpoint endpoint = new Endpoint(graph, "forward", "rev:*,dir:*"); - ArrayList paths = endpoint.visitPaths(swhId); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList paths = (ArrayList) endpoint.visitPaths(swhId).result; + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedPaths = new ArrayList(); expectedPaths.add( new SwhPath( "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000005" )); expectedPaths.add( new SwhPath( "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:dir:0000000000000000000000000000000000000012", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000005" )); expectedPaths.add( new SwhPath( "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000004" )); expectedPaths.add( new SwhPath( "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:dir:0000000000000000000000000000000000000012", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000004" )); expectedPaths.add( new SwhPath( "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:cnt:0000000000000000000000000000000000000007" )); expectedPaths.add( new SwhPath( "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:dir:0000000000000000000000000000000000000012", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:cnt:0000000000000000000000000000000000000007" )); expectedPaths.add( new SwhPath( "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:dir:0000000000000000000000000000000000000012", "swh:1:cnt:0000000000000000000000000000000000000011" )); expectedPaths.add( new SwhPath( "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rev:0000000000000000000000000000000000000003", "swh:1:dir:0000000000000000000000000000000000000002", "swh:1:cnt:0000000000000000000000000000000000000001" )); expectedPaths.add( new SwhPath( "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:cnt:0000000000000000000000000000000000000001" )); expectedPaths.add( new SwhPath( "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:dir:0000000000000000000000000000000000000012", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:cnt:0000000000000000000000000000000000000001" )); GraphTest.assertEqualsAnyOrder(expectedPaths, paths); assertSameNodesFromPaths(expectedPaths, nodes); } @Test public void forwardSnpToAllRevToAll() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:snp:0000000000000000000000000000000000000020"); Endpoint endpoint = new Endpoint(graph, "forward", "snp:*,rev:*"); - ArrayList paths = endpoint.visitPaths(swhId); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList paths = (ArrayList) endpoint.visitPaths(swhId).result; + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedPaths = new ArrayList(); expectedPaths.add( new SwhPath( "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rev:0000000000000000000000000000000000000003", "swh:1:dir:0000000000000000000000000000000000000002" )); expectedPaths.add( new SwhPath( "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008" )); expectedPaths.add( new SwhPath( "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rel:0000000000000000000000000000000000000010" )); GraphTest.assertEqualsAnyOrder(expectedPaths, paths); assertSameNodesFromPaths(expectedPaths, nodes); } @Test public void forwardNoEdges() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:snp:0000000000000000000000000000000000000020"); Endpoint endpoint = new Endpoint(graph, "forward", ""); - ArrayList paths = endpoint.visitPaths(swhId); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList paths = (ArrayList) endpoint.visitPaths(swhId).result; + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedPaths = new ArrayList(); expectedPaths.add( new SwhPath( "swh:1:snp:0000000000000000000000000000000000000020" )); GraphTest.assertEqualsAnyOrder(expectedPaths, paths); assertSameNodesFromPaths(expectedPaths, nodes); } @Test public void backwardRevToRevRevToRel() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:rev:0000000000000000000000000000000000000003"); Endpoint endpoint = new Endpoint(graph, "backward", "rev:rev,rev:rel"); - ArrayList paths = endpoint.visitPaths(swhId); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList paths = (ArrayList) endpoint.visitPaths(swhId).result; + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedPaths = new ArrayList(); expectedPaths.add( new SwhPath( "swh:1:rev:0000000000000000000000000000000000000003", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:rev:0000000000000000000000000000000000000018", "swh:1:rel:0000000000000000000000000000000000000019" )); expectedPaths.add( new SwhPath( "swh:1:rev:0000000000000000000000000000000000000003", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rel:0000000000000000000000000000000000000010" )); GraphTest.assertEqualsAnyOrder(expectedPaths, paths); assertSameNodesFromPaths(expectedPaths, nodes); } @Test public void forwardFromRootNodesOnly() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:ori:0000000000000000000000000000000000000021"); Endpoint endpoint = new Endpoint(graph, "forward", "*"); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedNodes = new ArrayList(); expectedNodes.add(new SwhId("swh:1:ori:0000000000000000000000000000000000000021")); expectedNodes.add(new SwhId("swh:1:snp:0000000000000000000000000000000000000020")); expectedNodes.add(new SwhId("swh:1:rel:0000000000000000000000000000000000000010")); expectedNodes.add(new SwhId("swh:1:rev:0000000000000000000000000000000000000009")); expectedNodes.add(new SwhId("swh:1:rev:0000000000000000000000000000000000000003")); expectedNodes.add(new SwhId("swh:1:dir:0000000000000000000000000000000000000002")); expectedNodes.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000001")); expectedNodes.add(new SwhId("swh:1:dir:0000000000000000000000000000000000000008")); expectedNodes.add(new SwhId("swh:1:dir:0000000000000000000000000000000000000006")); expectedNodes.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000004")); expectedNodes.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000005")); expectedNodes.add(new SwhId("swh:1:cnt:0000000000000000000000000000000000000007")); GraphTest.assertEqualsAnyOrder(expectedNodes, nodes); } @Test public void backwardRevToAllNodesOnly() { Graph graph = getGraph(); SwhId swhId = new SwhId("swh:1:rev:0000000000000000000000000000000000000003"); Endpoint endpoint = new Endpoint(graph, "backward", "rev:*"); - ArrayList nodes = endpoint.visitNodes(swhId); + ArrayList nodes = (ArrayList) endpoint.visitNodes(swhId).result; ArrayList expectedNodes = new ArrayList(); expectedNodes.add(new SwhId("swh:1:rev:0000000000000000000000000000000000000003")); expectedNodes.add(new SwhId("swh:1:rev:0000000000000000000000000000000000000009")); expectedNodes.add(new SwhId("swh:1:snp:0000000000000000000000000000000000000020")); expectedNodes.add(new SwhId("swh:1:rel:0000000000000000000000000000000000000010")); expectedNodes.add(new SwhId("swh:1:rev:0000000000000000000000000000000000000013")); expectedNodes.add(new SwhId("swh:1:rev:0000000000000000000000000000000000000018")); expectedNodes.add(new SwhId("swh:1:rel:0000000000000000000000000000000000000019")); GraphTest.assertEqualsAnyOrder(expectedNodes, nodes); } } diff --git a/java/server/src/test/java/org/softwareheritage/graph/WalkTest.java b/java/server/src/test/java/org/softwareheritage/graph/WalkTest.java index aa10997..4dcac9c 100644 --- a/java/server/src/test/java/org/softwareheritage/graph/WalkTest.java +++ b/java/server/src/test/java/org/softwareheritage/graph/WalkTest.java @@ -1,232 +1,232 @@ package org.softwareheritage.graph; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Assert; import org.junit.Test; import org.softwareheritage.graph.Endpoint; import org.softwareheritage.graph.Graph; import org.softwareheritage.graph.GraphTest; import org.softwareheritage.graph.SwhId; import org.softwareheritage.graph.SwhPath; public class WalkTest extends GraphTest { @Test public void forwardRootToLeaf() { Graph graph = getGraph(); Endpoint endpoint = new Endpoint(graph, "forward", "*"); SwhId src = new SwhId("swh:1:snp:0000000000000000000000000000000000000020"); String dstFmt = "swh:1:cnt:0000000000000000000000000000000000000005"; SwhPath solution1 = new SwhPath( "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000005" ); SwhPath solution2 = new SwhPath( "swh:1:snp:0000000000000000000000000000000000000020", "swh:1:rel:0000000000000000000000000000000000000010", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000005" ); - SwhPath dfsPath = endpoint.walk(src, dstFmt, "dfs"); - SwhPath bfsPath = endpoint.walk(src, dstFmt, "bfs"); + SwhPath dfsPath = (SwhPath) endpoint.walk(src, dstFmt, "dfs").result; + SwhPath bfsPath = (SwhPath) endpoint.walk(src, dstFmt, "bfs").result; List possibleSolutions = Arrays.asList(solution1, solution2); Assert.assertTrue(possibleSolutions.contains(dfsPath)); Assert.assertTrue(possibleSolutions.contains(bfsPath)); } @Test public void forwardLeafToLeaf() { Graph graph = getGraph(); Endpoint endpoint = new Endpoint(graph, "forward", "*"); SwhId src = new SwhId("swh:1:cnt:0000000000000000000000000000000000000007"); String dstFmt = "cnt"; SwhPath expectedPath = new SwhPath( "swh:1:cnt:0000000000000000000000000000000000000007" ); - SwhPath dfsPath = endpoint.walk(src, dstFmt, "dfs"); - SwhPath bfsPath = endpoint.walk(src, dstFmt, "bfs"); + SwhPath dfsPath = (SwhPath) endpoint.walk(src, dstFmt, "dfs").result; + SwhPath bfsPath = (SwhPath) endpoint.walk(src, dstFmt, "bfs").result; Assert.assertEquals(dfsPath, expectedPath); Assert.assertEquals(bfsPath, expectedPath); } @Test public void forwardRevToRev() { Graph graph = getGraph(); Endpoint endpoint = new Endpoint(graph, "forward", "rev:rev"); SwhId src = new SwhId("swh:1:rev:0000000000000000000000000000000000000018"); String dstFmt = "swh:1:rev:0000000000000000000000000000000000000003"; SwhPath expectedPath = new SwhPath( "swh:1:rev:0000000000000000000000000000000000000018", "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rev:0000000000000000000000000000000000000003" ); - SwhPath dfsPath = endpoint.walk(src, dstFmt, "dfs"); - SwhPath bfsPath = endpoint.walk(src, dstFmt, "bfs"); + SwhPath dfsPath = (SwhPath) endpoint.walk(src, dstFmt, "dfs").result; + SwhPath bfsPath = (SwhPath) endpoint.walk(src, dstFmt, "bfs").result; Assert.assertEquals(dfsPath, expectedPath); Assert.assertEquals(bfsPath, expectedPath); } @Test public void backwardRevToRev() { Graph graph = getGraph(); Endpoint endpoint = new Endpoint(graph, "backward", "rev:rev"); SwhId src = new SwhId("swh:1:rev:0000000000000000000000000000000000000003"); String dstFmt = "swh:1:rev:0000000000000000000000000000000000000018"; SwhPath expectedPath = new SwhPath( "swh:1:rev:0000000000000000000000000000000000000003", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rev:0000000000000000000000000000000000000013", "swh:1:rev:0000000000000000000000000000000000000018" ); - SwhPath dfsPath = endpoint.walk(src, dstFmt, "dfs"); - SwhPath bfsPath = endpoint.walk(src, dstFmt, "bfs"); + SwhPath dfsPath = (SwhPath) endpoint.walk(src, dstFmt, "dfs").result; + SwhPath bfsPath = (SwhPath) endpoint.walk(src, dstFmt, "bfs").result; Assert.assertEquals(dfsPath, expectedPath); Assert.assertEquals(bfsPath, expectedPath); } @Test public void backwardCntToFirstSnp() { Graph graph = getGraph(); Endpoint endpoint = new Endpoint(graph, "backward", "*"); SwhId src = new SwhId("swh:1:cnt:0000000000000000000000000000000000000001"); String dstFmt = "snp"; SwhPath solution1 = new SwhPath( "swh:1:cnt:0000000000000000000000000000000000000001", "swh:1:dir:0000000000000000000000000000000000000002", "swh:1:rev:0000000000000000000000000000000000000003", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:snp:0000000000000000000000000000000000000020" ); SwhPath solution2 = new SwhPath( "swh:1:cnt:0000000000000000000000000000000000000001", "swh:1:dir:0000000000000000000000000000000000000002", "swh:1:rev:0000000000000000000000000000000000000003", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rel:0000000000000000000000000000000000000010", "swh:1:snp:0000000000000000000000000000000000000020" ); SwhPath solution3 = new SwhPath( "swh:1:cnt:0000000000000000000000000000000000000001", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:snp:0000000000000000000000000000000000000020" ); SwhPath solution4 = new SwhPath( "swh:1:cnt:0000000000000000000000000000000000000001", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rel:0000000000000000000000000000000000000010", "swh:1:snp:0000000000000000000000000000000000000020" ); - SwhPath dfsPath = endpoint.walk(src, dstFmt, "dfs"); - SwhPath bfsPath = endpoint.walk(src, dstFmt, "bfs"); + SwhPath dfsPath = (SwhPath) endpoint.walk(src, dstFmt, "dfs").result; + SwhPath bfsPath = (SwhPath) endpoint.walk(src, dstFmt, "bfs").result; List possibleSolutions = Arrays.asList(solution1, solution2, solution3, solution4); Assert.assertTrue(possibleSolutions.contains(dfsPath)); Assert.assertTrue(possibleSolutions.contains(bfsPath)); } @Test public void forwardRevToFirstCnt() { Graph graph = getGraph(); Endpoint endpoint = new Endpoint(graph, "forward", "rev:*,dir:*"); SwhId src = new SwhId("swh:1:rev:0000000000000000000000000000000000000009"); String dstFmt = "cnt"; SwhPath solution1 = new SwhPath( "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:cnt:0000000000000000000000000000000000000007" ); SwhPath solution2 = new SwhPath( "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000005" ); SwhPath solution3 = new SwhPath( "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:dir:0000000000000000000000000000000000000006", "swh:1:cnt:0000000000000000000000000000000000000004" ); SwhPath solution4 = new SwhPath( "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:dir:0000000000000000000000000000000000000008", "swh:1:cnt:0000000000000000000000000000000000000001" ); SwhPath solution5 = new SwhPath( "swh:1:rev:0000000000000000000000000000000000000009", "swh:1:rev:0000000000000000000000000000000000000003", "swh:1:dir:0000000000000000000000000000000000000002", "swh:1:cnt:0000000000000000000000000000000000000001" ); - SwhPath dfsPath = endpoint.walk(src, dstFmt, "dfs"); - SwhPath bfsPath = endpoint.walk(src, dstFmt, "bfs"); + SwhPath dfsPath = (SwhPath) endpoint.walk(src, dstFmt, "dfs").result; + SwhPath bfsPath = (SwhPath) endpoint.walk(src, dstFmt, "bfs").result; List possibleSolutions = Arrays.asList(solution1, solution2, solution3, solution4, solution5); Assert.assertTrue(possibleSolutions.contains(dfsPath)); Assert.assertTrue(possibleSolutions.contains(bfsPath)); } @Test public void backwardDirToFirstRel() { Graph graph = getGraph(); Endpoint endpoint = new Endpoint(graph, "backward", "dir:dir,dir:rev,rev:*"); SwhId src = new SwhId("swh:1:dir:0000000000000000000000000000000000000016"); String dstFmt = "rel"; SwhPath expectedPath = new SwhPath( "swh:1:dir:0000000000000000000000000000000000000016", "swh:1:dir:0000000000000000000000000000000000000017", "swh:1:rev:0000000000000000000000000000000000000018", "swh:1:rel:0000000000000000000000000000000000000019" ); - SwhPath dfsPath = endpoint.walk(src, dstFmt, "dfs"); - SwhPath bfsPath = endpoint.walk(src, dstFmt, "bfs"); + SwhPath dfsPath = (SwhPath) endpoint.walk(src, dstFmt, "dfs").result; + SwhPath bfsPath = (SwhPath) endpoint.walk(src, dstFmt, "bfs").result; Assert.assertEquals(dfsPath, expectedPath); Assert.assertEquals(bfsPath, expectedPath); } }