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/08/10 14:54:48 UTC

tinkerpop git commit: Added the much needed Bytecode.getInstructions() method. Was able to really make GroovyTranslator and PythonTranslator more compact and easy to reason about. Optimized a few things in those respective translators. TranslationStrateg

Repository: tinkerpop
Updated Branches:
  refs/heads/TINKERPOP-1278 c3ec2f09a -> b11bf2077


Added the much needed Bytecode.getInstructions() method. Was able to really make GroovyTranslator and PythonTranslator more compact and easy to reason about. Optimized a few things in those respective translators. TranslationStrategy (used in testing) inserts bindings for various arguments like knows/created so we know that bindings in the various translations are working as expected. Bytecode.getStep/SourceInstructions() now returns Iterable, not List.


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

Branch: refs/heads/TINKERPOP-1278
Commit: b11bf2077036a7d0b4b7e7d06b2cfe870122e1a1
Parents: c3ec2f0
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Wed Aug 10 08:53:57 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Wed Aug 10 08:54:37 2016 -0600

----------------------------------------------------------------------
 .../gremlin/process/traversal/Bytecode.java     | 61 ++++++++++++++++----
 .../process/traversal/util/BytecodeHelper.java  | 13 +----
 .../graphson/GraphSONTraversalSerializers.java  |  4 +-
 .../gremlin/groovy/jsr223/GroovyTranslator.java | 39 +++++--------
 .../jsr223/GremlinJythonScriptEngine.java       |  2 +-
 .../gremlin/python/jsr223/PythonTranslator.java | 41 +++++--------
 .../jsr223/PythonGraphSONJavaTranslator.java    | 12 +---
 .../gremlin/python/jsr223/PythonProvider.java   |  2 +-
 .../decoration/TranslationStrategy.java         | 32 +++++++++-
 9 files changed, 114 insertions(+), 92 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java
