Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 0D819200C48 for ; Thu, 6 Apr 2017 13:33:34 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 0C408160B84; Thu, 6 Apr 2017 11:33:34 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 9541C160BB1 for ; Thu, 6 Apr 2017 13:33:30 +0200 (CEST) Received: (qmail 99239 invoked by uid 500); 6 Apr 2017 11:33:29 -0000 Mailing-List: contact commits-help@tinkerpop.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@tinkerpop.apache.org Delivered-To: mailing list commits@tinkerpop.apache.org Received: (qmail 98738 invoked by uid 99); 6 Apr 2017 11:33:29 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 06 Apr 2017 11:33:29 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id E093EF2181; Thu, 6 Apr 2017 11:33:28 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: spmallette@apache.org To: commits@tinkerpop.apache.org Date: Thu, 06 Apr 2017 11:33:46 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [19/50] tinkerpop git commit: Fixed VertexProgram test that verifies proper TraversalRequirements. archived-at: Thu, 06 Apr 2017 11:33:34 -0000 Fixed VertexProgram test that verifies proper TraversalRequirements. Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/12c7f013 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/12c7f013 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/12c7f013 Branch: refs/heads/TINKERPOP-1443 Commit: 12c7f01332d1bcb07ab1dda41d4c045403975a26 Parents: 1f99a51 Author: Daniel Kuppitz Authored: Mon Mar 13 16:01:12 2017 +0100 Committer: Stephen Mallette Committed: Wed Mar 29 11:21:06 2017 -0400 ---------------------------------------------------------------------- .../process/computer/GraphComputerTest.java | 199 +++++++++---------- 1 file changed, 92 insertions(+), 107 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/12c7f013/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java ---------------------------------------------------------------------- diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java index 40b03fe..5c66673 100644 --- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java +++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/computer/GraphComputerTest.java @@ -36,6 +36,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.Path; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.Traverser; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.EmptyPath; import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.VerificationException; import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement; import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet; @@ -47,6 +48,7 @@ import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.structure.VertexProperty; import org.apache.tinkerpop.gremlin.structure.util.StringFactory; import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils; +import org.javatuples.Pair; import org.junit.Ignore; import org.junit.Test; @@ -58,6 +60,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; @@ -108,9 +111,6 @@ import static org.junit.Assume.assumeNoException; @ExceptionCoverage(exceptionClass = Graph.Exceptions.class, methods = { "graphDoesNotSupportProvidedGraphComputer" }) -@ExceptionCoverage(exceptionClass = Path.Exceptions.class, methods = { - "shouldFailWithImproperTraverserRequirements" -}) @SuppressWarnings("ThrowableResultOfMethodCallIgnored") public class GraphComputerTest extends AbstractGremlinProcessTest { @@ -2351,30 +2351,26 @@ public class GraphComputerTest extends AbstractGremlinProcessTest { @LoadGraphWith(MODERN) public void shouldSucceedWithProperTraverserRequirements() throws Exception { - final AtomicInteger counter = new AtomicInteger(0); - final Map idsByName = new HashMap<>(); - final VertexProgramQ vp = VertexProgramQ.build().from("a").property("coworkers").create(); - - g.V().hasLabel("person").filter(outE("created")).valueMap(true, "name").forEachRemaining((Map map) -> - idsByName.put((String) ((List) map.get("name")).get(0), map.get(id))); + final VertexProgramQ vp = VertexProgramQ.build().property("pl").create(); + final Map> expected = new HashMap<>(); + expected.put("vadas", Collections.singletonList(2)); + expected.put("lop", Arrays.asList(2, 2, 2, 3)); + expected.put("josh", Collections.singletonList(2)); + expected.put("ripple", Arrays.asList(2, 3)); try { - g.V().as("a").out("created").in("created").program(vp).dedup() - .valueMap("name", "coworkers").forEachRemaining((Map map) -> { + g.V().repeat(__.out()).emit().program(vp).dedup() + .valueMap("name", "pl").forEachRemaining((Map map) -> { final String name = (String) ((List) map.get("name")).get(0); - final Map coworkers = (Map) ((List) map.get("coworkers")).get(0); - assertTrue(idsByName.containsKey(name)); - assertEquals(2, coworkers.size()); - idsByName.keySet().stream().filter(cn -> !cn.equals(name)).forEach(cn -> { - final Object cid = idsByName.get(cn); - assertTrue(coworkers.containsKey(cid)); - assertEquals(1L, coworkers.get(cid).longValue()); - }); - counter.incrementAndGet(); + final List pathLengths = (List) map.get("pl"); + assertTrue(expected.containsKey(name)); + final List expectedPathLengths = expected.remove(name); + assertTrue(expectedPathLengths.containsAll(pathLengths)); + assertTrue(pathLengths.containsAll(expectedPathLengths)); }); - assertEquals(3, counter.intValue()); + assertTrue(expected.isEmpty()); } catch (VerificationException ex) { assumeNoException(ex); } @@ -2382,29 +2378,11 @@ public class GraphComputerTest extends AbstractGremlinProcessTest { @Test @LoadGraphWith(MODERN) - @Ignore("Labeled paths now trigger LABELED_PATH requirements -- @dkuppitz") public void shouldFailWithImproperTraverserRequirements() throws Exception { - - final AtomicInteger counter = new AtomicInteger(0); - final Map idsByName = new HashMap<>(); - final VertexProgramQ vp = VertexProgramQ.build().from("a").property("coworkers"). - useTraverserRequirements(false).create(); - - g.V().hasLabel("person").filter(outE("created")).valueMap(true, "name").forEachRemaining((Map map) -> - idsByName.put((String) ((List) map.get("name")).get(0), map.get(id))); - + final VertexProgramQ vp = VertexProgramQ.build().property("pl").useTraverserRequirements(false).create(); try { - g.V().as("a").out("created").in("created").program(vp).dedup() - .valueMap("name", "coworkers").forEachRemaining((Map map) -> { - - final String name = (String) ((List) map.get("name")).get(0); - final Map coworkers = (Map) ((List) map.get("coworkers")).get(0); - assertTrue(idsByName.containsKey(name)); - assertTrue(coworkers.isEmpty()); - counter.incrementAndGet(); - }); - - assertEquals(3, counter.intValue()); + g.V().repeat(__.out()).emit().program(vp).dedup() + .forEachRemaining((Vertex v) -> assertFalse(v.property("pl").isPresent())); } catch (VerificationException ex) { assumeNoException(ex); } @@ -2413,13 +2391,16 @@ public class GraphComputerTest extends AbstractGremlinProcessTest { private static class VertexProgramQ implements VertexProgram { private static final String VERTEX_PROGRAM_Q_CFG_PREFIX = "gremlin.vertexProgramQ"; - private static final String MAP_KEY_CFG_KEY = VERTEX_PROGRAM_Q_CFG_PREFIX + ".source"; private static final String PROPERTY_CFG_KEY = VERTEX_PROGRAM_Q_CFG_PREFIX + ".property"; + private static final String LENGTHS_KEY = VERTEX_PROGRAM_Q_CFG_PREFIX + ".lengths"; private static final String USE_TRAVERSER_REQUIREMENTS_CFG_KEY = VERTEX_PROGRAM_Q_CFG_PREFIX + ".useTraverserRequirements"; + private final static Set MEMORY_COMPUTE_KEYS = Collections.singleton( + MemoryComputeKey.of(LENGTHS_KEY, Operator.addAll, true, true) + ); + private final Set elementComputeKeys; private Configuration configuration; - private String sourceKey; private String propertyKey; private Set traverserRequirements; @@ -2427,6 +2408,43 @@ public class GraphComputerTest extends AbstractGremlinProcessTest { elementComputeKeys = new HashSet<>(); } + public static Builder build() { + return new Builder(); + } + + static class Builder extends AbstractVertexProgramBuilder { + + private Builder() { + super(VertexProgramQ.class); + } + + @SuppressWarnings("unchecked") + @Override + public VertexProgramQ create(final Graph graph) { + if (graph != null) { + ConfigurationUtils.append(graph.configuration().subset(VERTEX_PROGRAM_Q_CFG_PREFIX), configuration); + } + return (VertexProgramQ) VertexProgram.createVertexProgram(graph, configuration); + } + + public VertexProgramQ create() { + return create(null); + } + + public Builder property(final String name) { + configuration.setProperty(PROPERTY_CFG_KEY, name); + return this; + } + + /** + * This is only configurable for the purpose of testing. In a real-world VP this would be a bad pattern. + */ + public Builder useTraverserRequirements(final boolean value) { + configuration.setProperty(USE_TRAVERSER_REQUIREMENTS_CFG_KEY, value); + return this; + } + } + @Override public void storeState(final Configuration config) { VertexProgram.super.storeState(config); @@ -2435,16 +2453,16 @@ public class GraphComputerTest extends AbstractGremlinProcessTest { } } + @Override public void loadState(final Graph graph, final Configuration config) { configuration = new BaseConfiguration(); if (config != null) { ConfigurationUtils.copy(config, configuration); } - sourceKey = configuration.getString(MAP_KEY_CFG_KEY); propertyKey = configuration.getString(PROPERTY_CFG_KEY); traverserRequirements = configuration.getBoolean(USE_TRAVERSER_REQUIREMENTS_CFG_KEY, true) - ? Collections.singleton(TraverserRequirement.LABELED_PATH) : Collections.emptySet(); + ? Collections.singleton(TraverserRequirement.PATH) : Collections.emptySet(); elementComputeKeys.add(VertexComputeKey.of(propertyKey, false)); } @@ -2454,34 +2472,36 @@ public class GraphComputerTest extends AbstractGremlinProcessTest { @Override public void execute(final Vertex vertex, final Messenger messenger, final Memory memory) { - final Property haltedTraversers = vertex.property(TraversalVertexProgram.HALTED_TRAVERSERS); - if (!haltedTraversers.isPresent()) return; - final Iterator iterator = haltedTraversers.value().iterator(); - if (iterator.hasNext()) { - List> list = new ArrayList<>(); - while (iterator.hasNext()) { - final Traverser t = (Traverser) iterator.next(); - try { - final Vertex source = (Vertex) t.path(sourceKey); - if (!source.id().equals(vertex.id())) { - final Map.Entry entry = new AbstractMap.SimpleEntry<>(source.id(), t.bulk()); - list.add(entry); + if (memory.isInitialIteration()) { + final Property haltedTraversers = vertex.property(TraversalVertexProgram.HALTED_TRAVERSERS); + if (!haltedTraversers.isPresent()) return; + final Iterator iterator = haltedTraversers.value().iterator(); + if (iterator.hasNext()) { + while (iterator.hasNext()) { + final Traverser t = (Traverser) iterator.next(); + if (!(t.path() instanceof EmptyPath)) { + final int pathLength = t.path().size(); + final List> memoryValue = new LinkedList<>(); + memoryValue.add(Pair.with(vertex, pathLength)); + memory.add(LENGTHS_KEY, memoryValue); + } + } + } + } else { + if (memory.exists(LENGTHS_KEY)) { + final List> lengths = memory.get(LENGTHS_KEY); + for (final Pair pair : lengths) { + if (pair.getValue0().equals(vertex)) { + vertex.property(VertexProperty.Cardinality.list, propertyKey, pair.getValue1()); } - assertFalse(traverserRequirements.isEmpty()); - } catch (Exception ex) { - assertTrue(traverserRequirements.isEmpty()); - validateException(Path.Exceptions.stepWithProvidedLabelDoesNotExist(sourceKey), ex); } } - final Map map = new HashMap<>(list.size(), 1f); - for (Map.Entry entry : list) map.put(entry.getKey(), entry.getValue()); - vertex.property(propertyKey, map); } } @Override public boolean terminate(final Memory memory) { - return memory.isInitialIteration(); + return !memory.isInitialIteration(); } @Override @@ -2494,6 +2514,11 @@ public class GraphComputerTest extends AbstractGremlinProcessTest { return elementComputeKeys; } + @Override + public Set getMemoryComputeKeys() { + return MEMORY_COMPUTE_KEYS; + } + @SuppressWarnings({"CloneDoesntDeclareCloneNotSupportedException", "CloneDoesntCallSuperClone"}) @Override public VertexProgram clone() { @@ -2525,46 +2550,6 @@ public class GraphComputerTest extends AbstractGremlinProcessTest { }; } - public static Builder build() { - return new Builder(); - } - - static class Builder extends AbstractVertexProgramBuilder { - - private Builder() { - super(VertexProgramQ.class); - } - - @SuppressWarnings("unchecked") - @Override - public VertexProgramQ create(final Graph graph) { - if (graph != null) { - ConfigurationUtils.append(graph.configuration().subset(VERTEX_PROGRAM_Q_CFG_PREFIX), configuration); - } - return (VertexProgramQ) VertexProgram.createVertexProgram(graph, configuration); - } - - public VertexProgramQ create() { - return create(null); - } - - public Builder from(final String label) { - configuration.setProperty(MAP_KEY_CFG_KEY, label); - return this; - } - - public Builder property(final String name) { - configuration.setProperty(PROPERTY_CFG_KEY, name); - return this; - } - /** - * This is only configurable for the purpose of testing. In a real-world VP this would be a bad pattern. - */ - public Builder useTraverserRequirements(final boolean value) { - configuration.setProperty(USE_TRAVERSER_REQUIREMENTS_CFG_KEY, value); - return this; - } - } } -} \ No newline at end of file +}