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 2019/11/25 14:52:07 UTC

[tinkerpop] branch travis-fix updated: enabled integration tests back since it won't fail anymore

This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch travis-fix
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/travis-fix by this push:
     new ec0b26d  enabled integration tests back since it won't fail anymore
ec0b26d is described below

commit ec0b26de3c6766fb1585fc537d5ca348624b42f9
Author: stephen <sp...@gmail.com>
AuthorDate: Mon Nov 25 09:50:57 2019 -0500

    enabled integration tests back since it won't fail anymore
    
    still no idea why it's passing as no changes i've made can be attributed to the fix
---
 .../gremlin/server/GremlinServerIntegrateTest.java | 1738 ++++++++++----------
 1 file changed, 869 insertions(+), 869 deletions(-)

diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
index da8dd38..5448a26 100644
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
+++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java
@@ -236,621 +236,621 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
         return scriptEngineConf;
     }
 
-//    @Test
-//    public void shouldScriptEvaluationErrorForRemoteTraversal() throws Exception {
-//        final GraphTraversalSource g = traversal().withRemote(conf);
-//
-//        try {
-//            // tests bad lambda
-//            g.inject(1).sideEffect(Lambda.consumer("(")).iterate();
-//            fail("This traversal should not have executed since lambda can't be compiled");
-//        } catch (Exception ex) {
-//            final Throwable t = ex.getCause();
-//            assertThat(t, instanceOf(ResponseException.class));
-//            assertEquals(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION, ((ResponseException) t).getResponseStatusCode());
-//        }
-//
-//        // make a graph with a cycle in it to force a long run traversal
-//        graphGetter.get().traversal().addV("person").as("p").addE("self").to("p").iterate();
-//
-//        try {
-//            // tests an "unending" traversal
-//            g.V().repeat(__.out()).until(__.outE().count().is(0)).iterate();
-//            fail("This traversal should have timed out");
-//        } catch (Exception ex) {
-//            final Throwable t = ex.getCause();
-//            assertThat(t, instanceOf(ResponseException.class));
-//            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
-//        }
-//    }
-//
-//    @Test
-//    public void shouldCloseChannelIfClientDoesntRespond() throws Exception {
-//        final SimpleClient client = TestClientFactory.createWebSocketClient();
-//        client.submit("1+1");
-//
-//        // since we do nothing for 2 seconds and the time limit for timeout on the server is 1 second, the server
-//        // will autoclose the channel
-//        Thread.sleep(2000);
-//
-//        assertThat(recordingAppender.logContainsAny(".*Closing channel - client is disconnected after idle period of .*$"), is(true));
-//
-//        client.close();
-//    }
-//
-//    @Test
-//    public void shouldPingChannelIfClientDies() throws Exception {
-//        final Client client = TestClientFactory.build().maxConnectionPoolSize(1).minConnectionPoolSize(1).keepAliveInterval(0).create().connect();
-//        client.submit("1+1").all().get();
-//
-//        // since we do nothing for 3 seconds and the time limit for ping is 1 second we should get *about* 3 pings -
-//        // i don't think the assertion needs to be too accurate. just need to make sure there's a ping message out
-//        // there record
-//        Thread.sleep(3000);
-//
-//        client.close();
-//
-//        // stop the server to be sure that logs flush
-//        stopServer();
-//
-//        assertThat(recordingAppender.logContainsAny(".*Checking channel - sending ping to client after idle period of .*$"), is(true));
-//    }
-//
-//    @Test
-//    public void shouldTimeOutRemoteTraversal() throws Exception {
-//        final GraphTraversalSource g = traversal().withRemote(conf);
-//
-//        try {
-//            // tests sleeping thread
-//            g.inject(1).sideEffect(Lambda.consumer("Thread.sleep(10000)")).iterate();
-//            fail("This traversal should have timed out");
-//        } catch (Exception ex) {
-//            final Throwable t = ex.getCause();
-//            assertThat(t, instanceOf(ResponseException.class));
-//            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
-//        }
-//
-//        // make a graph with a cycle in it to force a long run traversal
-//        graphGetter.get().traversal().addV("person").as("p").addE("self").to("p").iterate();
-//
-//        try {
-//            // tests an "unending" traversal
-//            g.V().repeat(__.out()).until(__.outE().count().is(0)).iterate();
-//            fail("This traversal should have timed out");
-//        } catch (Exception ex) {
-//            final Throwable t = ex.getCause();
-//            assertThat(t, instanceOf(ResponseException.class));
-//            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
-//        }
-//    }
-//
-//    @Test
-//    public void shouldTimeOutRemoteTraversalUsingDeprecatedConfiguration() throws Exception {
-//        final GraphTraversalSource g = traversal().withRemote(conf);
-//
-//        try {
-//            // tests sleeping thread
-//            g.inject(1).sideEffect(Lambda.consumer("Thread.sleep(10000)")).iterate();
-//            fail("This traversal should have timed out");
-//        } catch (Exception ex) {
-//            final Throwable t = ex.getCause();
-//            assertThat(t, instanceOf(ResponseException.class));
-//            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
-//        }
-//
-//        // make a graph with a cycle in it to force a long run traversal
-//        graphGetter.get().traversal().addV("person").as("p").addE("self").to("p").iterate();
-//
-//        try {
-//            // tests an "unending" traversal
-//            g.V().repeat(__.out()).until(__.outE().count().is(0)).iterate();
-//            fail("This traversal should have timed out");
-//        } catch (Exception ex) {
-//            final Throwable t = ex.getCause();
-//            assertThat(t, instanceOf(ResponseException.class));
-//            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
-//        }
-//    }
-//
-//    @Test
-//    public void shouldTimeOutRemoteTraversalWithPerRequestOption() {
-//        final GraphTraversalSource g = traversal().withRemote(conf);
-//
-//        try {
-//            // tests sleeping thread
-//            g.with(ARGS_SCRIPT_EVAL_TIMEOUT, 500L).inject(1).sideEffect(Lambda.consumer("Thread.sleep(10000)")).iterate();
-//            fail("This traversal should have timed out");
-//        } catch (Exception ex) {
-//            final Throwable t = ex.getCause();
-//            assertThat(t, instanceOf(ResponseException.class));
-//            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
-//        }
-//
-//        // make a graph with a cycle in it to force a long run traversal
-//        graphGetter.get().traversal().addV("person").as("p").addE("self").to("p").iterate();
-//
-//        try {
-//            // tests an "unending" traversal
-//            g.with(ARGS_SCRIPT_EVAL_TIMEOUT, 500L).V().repeat(__.out()).until(__.outE().count().is(0)).iterate();
-//            fail("This traversal should have timed out");
-//        } catch (Exception ex) {
-//            final Throwable t = ex.getCause();
-//            assertThat(t, instanceOf(ResponseException.class));
-//            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
-//        }
-//    }
-//
-//    @Test
-//    public void shouldProduceProperExceptionOnTimeout() throws Exception {
-//        final Cluster cluster = TestClientFactory.open();
-//        final Client client = cluster.connect(name.getMethodName());
-//
-//        boolean success = false;
-//        // Run a short test script a few times with progressively longer timeouts.
-//        // Each submissions should either succeed or fail with a timeout.
-//        // Note: the range of timeouts is intended to cover the case when the script finishes at about the
-//        // same time when the timeout occurs. In this situation either a timeout response or a successful
-//        // response is acceptable, however no other processing errors should occur.
-//        // Note: the timeout of 30 ms is generally sufficient for running a simple groovy script, so using longer
-//        // timeouts are not likely to results in a success/timeout response collision, which is the purpose
-//        // of this test.
-//        // Note: this test may have a false negative result, but a failure  would indicate a real problem.
-//        for(int i = 0; i < 30; i++) {
-//            int timeout = 1 + i;
-//            overrideEvaluationTimeout(timeout);
-//
-//            try {
-//                client.submit("x = 1 + 1").all().get().get(0).getInt();
-//                success = true;
-//            } catch (Exception ex) {
-//                final Throwable t = ex.getCause();
-//                assertThat("Unexpected exception with script evaluation timeout: " + timeout, t, instanceOf(ResponseException.class));
-//                assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
-//            }
-//        }
-//
-//        assertTrue("Some script submissions should succeed", success);
-//
-//        cluster.close();
-//    }
-//
-//    @Test
-//    public void shouldUseBaseScript() throws Exception {
-//        final Cluster cluster = TestClientFactory.open();
-//        final Client client = cluster.connect(name.getMethodName());
-//
-//        assertEquals("hello, stephen", client.submit("hello('stephen')").all().get().get(0).getString());
-//
-//        cluster.close();
-//    }
-//
-//    @Test
-//    public void shouldUseInterpreterMode() throws Exception {
-//        final Cluster cluster = TestClientFactory.open();
-//        final Client client = cluster.connect(name.getMethodName());
-//
-//        client.submit("def subtractAway(x,y){x-y};[]").all().get();
-//        client.submit("multiplyIt = { x,y -> x * y};[]").all().get();
-//
-//        assertEquals(2, client.submit("x = 1 + 1").all().get().get(0).getInt());
-//        assertEquals(3, client.submit("int y = x + 1").all().get().get(0).getInt());
-//        assertEquals(5, client.submit("def z = x + y").all().get().get(0).getInt());
-//
-//        final Map<String,Object> m = new HashMap<>();
-//        m.put("x", 10);
-//        assertEquals(-5, client.submit("z - x", m).all().get().get(0).getInt());
-//        assertEquals(15, client.submit("addItUp(x,z)", m).all().get().get(0).getInt());
-//        assertEquals(5, client.submit("subtractAway(x,z)", m).all().get().get(0).getInt());
-//        assertEquals(50, client.submit("multiplyIt(x,z)", m).all().get().get(0).getInt());
-//
-//        cluster.close();
-//    }
-//
-//    @Test
-//    public void shouldNotUseInterpreterMode() throws Exception {
-//        final Cluster cluster = TestClientFactory.open();
-//        final Client client = cluster.connect(name.getMethodName());
-//
-//        client.submit("def subtractAway(x,y){x-y};[]").all().get();
-//        client.submit("multiplyIt = { x,y -> x * y};[]").all().get();
-//
-//        assertEquals(2, client.submit("x = 1 + 1").all().get().get(0).getInt());
-//        assertEquals(3, client.submit("y = x + 1").all().get().get(0).getInt());
-//        assertEquals(5, client.submit("z = x + y").all().get().get(0).getInt());
-//
-//        final Map<String,Object> m = new HashMap<>();
-//        m.put("x", 10);
-//        assertEquals(-5, client.submit("z - x", m).all().get().get(0).getInt());
-//        assertEquals(15, client.submit("addItUp(x,z)", m).all().get().get(0).getInt());
-//        assertEquals(5, client.submit("subtractAway(x,z)", m).all().get().get(0).getInt());
-//        assertEquals(50, client.submit("multiplyIt(x,z)", m).all().get().get(0).getInt());
-//
-//        cluster.close();
-//    }
-//
-//    @Test
-//    public void shouldUseSimpleSandbox() throws Exception {
-//        final Cluster cluster = TestClientFactory.open();
-//        final Client client = cluster.connect();
-//
-//        assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
-//
-//        try {
-//            // this should return "nothing" - there should be no exception
-//            client.submit("java.lang.System.exit(0)").all().get();
-//            fail("The above should not have executed in any successful way as sandboxing is enabled");
-//        } catch (Exception ex) {
-//            assertThat(ex.getCause().getMessage(), containsString("[Static type checking] - Not authorized to call this method: java.lang.System#exit(int)"));
-//        } finally {
-//            cluster.close();
-//        }
-//    }
-//
-//    @Test
-//    public void shouldRespectHighWaterMarkSettingAndSucceed() throws Exception {
-//        // the highwatermark should get exceeded on the server and thus pause the writes, but have no problem catching
-//        // itself up - this is a tricky tests to get passing on all environments so this assumption will deny the
-//        // test for most cases
-//        TestHelper.assumeNonDeterministic();
-//
-//        final Cluster cluster = TestClientFactory.open();
-//        final Client client = cluster.connect();
-//
-//        try {
-//            final int resultCountToGenerate = 1000;
-//            final int batchSize = 3;
-//            final String fatty = IntStream.range(0, 175).mapToObj(String::valueOf).collect(Collectors.joining());
-//            final String fattyX = "['" + fatty + "'] * " + resultCountToGenerate;
-//
-//            // don't allow the thread to proceed until all results are accounted for
-//            final CountDownLatch latch = new CountDownLatch(resultCountToGenerate);
-//            final AtomicBoolean expected = new AtomicBoolean(false);
-//            final AtomicBoolean faulty = new AtomicBoolean(false);
-//            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
-//                    .addArg(Tokens.ARGS_BATCH_SIZE, batchSize)
-//                    .addArg(Tokens.ARGS_GREMLIN, fattyX).create();
-//
-//            client.submitAsync(request).thenAcceptAsync(r -> {
-//                r.stream().forEach(item -> {
-//                    try {
-//                        final String aFattyResult = item.getString();
-//                        expected.set(aFattyResult.equals(fatty));
-//                    } catch (Exception ex) {
-//                        ex.printStackTrace();
-//                        faulty.set(true);
-//                    } finally {
-//                        latch.countDown();
-//                    }
-//                });
-//            });
-//
-//            assertThat(latch.await(30000, TimeUnit.MILLISECONDS), is(true));
-//            assertEquals(0, latch.getCount());
-//            assertThat(faulty.get(), is(false));
-//            assertThat(expected.get(), is(true));
-//
-//            assertThat(recordingAppender.getMessages().stream().anyMatch(m -> m.contains("Pausing response writing as writeBufferHighWaterMark exceeded on")), is(true));
-//        } catch (Exception ex) {
-//            fail("Shouldn't have tossed an exception");
-//        } finally {
-//            cluster.close();
-//        }
-//    }
-//
-//    @Test
-//    public void shouldReturnInvalidRequestArgsWhenGremlinArgIsNotSupplied() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL).create();
-//            final ResponseMessage result = client.submit(request).get(0);
-//            assertThat(result.getStatus().getCode(), is(not(ResponseStatusCode.PARTIAL_CONTENT)));
-//            assertEquals(result.getStatus().getCode(), ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS);
-//        }
-//    }
-//
-//    @Test
-//    public void shouldReturnInvalidRequestArgsWhenInvalidReservedBindingKeyIsUsed() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final Map<String, Object> bindings = new HashMap<>();
-//            bindings.put(T.id.getAccessor(), "123");
-//            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
-//                    .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
-//                    .addArg(Tokens.ARGS_BINDINGS, bindings).create();
-//            final CountDownLatch latch = new CountDownLatch(1);
-//            final AtomicBoolean pass = new AtomicBoolean(false);
-//            client.submit(request, result -> {
-//                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
-//                    pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
-//                    latch.countDown();
-//                }
-//            });
-//
-//            if (!latch.await(3000, TimeUnit.MILLISECONDS))
-//                fail("Request should have returned error, but instead timed out");
-//            assertThat(pass.get(), is(true));
-//        }
-//
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final Map<String, Object> bindings = new HashMap<>();
-//            bindings.put("id", "123");
-//            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
-//                    .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
-//                    .addArg(Tokens.ARGS_BINDINGS, bindings).create();
-//            final CountDownLatch latch = new CountDownLatch(1);
-//            final AtomicBoolean pass = new AtomicBoolean(false);
-//            client.submit(request, result -> {
-//                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
-//                    pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
-//                    latch.countDown();
-//                }
-//            });
-//
-//            if (!latch.await(3000, TimeUnit.MILLISECONDS))
-//                fail("Request should have returned error, but instead timed out");
-//            assertTrue(pass.get());
-//        }
-//    }
-//
-//    @Test
-//    public void shouldReturnInvalidRequestArgsWhenInvalidTypeBindingKeyIsUsed() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final Map<Object, Object> bindings = new HashMap<>();
-//            bindings.put(1, "123");
-//            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
-//                    .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
-//                    .addArg(Tokens.ARGS_BINDINGS, bindings).create();
-//            final CountDownLatch latch = new CountDownLatch(1);
-//            final AtomicBoolean pass = new AtomicBoolean(false);
-//            client.submit(request, result -> {
-//                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
-//                    pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
-//                    latch.countDown();
-//                }
-//            });
-//
-//            if (!latch.await(3000, TimeUnit.MILLISECONDS))
-//                fail("Request should have returned error, but instead timed out");
-//            assertThat(pass.get(), is(true));
-//        }
-//    }
-//
-//    @Test
-//    public void shouldReturnInvalidRequestArgsWhenBindingCountExceedsAllowable() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final Map<Object, Object> bindings = new HashMap<>();
-//            bindings.put("x", 123);
-//            bindings.put("y", 123);
-//            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
-//                    .addArg(Tokens.ARGS_GREMLIN, "x+y")
-//                    .addArg(Tokens.ARGS_BINDINGS, bindings).create();
-//            final CountDownLatch latch = new CountDownLatch(1);
-//            final AtomicBoolean pass = new AtomicBoolean(false);
-//            client.submit(request, result -> {
-//                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
-//                    pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
-//                    latch.countDown();
-//                }
-//            });
-//
-//            if (!latch.await(3000, TimeUnit.MILLISECONDS))
-//                fail("Request should have returned error, but instead timed out");
-//            assertThat(pass.get(), is(true));
-//        }
-//
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final Map<Object, Object> bindings = new HashMap<>();
-//            bindings.put("x", 123);
-//            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
-//                    .addArg(Tokens.ARGS_GREMLIN, "x+123")
-//                    .addArg(Tokens.ARGS_BINDINGS, bindings).create();
-//            final CountDownLatch latch = new CountDownLatch(1);
-//            final AtomicBoolean pass = new AtomicBoolean(false);
-//            client.submit(request, result -> {
-//                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
-//                    pass.set(ResponseStatusCode.SUCCESS == result.getStatus().getCode() && (((int) ((List) result.getResult().getData()).get(0) == 246)));
-//                    latch.countDown();
-//                }
-//            });
-//
-//            if (!latch.await(3000, TimeUnit.MILLISECONDS))
-//                fail("Request should have returned error, but instead timed out");
-//            assertThat(pass.get(), is(true));
-//        }
-//    }
-//
-//    @Test
-//    public void shouldReturnInvalidRequestArgsWhenInvalidNullBindingKeyIsUsed() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final Map<String, Object> bindings = new HashMap<>();
-//            bindings.put(null, "123");
-//            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
-//                    .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
-//                    .addArg(Tokens.ARGS_BINDINGS, bindings).create();
-//            final CountDownLatch latch = new CountDownLatch(1);
-//            final AtomicBoolean pass = new AtomicBoolean(false);
-//            client.submit(request, result -> {
-//                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
-//                    pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
-//                    latch.countDown();
-//                }
-//            });
-//
-//            if (!latch.await(3000, TimeUnit.MILLISECONDS))
-//                fail("Request should have returned error, but instead timed out");
-//            assertThat(pass.get(), is(true));
-//        }
-//    }
-//
-//    @Test
-//    @SuppressWarnings("unchecked")
-//    public void shouldBatchResultsByTwos() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
-//                    .addArg(Tokens.ARGS_GREMLIN, "[0,1,2,3,4,5,6,7,8,9]").create();
-//
-//            final List<ResponseMessage> msgs = client.submit(request);
-//            assertEquals(5, client.submit(request).size());
-//            assertEquals(0, ((List<Integer>) msgs.get(0).getResult().getData()).get(0).intValue());
-//            assertEquals(1, ((List<Integer>) msgs.get(0).getResult().getData()).get(1).intValue());
-//            assertEquals(2, ((List<Integer>) msgs.get(1).getResult().getData()).get(0).intValue());
-//            assertEquals(3, ((List<Integer>) msgs.get(1).getResult().getData()).get(1).intValue());
-//            assertEquals(4, ((List<Integer>) msgs.get(2).getResult().getData()).get(0).intValue());
-//            assertEquals(5, ((List<Integer>) msgs.get(2).getResult().getData()).get(1).intValue());
-//            assertEquals(6, ((List<Integer>) msgs.get(3).getResult().getData()).get(0).intValue());
-//            assertEquals(7, ((List<Integer>) msgs.get(3).getResult().getData()).get(1).intValue());
-//            assertEquals(8, ((List<Integer>) msgs.get(4).getResult().getData()).get(0).intValue());
-//            assertEquals(9, ((List<Integer>) msgs.get(4).getResult().getData()).get(1).intValue());
-//        }
-//    }
-//
-//    @Test
-//    @SuppressWarnings("unchecked")
-//    public void shouldBatchResultsByOnesByOverridingFromClientSide() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
-//                    .addArg(Tokens.ARGS_GREMLIN, "[0,1,2,3,4,5,6,7,8,9]")
-//                    .addArg(Tokens.ARGS_BATCH_SIZE, 1).create();
-//
-//            final List<ResponseMessage> msgs = client.submit(request);
-//            assertEquals(10, msgs.size());
-//            IntStream.rangeClosed(0, 9).forEach(i -> assertEquals(i, ((List<Integer>) msgs.get(i).getResult().getData()).get(0).intValue()));
-//        }
-//    }
-//
-//    @Test
-//    public void shouldNotThrowNoSuchElementException() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()){
-//            // this should return "nothing" - there should be no exception
-//            final List<ResponseMessage> responses = client.submit("g.V().has('name','kadfjaldjfla')");
-//            assertNull(responses.get(0).getResult().getData());
-//        }
-//    }
-//
-//    @Test
-//    @SuppressWarnings("unchecked")
-//    public void shouldReceiveFailureTimeOutOnScriptEval() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()){
-//            final List<ResponseMessage> responses = client.submit("Thread.sleep(3000);'some-stuff-that-should not return'");
-//            assertThat(responses.get(0).getStatus().getMessage(), startsWith("Evaluation exceeded the configured 'evaluationTimeout' threshold of 1000 ms"));
-//
-//            // validate that we can still send messages to the server
-//            assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
-//        }
-//    }
-//
-//    @Test
-//    @SuppressWarnings("unchecked")
-//    public void shouldReceiveFailureTimeOutOnScriptEvalUsingOverride() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final RequestMessage msg = RequestMessage.build("eval")
-//                    .addArg(ARGS_SCRIPT_EVAL_TIMEOUT, 100L)
-//                    .addArg(Tokens.ARGS_GREMLIN, "Thread.sleep(3000);'some-stuff-that-should not return'")
-//                    .create();
-//            final List<ResponseMessage> responses = client.submit(msg);
-//            assertThat(responses.get(0).getStatus().getMessage(), startsWith("Evaluation exceeded the configured 'evaluationTimeout' threshold of 100 ms"));
-//
-//            // validate that we can still send messages to the server
-//            assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
-//        }
-//    }
-//
-//    @Test
-//    @SuppressWarnings("unchecked")
-//    public void shouldReceiveFailureTimeOutOnEvalUsingOverride() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final RequestMessage msg = RequestMessage.build("eval")
-//                    .addArg(Tokens.ARGS_EVAL_TIMEOUT, 100L)
-//                    .addArg(Tokens.ARGS_GREMLIN, "Thread.sleep(3000);'some-stuff-that-should not return'")
-//                    .create();
-//            final List<ResponseMessage> responses = client.submit(msg);
-//            assertThat(responses.get(0).getStatus().getMessage(), startsWith("Evaluation exceeded the configured 'evaluationTimeout' threshold of 100 ms"));
-//
-//            // validate that we can still send messages to the server
-//            assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
-//        }
-//    }
-//
-//    @Test
-//    public void shouldReceiveFailureTimeOutOnScriptEvalOfOutOfControlLoop() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()){
-//            // timeout configured for 1 second so the timed interrupt should trigger prior to the
-//            // evaluationTimeout which is at 30 seconds by default
-//            final List<ResponseMessage> responses = client.submit("while(true){}");
-//            assertThat(responses.get(0).getStatus().getMessage(), startsWith("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider"));
-//
-//            // validate that we can still send messages to the server
-//            assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
-//        }
-//    }
-//
-//    @Test
-//    @SuppressWarnings("unchecked")
-//    public void shouldLoadInitScript() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()){
-//            assertEquals(2, ((List<Integer>) client.submit("addItUp(1,1)").get(0).getResult().getData()).get(0).intValue());
-//        }
-//    }
-//
-//    @Test
-//    public void shouldGarbageCollectPhantomButNotHard() throws Exception {
-//        final Cluster cluster = TestClientFactory.open();
-//        final Client client = cluster.connect();
-//
-//        assertEquals(2, client.submit("addItUp(1,1)").all().join().get(0).getInt());
-//        assertEquals(0, client.submit("def subtract(x,y){x-y};subtract(1,1)").all().join().get(0).getInt());
-//        assertEquals(0, client.submit("subtract(1,1)").all().join().get(0).getInt());
-//
-//        final Map<String, Object> bindings = new HashMap<>();
-//        bindings.put(GremlinGroovyScriptEngine.KEY_REFERENCE_TYPE, GremlinGroovyScriptEngine.REFERENCE_TYPE_PHANTOM);
-//        assertEquals(4, client.submit("def multiply(x,y){x*y};multiply(2,2)", bindings).all().join().get(0).getInt());
-//
-//        try {
-//            client.submit("multiply(2,2)").all().join().get(0).getInt();
-//            fail("Should throw an exception since reference is phantom.");
-//        } catch (RuntimeException ignored) {
-//
-//        } finally {
-//            cluster.close();
-//        }
-//    }
-//
-//    @Test
-//    public void shouldReceiveFailureOnBadGraphSONSerialization() throws Exception {
-//        final Cluster cluster = TestClientFactory.build().serializer(Serializers.GRAPHSON_V3D0).create();
-//        final Client client = cluster.connect();
-//
-//        try {
-//            client.submit("def class C { def C getC(){return this}}; new C()").all().join();
-//            fail("Should throw an exception.");
-//        } catch (RuntimeException re) {
-//            final Throwable root = ExceptionUtils.getRootCause(re);
-//            assertThat(root.getMessage(), CoreMatchers.startsWith("Error during serialization: Direct self-reference leading to cycle (through reference chain:"));
-//
-//            // validate that we can still send messages to the server
-//            assertEquals(2, client.submit("1+1").all().join().get(0).getInt());
-//        } finally {
-//            cluster.close();
-//        }
-//    }
-//
-//    @Test
-//    public void shouldReceiveFailureOnBadGryoSerialization() throws Exception {
-//        final Cluster cluster = TestClientFactory.build().serializer(Serializers.GRYO_V1D0).create();
-//        final Client client = cluster.connect();
-//
-//        try {
-//            client.submit("java.awt.Color.RED").all().join();
-//            fail("Should throw an exception.");
-//        } catch (RuntimeException re) {
-//            final Throwable root = ExceptionUtils.getRootCause(re);
-//            assertThat(root.getMessage(), CoreMatchers.startsWith("Error during serialization: Class is not registered: java.awt.Color"));
-//
-//            // validate that we can still send messages to the server
-//            assertEquals(2, client.submit("1+1").all().join().get(0).getInt());
-//        } finally {
-//            cluster.close();
-//        }
-//    }
-//
+    @Test
+    public void shouldScriptEvaluationErrorForRemoteTraversal() throws Exception {
+        final GraphTraversalSource g = traversal().withRemote(conf);
+
+        try {
+            // tests bad lambda
+            g.inject(1).sideEffect(Lambda.consumer("(")).iterate();
+            fail("This traversal should not have executed since lambda can't be compiled");
+        } catch (Exception ex) {
+            final Throwable t = ex.getCause();
+            assertThat(t, instanceOf(ResponseException.class));
+            assertEquals(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION, ((ResponseException) t).getResponseStatusCode());
+        }
+
+        // make a graph with a cycle in it to force a long run traversal
+        graphGetter.get().traversal().addV("person").as("p").addE("self").to("p").iterate();
+
+        try {
+            // tests an "unending" traversal
+            g.V().repeat(__.out()).until(__.outE().count().is(0)).iterate();
+            fail("This traversal should have timed out");
+        } catch (Exception ex) {
+            final Throwable t = ex.getCause();
+            assertThat(t, instanceOf(ResponseException.class));
+            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
+        }
+    }
+
+    @Test
+    public void shouldCloseChannelIfClientDoesntRespond() throws Exception {
+        final SimpleClient client = TestClientFactory.createWebSocketClient();
+        client.submit("1+1");
+
+        // since we do nothing for 2 seconds and the time limit for timeout on the server is 1 second, the server
+        // will autoclose the channel
+        Thread.sleep(2000);
+
+        assertThat(recordingAppender.logContainsAny(".*Closing channel - client is disconnected after idle period of .*$"), is(true));
+
+        client.close();
+    }
+
+    @Test
+    public void shouldPingChannelIfClientDies() throws Exception {
+        final Client client = TestClientFactory.build().maxConnectionPoolSize(1).minConnectionPoolSize(1).keepAliveInterval(0).create().connect();
+        client.submit("1+1").all().get();
+
+        // since we do nothing for 3 seconds and the time limit for ping is 1 second we should get *about* 3 pings -
+        // i don't think the assertion needs to be too accurate. just need to make sure there's a ping message out
+        // there record
+        Thread.sleep(3000);
+
+        client.close();
+
+        // stop the server to be sure that logs flush
+        stopServer();
+
+        assertThat(recordingAppender.logContainsAny(".*Checking channel - sending ping to client after idle period of .*$"), is(true));
+    }
+
+    @Test
+    public void shouldTimeOutRemoteTraversal() throws Exception {
+        final GraphTraversalSource g = traversal().withRemote(conf);
+
+        try {
+            // tests sleeping thread
+            g.inject(1).sideEffect(Lambda.consumer("Thread.sleep(10000)")).iterate();
+            fail("This traversal should have timed out");
+        } catch (Exception ex) {
+            final Throwable t = ex.getCause();
+            assertThat(t, instanceOf(ResponseException.class));
+            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
+        }
+
+        // make a graph with a cycle in it to force a long run traversal
+        graphGetter.get().traversal().addV("person").as("p").addE("self").to("p").iterate();
+
+        try {
+            // tests an "unending" traversal
+            g.V().repeat(__.out()).until(__.outE().count().is(0)).iterate();
+            fail("This traversal should have timed out");
+        } catch (Exception ex) {
+            final Throwable t = ex.getCause();
+            assertThat(t, instanceOf(ResponseException.class));
+            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
+        }
+    }
+
+    @Test
+    public void shouldTimeOutRemoteTraversalUsingDeprecatedConfiguration() throws Exception {
+        final GraphTraversalSource g = traversal().withRemote(conf);
+
+        try {
+            // tests sleeping thread
+            g.inject(1).sideEffect(Lambda.consumer("Thread.sleep(10000)")).iterate();
+            fail("This traversal should have timed out");
+        } catch (Exception ex) {
+            final Throwable t = ex.getCause();
+            assertThat(t, instanceOf(ResponseException.class));
+            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
+        }
+
+        // make a graph with a cycle in it to force a long run traversal
+        graphGetter.get().traversal().addV("person").as("p").addE("self").to("p").iterate();
+
+        try {
+            // tests an "unending" traversal
+            g.V().repeat(__.out()).until(__.outE().count().is(0)).iterate();
+            fail("This traversal should have timed out");
+        } catch (Exception ex) {
+            final Throwable t = ex.getCause();
+            assertThat(t, instanceOf(ResponseException.class));
+            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
+        }
+    }
+
+    @Test
+    public void shouldTimeOutRemoteTraversalWithPerRequestOption() {
+        final GraphTraversalSource g = traversal().withRemote(conf);
+
+        try {
+            // tests sleeping thread
+            g.with(ARGS_SCRIPT_EVAL_TIMEOUT, 500L).inject(1).sideEffect(Lambda.consumer("Thread.sleep(10000)")).iterate();
+            fail("This traversal should have timed out");
+        } catch (Exception ex) {
+            final Throwable t = ex.getCause();
+            assertThat(t, instanceOf(ResponseException.class));
+            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
+        }
+
+        // make a graph with a cycle in it to force a long run traversal
+        graphGetter.get().traversal().addV("person").as("p").addE("self").to("p").iterate();
+
+        try {
+            // tests an "unending" traversal
+            g.with(ARGS_SCRIPT_EVAL_TIMEOUT, 500L).V().repeat(__.out()).until(__.outE().count().is(0)).iterate();
+            fail("This traversal should have timed out");
+        } catch (Exception ex) {
+            final Throwable t = ex.getCause();
+            assertThat(t, instanceOf(ResponseException.class));
+            assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
+        }
+    }
+
+    @Test
+    public void shouldProduceProperExceptionOnTimeout() throws Exception {
+        final Cluster cluster = TestClientFactory.open();
+        final Client client = cluster.connect(name.getMethodName());
+
+        boolean success = false;
+        // Run a short test script a few times with progressively longer timeouts.
+        // Each submissions should either succeed or fail with a timeout.
+        // Note: the range of timeouts is intended to cover the case when the script finishes at about the
+        // same time when the timeout occurs. In this situation either a timeout response or a successful
+        // response is acceptable, however no other processing errors should occur.
+        // Note: the timeout of 30 ms is generally sufficient for running a simple groovy script, so using longer
+        // timeouts are not likely to results in a success/timeout response collision, which is the purpose
+        // of this test.
+        // Note: this test may have a false negative result, but a failure  would indicate a real problem.
+        for(int i = 0; i < 30; i++) {
+            int timeout = 1 + i;
+            overrideEvaluationTimeout(timeout);
+
+            try {
+                client.submit("x = 1 + 1").all().get().get(0).getInt();
+                success = true;
+            } catch (Exception ex) {
+                final Throwable t = ex.getCause();
+                assertThat("Unexpected exception with script evaluation timeout: " + timeout, t, instanceOf(ResponseException.class));
+                assertEquals(ResponseStatusCode.SERVER_ERROR_TIMEOUT, ((ResponseException) t).getResponseStatusCode());
+            }
+        }
+
+        assertTrue("Some script submissions should succeed", success);
+
+        cluster.close();
+    }
+
+    @Test
+    public void shouldUseBaseScript() throws Exception {
+        final Cluster cluster = TestClientFactory.open();
+        final Client client = cluster.connect(name.getMethodName());
+
+        assertEquals("hello, stephen", client.submit("hello('stephen')").all().get().get(0).getString());
+
+        cluster.close();
+    }
+
+    @Test
+    public void shouldUseInterpreterMode() throws Exception {
+        final Cluster cluster = TestClientFactory.open();
+        final Client client = cluster.connect(name.getMethodName());
+
+        client.submit("def subtractAway(x,y){x-y};[]").all().get();
+        client.submit("multiplyIt = { x,y -> x * y};[]").all().get();
+
+        assertEquals(2, client.submit("x = 1 + 1").all().get().get(0).getInt());
+        assertEquals(3, client.submit("int y = x + 1").all().get().get(0).getInt());
+        assertEquals(5, client.submit("def z = x + y").all().get().get(0).getInt());
+
+        final Map<String,Object> m = new HashMap<>();
+        m.put("x", 10);
+        assertEquals(-5, client.submit("z - x", m).all().get().get(0).getInt());
+        assertEquals(15, client.submit("addItUp(x,z)", m).all().get().get(0).getInt());
+        assertEquals(5, client.submit("subtractAway(x,z)", m).all().get().get(0).getInt());
+        assertEquals(50, client.submit("multiplyIt(x,z)", m).all().get().get(0).getInt());
+
+        cluster.close();
+    }
+
+    @Test
+    public void shouldNotUseInterpreterMode() throws Exception {
+        final Cluster cluster = TestClientFactory.open();
+        final Client client = cluster.connect(name.getMethodName());
+
+        client.submit("def subtractAway(x,y){x-y};[]").all().get();
+        client.submit("multiplyIt = { x,y -> x * y};[]").all().get();
+
+        assertEquals(2, client.submit("x = 1 + 1").all().get().get(0).getInt());
+        assertEquals(3, client.submit("y = x + 1").all().get().get(0).getInt());
+        assertEquals(5, client.submit("z = x + y").all().get().get(0).getInt());
+
+        final Map<String,Object> m = new HashMap<>();
+        m.put("x", 10);
+        assertEquals(-5, client.submit("z - x", m).all().get().get(0).getInt());
+        assertEquals(15, client.submit("addItUp(x,z)", m).all().get().get(0).getInt());
+        assertEquals(5, client.submit("subtractAway(x,z)", m).all().get().get(0).getInt());
+        assertEquals(50, client.submit("multiplyIt(x,z)", m).all().get().get(0).getInt());
+
+        cluster.close();
+    }
+
+    @Test
+    public void shouldUseSimpleSandbox() throws Exception {
+        final Cluster cluster = TestClientFactory.open();
+        final Client client = cluster.connect();
+
+        assertEquals(2, client.submit("1+1").all().get().get(0).getInt());
+
+        try {
+            // this should return "nothing" - there should be no exception
+            client.submit("java.lang.System.exit(0)").all().get();
+            fail("The above should not have executed in any successful way as sandboxing is enabled");
+        } catch (Exception ex) {
+            assertThat(ex.getCause().getMessage(), containsString("[Static type checking] - Not authorized to call this method: java.lang.System#exit(int)"));
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldRespectHighWaterMarkSettingAndSucceed() throws Exception {
+        // the highwatermark should get exceeded on the server and thus pause the writes, but have no problem catching
+        // itself up - this is a tricky tests to get passing on all environments so this assumption will deny the
+        // test for most cases
+        TestHelper.assumeNonDeterministic();
+
+        final Cluster cluster = TestClientFactory.open();
+        final Client client = cluster.connect();
+
+        try {
+            final int resultCountToGenerate = 1000;
+            final int batchSize = 3;
+            final String fatty = IntStream.range(0, 175).mapToObj(String::valueOf).collect(Collectors.joining());
+            final String fattyX = "['" + fatty + "'] * " + resultCountToGenerate;
+
+            // don't allow the thread to proceed until all results are accounted for
+            final CountDownLatch latch = new CountDownLatch(resultCountToGenerate);
+            final AtomicBoolean expected = new AtomicBoolean(false);
+            final AtomicBoolean faulty = new AtomicBoolean(false);
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+                    .addArg(Tokens.ARGS_BATCH_SIZE, batchSize)
+                    .addArg(Tokens.ARGS_GREMLIN, fattyX).create();
+
+            client.submitAsync(request).thenAcceptAsync(r -> {
+                r.stream().forEach(item -> {
+                    try {
+                        final String aFattyResult = item.getString();
+                        expected.set(aFattyResult.equals(fatty));
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                        faulty.set(true);
+                    } finally {
+                        latch.countDown();
+                    }
+                });
+            });
+
+            assertThat(latch.await(30000, TimeUnit.MILLISECONDS), is(true));
+            assertEquals(0, latch.getCount());
+            assertThat(faulty.get(), is(false));
+            assertThat(expected.get(), is(true));
+
+            assertThat(recordingAppender.getMessages().stream().anyMatch(m -> m.contains("Pausing response writing as writeBufferHighWaterMark exceeded on")), is(true));
+        } catch (Exception ex) {
+            fail("Shouldn't have tossed an exception");
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldReturnInvalidRequestArgsWhenGremlinArgIsNotSupplied() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL).create();
+            final ResponseMessage result = client.submit(request).get(0);
+            assertThat(result.getStatus().getCode(), is(not(ResponseStatusCode.PARTIAL_CONTENT)));
+            assertEquals(result.getStatus().getCode(), ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS);
+        }
+    }
+
+    @Test
+    public void shouldReturnInvalidRequestArgsWhenInvalidReservedBindingKeyIsUsed() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final Map<String, Object> bindings = new HashMap<>();
+            bindings.put(T.id.getAccessor(), "123");
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+                    .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
+                    .addArg(Tokens.ARGS_BINDINGS, bindings).create();
+            final CountDownLatch latch = new CountDownLatch(1);
+            final AtomicBoolean pass = new AtomicBoolean(false);
+            client.submit(request, result -> {
+                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
+                    pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
+                    latch.countDown();
+                }
+            });
+
+            if (!latch.await(3000, TimeUnit.MILLISECONDS))
+                fail("Request should have returned error, but instead timed out");
+            assertThat(pass.get(), is(true));
+        }
+
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final Map<String, Object> bindings = new HashMap<>();
+            bindings.put("id", "123");
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+                    .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
+                    .addArg(Tokens.ARGS_BINDINGS, bindings).create();
+            final CountDownLatch latch = new CountDownLatch(1);
+            final AtomicBoolean pass = new AtomicBoolean(false);
+            client.submit(request, result -> {
+                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
+                    pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
+                    latch.countDown();
+                }
+            });
+
+            if (!latch.await(3000, TimeUnit.MILLISECONDS))
+                fail("Request should have returned error, but instead timed out");
+            assertTrue(pass.get());
+        }
+    }
+
+    @Test
+    public void shouldReturnInvalidRequestArgsWhenInvalidTypeBindingKeyIsUsed() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final Map<Object, Object> bindings = new HashMap<>();
+            bindings.put(1, "123");
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+                    .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
+                    .addArg(Tokens.ARGS_BINDINGS, bindings).create();
+            final CountDownLatch latch = new CountDownLatch(1);
+            final AtomicBoolean pass = new AtomicBoolean(false);
+            client.submit(request, result -> {
+                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
+                    pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
+                    latch.countDown();
+                }
+            });
+
+            if (!latch.await(3000, TimeUnit.MILLISECONDS))
+                fail("Request should have returned error, but instead timed out");
+            assertThat(pass.get(), is(true));
+        }
+    }
+
+    @Test
+    public void shouldReturnInvalidRequestArgsWhenBindingCountExceedsAllowable() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final Map<Object, Object> bindings = new HashMap<>();
+            bindings.put("x", 123);
+            bindings.put("y", 123);
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+                    .addArg(Tokens.ARGS_GREMLIN, "x+y")
+                    .addArg(Tokens.ARGS_BINDINGS, bindings).create();
+            final CountDownLatch latch = new CountDownLatch(1);
+            final AtomicBoolean pass = new AtomicBoolean(false);
+            client.submit(request, result -> {
+                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
+                    pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
+                    latch.countDown();
+                }
+            });
+
+            if (!latch.await(3000, TimeUnit.MILLISECONDS))
+                fail("Request should have returned error, but instead timed out");
+            assertThat(pass.get(), is(true));
+        }
+
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final Map<Object, Object> bindings = new HashMap<>();
+            bindings.put("x", 123);
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+                    .addArg(Tokens.ARGS_GREMLIN, "x+123")
+                    .addArg(Tokens.ARGS_BINDINGS, bindings).create();
+            final CountDownLatch latch = new CountDownLatch(1);
+            final AtomicBoolean pass = new AtomicBoolean(false);
+            client.submit(request, result -> {
+                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
+                    pass.set(ResponseStatusCode.SUCCESS == result.getStatus().getCode() && (((int) ((List) result.getResult().getData()).get(0) == 246)));
+                    latch.countDown();
+                }
+            });
+
+            if (!latch.await(3000, TimeUnit.MILLISECONDS))
+                fail("Request should have returned error, but instead timed out");
+            assertThat(pass.get(), is(true));
+        }
+    }
+
+    @Test
+    public void shouldReturnInvalidRequestArgsWhenInvalidNullBindingKeyIsUsed() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final Map<String, Object> bindings = new HashMap<>();
+            bindings.put(null, "123");
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+                    .addArg(Tokens.ARGS_GREMLIN, "[1,2,3,4,5,6,7,8,9,0]")
+                    .addArg(Tokens.ARGS_BINDINGS, bindings).create();
+            final CountDownLatch latch = new CountDownLatch(1);
+            final AtomicBoolean pass = new AtomicBoolean(false);
+            client.submit(request, result -> {
+                if (result.getStatus().getCode() != ResponseStatusCode.PARTIAL_CONTENT) {
+                    pass.set(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS == result.getStatus().getCode());
+                    latch.countDown();
+                }
+            });
+
+            if (!latch.await(3000, TimeUnit.MILLISECONDS))
+                fail("Request should have returned error, but instead timed out");
+            assertThat(pass.get(), is(true));
+        }
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void shouldBatchResultsByTwos() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+                    .addArg(Tokens.ARGS_GREMLIN, "[0,1,2,3,4,5,6,7,8,9]").create();
+
+            final List<ResponseMessage> msgs = client.submit(request);
+            assertEquals(5, client.submit(request).size());
+            assertEquals(0, ((List<Integer>) msgs.get(0).getResult().getData()).get(0).intValue());
+            assertEquals(1, ((List<Integer>) msgs.get(0).getResult().getData()).get(1).intValue());
+            assertEquals(2, ((List<Integer>) msgs.get(1).getResult().getData()).get(0).intValue());
+            assertEquals(3, ((List<Integer>) msgs.get(1).getResult().getData()).get(1).intValue());
+            assertEquals(4, ((List<Integer>) msgs.get(2).getResult().getData()).get(0).intValue());
+            assertEquals(5, ((List<Integer>) msgs.get(2).getResult().getData()).get(1).intValue());
+            assertEquals(6, ((List<Integer>) msgs.get(3).getResult().getData()).get(0).intValue());
+            assertEquals(7, ((List<Integer>) msgs.get(3).getResult().getData()).get(1).intValue());
+            assertEquals(8, ((List<Integer>) msgs.get(4).getResult().getData()).get(0).intValue());
+            assertEquals(9, ((List<Integer>) msgs.get(4).getResult().getData()).get(1).intValue());
+        }
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void shouldBatchResultsByOnesByOverridingFromClientSide() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+                    .addArg(Tokens.ARGS_GREMLIN, "[0,1,2,3,4,5,6,7,8,9]")
+                    .addArg(Tokens.ARGS_BATCH_SIZE, 1).create();
+
+            final List<ResponseMessage> msgs = client.submit(request);
+            assertEquals(10, msgs.size());
+            IntStream.rangeClosed(0, 9).forEach(i -> assertEquals(i, ((List<Integer>) msgs.get(i).getResult().getData()).get(0).intValue()));
+        }
+    }
+
+    @Test
+    public void shouldNotThrowNoSuchElementException() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()){
+            // this should return "nothing" - there should be no exception
+            final List<ResponseMessage> responses = client.submit("g.V().has('name','kadfjaldjfla')");
+            assertNull(responses.get(0).getResult().getData());
+        }
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void shouldReceiveFailureTimeOutOnScriptEval() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()){
+            final List<ResponseMessage> responses = client.submit("Thread.sleep(3000);'some-stuff-that-should not return'");
+            assertThat(responses.get(0).getStatus().getMessage(), startsWith("Evaluation exceeded the configured 'evaluationTimeout' threshold of 1000 ms"));
+
+            // validate that we can still send messages to the server
+            assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
+        }
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void shouldReceiveFailureTimeOutOnScriptEvalUsingOverride() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final RequestMessage msg = RequestMessage.build("eval")
+                    .addArg(ARGS_SCRIPT_EVAL_TIMEOUT, 100L)
+                    .addArg(Tokens.ARGS_GREMLIN, "Thread.sleep(3000);'some-stuff-that-should not return'")
+                    .create();
+            final List<ResponseMessage> responses = client.submit(msg);
+            assertThat(responses.get(0).getStatus().getMessage(), startsWith("Evaluation exceeded the configured 'evaluationTimeout' threshold of 100 ms"));
+
+            // validate that we can still send messages to the server
+            assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
+        }
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void shouldReceiveFailureTimeOutOnEvalUsingOverride() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final RequestMessage msg = RequestMessage.build("eval")
+                    .addArg(Tokens.ARGS_EVAL_TIMEOUT, 100L)
+                    .addArg(Tokens.ARGS_GREMLIN, "Thread.sleep(3000);'some-stuff-that-should not return'")
+                    .create();
+            final List<ResponseMessage> responses = client.submit(msg);
+            assertThat(responses.get(0).getStatus().getMessage(), startsWith("Evaluation exceeded the configured 'evaluationTimeout' threshold of 100 ms"));
+
+            // validate that we can still send messages to the server
+            assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
+        }
+    }
+
+    @Test
+    public void shouldReceiveFailureTimeOutOnScriptEvalOfOutOfControlLoop() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()){
+            // timeout configured for 1 second so the timed interrupt should trigger prior to the
+            // evaluationTimeout which is at 30 seconds by default
+            final List<ResponseMessage> responses = client.submit("while(true){}");
+            assertThat(responses.get(0).getStatus().getMessage(), startsWith("Timeout during script evaluation triggered by TimedInterruptCustomizerProvider"));
+
+            // validate that we can still send messages to the server
+            assertEquals(2, ((List<Integer>) client.submit("1+1").get(0).getResult().getData()).get(0).intValue());
+        }
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void shouldLoadInitScript() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()){
+            assertEquals(2, ((List<Integer>) client.submit("addItUp(1,1)").get(0).getResult().getData()).get(0).intValue());
+        }
+    }
+
+    @Test
+    public void shouldGarbageCollectPhantomButNotHard() throws Exception {
+        final Cluster cluster = TestClientFactory.open();
+        final Client client = cluster.connect();
+
+        assertEquals(2, client.submit("addItUp(1,1)").all().join().get(0).getInt());
+        assertEquals(0, client.submit("def subtract(x,y){x-y};subtract(1,1)").all().join().get(0).getInt());
+        assertEquals(0, client.submit("subtract(1,1)").all().join().get(0).getInt());
+
+        final Map<String, Object> bindings = new HashMap<>();
+        bindings.put(GremlinGroovyScriptEngine.KEY_REFERENCE_TYPE, GremlinGroovyScriptEngine.REFERENCE_TYPE_PHANTOM);
+        assertEquals(4, client.submit("def multiply(x,y){x*y};multiply(2,2)", bindings).all().join().get(0).getInt());
+
+        try {
+            client.submit("multiply(2,2)").all().join().get(0).getInt();
+            fail("Should throw an exception since reference is phantom.");
+        } catch (RuntimeException ignored) {
+
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldReceiveFailureOnBadGraphSONSerialization() throws Exception {
+        final Cluster cluster = TestClientFactory.build().serializer(Serializers.GRAPHSON_V3D0).create();
+        final Client client = cluster.connect();
+
+        try {
+            client.submit("def class C { def C getC(){return this}}; new C()").all().join();
+            fail("Should throw an exception.");
+        } catch (RuntimeException re) {
+            final Throwable root = ExceptionUtils.getRootCause(re);
+            assertThat(root.getMessage(), CoreMatchers.startsWith("Error during serialization: Direct self-reference leading to cycle (through reference chain:"));
+
+            // validate that we can still send messages to the server
+            assertEquals(2, client.submit("1+1").all().join().get(0).getInt());
+        } finally {
+            cluster.close();
+        }
+    }
+
+    @Test
+    public void shouldReceiveFailureOnBadGryoSerialization() throws Exception {
+        final Cluster cluster = TestClientFactory.build().serializer(Serializers.GRYO_V1D0).create();
+        final Client client = cluster.connect();
+
+        try {
+            client.submit("java.awt.Color.RED").all().join();
+            fail("Should throw an exception.");
+        } catch (RuntimeException re) {
+            final Throwable root = ExceptionUtils.getRootCause(re);
+            assertThat(root.getMessage(), CoreMatchers.startsWith("Error during serialization: Class is not registered: java.awt.Color"));
+
+            // validate that we can still send messages to the server
+            assertEquals(2, client.submit("1+1").all().join().get(0).getInt());
+        } finally {
+            cluster.close();
+        }
+    }
+
     @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
     @Test
     public void shouldBlockRequestWhenTooBig() throws Exception {
@@ -941,258 +941,258 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration
             assertEquals(ResponseStatusCode.SUCCESS, responses.get(0).getStatus().getCode());
         }
     }
-//
-//    @Test
-//    public void shouldHavePartialContentWithLongResultsCollection() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
-//                    .addArg(Tokens.ARGS_GREMLIN, "new String[100]").create();
-//            final List<ResponseMessage> responses = client.submit(request);
-//            assertThat(responses.size(), Matchers.greaterThan(1));
-//            for (Iterator<ResponseMessage> it = responses.iterator(); it.hasNext(); ) {
-//                final ResponseMessage msg = it.next();
-//                final ResponseStatusCode expected = it.hasNext() ? ResponseStatusCode.PARTIAL_CONTENT : ResponseStatusCode.SUCCESS;
-//                assertEquals(expected, msg.getStatus().getCode());
-//            }
-//        }
-//    }
-//
-//    @Test
-//    public void shouldFailWithBadScriptEval() throws Exception {
-//        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
-//            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
-//                    .addArg(Tokens.ARGS_GREMLIN, "new String().doNothingAtAllBecauseThis is a syntax error").create();
-//            final List<ResponseMessage> responses = client.submit(request);
-//            assertEquals(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION, responses.get(0).getStatus().getCode());
-//            assertEquals(1, responses.size());
-//        }
-//    }
-//
-//    @Test
-//    public void shouldSupportLambdasUsingWithRemote() throws Exception {
-//        final GraphTraversalSource g = traversal().withRemote(conf);
-//        g.addV("person").property("age", 20).iterate();
-//        g.addV("person").property("age", 10).iterate();
-//        assertEquals(50L, g.V().hasLabel("person").map(Lambda.function("it.get().value('age') + 10")).sum().next());
-//    }
-//
-//    @Test
-//    public void shouldGetSideEffectKeysAndStatusUsingWithRemote() throws Exception {
-//        final GraphTraversalSource g = traversal().withRemote(conf);
-//        g.addV("person").property("age", 20).iterate();
-//        g.addV("person").property("age", 10).iterate();
-//        final GraphTraversal traversal = g.V().aggregate("a").aggregate("b");
-//        traversal.iterate();
-//        final DriverRemoteTraversalSideEffects se = (DriverRemoteTraversalSideEffects) traversal.asAdmin().getSideEffects();
-//        assertThat(se.statusAttributes().containsKey(Tokens.ARGS_HOST), is(true));
-//
-//        // Get keys
-//        final Set<String> sideEffectKeys = se.keys();
-//        assertEquals(2, sideEffectKeys.size());
-//
-//        // Get side effects
-//        final BulkSet aSideEffects = se.get("a");
-//        assertThat(aSideEffects.isEmpty(), is(false));
-//        final BulkSet bSideEffects = se.get("b");
-//        assertThat(bSideEffects.isEmpty(), is(false));
-//
-//        // Should get local keys/side effects after close
-//        se.close();
-//
-//        final Set<String> localSideEffectKeys = se.keys();
-//        assertEquals(2, localSideEffectKeys.size());
-//
-//        final BulkSet localASideEffects = se.get("a");
-//        assertThat(localASideEffects.isEmpty(), is(false));
-//
-//        final BulkSet localBSideEffects = se.get("b");
-//        assertThat(localBSideEffects.isEmpty(), is(false));
-//
-//        final GraphTraversal gdotv = g.V();
-//        gdotv.toList();
-//        final DriverRemoteTraversalSideEffects gdotvSe = (DriverRemoteTraversalSideEffects) gdotv.asAdmin().getSideEffects();
-//        assertThat(gdotvSe.statusAttributes().containsKey(Tokens.ARGS_HOST), is(true));
-//    }
-//
-//    @Test
-//    public void shouldCloseSideEffectsUsingWithRemote() throws Exception {
-//        final GraphTraversalSource g = traversal().withRemote(conf);
-//        g.addV("person").property("age", 20).iterate();
-//        g.addV("person").property("age", 10).iterate();
-//        final GraphTraversal traversal = g.V().aggregate("a").aggregate("b");
-//        traversal.iterate();
-//        final DriverRemoteTraversalSideEffects se = (DriverRemoteTraversalSideEffects) traversal.asAdmin().getSideEffects();
-//        final BulkSet sideEffects = se.get("a");
-//        assertThat(sideEffects.isEmpty(), is(false));
-//        se.close();
-//
-//        // Can't get new side effects after close
-//        try {
-//            se.get("b");
-//            fail("The traversal is closed");
-//        } catch (Exception ex) {
-//            assertThat(ex, instanceOf(IllegalStateException.class));
-//            assertEquals("Traversal has been closed - no new side-effects can be retrieved", ex.getMessage());
-//        }
-//
-//        // Earlier keys should be cached locally
-//        final Set<String> localSideEffectKeys = se.keys();
-//        assertEquals(2, localSideEffectKeys.size());
-//        final BulkSet localSideEffects = se.get("a");
-//        assertThat(localSideEffects.isEmpty(), is(false));
-//
-//        // Try to get side effect from server
-//        final Cluster cluster = TestClientFactory.open();
-//        final Client client = cluster.connect();
-//        final Field field = DriverRemoteTraversalSideEffects.class.getDeclaredField("serverSideEffect");
-//        field.setAccessible(true);
-//        final UUID serverSideEffectId = (UUID) field.get(se);
-//        final Map<String, String> aliases = new HashMap<>();
-//        aliases.put("g", "g");
-//        final RequestMessage msg = RequestMessage.build(Tokens.OPS_GATHER)
-//                .addArg(Tokens.ARGS_SIDE_EFFECT, serverSideEffectId)
-//                .addArg(Tokens.ARGS_SIDE_EFFECT_KEY, "b")
-//                .addArg(Tokens.ARGS_ALIASES, aliases)
-//                .processor("traversal").create();
-//        boolean error;
-//        try {
-//            client.submitAsync(msg).get().one();
-//            error = false;
-//        } catch (Exception ex) {
-//            error = true;
-//        }
-//        assertThat(error, is(true));
-//    }
-//
-//    @Test
-//    public void shouldBlockWhenGettingSideEffectKeysUsingWithRemote() throws Exception {
-//        final GraphTraversalSource g = traversal().withRemote(conf);
-//        g.addV("person").property("age", 20).iterate();
-//        g.addV("person").property("age", 10).iterate();
-//        final GraphTraversal traversal = g.V().aggregate("a")
-//                .sideEffect(Lambda.consumer("{Thread.sleep(3000)}"))
-//                .aggregate("b");
-//
-//        // force strategy application - if this doesn't happen then getSideEffects() returns DefaultTraversalSideEffects
-//        traversal.hasNext();
-//
-//        // start a separate thread to iterate
-//        final Thread t = new Thread(traversal::iterate);
-//        t.start();
-//
-//        // blocks here until traversal iteration is complete
-//        final DriverRemoteTraversalSideEffects se = (DriverRemoteTraversalSideEffects) traversal.asAdmin().getSideEffects();
-//
-//        // Get keys
-//        final Set<String> sideEffectKeys = se.keys();
-//        assertEquals(2, sideEffectKeys.size());
-//
-//        // Get side effects
-//        final BulkSet aSideEffects = se.get("a");
-//        assertThat(aSideEffects.isEmpty(), is(false));
-//        final BulkSet bSideEffects = se.get("b");
-//        assertThat(bSideEffects.isEmpty(), is(false));
-//
-//        // Should get local keys/side effects after close
-//        se.close();
-//
-//        final Set<String> localSideEffectKeys = se.keys();
-//        assertEquals(2, localSideEffectKeys.size());
-//
-//        final BulkSet localASideEffects = se.get("a");
-//        assertThat(localASideEffects.isEmpty(), is(false));
-//
-//        final BulkSet localBSideEffects = se.get("b");
-//        assertThat(localBSideEffects.isEmpty(), is(false));
-//    }
-//
-//    @Test
-//    public void shouldBlockWhenGettingSideEffectValuesUsingWithRemote() throws Exception {
-//        final GraphTraversalSource g = traversal().withRemote(conf);
-//        g.addV("person").property("age", 20).iterate();
-//        g.addV("person").property("age", 10).iterate();
-//        final GraphTraversal traversal = g.V().aggregate("a")
-//                .sideEffect(Lambda.consumer("{Thread.sleep(3000)}"))
-//                .aggregate("b");
-//
-//        // force strategy application - if this doesn't happen then getSideEffects() returns DefaultTraversalSideEffects
-//        traversal.hasNext();
-//
-//        // start a separate thread to iterate
-//        final Thread t = new Thread(traversal::iterate);
-//        t.start();
-//
-//        // blocks here until traversal iteration is complete
-//        final DriverRemoteTraversalSideEffects se = (DriverRemoteTraversalSideEffects) traversal.asAdmin().getSideEffects();
-//
-//        // Get side effects
-//        final BulkSet aSideEffects = se.get("a");
-//        assertThat(aSideEffects.isEmpty(), is(false));
-//        final BulkSet bSideEffects = se.get("b");
-//        assertThat(bSideEffects.isEmpty(), is(false));
-//
-//        // Get keys
-//        final Set<String> sideEffectKeys = se.keys();
-//        assertEquals(2, sideEffectKeys.size());
-//
-//        // Should get local keys/side effects after close
-//        se.close();
-//
-//        final Set<String> localSideEffectKeys = se.keys();
-//        assertEquals(2, localSideEffectKeys.size());
-//
-//        final BulkSet localASideEffects = se.get("a");
-//        assertThat(localASideEffects.isEmpty(), is(false));
-//
-//        final BulkSet localBSideEffects = se.get("b");
-//        assertThat(localBSideEffects.isEmpty(), is(false));
-//    }
-//
-//    @Test
-//    public void shouldDoNonBlockingPromiseWithRemote() throws Exception {
-//        final GraphTraversalSource g = traversal().withRemote(conf);
-//        g.addV("person").property("age", 20).promise(Traversal::iterate).join();
-//        g.addV("person").property("age", 10).promise(Traversal::iterate).join();
-//        assertEquals(50L, g.V().hasLabel("person").map(Lambda.function("it.get().value('age') + 10")).sum().promise(t -> t.next()).join());
-//        g.addV("person").property("age", 20).promise(Traversal::iterate).join();
-//
-//        final Traversal<Vertex,Integer> traversal = g.V().hasLabel("person").has("age", 20).values("age");
-//        int age = traversal.promise(t -> t.next(1).get(0)).join();
-//        assertEquals(20, age);
-//        assertEquals(20, (int)traversal.next());
-//        assertThat(traversal.hasNext(), is(false));
-//
-//        final Traversal traversalCloned = g.V().hasLabel("person").has("age", 20).values("age");
-//        assertEquals(20, traversalCloned.next());
-//        assertEquals(20, traversalCloned.promise(t -> ((Traversal) t).next(1).get(0)).join());
-//        assertThat(traversalCloned.promise(t -> ((Traversal) t).hasNext()).join(), is(false));
-//
-//        assertEquals(3, g.V().promise(Traversal::toList).join().size());
-//    }
-//
-//    @Test
-//    public void shouldProvideBetterExceptionForMethodCodeTooLarge() {
-//        final int numberOfParameters = 4000;
-//        final Map<String,Object> b = new HashMap<>();
-//
-//        // generate a script with a ton of bindings usage to generate a "code too large" exception
-//        String script = "x = 0";
-//        for (int ix = 0; ix < numberOfParameters; ix++) {
-//            if (ix > 0 && ix % 100 == 0) {
-//                script = script + ";" + System.lineSeparator() + "x = x";
-//            }
-//            script = script + " + x" + ix;
-//            b.put("x" + ix, ix);
-//        }
-//
-//        final Cluster cluster = TestClientFactory.build().maxContentLength(4096000).create();
-//        final Client client = cluster.connect();
-//
-//        try {
-//            client.submit(script, b).all().get();
-//            fail("Should have tanked out because of number of parameters used and size of the compile script");
-//        } catch (Exception ex) {
-//            assertThat(ex.getMessage(), containsString("The Gremlin statement that was submitted exceeds the maximum compilation size allowed by the JVM"));
-//        }
-//    }
+
+    @Test
+    public void shouldHavePartialContentWithLongResultsCollection() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+                    .addArg(Tokens.ARGS_GREMLIN, "new String[100]").create();
+            final List<ResponseMessage> responses = client.submit(request);
+            assertThat(responses.size(), Matchers.greaterThan(1));
+            for (Iterator<ResponseMessage> it = responses.iterator(); it.hasNext(); ) {
+                final ResponseMessage msg = it.next();
+                final ResponseStatusCode expected = it.hasNext() ? ResponseStatusCode.PARTIAL_CONTENT : ResponseStatusCode.SUCCESS;
+                assertEquals(expected, msg.getStatus().getCode());
+            }
+        }
+    }
+
+    @Test
+    public void shouldFailWithBadScriptEval() throws Exception {
+        try (SimpleClient client = TestClientFactory.createWebSocketClient()) {
+            final RequestMessage request = RequestMessage.build(Tokens.OPS_EVAL)
+                    .addArg(Tokens.ARGS_GREMLIN, "new String().doNothingAtAllBecauseThis is a syntax error").create();
+            final List<ResponseMessage> responses = client.submit(request);
+            assertEquals(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION, responses.get(0).getStatus().getCode());
+            assertEquals(1, responses.size());
+        }
+    }
+
+    @Test
+    public void shouldSupportLambdasUsingWithRemote() throws Exception {
+        final GraphTraversalSource g = traversal().withRemote(conf);
+        g.addV("person").property("age", 20).iterate();
+        g.addV("person").property("age", 10).iterate();
+        assertEquals(50L, g.V().hasLabel("person").map(Lambda.function("it.get().value('age') + 10")).sum().next());
+    }
+
+    @Test
+    public void shouldGetSideEffectKeysAndStatusUsingWithRemote() throws Exception {
+        final GraphTraversalSource g = traversal().withRemote(conf);
+        g.addV("person").property("age", 20).iterate();
+        g.addV("person").property("age", 10).iterate();
+        final GraphTraversal traversal = g.V().aggregate("a").aggregate("b");
+        traversal.iterate();
+        final DriverRemoteTraversalSideEffects se = (DriverRemoteTraversalSideEffects) traversal.asAdmin().getSideEffects();
+        assertThat(se.statusAttributes().containsKey(Tokens.ARGS_HOST), is(true));
+
+        // Get keys
+        final Set<String> sideEffectKeys = se.keys();
+        assertEquals(2, sideEffectKeys.size());
+
+        // Get side effects
+        final BulkSet aSideEffects = se.get("a");
+        assertThat(aSideEffects.isEmpty(), is(false));
+        final BulkSet bSideEffects = se.get("b");
+        assertThat(bSideEffects.isEmpty(), is(false));
+
+        // Should get local keys/side effects after close
+        se.close();
+
+        final Set<String> localSideEffectKeys = se.keys();
+        assertEquals(2, localSideEffectKeys.size());
+
+        final BulkSet localASideEffects = se.get("a");
+        assertThat(localASideEffects.isEmpty(), is(false));
+
+        final BulkSet localBSideEffects = se.get("b");
+        assertThat(localBSideEffects.isEmpty(), is(false));
+
+        final GraphTraversal gdotv = g.V();
+        gdotv.toList();
+        final DriverRemoteTraversalSideEffects gdotvSe = (DriverRemoteTraversalSideEffects) gdotv.asAdmin().getSideEffects();
+        assertThat(gdotvSe.statusAttributes().containsKey(Tokens.ARGS_HOST), is(true));
+    }
+
+    @Test
+    public void shouldCloseSideEffectsUsingWithRemote() throws Exception {
+        final GraphTraversalSource g = traversal().withRemote(conf);
+        g.addV("person").property("age", 20).iterate();
+        g.addV("person").property("age", 10).iterate();
+        final GraphTraversal traversal = g.V().aggregate("a").aggregate("b");
+        traversal.iterate();
+        final DriverRemoteTraversalSideEffects se = (DriverRemoteTraversalSideEffects) traversal.asAdmin().getSideEffects();
+        final BulkSet sideEffects = se.get("a");
+        assertThat(sideEffects.isEmpty(), is(false));
+        se.close();
+
+        // Can't get new side effects after close
+        try {
+            se.get("b");
+            fail("The traversal is closed");
+        } catch (Exception ex) {
+            assertThat(ex, instanceOf(IllegalStateException.class));
+            assertEquals("Traversal has been closed - no new side-effects can be retrieved", ex.getMessage());
+        }
+
+        // Earlier keys should be cached locally
+        final Set<String> localSideEffectKeys = se.keys();
+        assertEquals(2, localSideEffectKeys.size());
+        final BulkSet localSideEffects = se.get("a");
+        assertThat(localSideEffects.isEmpty(), is(false));
+
+        // Try to get side effect from server
+        final Cluster cluster = TestClientFactory.open();
+        final Client client = cluster.connect();
+        final Field field = DriverRemoteTraversalSideEffects.class.getDeclaredField("serverSideEffect");
+        field.setAccessible(true);
+        final UUID serverSideEffectId = (UUID) field.get(se);
+        final Map<String, String> aliases = new HashMap<>();
+        aliases.put("g", "g");
+        final RequestMessage msg = RequestMessage.build(Tokens.OPS_GATHER)
+                .addArg(Tokens.ARGS_SIDE_EFFECT, serverSideEffectId)
+                .addArg(Tokens.ARGS_SIDE_EFFECT_KEY, "b")
+                .addArg(Tokens.ARGS_ALIASES, aliases)
+                .processor("traversal").create();
+        boolean error;
+        try {
+            client.submitAsync(msg).get().one();
+            error = false;
+        } catch (Exception ex) {
+            error = true;
+        }
+        assertThat(error, is(true));
+    }
+
+    @Test
+    public void shouldBlockWhenGettingSideEffectKeysUsingWithRemote() throws Exception {
+        final GraphTraversalSource g = traversal().withRemote(conf);
+        g.addV("person").property("age", 20).iterate();
+        g.addV("person").property("age", 10).iterate();
+        final GraphTraversal traversal = g.V().aggregate("a")
+                .sideEffect(Lambda.consumer("{Thread.sleep(3000)}"))
+                .aggregate("b");
+
+        // force strategy application - if this doesn't happen then getSideEffects() returns DefaultTraversalSideEffects
+        traversal.hasNext();
+
+        // start a separate thread to iterate
+        final Thread t = new Thread(traversal::iterate);
+        t.start();
+
+        // blocks here until traversal iteration is complete
+        final DriverRemoteTraversalSideEffects se = (DriverRemoteTraversalSideEffects) traversal.asAdmin().getSideEffects();
+
+        // Get keys
+        final Set<String> sideEffectKeys = se.keys();
+        assertEquals(2, sideEffectKeys.size());
+
+        // Get side effects
+        final BulkSet aSideEffects = se.get("a");
+        assertThat(aSideEffects.isEmpty(), is(false));
+        final BulkSet bSideEffects = se.get("b");
+        assertThat(bSideEffects.isEmpty(), is(false));
+
+        // Should get local keys/side effects after close
+        se.close();
+
+        final Set<String> localSideEffectKeys = se.keys();
+        assertEquals(2, localSideEffectKeys.size());
+
+        final BulkSet localASideEffects = se.get("a");
+        assertThat(localASideEffects.isEmpty(), is(false));
+
+        final BulkSet localBSideEffects = se.get("b");
+        assertThat(localBSideEffects.isEmpty(), is(false));
+    }
+
+    @Test
+    public void shouldBlockWhenGettingSideEffectValuesUsingWithRemote() throws Exception {
+        final GraphTraversalSource g = traversal().withRemote(conf);
+        g.addV("person").property("age", 20).iterate();
+        g.addV("person").property("age", 10).iterate();
+        final GraphTraversal traversal = g.V().aggregate("a")
+                .sideEffect(Lambda.consumer("{Thread.sleep(3000)}"))
+                .aggregate("b");
+
+        // force strategy application - if this doesn't happen then getSideEffects() returns DefaultTraversalSideEffects
+        traversal.hasNext();
+
+        // start a separate thread to iterate
+        final Thread t = new Thread(traversal::iterate);
+        t.start();
+
+        // blocks here until traversal iteration is complete
+        final DriverRemoteTraversalSideEffects se = (DriverRemoteTraversalSideEffects) traversal.asAdmin().getSideEffects();
+
+        // Get side effects
+        final BulkSet aSideEffects = se.get("a");
+        assertThat(aSideEffects.isEmpty(), is(false));
+        final BulkSet bSideEffects = se.get("b");
+        assertThat(bSideEffects.isEmpty(), is(false));
+
+        // Get keys
+        final Set<String> sideEffectKeys = se.keys();
+        assertEquals(2, sideEffectKeys.size());
+
+        // Should get local keys/side effects after close
+        se.close();
+
+        final Set<String> localSideEffectKeys = se.keys();
+        assertEquals(2, localSideEffectKeys.size());
+
+        final BulkSet localASideEffects = se.get("a");
+        assertThat(localASideEffects.isEmpty(), is(false));
+
+        final BulkSet localBSideEffects = se.get("b");
+        assertThat(localBSideEffects.isEmpty(), is(false));
+    }
+
+    @Test
+    public void shouldDoNonBlockingPromiseWithRemote() throws Exception {
+        final GraphTraversalSource g = traversal().withRemote(conf);
+        g.addV("person").property("age", 20).promise(Traversal::iterate).join();
+        g.addV("person").property("age", 10).promise(Traversal::iterate).join();
+        assertEquals(50L, g.V().hasLabel("person").map(Lambda.function("it.get().value('age') + 10")).sum().promise(t -> t.next()).join());
+        g.addV("person").property("age", 20).promise(Traversal::iterate).join();
+
+        final Traversal<Vertex,Integer> traversal = g.V().hasLabel("person").has("age", 20).values("age");
+        int age = traversal.promise(t -> t.next(1).get(0)).join();
+        assertEquals(20, age);
+        assertEquals(20, (int)traversal.next());
+        assertThat(traversal.hasNext(), is(false));
+
+        final Traversal traversalCloned = g.V().hasLabel("person").has("age", 20).values("age");
+        assertEquals(20, traversalCloned.next());
+        assertEquals(20, traversalCloned.promise(t -> ((Traversal) t).next(1).get(0)).join());
+        assertThat(traversalCloned.promise(t -> ((Traversal) t).hasNext()).join(), is(false));
+
+        assertEquals(3, g.V().promise(Traversal::toList).join().size());
+    }
+
+    @Test
+    public void shouldProvideBetterExceptionForMethodCodeTooLarge() {
+        final int numberOfParameters = 4000;
+        final Map<String,Object> b = new HashMap<>();
+
+        // generate a script with a ton of bindings usage to generate a "code too large" exception
+        String script = "x = 0";
+        for (int ix = 0; ix < numberOfParameters; ix++) {
+            if (ix > 0 && ix % 100 == 0) {
+                script = script + ";" + System.lineSeparator() + "x = x";
+            }
+            script = script + " + x" + ix;
+            b.put("x" + ix, ix);
+        }
+
+        final Cluster cluster = TestClientFactory.build().maxContentLength(4096000).create();
+        final Client client = cluster.connect();
+
+        try {
+            client.submit(script, b).all().get();
+            fail("Should have tanked out because of number of parameters used and size of the compile script");
+        } catch (Exception ex) {
+            assertThat(ex.getMessage(), containsString("The Gremlin statement that was submitted exceeds the maximum compilation size allowed by the JVM"));
+        }
+    }
 }