index 0be140c..ef82d8e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java
@@ -20,21 +20,24 @@
 package org.apache.tinkerpop.gremlin.process.traversal;
 
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 /**
- * When a {@link TraversalSource} is manipulated, a {@link Traversal} is spawned and then mutated, a language
- * agnostic representation of those mutations is recorded in a byte code instance. Byte code is simply a list
- * of ordered instructions where an instruction is a string operator and an array of arguments. Byte code is used by
- * {@link Translator} instances which translate a traversal to another language by analyzing the
- * byte code as opposed to the Java traversal object representation on heap.
+ * When a {@link TraversalSource} is manipulated and then a {@link Traversal} is spawned and mutated, a language
+ * agnostic representation of those mutations is recorded in a bytecode instance. Bytecode is simply a list
+ * of ordered instructions where an instruction is a string operator and a (flattened) array of arguments.
+ * Bytecode is used by {@link Translator} instances which are able to translate a traversal in one language to another
+ * by analyzing the bytecode as opposed to the Java traversal object representation on heap.
+ * <p>
+ * Bytecode can be serialized between environments and machines by way of a GraphSON representation.
+ * Thus, Gremlin-Python can create bytecode in Python and ship it to Gremlin-Java for evaluation in Java.
  *
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
@@ -42,9 +45,14 @@ public final class Bytecode implements Cloneable, Serializable {
 
     private List<Instruction> sourceInstructions = new ArrayList<>();
     private List<Instruction> stepInstructions = new ArrayList<>();
-    // required for Gremlin-Java
     private transient Bindings bindings = null;
 
+    /**
+     * Add a {@link TraversalSource} instruction to the bytecode.
+     *
+     * @param sourceName the traversal source method name (e.g. withSack())
+     * @param arguments  the traversal source method arguments
+     */
     public void addSource(final String sourceName, final Object... arguments) {
         if (sourceName.equals(TraversalSource.Symbols.withBindings)) {
             this.bindings = (Bindings) arguments[0];
@@ -55,19 +63,50 @@ public final class Bytecode implements Cloneable, Serializable {
         }
     }
 
+    /**
+     * Add a {@link Traversal} instruction to the bytecode.
+     *
+     * @param stepName  the traversal method name (e.g. out())
+     * @param arguments the traversal method arguments
+     */
     public void addStep(final String stepName, final Object... arguments) {
         this.stepInstructions.add(new Instruction(stepName, flattenArguments(arguments)));
         if (null != this.bindings) this.bindings.clear();
     }
 
-    public List<Instruction> getSourceInstructions() {
-        return Collections.unmodifiableList(this.sourceInstructions);
+    /**
+     * Get the {@link TraversalSource} instructions associated with this bytecode.
+     *
+     * @return an iterable of instructions
+     */
+    public Iterable<Instruction> getSourceInstructions() {
+        return this.sourceInstructions;
     }
 
-    public List<Instruction> getStepInstructions() {
-        return Collections.unmodifiableList(this.stepInstructions);
+    /**
+     * Get the {@link Traversal} instructions associated with this bytecode.
+     *
+     * @return an iterable of instructions
+     */
+    public Iterable<Instruction> getStepInstructions() {
+        return this.stepInstructions;
     }
 
+    /**
+     * Get both the {@link TraversalSource} and {@link Traversal} instructions of this bytecode.
+     * The traversal source instructions are provided prior to the traversal instructions.
+     *
+     * @return an interable of all the instructions in this bytecode
+     */
+    public Iterable<Instruction> getInstructions() {
+        return () -> IteratorUtils.concat(this.sourceInstructions.iterator(), this.stepInstructions.iterator());
+    }
+
+    /**
+     * Get all the bindings (in a nested, recurssive manner) from all the arguments of all the instructions of this bytecode.
+     *
+     * @return a map of string variable and object value bindings
+     */
     public Map<String, Object> getBindings() {
         final Map<String, Object> bindingsMap = new HashMap<>();
         for (final Instruction instruction : this.sourceInstructions) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
index 43f3828..dc611d6 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/BytecodeHelper.java
@@ -48,18 +48,7 @@ public final class BytecodeHelper {
     }
 
     public static Optional<String> getLambdaLanguage(final Bytecode bytecode) {
-        for (final Bytecode.Instruction instruction : bytecode.getSourceInstructions()) {
-            for (Object object : instruction.getArguments()) {
-                if (object instanceof Lambda)
-                    return Optional.of(((Lambda) object).getLambdaLanguage());
-                else if (object instanceof Bytecode) {
-                    final Optional<String> temp = BytecodeHelper.getLambdaLanguage((Bytecode) object);
-                    if (temp.isPresent())
-                        return temp;
-                }
-            }
-        }
-        for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) {
+        for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
             for (Object object : instruction.getArguments()) {
                 if (object instanceof Lambda)
                     return Optional.of(((Lambda) object).getLambdaLanguage());

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java
index 037ce96..89f0b42 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONTraversalSerializers.java
@@ -88,7 +88,7 @@ public final class GraphSONTraversalSerializers {
                 throws IOException {
             jsonGenerator.writeStartObject();
             jsonGenerator.writeStringField("@type", "Bytecode");
-            if (!bytecode.getSourceInstructions().isEmpty()) {
+            if (bytecode.getSourceInstructions().iterator().hasNext()) {
                 jsonGenerator.writeArrayFieldStart("source");
                 for (final Bytecode.Instruction instruction : bytecode.getSourceInstructions()) {
                     jsonGenerator.writeStartArray();
@@ -100,7 +100,7 @@ public final class GraphSONTraversalSerializers {
                 }
                 jsonGenerator.writeEndArray();
             }
-            if (!bytecode.getStepInstructions().isEmpty()) {
+            if (bytecode.getStepInstructions().iterator().hasNext()) {
                 jsonGenerator.writeArrayFieldStart("step");
                 for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) {
                     jsonGenerator.writeStartArray();

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java
index fdb3ece..9349c90 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java
@@ -33,7 +33,6 @@ import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.util.function.Lambda;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -88,31 +87,23 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
 
     private String internalTranslate(final String start, final Bytecode bytecode) {
         final StringBuilder traversalScript = new StringBuilder(start);
-        for (final Bytecode.Instruction instruction : bytecode.getSourceInstructions()) {
-            processInstruction(traversalScript, instruction);
-        }
-        for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) {
-            processInstruction(traversalScript, instruction);
-        }
-        return traversalScript.toString();
-    }
-
-    private void processInstruction(final StringBuilder traversalScript, final Bytecode.Instruction instruction) {
-        final String methodName = instruction.getOperator();
-        if (methodName.equals(TraversalSource.Symbols.withStrategies))
-            return;
-        final Object[] arguments = instruction.getArguments();
-        final List<Object> objects = Arrays.asList(arguments);
-        if (objects.isEmpty())
-            traversalScript.append(".").append(methodName).append("()");
-        else {
-            traversalScript.append(".");
-            String temp = methodName + "(";
-            for (final Object object : objects) {
-                temp = temp + convertToString(object) + ",";
+        for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
+            final String methodName = instruction.getOperator();
+            if (methodName.equals(TraversalSource.Symbols.withStrategies))
+                continue;
+            final Object[] arguments = instruction.getArguments();
+            if (0 == arguments.length)
+                traversalScript.append(".").append(methodName).append("()");
+            else {
+                traversalScript.append(".");
+                String temp = methodName + "(";
+                for (final Object object : arguments) {
+                    temp = temp + convertToString(object) + ",";
+                }
+                traversalScript.append(temp.substring(0, temp.length() - 1)).append(")");
             }
-            traversalScript.append(temp.substring(0, temp.length() - 1)).append(")");
         }
+        return traversalScript.toString();
     }
 
     private String convertToString(final Object object) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
index 3ea21e4..a10cb3f 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/GremlinJythonScriptEngine.java
@@ -119,7 +119,7 @@ public class GremlinJythonScriptEngine implements GremlinScriptEngine {
     public Traversal.Admin eval(final Bytecode bytecode, final Bindings bindings) throws ScriptException {
         bindings.putAll(bytecode.getBindings());
         // TODO: this is kinda bad because it makes the assumption that we will always alias to "g" (which is generally true, but maybe better to not hardcode?)
-        return (Traversal.Admin) this.eval(new PythonTranslator("g", "__").translate(bytecode), bindings);
+        return (Traversal.Admin) this.eval(PythonTranslator.of("g", "__").translate(bytecode), bindings);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
index 70bb38b..20cc21b 100644
--- a/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
+++ b/gremlin-python/src/main/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonTranslator.java
@@ -62,14 +62,22 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
     private String anonymousTraversal;
     private final boolean importStatics;
 
-    public PythonTranslator(final String traversalSource, final String anonymousTraversal, final boolean importStatics) {
+    private PythonTranslator(final String traversalSource, final String anonymousTraversal, final boolean importStatics) {
         this.traversalSource = traversalSource;
         this.anonymousTraversal = anonymousTraversal;
         this.importStatics = importStatics;
     }
 
-    public PythonTranslator(final String traversalSource, final String anonymousTraversal) {
-        this(traversalSource, anonymousTraversal, false);
+    public static final PythonTranslator of(final String traversalSource, final String anonymousTraversal, final boolean importStatics) {
+        return new PythonTranslator(traversalSource, anonymousTraversal, importStatics);
+    }
+
+    public static final PythonTranslator of(final String traversalSource, final String anonymousTraversal) {
+        return new PythonTranslator(traversalSource, anonymousTraversal, false);
+    }
+
+    public static final PythonTranslator of(final String traversalSource) {
+        return new PythonTranslator(traversalSource, "__", false);
     }
 
     @Override
@@ -104,32 +112,12 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
 
     private String internalTranslate(final String start, final Bytecode bytecode) {
         final StringBuilder traversalScript = new StringBuilder(start);
-        for (final Bytecode.Instruction instruction : bytecode.getSourceInstructions()) {
+        for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
             final String methodName = instruction.getOperator();
+            final Object[] arguments = instruction.getArguments();
             if (methodName.equals(TraversalSource.Symbols.withStrategies))
                 continue;
-            final Object[] arguments = instruction.getArguments();
-            if (0 == arguments.length)
-                traversalScript.append(".").append(SymbolHelper.toPython(methodName)).append("()");
-            else {
-                traversalScript.append(".");
-                String temp = SymbolHelper.toPython(methodName) + "(";
-                for (final Object object : arguments) {
-                    temp = temp + convertToString(object) + ",";
-                }
-                traversalScript.append(temp.substring(0, temp.length() - 1)).append(")");
-            }
-
-            // clip off __.
-            if (this.importStatics && traversalScript.substring(0, 3).startsWith(this.anonymousTraversal + ".")
-                    && !NO_STATIC.stream().filter(name -> traversalScript.substring(3).startsWith(SymbolHelper.toPython(name))).findAny().isPresent()) {
-                traversalScript.delete(0, 3);
-            }
-        }
-        for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) {
-            final String methodName = instruction.getOperator();
-            final Object[] arguments = instruction.getArguments();
-            if (0 == arguments.length)
+            else if (0 == arguments.length)
                 traversalScript.append(".").append(SymbolHelper.toPython(methodName)).append("()");
             else if (methodName.equals("range") && 2 == arguments.length)
                 traversalScript.append("[").append(arguments[0]).append(":").append(arguments[1]).append("]");
@@ -145,7 +133,6 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
                 }
                 traversalScript.append(temp.substring(0, temp.length() - 1)).append(")");
             }
-
             // clip off __.
             if (this.importStatics && traversalScript.substring(0, 3).startsWith(this.anonymousTraversal + ".")
                     && !NO_STATIC.stream().filter(name -> traversalScript.substring(3).startsWith(SymbolHelper.toPython(name))).findAny().isPresent()) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java
index 2a55228..f4e5cc7 100644
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonGraphSONJavaTranslator.java
@@ -24,8 +24,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
 import org.apache.tinkerpop.gremlin.process.traversal.Translator;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
-import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.VerificationException;
-import org.apache.tinkerpop.gremlin.process.traversal.util.EmptyTraversal;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONReader;
 import org.apache.tinkerpop.gremlin.util.ScriptEngineCache;
 
@@ -37,7 +35,7 @@ import java.io.ByteArrayInputStream;
 /**
  * @author Marko A. Rodriguez (http://markorodriguez.com)
  */
-public class PythonGraphSONJavaTranslator<S extends TraversalSource, T extends Traversal.Admin<?, ?>> implements Translator.StepTranslator<S, T> {
+final class PythonGraphSONJavaTranslator<S extends TraversalSource, T extends Traversal.Admin<?, ?>> implements Translator.StepTranslator<S, T> {
 
     private final PythonTranslator pythonTranslator;
     private final JavaTranslator<S, T> javaTranslator;
@@ -65,14 +63,6 @@ public class PythonGraphSONJavaTranslator<S extends TraversalSource, T extends T
 
     @Override
     public T translate(final Bytecode bytecode) {
-
-        for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) {
-            for (final Object argument : instruction.getArguments()) {
-                if (argument.toString().contains("$"))
-                    throw new VerificationException("Lambdas are currently not supported: " + bytecode, EmptyTraversal.instance());
-            }
-        }
-
         try {
             final ScriptEngine jythonEngine = ScriptEngineCache.get("jython");
             final Bindings bindings = jythonEngine.createBindings();

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonProvider.java
----------------------------------------------------------------------
diff --git a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonProvider.java b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonProvider.java
index 56b0963..1414f8b 100644
--- a/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonProvider.java
+++ b/gremlin-python/src/test/java/org/apache/tinkerpop/gremlin/python/jsr223/PythonProvider.java
@@ -157,7 +157,7 @@ public class PythonProvider extends AbstractGraphProvider {
                 throw new IllegalStateException(e.getMessage(), e);
             }
             final GraphTraversalSource g = graph.traversal();
-            return g.withStrategies(new TranslationStrategy(g, new PythonGraphSONJavaTranslator<>(new PythonTranslator("g", "__", IMPORT_STATICS), JavaTranslator.of(g))));
+            return g.withStrategies(new TranslationStrategy(g, new PythonGraphSONJavaTranslator<>(PythonTranslator.of("g", "__", IMPORT_STATICS), JavaTranslator.of(g))));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/b11bf207/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java
index 5ad7401..92c9483 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/decoration/TranslationStrategy.java
@@ -22,6 +22,7 @@ package org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration;
 import org.apache.tinkerpop.gremlin.jsr223.GremlinScriptEngine;
 import org.apache.tinkerpop.gremlin.jsr223.SingleGremlinScriptEngineManager;
 import org.apache.tinkerpop.gremlin.process.remote.traversal.strategy.decoration.RemoteStrategy;
+import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
 import org.apache.tinkerpop.gremlin.process.traversal.Step;
 import org.apache.tinkerpop.gremlin.process.traversal.Translator;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
@@ -71,13 +72,16 @@ public final class TranslationStrategy extends AbstractTraversalStrategy<Travers
         // verifications to ensure unsupported steps do not exist in the traversal
         if (Boolean.valueOf(System.getProperty("is.testing", "false")) &&
                 (traversal.getBytecode().toString().contains("$") || traversal.getBytecode().toString().contains("HashSetSupplier")))
-            throw new VerificationException("Test suite does not support profiling nor lambdas", traversal);
+            throw new VerificationException("Test suite does not support lambdas", traversal);
 
         final Traversal.Admin<?, ?> translatedTraversal;
+        final Bytecode bytecode = Boolean.valueOf(System.getProperty("is.testing", "false")) ?
+                insertBindingsForTesting(traversal.getBytecode()) :
+                traversal.getBytecode();
         ////////////////
         if (this.translator instanceof Translator.StepTranslator) {
             // reflection based translation
-            translatedTraversal = (Traversal.Admin<?, ?>) this.translator.translate(traversal.getBytecode());
+            translatedTraversal = (Traversal.Admin<?, ?>) this.translator.translate(bytecode);
         } else if (this.translator instanceof Translator.ScriptTranslator) {
             try {
                 // script based translation
@@ -85,7 +89,7 @@ public final class TranslationStrategy extends AbstractTraversalStrategy<Travers
                 final Bindings bindings = scriptEngine.createBindings();
                 bindings.putAll(scriptEngine.getContext().getBindings(ScriptContext.ENGINE_SCOPE));
                 bindings.put(this.translator.getTraversalSource().toString(), this.traversalSource);
-                translatedTraversal = (Traversal.Admin<?, ?>) scriptEngine.eval(traversal.getBytecode(), bindings);
+                translatedTraversal = (Traversal.Admin<?, ?>) scriptEngine.eval(bytecode, bindings);
             } catch (final Exception e) {
                 throw new IllegalArgumentException(e.getMessage(), e);
             }
@@ -106,4 +110,26 @@ public final class TranslationStrategy extends AbstractTraversalStrategy<Travers
         return POSTS;
     }
 
+    private static final Bytecode insertBindingsForTesting(final Bytecode bytecode) {
+        final Bytecode newBytecode = new Bytecode();
+        bytecode.getSourceInstructions().forEach(instruction -> newBytecode.addSource(instruction.getOperator(), instruction.getArguments()));
+        for (final Bytecode.Instruction instruction : bytecode.getStepInstructions()) {
+            final Object[] args = instruction.getArguments();
+            final Object[] newArgs = new Object[args.length];
+
+            for (int i = 0; i < args.length; i++) {
+                if (args[i].equals("knows"))
+                    newArgs[i] = new Bytecode.Binding<>("a", "knows");
+                else if (args[i].equals("created"))
+                    newArgs[i] = new Bytecode.Binding<>("b", "created");
+                else if (args[i].equals(10))
+                    newArgs[i] = new Bytecode.Binding<>("c", 10);
+                else
+                    newArgs[i] = args[i];
+            }
+            newBytecode.addStep(instruction.getOperator(), newArgs);
+        }
+        return newBytecode;
+    }
+
 }