You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2018/06/13 09:45:20 UTC
[1/3] tinkerpop git commit: TINKERPOP-1518 GraphProvider allows for
caching of graph features
Repository: tinkerpop
Updated Branches:
refs/heads/master f3506ee3b -> ad19a1179
TINKERPOP-1518 GraphProvider allows for caching of graph features
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/aec17098
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/aec17098
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/aec17098
Branch: refs/heads/master
Commit: aec170982aa03d1a07248721cb045ba95e11188b
Parents: ae2f304
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Jun 7 20:15:53 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Jun 7 20:15:53 2018 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
docs/src/dev/provider/index.asciidoc | 4 ++
docs/src/upgrade/release-3.4.x.asciidoc | 20 ++++++
.../tinkerpop/gremlin/structure/Graph.java | 1 -
.../tinkerpop/gremlin/AbstractGremlinTest.java | 64 ++++++++++++++------
.../apache/tinkerpop/gremlin/GraphManager.java | 5 ++
.../apache/tinkerpop/gremlin/GraphProvider.java | 16 +++++
.../neo4j/AbstractNeo4jGraphProvider.java | 23 ++++++-
8 files changed, 114 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/aec17098/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index e886107..a846363 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -33,6 +33,7 @@ This release also includes changes from <<release-3-3-3, 3.3.3>>.
* `min()` and `max()` now support all types implementing `Comparable`.
* Change the `toString()` of `Path` to be standardized as other graph elements are.
* `hadoop-gremlin` no longer generates a test artifact.
+* Allowed `GraphProvider` to expose a cached `Graph.Feature` object so that the test suite could re-use them to speed test runs.
* Fixed a bug in `ReducingBarrierStep`, that returned the provided seed value despite no elements being available.
* Changed the order of `select()` scopes. The order is now: maps, side-effects, paths.
* Removed previously deprecated Credentials DSL infrastructure.
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/aec17098/docs/src/dev/provider/index.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/dev/provider/index.asciidoc b/docs/src/dev/provider/index.asciidoc
index f6a964b..896f85c 100644
--- a/docs/src/dev/provider/index.asciidoc
+++ b/docs/src/dev/provider/index.asciidoc
@@ -662,6 +662,10 @@ should validate that the ignored tests are appropriately bypassed and that there
definitions. Moreover, implementers should consider filling gaps in their own test suites, especially when
IO-related tests are being ignored.
+TIP: If it is expensive to construct a new `Graph` instance, consider implementing `GraphProvider.getStaticFeatures()`
+which can help by caching a static feature set for instances produced by that `GraphProvider` and allow the test suite
+to avoid that construction cost if the test is ignored.
+
The only test-class that requires any code investment is the `GraphProvider` implementation class. This class is a
used by the test suite to construct `Graph` configurations and instances and provides information about the
implementation itself. In most cases, it is best to simply extend `AbstractGraphProvider` as it provides many
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/aec17098/docs/src/upgrade/release-3.4.x.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.4.x.asciidoc b/docs/src/upgrade/release-3.4.x.asciidoc
index 851d458..741fb3c 100644
--- a/docs/src/upgrade/release-3.4.x.asciidoc
+++ b/docs/src/upgrade/release-3.4.x.asciidoc
@@ -241,6 +241,26 @@ See: link:https://issues.apache.org/jira/browse/TINKERPOP-1522[TINKERPOP-1522]
==== Graph Database Providers
+===== Caching Graph Features
+
+For graph implementations that have expensive creation times, it can be time consuming to run the TinkerPop test suite
+as each test run requires a `Graph` instance even if the test is ultimately ignored becaue it doesn't pass the feature
+checks. To possibly help alleviate this problem, the `GraphProvider` interface now includes this method:
+
+[source,java]
+----
+public default Optional<Graph.Features> getStaticFeatures() {
+ return Optional.empty();
+}
+----
+
+This method can be implemented to return a cacheable set of features for a `Graph` generated from that `GraphProvider`.
+Assuming this method is faster than the cost of creating a new `Graph` instance, the test suite should execute
+significantly faster depending on how many tests end up being ignored.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1518[TINKERPOP-1518],
+link:
+
===== Configuring Interface
There were some changes to interfaces that were related to `Step`. A new `Configuring` interface was added that was
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/aec17098/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
index 2fbfe03..dc14cc6 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
@@ -40,7 +40,6 @@ import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
-import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/aec17098/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
index 25d7a55..8f55329 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
@@ -29,9 +29,9 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+import org.javatuples.Pair;
import org.junit.After;
import org.junit.Before;
-import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.rules.TestName;
import org.slf4j.Logger;
@@ -40,9 +40,11 @@ import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Random;
+import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@@ -61,6 +63,9 @@ import static org.junit.Assume.assumeThat;
*/
public abstract class AbstractGremlinTest {
private static final Logger logger = LoggerFactory.getLogger(AbstractGremlinTest.class);
+
+ protected static final Map<Pair<Class<?>, String>, Boolean> featureCache = new HashMap<>();
+
protected Graph graph;
protected GraphTraversalSource g;
protected Configuration config;
@@ -75,8 +80,26 @@ public abstract class AbstractGremlinTest {
final LoadGraphWith[] loadGraphWiths = testMethod.getAnnotationsByType(LoadGraphWith.class);
final LoadGraphWith loadGraphWith = loadGraphWiths.length == 0 ? null : loadGraphWiths[0];
final LoadGraphWith.GraphData loadGraphWithData = null == loadGraphWith ? null : loadGraphWith.value();
+ final Set<FeatureRequirement> featureRequirementSet = getFeatureRequirementsForTest(testMethod, loadGraphWiths);
graphProvider = GraphManager.getGraphProvider();
+
+ final Optional<Graph.Features> staticFeatures = graphProvider.getStaticFeatures();
+ if (staticFeatures.isPresent()) {
+ for (FeatureRequirement fr : featureRequirementSet) {
+ try {
+ assumeThat(String.format("StaticFeatures of the graph do not support all of the features required by this test so it will be ignored: %s.%s=%s",
+ fr.featureClass().getSimpleName(), fr.feature(), fr.supported()),
+ staticFeatures.get().supports(fr.featureClass(), fr.feature()), is(fr.supported()));
+ } catch (NoSuchMethodException nsme) {
+ throw new NoSuchMethodException(String.format("[supports%s] is not a valid feature on %s", fr.feature(), fr.featureClass()));
+ } catch (UnsupportedOperationException uoe) {
+ // no worries - it just means that we can't use the cache to support this check and will have to
+ // incur the cost of instantiating a graph instance directly
+ }
+ }
+ }
+
graphProvider.getTestListener().ifPresent(l -> l.onTestStart(this.getClass(), name.getMethodName()));
config = graphProvider.standardGraphConfiguration(this.getClass(), name.getMethodName(), loadGraphWithData);
@@ -87,24 +110,11 @@ public abstract class AbstractGremlinTest {
graph = graphProvider.openTestGraph(config);
g = graphProvider.traversal(graph);
- // get feature requirements on the test method and add them to the list of ones to check
- final FeatureRequirement[] featureRequirement = testMethod.getAnnotationsByType(FeatureRequirement.class);
- final List<FeatureRequirement> frs = new ArrayList<>(Arrays.asList(featureRequirement));
-
- // if the graph is loading data then it will come with it's own requirements
- if (loadGraphWiths.length > 0) frs.addAll(loadGraphWiths[0].value().featuresRequired());
-
- // if the graph has a set of feature requirements bundled together then add those
- final FeatureRequirementSet[] featureRequirementSets = testMethod.getAnnotationsByType(FeatureRequirementSet.class);
- if (featureRequirementSets.length > 0)
- frs.addAll(Arrays.stream(featureRequirementSets)
- .flatMap(f -> f.value().featuresRequired().stream()).collect(Collectors.toList()));
-
- // process the unique set of feature requirements
- final Set<FeatureRequirement> featureRequirementSet = new HashSet<>(frs);
for (FeatureRequirement fr : featureRequirementSet) {
try {
- //System.out.println(String.format("Assume that %s meets Feature Requirement - %s - with %s", fr.featureClass().getSimpleName(), fr.feature(), fr.supported()));
+ // even if we checked static features above it's of little cost to recheck again with the real graph
+ // once it is instantiated. the real cost savings is preventing graph creation in the first place so
+ // let's double check that all is legit.
assumeThat(String.format("%s does not support all of the features required by this test so it will be ignored: %s.%s=%s",
graph.getClass().getSimpleName(), fr.featureClass().getSimpleName(), fr.feature(), fr.supported()),
graph.features().supports(fr.featureClass(), fr.feature()), is(fr.supported()));
@@ -263,6 +273,24 @@ public abstract class AbstractGremlinTest {
AbstractGremlinTest.verifyUniqueStepIds(traversal, 0, new HashSet<>());
}
+ private static Set<FeatureRequirement> getFeatureRequirementsForTest(final Method testMethod, final LoadGraphWith[] loadGraphWiths) {
+ // get feature requirements on the test method and add them to the list of ones to check
+ final FeatureRequirement[] featureRequirement = testMethod.getAnnotationsByType(FeatureRequirement.class);
+ final List<FeatureRequirement> frs = new ArrayList<>(Arrays.asList(featureRequirement));
+
+ // if the graph is loading data then it will come with it's own requirements
+ if (loadGraphWiths.length > 0) frs.addAll(loadGraphWiths[0].value().featuresRequired());
+
+ // if the graph has a set of feature requirements bundled together then add those
+ final FeatureRequirementSet[] featureRequirementSets = testMethod.getAnnotationsByType(FeatureRequirementSet.class);
+ if (featureRequirementSets.length > 0)
+ frs.addAll(Arrays.stream(featureRequirementSets)
+ .flatMap(f -> f.value().featuresRequired().stream()).collect(Collectors.toList()));
+
+ // process the unique set of feature requirements
+ return new HashSet<>(frs);
+ }
+
private static void verifyUniqueStepIds(final Traversal.Admin<?, ?> traversal, final int depth, final Set<String> ids) {
for (final Step step : traversal.asAdmin().getSteps()) {
/*for (int i = 0; i < depth; i++) System.out.print("\t");
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/aec17098/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/GraphManager.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/GraphManager.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/GraphManager.java
index 6886465..7506226 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/GraphManager.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/GraphManager.java
@@ -183,6 +183,11 @@ public class GraphManager {
if (innerGraphProvider instanceof AutoCloseable)
((AutoCloseable) innerGraphProvider).close();
}
+
+ @Override
+ public Optional<Graph.Features> getStaticFeatures() {
+ return innerGraphProvider.getStaticFeatures();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/aec17098/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/GraphProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/GraphProvider.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/GraphProvider.java
index c785cfc..1fcb147 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/GraphProvider.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/GraphProvider.java
@@ -294,6 +294,22 @@ public interface GraphProvider {
}
/**
+ * Gets a {@link Graph.Features} implementation that contains graph feature configuration that will never change
+ * from execution to execution of the tests given this current {@code GraphProvider} implementation. Implementing
+ * this method will allow the test suite to avoid creation of a {@link Graph} instance and thus speed up the
+ * execution of tests if that creation process is expensive. It is important that this static set of features be
+ * representative of what the {@link Graph} instance produced by this {@code GraphProvider} can actually do or
+ * else the cost of {@link Graph} instantiation will be incurred when it doesn't need to be. It is also important
+ * that this method be faster than the cost of {@link Graph} creation in the first place or there really won't be
+ * any difference in execution speed. In cases where some features are static and others are not, simply throw
+ * an {@code UnsupportedOperationException} from those features to let the test suite know that it cannot rely
+ * on them and the test suite will revert to using a constructed {@link Graph} instance.
+ */
+ public default Optional<Graph.Features> getStaticFeatures() {
+ return Optional.empty();
+ }
+
+ /**
* An annotation to be applied to a {@code GraphProvider} implementation that provides additional information
* about its intentions. The {@code Descriptor} is required by those {@code GraphProvider} implementations
* that will be assigned to test suites that use
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/aec17098/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/AbstractNeo4jGraphProvider.java
----------------------------------------------------------------------
diff --git a/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/AbstractNeo4jGraphProvider.java b/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/AbstractNeo4jGraphProvider.java
index 9226822..514ef2b 100644
--- a/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/AbstractNeo4jGraphProvider.java
+++ b/neo4j-gremlin/src/test/java/org/apache/tinkerpop/gremlin/neo4j/AbstractNeo4jGraphProvider.java
@@ -32,6 +32,7 @@ import org.apache.tinkerpop.gremlin.structure.Graph;
import java.io.File;
import java.util.HashSet;
+import java.util.Optional;
import java.util.Random;
import java.util.Set;
@@ -49,6 +50,26 @@ public abstract class AbstractNeo4jGraphProvider extends AbstractGraphProvider {
add(Neo4jVertexProperty.class);
}};
+ protected Graph.Features features = null;
+
+ @Override
+ public Graph openTestGraph(final Configuration config) {
+ final Graph graph = super.openTestGraph(config);
+
+ // we can just use the initial set of features taken from the first graph generated from the provider because
+ // neo4j feature won't ever change. don't think there is any danger of keeping this instance about even if
+ // the original graph instance goes out of scope.
+ if (null == features) {
+ this.features = graph.features();
+ }
+ return graph;
+ }
+
+ @Override
+ public Optional<Graph.Features> getStaticFeatures() {
+ return Optional.ofNullable(features);
+ }
+
@Override
public void clear(final Graph graph, final Configuration configuration) throws Exception {
if (null != graph) {
@@ -56,7 +77,7 @@ public abstract class AbstractNeo4jGraphProvider extends AbstractGraphProvider {
graph.close();
}
- if (configuration.containsKey(Neo4jGraph.CONFIG_DIRECTORY)) {
+ if (configuration != null && configuration.containsKey(Neo4jGraph.CONFIG_DIRECTORY)) {
// this is a non-in-sideEffects configuration so blow away the directory
final File graphDirectory = new File(configuration.getString(Neo4jGraph.CONFIG_DIRECTORY));
deleteDirectory(graphDirectory);
[3/3] tinkerpop git commit: Merge branch 'TINKERPOP-1518'
Posted by sp...@apache.org.
Merge branch 'TINKERPOP-1518'
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/ad19a117
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/ad19a117
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/ad19a117
Branch: refs/heads/master
Commit: ad19a1179d241340e81413fd951c00dd9cb82058
Parents: f3506ee 221fda5
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Jun 13 05:44:54 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed Jun 13 05:44:54 2018 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
docs/src/dev/provider/index.asciidoc | 4 +
docs/src/upgrade/release-3.4.x.asciidoc | 20 +++++
.../tinkerpop/gremlin/structure/Graph.java | 1 -
.../tinkerpop/gremlin/AbstractGremlinTest.java | 78 +++++++++++++-------
.../apache/tinkerpop/gremlin/GraphManager.java | 5 ++
.../apache/tinkerpop/gremlin/GraphProvider.java | 16 ++++
.../neo4j/AbstractNeo4jGraphProvider.java | 23 +++++-
8 files changed, 121 insertions(+), 27 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ad19a117/docs/src/upgrade/release-3.4.x.asciidoc
----------------------------------------------------------------------
[2/3] tinkerpop git commit: TINKERPOP-1518 Minor refactoring -
extracted requirement check function
Posted by sp...@apache.org.
TINKERPOP-1518 Minor refactoring - extracted requirement check function
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/221fda58
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/221fda58
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/221fda58
Branch: refs/heads/master
Commit: 221fda584c6baf7c65eb4e6eebf72bb0ba251de4
Parents: aec1709
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Jun 8 07:45:29 2018 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri Jun 8 07:45:29 2018 -0400
----------------------------------------------------------------------
.../tinkerpop/gremlin/AbstractGremlinTest.java | 52 ++++++++++----------
1 file changed, 26 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/221fda58/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
index 8f55329..7ca44ba 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/AbstractGremlinTest.java
@@ -37,6 +37,7 @@ import org.junit.rules.TestName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
@@ -64,8 +65,6 @@ import static org.junit.Assume.assumeThat;
public abstract class AbstractGremlinTest {
private static final Logger logger = LoggerFactory.getLogger(AbstractGremlinTest.class);
- protected static final Map<Pair<Class<?>, String>, Boolean> featureCache = new HashMap<>();
-
protected Graph graph;
protected GraphTraversalSource g;
protected Configuration config;
@@ -84,20 +83,10 @@ public abstract class AbstractGremlinTest {
graphProvider = GraphManager.getGraphProvider();
+ // pre-check if available from graph provider to avoid graph creation
final Optional<Graph.Features> staticFeatures = graphProvider.getStaticFeatures();
if (staticFeatures.isPresent()) {
- for (FeatureRequirement fr : featureRequirementSet) {
- try {
- assumeThat(String.format("StaticFeatures of the graph do not support all of the features required by this test so it will be ignored: %s.%s=%s",
- fr.featureClass().getSimpleName(), fr.feature(), fr.supported()),
- staticFeatures.get().supports(fr.featureClass(), fr.feature()), is(fr.supported()));
- } catch (NoSuchMethodException nsme) {
- throw new NoSuchMethodException(String.format("[supports%s] is not a valid feature on %s", fr.feature(), fr.featureClass()));
- } catch (UnsupportedOperationException uoe) {
- // no worries - it just means that we can't use the cache to support this check and will have to
- // incur the cost of instantiating a graph instance directly
- }
- }
+ assumeRequirementsAreMetForTest(featureRequirementSet, staticFeatures.get(), true);
}
graphProvider.getTestListener().ifPresent(l -> l.onTestStart(this.getClass(), name.getMethodName()));
@@ -110,18 +99,10 @@ public abstract class AbstractGremlinTest {
graph = graphProvider.openTestGraph(config);
g = graphProvider.traversal(graph);
- for (FeatureRequirement fr : featureRequirementSet) {
- try {
- // even if we checked static features above it's of little cost to recheck again with the real graph
- // once it is instantiated. the real cost savings is preventing graph creation in the first place so
- // let's double check that all is legit.
- assumeThat(String.format("%s does not support all of the features required by this test so it will be ignored: %s.%s=%s",
- graph.getClass().getSimpleName(), fr.featureClass().getSimpleName(), fr.feature(), fr.supported()),
- graph.features().supports(fr.featureClass(), fr.feature()), is(fr.supported()));
- } catch (NoSuchMethodException nsme) {
- throw new NoSuchMethodException(String.format("[supports%s] is not a valid feature on %s", fr.feature(), fr.featureClass()));
- }
- }
+ // even if we checked static features earlier it's of little cost to recheck again with the real graph
+ // once it is instantiated. the real cost savings is preventing graph creation in the first place so
+ // let's double check that all is legit.
+ assumeRequirementsAreMetForTest(featureRequirementSet, graph.features(), false);
beforeLoadGraphWith(graph);
@@ -131,6 +112,25 @@ public abstract class AbstractGremlinTest {
afterLoadGraphWith(graph);
}
+ private static void assumeRequirementsAreMetForTest(final Set<FeatureRequirement> featureRequirementSet,
+ final Graph.Features features, final boolean staticCheck)
+ throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ for (FeatureRequirement fr : featureRequirementSet) {
+ try {
+ assumeThat(String.format("Features of the graph do not support all of the features required by this test so it will be ignored: %s.%s=%s",
+ fr.featureClass().getSimpleName(), fr.feature(), fr.supported()),
+ features.supports(fr.featureClass(), fr.feature()), is(fr.supported()));
+ } catch (NoSuchMethodException nsme) {
+ throw new NoSuchMethodException(String.format("[supports%s] is not a valid feature on %s", fr.feature(), fr.featureClass()));
+ } catch (UnsupportedOperationException uoe) {
+ // no worries if this is a check of static features - it just means that we can't use the cache to
+ // support this check and will have to incur the cost of instantiating a graph instance directly. but,
+ // if this is not a static check then something else is amiss and we should throw.
+ if (staticCheck) throw uoe;
+ }
+ }
+ }
+
protected void beforeLoadGraphWith(final Graph g) throws Exception {
// do nothing
}