You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2016/05/04 19:48:52 UTC

[07/15] incubator-tinkerpop git commit: Refactored Traversal interruption tests.

Refactored Traversal interruption tests.

Provided better coverage and easier maintenance by making the tests parameterized.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/8b4e670c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/8b4e670c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/8b4e670c

Branch: refs/heads/TINKERPOP-1288
Commit: 8b4e670c268f3522457454ffed60b8d8b37da517
Parents: 3a5f738
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Apr 20 07:52:01 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed May 4 06:43:35 2016 -0400

----------------------------------------------------------------------
 .../process/AbstractGremlinProcessTest.java     |   8 +-
 .../gremlin/process/ProcessStandardSuite.java   |   2 +
 .../process/traversal/CoreTraversalTest.java    | 130 -------------------
 .../traversal/TraversalInterruptionTest.java    | 114 ++++++++++++++++
 4 files changed, 123 insertions(+), 131 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8b4e670c/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
index 0c0f19d..201822c 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/AbstractGremlinProcessTest.java
@@ -72,10 +72,16 @@ public abstract class AbstractGremlinProcessTest extends AbstractGremlinTest {
 
         try {
             // ignore tests that aren't supported by a specific TraversalEngine
-            final IgnoreEngine ignoreEngine = this.getClass().getMethod(name.getMethodName()).getAnnotation(IgnoreEngine.class);
+            final String testName = name.getMethodName();
+
+            // tests that are parameterized have a square bracket with parameterized name appended to the actual
+            // test method name. have to strip that off so that reflection can find it
+            final String methodName = testName.contains("[") ? testName.substring(0, testName.indexOf('[')) : testName;
+            final IgnoreEngine ignoreEngine = this.getClass().getMethod(methodName).getAnnotation(IgnoreEngine.class);
             if (ignoreEngine != null)
                 assumeTrue(String.format("This test is ignored for %s", ignoreEngine.value()), !ignoreEngine.value().equals(GraphManager.getTraversalEngineType()));
         } catch (NoSuchMethodException nsme) {
+            // some tests are parameterized
             throw new RuntimeException(String.format("Could not find test method %s in test case %s", name.getMethodName(), this.getClass().getName()));
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8b4e670c/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
index 5bd1f5a..644555d 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/ProcessStandardSuite.java
@@ -21,6 +21,7 @@ package org.apache.tinkerpop.gremlin.process;
 import org.apache.tinkerpop.gremlin.AbstractGremlinSuite;
 import org.apache.tinkerpop.gremlin.process.traversal.CoreTraversalTest;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.BranchTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.ChooseTest;
 import org.apache.tinkerpop.gremlin.process.traversal.step.branch.OptionalTest;
@@ -173,6 +174,7 @@ public class ProcessStandardSuite extends AbstractGremlinSuite {
 
             // compliance
             CoreTraversalTest.class,
+            TraversalInterruptionTest.class,
 
             // decorations
             ElementIdStrategyProcessTest.class,

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8b4e670c/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/CoreTraversalTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/CoreTraversalTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/CoreTraversalTest.java
index 200d94b..930030e 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/CoreTraversalTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/CoreTraversalTest.java
@@ -24,13 +24,11 @@ import org.apache.tinkerpop.gremlin.LoadGraphWith;
 import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalInterruptedException;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Transaction;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
-import org.hamcrest.CoreMatchers;
 import org.junit.Test;
 
 import java.util.HashSet;
@@ -38,12 +36,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Random;
 import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 
-import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.GRATEFUL;
 import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
 import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*;
 import static org.apache.tinkerpop.gremlin.structure.Graph.Features.GraphFeatures.FEATURE_TRANSACTIONS;
@@ -62,130 +56,6 @@ import static org.junit.Assert.*;
 public class CoreTraversalTest extends AbstractGremlinProcessTest {
 
     @Test
-    @LoadGraphWith(GRATEFUL)
-    public void shouldRespectThreadInterruptionInGraphStep() throws Exception {
-        final AtomicBoolean exceptionThrown = new AtomicBoolean(false);
-        final CountDownLatch startedIterating = new CountDownLatch(1);
-        final Thread t = new Thread(() -> {
-            try {
-                final Traversal traversal = g.V().sideEffect(traverser -> {
-                    startedIterating.countDown();
-
-                    // ensure that the whole traversal doesn't iterate out before we get a chance to interrupt
-                    if (startedIterating.getCount() == 0) {
-                        try {
-                            Thread.sleep(3000);
-                        } catch (Exception ignored) {
-                            Thread.currentThread().interrupt();
-                        }
-                    }
-                });
-                traversal.iterate();
-            } catch (Exception ex) {
-                exceptionThrown.set(ex instanceof TraversalInterruptedException);
-            }
-        });
-
-        t.start();
-
-        // total time for test should not exceed 5 seconds - this prevents the test from just hanging and allows
-        // it to finish with failure
-        assertThat(startedIterating.await(5000, TimeUnit.MILLISECONDS), CoreMatchers.is(true));
-
-        t.interrupt();
-        t.join();
-
-        // ensure that some but not all of the traversal was iterated and that the right exception was tossed
-        assertThat(exceptionThrown.get(), CoreMatchers.is(true));
-    }
-
-    @Test
-    @LoadGraphWith(GRATEFUL)
-    public void shouldRespectThreadInterruptionInVertexStep() throws Exception {
-        final AtomicBoolean exceptionThrown = new AtomicBoolean(false);
-        final CountDownLatch startedIterating = new CountDownLatch(1);
-        final Thread t = new Thread(() -> {
-            try {
-                final AtomicBoolean first = new AtomicBoolean(true);
-                final Traversal traversal = g.V().sideEffect(traverser -> {
-                    // let the first iteration flow through
-                    if (!first.compareAndSet(true, false)) {
-                        // ensure that the whole traversal doesn't iterate out before we get a chance to interrupt
-                        // the next iteration should stop so we can force the interrupt to be handled by VertexStep
-                        try {
-                            Thread.sleep(3000);
-                        } catch (Exception ignored) {
-                            // make sure that the interrupt propagates in case the interrupt occurs during sleep.
-                            // this should ensure VertexStep gets to try to throw the TraversalInterruptedException
-                            Thread.currentThread().interrupt();
-                        }
-                    }
-                }).out().sideEffect(traverser -> {
-                    startedIterating.countDown();
-                });
-                traversal.iterate();
-            } catch (Exception ex) {
-                exceptionThrown.set(ex instanceof TraversalInterruptedException);
-            }
-        });
-
-        t.start();
-
-        // total time for test should not exceed 5 seconds - this prevents the test from just hanging and allows
-        // it to finish with failure
-        assertThat(startedIterating.await(5000, TimeUnit.MILLISECONDS), CoreMatchers.is(true));
-
-        t.interrupt();
-        t.join();
-
-        // ensure that some but not all of the traversal was iterated and that the right exception was tossed
-        assertThat(exceptionThrown.get(), CoreMatchers.is(true));
-    }
-
-    @Test
-    @LoadGraphWith(GRATEFUL)
-    public void shouldRespectThreadInterruptionInPropertyStep() throws Exception {
-        final AtomicBoolean exceptionThrown = new AtomicBoolean(false);
-        final CountDownLatch startedIterating = new CountDownLatch(1);
-        final Thread t = new Thread(() -> {
-            try {
-                final AtomicBoolean first = new AtomicBoolean(true);
-                final Traversal traversal = g.V().sideEffect(traverser -> {
-                    // let the first iteration flow through
-                    if (!first.compareAndSet(true, false)) {
-                        // ensure that the whole traversal doesn't iterate out before we get a chance to interrupt
-                        // the next iteration should stop so we can force the interrupt to be handled by PropertyStep
-                        try {
-                            Thread.sleep(3000);
-                        } catch (Exception ignored) {
-                            // make sure that the interrupt propagates in case the interrupt occurs during sleep.
-                            // this should ensure PropertyStep gets to try to throw the TraversalInterruptedException
-                            Thread.currentThread().interrupt();
-                        }
-                    }
-                }).properties().sideEffect(traverser -> {
-                    startedIterating.countDown();
-                });
-                traversal.iterate();
-            } catch (Exception ex) {
-                exceptionThrown.set(ex instanceof TraversalInterruptedException);
-            }
-        });
-
-        t.start();
-
-        // total time for test should not exceed 5 seconds - this prevents the test from just hanging and allows
-        // it to finish with failure
-        assertThat(startedIterating.await(5000, TimeUnit.MILLISECONDS), CoreMatchers.is(true));
-
-        t.interrupt();
-        t.join();
-
-        // ensure that some but not all of the traversal was iterated and that the right exception was tossed
-        assertThat(exceptionThrown.get(), CoreMatchers.is(true));
-    }
-
-    @Test
     @LoadGraphWith
     public void shouldNeverPropagateANoBulkTraverser() {
         assertFalse(g.V().dedup().sideEffect(t -> t.asAdmin().setBulk(0)).hasNext());

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8b4e670c/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalInterruptionTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalInterruptionTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalInterruptionTest.java
new file mode 100644
index 0000000..e9d584f
--- /dev/null
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalInterruptionTest.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal;
+
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.process.AbstractGremlinProcessTest;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalInterruptedException;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.GRATEFUL;
+import static org.junit.Assert.assertThat;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@RunWith(Parameterized.class)
+public class TraversalInterruptionTest extends AbstractGremlinProcessTest {
+
+    @Parameterized.Parameters(name = "expectInterruption({0})")
+    public static Iterable<Object[]> data() {
+        return Arrays.asList(new Object[][]{
+                {"g_V", (Function<GraphTraversalSource, GraphTraversal<?,?>>) g -> g.V(), (UnaryOperator<GraphTraversal<?,?>>) t -> t},
+                {"g_V_out", (Function<GraphTraversalSource, GraphTraversal<?,?>>) g -> g.V(), (UnaryOperator<GraphTraversal<?,?>>) t -> t.out()},
+                {"g_V_outE", (Function<GraphTraversalSource, GraphTraversal<?,?>>) g -> g.V(), (UnaryOperator<GraphTraversal<?,?>>) t -> t.outE()},
+                {"g_V_in", (Function<GraphTraversalSource, GraphTraversal<?,?>>) g -> g.V(), (UnaryOperator<GraphTraversal<?,?>>) t -> t.in()},
+                {"g_V_inE", (Function<GraphTraversalSource, GraphTraversal<?,?>>) g -> g.V(), (UnaryOperator<GraphTraversal<?,?>>) t -> t.inE()},
+                {"g_V_properties", (Function<GraphTraversalSource, GraphTraversal<?,?>>) g -> g.V(), (UnaryOperator<GraphTraversal<?,?>>) t -> t.properties()},
+                {"g_E", (Function<GraphTraversalSource, GraphTraversal<?,?>>) g -> g.E(), (UnaryOperator<GraphTraversal<?,?>>) t -> t},
+                {"g_E_outV", (Function<GraphTraversalSource, GraphTraversal<?,?>>) g -> g.E(), (UnaryOperator<GraphTraversal<?,?>>) t -> t.outV()},
+                {"g_E_inV", (Function<GraphTraversalSource, GraphTraversal<?,?>>) g -> g.E(), (UnaryOperator<GraphTraversal<?,?>>) t -> t.inV()},
+                {"g_E_properties", (Function<GraphTraversalSource, GraphTraversal<?,?>>) g -> g.E(), (UnaryOperator<GraphTraversal<?,?>>) t -> t.properties()},
+        });
+    }
+
+    @Parameterized.Parameter(value = 0)
+    public String name;
+
+    @Parameterized.Parameter(value = 1)
+    public Function<GraphTraversalSource,GraphTraversal<?,?>> traversalBeforePause;
+
+    @Parameterized.Parameter(value = 2)
+    public UnaryOperator<GraphTraversal<?,?>> traversalAfterPause;
+
+    @Test
+    @LoadGraphWith(GRATEFUL)
+    public void shouldRespectThreadInterruptionInVertexStep() throws Exception {
+        final AtomicBoolean exceptionThrown = new AtomicBoolean(false);
+        final CountDownLatch startedIterating = new CountDownLatch(1);
+        final Thread t = new Thread(() -> {
+            try {
+                final AtomicBoolean first = new AtomicBoolean(true);
+                final Traversal traversal = traversalAfterPause.apply(traversalBeforePause.apply(g).sideEffect(traverser -> {
+                    // let the first iteration flow through
+                    if (!first.compareAndSet(true, false)) {
+                        // ensure that the whole traversal doesn't iterate out before we get a chance to interrupt
+                        // the next iteration should stop so we can force the interrupt to be handled by VertexStep
+                        try {
+                            Thread.sleep(3000);
+                        } catch (Exception ignored) {
+                            // make sure that the interrupt propagates in case the interrupt occurs during sleep.
+                            // this should ensure VertexStep gets to try to throw the TraversalInterruptedException
+                            Thread.currentThread().interrupt();
+                        }
+                    }
+                })).sideEffect(traverser -> {
+                    startedIterating.countDown();
+                });
+                traversal.iterate();
+            } catch (Exception ex) {
+                exceptionThrown.set(ex instanceof TraversalInterruptedException);
+            }
+        });
+
+        t.start();
+
+        // total time for test should not exceed 5 seconds - this prevents the test from just hanging and allows
+        // it to finish with failure
+        assertThat(startedIterating.await(5000, TimeUnit.MILLISECONDS), CoreMatchers.is(true));
+
+        t.interrupt();
+        t.join();
+
+        // ensure that some but not all of the traversal was iterated and that the right exception was tossed
+        assertThat(exceptionThrown.get(), CoreMatchers.is(true));
+    }
+}