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));
+ }
+}