Repository: tinkerpop Updated Branches: refs/heads/TINKERPOP-1352 989977f67 -> 033a44d1a
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/033a44d1/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java index a5bdb2f..8515e8a 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java @@ -129,843 +129,843 @@ public class GremlinDriverIntegrateTest extends AbstractGremlinServerIntegration return settings; } -// @Test -// public void shouldEventuallySucceedAfterChannelLevelError() throws Exception { -// final Cluster cluster = Cluster.build().addContactPoint("localhost") -// .reconnectIntialDelay(500) -// .reconnectInterval(500) -// .maxContentLength(1024).create(); -// final Client client = cluster.connect(); -// -// try { -// client.submit("def x = '';(0..<1024).each{x = x + '$it'};x").all().get(); -// fail("Request should have failed because it exceeded the max content length allowed"); -// } catch (Exception ex) { -// final Throwable root = ExceptionUtils.getRootCause(ex); -// assertThat(root.getMessage(), containsString("Max frame length of 1024 has been exceeded.")); -// } -// -// assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldEventuallySucceedAfterMuchFailure() throws Exception { -// final Cluster cluster = Cluster.build().addContactPoint("localhost").create(); -// final Client client = cluster.connect(); -// -// // tested independently to 10000 iterations but for speed, bumped back to 1000 -// IntStream.range(0,1000).forEach(i -> { -// try { -// client.submit("1 + 9 9").all().join().get(0).getInt(); -// fail("Should not have gone through due to syntax error"); -// } catch (Exception ex) { -// final Throwable root = ExceptionUtils.getRootCause(ex); -// assertThat(root, instanceOf(ResponseException.class)); -// } -// }); -// -// assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldEventuallySucceedOnSameServer() throws Exception { -// stopServer(); -// -// final Cluster cluster = Cluster.build().addContactPoint("localhost").create(); -// final Client client = cluster.connect(); -// -// try { -// client.submit("1+1").all().join().get(0).getInt(); -// fail("Should not have gone through because the server is not running"); -// } catch (Exception i) { -// final Throwable root = ExceptionUtils.getRootCause(i); -// assertThat(root, instanceOf(TimeoutException.class)); -// } -// -// startServer(); -// -// // default reconnect time is 1 second so wait some extra time to be sure it has time to try to bring it -// // back to life -// TimeUnit.SECONDS.sleep(3); -// assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldEventuallySucceedWithRoundRobin() throws Exception { -// final String noGremlinServer = "74.125.225.19"; -// final Cluster cluster = Cluster.build(noGremlinServer).addContactPoint("localhost").create(); -// final Client client = cluster.connect(); -// -// // the first host is dead on init. request should succeed on localhost -// assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); -// assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); -// assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); -// assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); -// assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldHandleResultsOfAllSizes() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(); -// -// final String script = "g.V().drop().iterate();\n" + -// "\n" + -// "List ids = new ArrayList();\n" + -// "\n" + -// "int ii = 0;\n" + -// "Vertex v = graph.addVertex();\n" + -// "v.property(\"ii\", ii);\n" + -// "v.property(\"sin\", Math.sin(ii));\n" + -// "ids.add(v.id());\n" + -// "\n" + -// "Random rand = new Random();\n" + -// "for (; ii < size; ii++) {\n" + -// " v = graph.addVertex();\n" + -// " v.property(\"ii\", ii);\n" + -// " v.property(\"sin\", Math.sin(ii/5.0));\n" + -// " Vertex u = g.V(ids.get(rand.nextInt(ids.size()))).next();\n" + -// " v.addEdge(\"linked\", u);\n" + -// " ids.add(u.id());\n" + -// " ids.add(v.id());\n" + -// "}\n" + -// "g.V()"; -// -// final List<Integer> sizes = Arrays.asList(1, 10, 20, 50, 75, 100, 250, 500, 750, 1000, 5000, 10000); -// for (Integer size : sizes) { -// final Map<String, Object> params = new HashMap<>(); -// params.put("size", size - 1); -// final ResultSet results = client.submit(script, params); -// -// assertEquals(size.intValue(), results.all().get().size()); -// } -// -// cluster.close(); -// } -// -// @Test -// public void shouldFailWithBadClientSideSerialization() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(); -// -// final ResultSet results = client.submit("java.awt.Color.RED"); -// -// try { -// results.all().join(); -// fail("Should have thrown exception over bad serialization"); -// } catch (Exception ex) { -// final Throwable inner = ExceptionUtils.getRootCause(ex); -// assertTrue(inner instanceof RuntimeException); -// assertThat(inner.getMessage(), startsWith("Encountered unregistered class ID:")); -// } -// -// // should not die completely just because we had a bad serialization error. that kind of stuff happens -// // from time to time, especially in the console if you're just exploring. -// assertEquals(2, client.submit("1+1").all().get().get(0).getInt()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldFailWithScriptExecutionException() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(); -// -// final ResultSet results = client.submit("1/0"); -// -// try { -// results.all().join(); -// fail("Should have thrown exception over bad serialization"); -// } catch (Exception ex) { -// final Throwable inner = ExceptionUtils.getRootCause(ex); -// assertTrue(inner instanceof ResponseException); -// assertThat(inner.getMessage(), endsWith("Division by zero")); -// } -// -// // should not die completely just because we had a bad serialization error. that kind of stuff happens -// // from time to time, especially in the console if you're just exploring. -// assertEquals(2, client.submit("1+1").all().get().get(0).getInt()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldProcessRequestsOutOfOrder() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(); -// -// final ResultSet rsFive = client.submit("Thread.sleep(5000);'five'"); -// final ResultSet rsZero = client.submit("'zero'"); -// -// final CompletableFuture<List<Result>> futureFive = rsFive.all(); -// final CompletableFuture<List<Result>> futureZero = rsZero.all(); -// -// final long start = System.nanoTime(); -// assertFalse(futureFive.isDone()); -// assertEquals("zero", futureZero.get().get(0).getString()); -// -// logger.info("Eval of 'zero' complete: " + TimeUtil.millisSince(start)); -// -// assertFalse(futureFive.isDone()); -// assertEquals("five", futureFive.get(10, TimeUnit.SECONDS).get(0).getString()); -// -// logger.info("Eval of 'five' complete: " + TimeUtil.millisSince(start)); -// } -// -// @Test -// public void shouldProcessSessionRequestsInOrder() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(name.getMethodName()); -// -// final ResultSet rsFive = client.submit("Thread.sleep(5000);'five'"); -// final ResultSet rsZero = client.submit("'zero'"); -// -// final CompletableFuture<List<Result>> futureFive = rsFive.all(); -// final CompletableFuture<List<Result>> futureZero = rsZero.all(); -// -// final AtomicBoolean hit = new AtomicBoolean(false); -// while (!futureFive.isDone()) { -// // futureZero can't finish before futureFive - racy business here? -// assertThat(futureZero.isDone(), is(false)); -// hit.set(true); -// } -// -// // should have entered the loop at least once and thus proven that futureZero didn't return ahead of -// // futureFive -// assertThat(hit.get(), is(true)); -// -// assertEquals("zero", futureZero.get().get(0).getString()); -// assertEquals("five", futureFive.get(10, TimeUnit.SECONDS).get(0).getString()); -// } -// -// @Test -// public void shouldWaitForAllResultsToArrive() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(); -// -// final AtomicInteger checked = new AtomicInteger(0); -// final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); -// while (!results.allItemsAvailable()) { -// assertTrue(results.getAvailableItemCount() < 10); -// checked.incrementAndGet(); -// Thread.sleep(100); -// } -// -// assertTrue(checked.get() > 0); -// assertEquals(9, results.getAvailableItemCount()); -// cluster.close(); -// } -// -// @Test -// public void shouldWorkOverNioTransport() throws Exception { -// final Cluster cluster = Cluster.build().channelizer(Channelizer.NioChannelizer.class.getName()).create(); -// final Client client = cluster.connect(); -// -// final AtomicInteger checked = new AtomicInteger(0); -// final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); -// while (!results.allItemsAvailable()) { -// assertTrue(results.getAvailableItemCount() < 10); -// checked.incrementAndGet(); -// Thread.sleep(100); -// } -// -// assertTrue(checked.get() > 0); -// assertEquals(9, results.getAvailableItemCount()); -// cluster.close(); -// } -// -// @Test -// public void shouldStream() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(); -// -// final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); -// final AtomicInteger counter = new AtomicInteger(0); -// results.stream().map(i -> i.get(Integer.class) * 2).forEach(i -> assertEquals(counter.incrementAndGet() * 2, Integer.parseInt(i.toString()))); -// assertEquals(9, counter.get()); -// assertThat(results.allItemsAvailable(), is(true)); -// -// // cant stream it again -// assertThat(results.stream().iterator().hasNext(), is(false)); -// -// cluster.close(); -// } -// -// @Test -// public void shouldIterate() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(); -// -// final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); -// final Iterator<Result> itty = results.iterator(); -// final AtomicInteger counter = new AtomicInteger(0); -// while (itty.hasNext()) { -// counter.incrementAndGet(); -// assertEquals(counter.get(), itty.next().getInt()); -// } -// -// assertEquals(9, counter.get()); -// assertThat(results.allItemsAvailable(), is(true)); -// -// // can't stream it again -// assertThat(results.iterator().hasNext(), is(false)); -// -// cluster.close(); -// } -// -// @Test -// public void shouldGetSomeThenSomeMore() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(); -// -// final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); -// final CompletableFuture<List<Result>> batch1 = results.some(5); -// final CompletableFuture<List<Result>> batch2 = results.some(5); -// final CompletableFuture<List<Result>> batchNothingLeft = results.some(5); -// -// assertEquals(5, batch1.get().size()); -// assertEquals(1, batch1.get().get(0).getInt()); -// assertEquals(2, batch1.get().get(1).getInt()); -// assertEquals(3, batch1.get().get(2).getInt()); -// assertEquals(4, batch1.get().get(3).getInt()); -// assertEquals(5, batch1.get().get(4).getInt()); -// -// assertEquals(4, batch2.get().size()); -// assertEquals(6, batch2.get().get(0).getInt()); -// assertEquals(7, batch2.get().get(1).getInt()); -// assertEquals(8, batch2.get().get(2).getInt()); -// assertEquals(9, batch2.get().get(3).getInt()); -// -// assertEquals(0, batchNothingLeft.get().size()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldGetOneThenSomeThenSomeMore() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(); -// -// final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); -// final Result one = results.one(); -// final CompletableFuture<List<Result>> batch1 = results.some(4); -// final CompletableFuture<List<Result>> batch2 = results.some(5); -// final CompletableFuture<List<Result>> batchNothingLeft = results.some(5); -// -// assertEquals(1, one.getInt()); -// -// assertEquals(4, batch1.get().size()); -// assertEquals(2, batch1.get().get(0).getInt()); -// assertEquals(3, batch1.get().get(1).getInt()); -// assertEquals(4, batch1.get().get(2).getInt()); -// assertEquals(5, batch1.get().get(3).getInt()); -// -// assertEquals(4, batch2.get().size()); -// assertEquals(6, batch2.get().get(0).getInt()); -// assertEquals(7, batch2.get().get(1).getInt()); -// assertEquals(8, batch2.get().get(2).getInt()); -// assertEquals(9, batch2.get().get(3).getInt()); -// -// assertEquals(0, batchNothingLeft.get().size()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldAvoidDeadlockOnCallToResultSetDotAll() throws Exception { -// -// // This test arose from this issue: https://github.org/apache/tinkerpop/tinkerpop3/issues/515 -// // -// // ResultSet.all returns a CompletableFuture that blocks on the worker pool until isExhausted returns false. -// // isExhausted in turn needs a thread on the worker pool to even return. So its totally possible to consume all -// // threads on the worker pool waiting for .all to finish such that you can't even get one to wait for -// // isExhausted to run. -// // -// // Note that all() doesn't work as described above anymore. It waits for callback on readComplete rather -// // than blocking on isExhausted. -// final int workerPoolSizeForDriver = 2; -// -// // the number of requests 4 times the size of the worker pool as this originally did produce the problem -// // described above in the javadoc of the test (though an equivalent number also produced it), but this has -// // been tested to much higher multiples and passes. note that the maxWaitForConnection setting is high so -// // that the client doesn't timeout waiting for an available connection. obviously this can also be fixed -// // by increasing the maxConnectionPoolSize. -// final int requests = workerPoolSizeForDriver * 4; -// final Cluster cluster = Cluster.build() -// .workerPoolSize(workerPoolSizeForDriver) -// .maxWaitForConnection(300000) -// .create(); -// final Client client = cluster.connect(); -// -// final CountDownLatch latch = new CountDownLatch(requests); -// final AtomicReference[] refs = new AtomicReference[requests]; -// IntStream.range(0, requests).forEach(ix -> { -// refs[ix] = new AtomicReference(); -// client.submitAsync("Thread.sleep(5000);[1,2,3,4,5,6,7,8,9]").thenAccept(rs -> -// rs.all().thenAccept(refs[ix]::set).thenRun(latch::countDown)); -// }); -// -// // countdown should have reached zero as results should have eventually been all returned and processed -// assertTrue(latch.await(20, TimeUnit.SECONDS)); -// -// final List<Integer> expected = IntStream.range(1, 10).boxed().collect(Collectors.toList()); -// IntStream.range(0, requests).forEach(r -> -// assertTrue(expected.containsAll(((List<Result>) refs[r].get()).stream().map(resultItem -> new Integer(resultItem.getInt())).collect(Collectors.toList())))); -// } -// -// @Test -// public void shouldCloseWithServerDown() throws Exception { -// final Cluster cluster = Cluster.open(); -// cluster.connect().init(); -// -// stopServer(); -// -// cluster.close(); -// } -// -// @Test -// public void shouldMarkHostDeadSinceServerIsDown() throws Exception { -// final Cluster cluster = Cluster.open(); -// assertEquals(0, cluster.availableHosts().size()); -// cluster.connect().init(); -// assertEquals(1, cluster.availableHosts().size()); -// -// stopServer(); -// -// cluster.connect().init(); -// assertEquals(0, cluster.availableHosts().size()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldFailWithBadServerSideSerialization() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(); -// -// final ResultSet results = client.submit("TinkerGraph.open().variables()"); -// -// try { -// results.all().join(); -// fail(); -// } catch (Exception ex) { -// final Throwable inner = ExceptionUtils.getRootCause(ex); -// assertTrue(inner instanceof ResponseException); -// assertEquals(ResponseStatusCode.SERVER_ERROR_SERIALIZATION, ((ResponseException) inner).getResponseStatusCode()); -// } -// -// // should not die completely just because we had a bad serialization error. that kind of stuff happens -// // from time to time, especially in the console if you're just exploring. -// assertEquals(2, client.submit("1+1").all().get().get(0).getInt()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldSerializeToStringWhenRequested() throws Exception { -// final Map<String, Object> m = new HashMap<>(); -// m.put("serializeResultToString", true); -// final GryoMessageSerializerV1d0 serializer = new GryoMessageSerializerV1d0(); -// serializer.configure(m, null); -// -// final Cluster cluster = Cluster.build().serializer(serializer).create(); -// final Client client = cluster.connect(); -// -// final ResultSet resultSet = client.submit("TinkerFactory.createClassic()"); -// final List<Result> results = resultSet.all().join(); -// assertEquals(1, results.size()); -// assertEquals("tinkergraph[vertices:6 edges:6]", results.get(0).getString()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldDeserializeWithCustomClasses() throws Exception { -// final Map<String, Object> m = new HashMap<>(); -// m.put("custom", Arrays.asList(String.format("%s;%s", JsonBuilder.class.getCanonicalName(), JsonBuilderGryoSerializer.class.getCanonicalName()))); -// final GryoMessageSerializerV1d0 serializer = new GryoMessageSerializerV1d0(); -// serializer.configure(m, null); -// -// final Cluster cluster = Cluster.build().serializer(serializer).create(); -// final Client client = cluster.connect(); -// -// final List<Result> json = client.submit("b = new JsonBuilder();b.people{person {fname 'stephen'\nlname 'mallette'}};b").all().join(); -// assertEquals("{\"people\":{\"person\":{\"fname\":\"stephen\",\"lname\":\"mallette\"}}}", json.get(0).getString()); -// cluster.close(); -// } -// -// @Test -// public void shouldWorkWithGraphSONSerialization() throws Exception { -// final Cluster cluster = Cluster.build("localhost").serializer(Serializers.GRAPHSON_V1D0).create(); -// final Client client = cluster.connect(); -// -// final List<Result> r = client.submit("TinkerFactory.createModern().traversal().V(1)").all().join(); -// assertEquals(1, r.size()); -// -// final Map<String,Object> m = r.get(0).get(Map.class); -// assertEquals(4, m.size()); -// assertEquals(1, m.get("id")); -// assertEquals("person", m.get("label")); -// assertEquals("vertex", m.get("type")); -// -// final Map<String,Object> properties = (Map<String,Object>) m.get("properties"); -// assertEquals(2, properties.size()); -// -// final List<Object> names = (List<Object>) properties.get("name"); -// assertEquals(1, names.size()); -// -// final Map<String,Object> nameProperties = (Map<String,Object>) names.get(0); -// assertEquals(2, nameProperties.size()); -// assertEquals(0l, nameProperties.get("id")); -// assertEquals("marko", nameProperties.get("value")); -// -// final List<Object> ages = (List<Object>) properties.get("age"); -// assertEquals(1, ages.size()); -// -// final Map<String,Object> ageProperties = (Map<String,Object>) ages.get(0); -// assertEquals(2, ageProperties.size()); -// assertEquals(1l, ageProperties.get("id")); -// assertEquals(29, ageProperties.get("value")); -// -// cluster.close(); -// } -// -// @Test -// @org.junit.Ignore("Can't seem to make this test pass consistently") -// public void shouldHandleRequestSentThatNeverReturns() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(); -// -// final ResultSet results = client.submit("Thread.sleep(10000); 'should-not-ever-get-back-coz-we-killed-the-server'"); -// -// stopServer(); -// -// // give the server a chance to kill everything -// Thread.sleep(1000); -// -// try { -// results.all().get(10000, TimeUnit.MILLISECONDS); -// fail("Server was stopped before the request could execute"); -// } catch (TimeoutException toe) { -// fail("Should not have tossed a TimeOutException getting the result"); -// } catch (Exception ex) { -// final Throwable cause = ExceptionUtils.getCause(ex); -// assertThat(cause.getMessage(), containsString("rejected from java.util.concurrent.ThreadPoolExecutor")); -// } -// -// cluster.close(); -// } -// -// @Test -// public void shouldFailClientSideWithTooLargeAResponse() { -// final Cluster cluster = Cluster.build().maxContentLength(1).create(); -// final Client client = cluster.connect(); -// -// try { -// final String fatty = IntStream.range(0, 100).mapToObj(String::valueOf).collect(Collectors.joining()); -// client.submit("'" + fatty + "'").all().get(); -// fail("Should throw an exception."); -// } catch (Exception re) { -// final Throwable root = ExceptionUtils.getRootCause(re); -// assertTrue(root.getMessage().equals("Max frame length of 1 has been exceeded.")); -// } finally { -// cluster.close(); -// } -// } -// -// @Test -// public void shouldReturnNiceMessageFromOpSelector() { -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(); -// -// try { -// final Map m = new HashMap<>(); -// m.put(null, "a null key will force a throw of OpProcessorException in message validation"); -// client.submit("1+1", m).all().get(); -// fail("Should throw an exception."); -// } catch (Exception re) { -// final Throwable root = ExceptionUtils.getRootCause(re); -// assertEquals("The [eval] message is using one or more invalid binding keys - they must be of type String and cannot be null", root.getMessage()); -// } finally { -// cluster.close(); -// } -// } -// -// @Test -// public void shouldExecuteScriptInSession() throws Exception { -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(name.getMethodName()); -// -// final ResultSet results1 = client.submit("x = [1,2,3,4,5,6,7,8,9]"); -// assertEquals(9, results1.all().get().size()); -// -// final ResultSet results2 = client.submit("x[0]+1"); -// assertEquals(2, results2.all().get().get(0).getInt()); -// -// final ResultSet results3 = client.submit("x[1]+2"); -// assertEquals(4, results3.all().get().get(0).getInt()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldNotThrowNoSuchElementException() throws Exception { -// final Cluster cluster = Cluster.open(); -// final Client client = cluster.connect(); -// -// try { -// // this should return "nothing" - there should be no exception -// assertNull(client.submit("g.V().has('name','kadfjaldjfla')").one()); -// } finally { -// cluster.close(); -// } -// } -// -// @Test -// public void shouldCloseSession() throws Exception { -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(name.getMethodName()); -// -// final ResultSet results1 = client.submit("x = [1,2,3,4,5,6,7,8,9]"); -// assertEquals(9, results1.all().get().size()); -// final ResultSet results2 = client.submit("x[0]+1"); -// assertEquals(2, results2.all().get().get(0).getInt()); -// -// client.close(); -// -// try { -// client.submit("x[0]+1"); -// fail("Should have thrown an exception because the connection is closed"); -// } catch (Exception ex) { -// final Throwable root = ExceptionUtils.getRootCause(ex); -// assertThat(root, instanceOf(ConnectionException.class)); -// } -// } -// -// @Test -// public void shouldExecuteScriptInSessionAssumingDefaultedImports() throws Exception { -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(name.getMethodName()); -// -// final ResultSet results1 = client.submit("TinkerFactory.class.name"); -// assertEquals(TinkerFactory.class.getName(), results1.all().get().get(0).getString()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldExecuteScriptInSessionOnTransactionalGraph() throws Exception { -// assumeNeo4jIsPresent(); -// -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(name.getMethodName()); -// -// final Vertex vertexBeforeTx = client.submit("v=graph.addVertex(\"name\",\"stephen\")").all().get().get(0).getVertex(); -// assertEquals("stephen", vertexBeforeTx.values("name").next()); -// -// final Vertex vertexFromV = client.submit("graph.vertices().next()").all().get().get(0).getVertex(); -// assertEquals("stephen", vertexFromV.values("name").next()); -// -// final Vertex vertexFromBinding = client.submit("v").all().get().get(0).getVertex(); -// assertEquals("stephen", vertexFromBinding.values("name").next()); -// -// final Vertex vertexAfterTx = client.submit("v.property(\"color\",\"blue\"); graph.tx().commit(); v").all().get().get(0).getVertex(); -// assertEquals("stephen", vertexAfterTx.values("name").next()); -// assertEquals("blue", vertexAfterTx.values("color").next()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldExecuteScriptInSessionOnTransactionalWithManualTransactionsGraph() throws Exception { -// assumeNeo4jIsPresent(); -// -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(name.getMethodName()); -// final Client sessionlessClient = cluster.connect(); -// client.submit("graph.tx().onReadWrite(Transaction.READ_WRITE_BEHAVIOR.MANUAL);null").all().get(); -// client.submit("graph.tx().open()").all().get(); -// -// final Vertex vertexBeforeTx = client.submit("v=graph.addVertex(\"name\",\"stephen\")").all().get().get(0).getVertex(); -// assertEquals("stephen", vertexBeforeTx.values("name").next()); -// -// final Vertex vertexFromV = client.submit("graph.vertices().next()").all().get().get(0).getVertex(); -// assertEquals("stephen", vertexFromV.values("name").next()); -// -// final Vertex vertexFromBinding = client.submit("v").all().get().get(0).getVertex(); -// assertEquals("stephen", vertexFromBinding.values("name").next()); -// -// client.submit("v.property(\"color\",\"blue\")").all().get(); -// client.submit("graph.tx().commit()").all().get(); -// -// // Run a sessionless request to change transaction.readWriteConsumer back to AUTO -// // The will make the next in session request fail if consumers aren't ThreadLocal -// sessionlessClient.submit("graph.vertices().next()").all().get(); -// -// client.submit("graph.tx().open()").all().get(); -// -// final Vertex vertexAfterTx = client.submit("graph.vertices().next()").all().get().get(0).getVertex(); -// assertEquals("stephen", vertexAfterTx.values("name").next()); -// assertEquals("blue", vertexAfterTx.values("color").next()); -// -// client.submit("graph.tx().rollback()").all().get(); -// -// cluster.close(); -// } -// -// @Test -// public void shouldExecuteInSessionAndSessionlessWithoutOpeningTransaction() throws Exception { -// assumeNeo4jIsPresent(); -// -// final Cluster cluster = Cluster.build().create(); -// final Client sessionClient = cluster.connect(name.getMethodName()); -// final Client sessionlessClient = cluster.connect(); -// -// //open transaction in session, then add vertex and commit -// sessionClient.submit("graph.tx().open()").all().get(); -// final Vertex vertexBeforeTx = sessionClient.submit("v=graph.addVertex(\"name\",\"stephen\")").all().get().get(0).getVertex(); -// assertEquals("stephen", vertexBeforeTx.values("name").next()); -// sessionClient.submit("graph.tx().commit()").all().get(); -// -// // check that session transaction is closed -// final boolean isOpen = sessionClient.submit("graph.tx().isOpen()").all().get().get(0).getBoolean(); -// assertTrue("Transaction should be closed", !isOpen); -// -// //run a sessionless read -// sessionlessClient.submit("graph.traversal().V()").all().get(); -// -// // check that session transaction is still closed -// final boolean isOpenAfterSessionless = sessionClient.submit("graph.tx().isOpen()").all().get().get(0).getBoolean(); -// assertTrue("Transaction should stil be closed", !isOpenAfterSessionless); -// -// } -// -// @Test -// public void shouldExecuteSessionlessScriptOnTransactionalGraph() throws Exception { -// assumeNeo4jIsPresent(); -// -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(); -// -// // this line is important because it tests GraphTraversal which has a certain transactional path -// final Vertex vertexRequest1 = client.submit("g.addV(\"name\",\"stephen\")").all().get().get(0).getVertex(); -// assertEquals("stephen", vertexRequest1.values("name").next()); -// -// final Vertex vertexRequest2 = client.submit("graph.vertices().next()").all().get().get(0).getVertex(); -// assertEquals("stephen", vertexRequest2.values("name").next()); -// -// // this line is important because it tests the other transactional path -// final Vertex vertexRequest3 = client.submit("graph.addVertex(\"name\",\"marko\")").all().get().get(0).getVertex(); -// assertEquals("marko", vertexRequest3.values("name").next()); -// -// assertEquals(2, client.submit("g.V().count()").all().get().get(0).getLong()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldExecuteScriptInSessionWithBindingsSavedOnServerBetweenRequests() throws Exception { -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(name.getMethodName()); -// -// final Map<String, Object> bindings1 = new HashMap<>(); -// bindings1.put("a", 100); -// bindings1.put("b", 200); -// final ResultSet results1 = client.submit("x = a + b", bindings1); -// assertEquals(300, results1.one().getInt()); -// -// final Map<String, Object> bindings2 = new HashMap<>(); -// bindings2.put("b", 100); -// final ResultSet results2 = client.submit("x + b + a", bindings2); -// assertEquals(500, results2.one().getInt()); -// -// final Map<String, Object> bindings3 = new HashMap<>(); -// bindings3.put("x", 100); -// final ResultSet results3 = client.submit("x + b + a + 1", bindings3); -// assertEquals(301, results3.one().getInt()); -// -// final Map<String, Object> bindings4 = new HashMap<>(); -// final ResultSet results4 = client.submit("x + b + a + 1", bindings4); -// assertEquals(301, results4.one().getInt()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldExecuteScriptsInMultipleSession() throws Exception { -// final Cluster cluster = Cluster.build().create(); -// final Client client1 = cluster.connect(name.getMethodName() + "1"); -// final Client client2 = cluster.connect(name.getMethodName() + "2"); -// final Client client3 = cluster.connect(name.getMethodName() + "3"); -// -// final ResultSet results11 = client1.submit("x = 1"); -// final ResultSet results21 = client2.submit("x = 2"); -// final ResultSet results31 = client3.submit("x = 3"); -// assertEquals(1, results11.all().get().get(0).getInt()); -// assertEquals(2, results21.all().get().get(0).getInt()); -// assertEquals(3, results31.all().get().get(0).getInt()); -// -// final ResultSet results12 = client1.submit("x + 100"); -// final ResultSet results22 = client2.submit("x * 2"); -// final ResultSet results32 = client3.submit("x * 10"); -// assertEquals(101, results12.all().get().get(0).getInt()); -// assertEquals(4, results22.all().get().get(0).getInt()); -// assertEquals(30, results32.all().get().get(0).getInt()); -// -// cluster.close(); -// } -// -// @Test -// public void shouldNotHaveKnowledgeOfBindingsBetweenRequestsWhenSessionless() throws Exception { -// final Cluster cluster = Cluster.build().create(); -// final Client client1 = cluster.connect(); -// final Client client2 = cluster.connect(); -// final Client client3 = cluster.connect(); -// -// final ResultSet results11 = client1.submit("x = 1"); -// final ResultSet results21 = client2.submit("x = 2"); -// final ResultSet results31 = client3.submit("x = 3"); -// assertEquals(1, results11.all().get().get(0).getInt()); -// assertEquals(2, results21.all().get().get(0).getInt()); -// assertEquals(3, results31.all().get().get(0).getInt()); -// -// try { -// client1.submit("x").all().get(); -// fail("The variable 'x' should not be present on the new request."); -// } catch (Exception ex) { -// final Throwable root = ExceptionUtils.getRootCause(ex); -// assertThat(root, IsInstanceOf.instanceOf(ResponseException.class)); -// assertThat(root.getMessage(), containsString("No such property: x for class")); -// } -// -// try { -// client2.submit("x").all().get(); -// fail("The variable 'x' should not be present on the new request."); -// } catch (Exception ex) { -// final Throwable root = ExceptionUtils.getRootCause(ex); -// assertThat(root, IsInstanceOf.instanceOf(ResponseException.class)); -// assertThat(root.getMessage(), containsString("No such property: x for class")); -// } -// -// try { -// client3.submit("x").all().get(); -// fail("The variable 'x' should not be present on the new request."); -// } catch (Exception ex) { -// final Throwable root = ExceptionUtils.getRootCause(ex); -// assertThat(root, IsInstanceOf.instanceOf(ResponseException.class)); -// assertThat(root.getMessage(), containsString("No such property: x for class")); -// } -// -// cluster.close(); -// } + @Test + public void shouldEventuallySucceedAfterChannelLevelError() throws Exception { + final Cluster cluster = Cluster.build().addContactPoint("localhost") + .reconnectIntialDelay(500) + .reconnectInterval(500) + .maxContentLength(1024).create(); + final Client client = cluster.connect(); + + try { + client.submit("def x = '';(0..<1024).each{x = x + '$it'};x").all().get(); + fail("Request should have failed because it exceeded the max content length allowed"); + } catch (Exception ex) { + final Throwable root = ExceptionUtils.getRootCause(ex); + assertThat(root.getMessage(), containsString("Max frame length of 1024 has been exceeded.")); + } + + assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); + + cluster.close(); + } + + @Test + public void shouldEventuallySucceedAfterMuchFailure() throws Exception { + final Cluster cluster = Cluster.build().addContactPoint("localhost").create(); + final Client client = cluster.connect(); + + // tested independently to 10000 iterations but for speed, bumped back to 1000 + IntStream.range(0,1000).forEach(i -> { + try { + client.submit("1 + 9 9").all().join().get(0).getInt(); + fail("Should not have gone through due to syntax error"); + } catch (Exception ex) { + final Throwable root = ExceptionUtils.getRootCause(ex); + assertThat(root, instanceOf(ResponseException.class)); + } + }); + + assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); + + cluster.close(); + } + + @Test + public void shouldEventuallySucceedOnSameServer() throws Exception { + stopServer(); + + final Cluster cluster = Cluster.build().addContactPoint("localhost").create(); + final Client client = cluster.connect(); + + try { + client.submit("1+1").all().join().get(0).getInt(); + fail("Should not have gone through because the server is not running"); + } catch (Exception i) { + final Throwable root = ExceptionUtils.getRootCause(i); + assertThat(root, instanceOf(TimeoutException.class)); + } + + startServer(); + + // default reconnect time is 1 second so wait some extra time to be sure it has time to try to bring it + // back to life + TimeUnit.SECONDS.sleep(3); + assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); + + cluster.close(); + } + + @Test + public void shouldEventuallySucceedWithRoundRobin() throws Exception { + final String noGremlinServer = "74.125.225.19"; + final Cluster cluster = Cluster.build(noGremlinServer).addContactPoint("localhost").create(); + final Client client = cluster.connect(); + + // the first host is dead on init. request should succeed on localhost + assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); + assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); + assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); + assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); + assertEquals(2, client.submit("1+1").all().join().get(0).getInt()); + + cluster.close(); + } + + @Test + public void shouldHandleResultsOfAllSizes() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(); + + final String script = "g.V().drop().iterate();\n" + + "\n" + + "List ids = new ArrayList();\n" + + "\n" + + "int ii = 0;\n" + + "Vertex v = graph.addVertex();\n" + + "v.property(\"ii\", ii);\n" + + "v.property(\"sin\", Math.sin(ii));\n" + + "ids.add(v.id());\n" + + "\n" + + "Random rand = new Random();\n" + + "for (; ii < size; ii++) {\n" + + " v = graph.addVertex();\n" + + " v.property(\"ii\", ii);\n" + + " v.property(\"sin\", Math.sin(ii/5.0));\n" + + " Vertex u = g.V(ids.get(rand.nextInt(ids.size()))).next();\n" + + " v.addEdge(\"linked\", u);\n" + + " ids.add(u.id());\n" + + " ids.add(v.id());\n" + + "}\n" + + "g.V()"; + + final List<Integer> sizes = Arrays.asList(1, 10, 20, 50, 75, 100, 250, 500, 750, 1000, 5000, 10000); + for (Integer size : sizes) { + final Map<String, Object> params = new HashMap<>(); + params.put("size", size - 1); + final ResultSet results = client.submit(script, params); + + assertEquals(size.intValue(), results.all().get().size()); + } + + cluster.close(); + } + + @Test + public void shouldFailWithBadClientSideSerialization() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(); + + final ResultSet results = client.submit("java.awt.Color.RED"); + + try { + results.all().join(); + fail("Should have thrown exception over bad serialization"); + } catch (Exception ex) { + final Throwable inner = ExceptionUtils.getRootCause(ex); + assertTrue(inner instanceof RuntimeException); + assertThat(inner.getMessage(), startsWith("Encountered unregistered class ID:")); + } + + // should not die completely just because we had a bad serialization error. that kind of stuff happens + // from time to time, especially in the console if you're just exploring. + assertEquals(2, client.submit("1+1").all().get().get(0).getInt()); + + cluster.close(); + } + + @Test + public void shouldFailWithScriptExecutionException() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(); + + final ResultSet results = client.submit("1/0"); + + try { + results.all().join(); + fail("Should have thrown exception over bad serialization"); + } catch (Exception ex) { + final Throwable inner = ExceptionUtils.getRootCause(ex); + assertTrue(inner instanceof ResponseException); + assertThat(inner.getMessage(), endsWith("Division by zero")); + } + + // should not die completely just because we had a bad serialization error. that kind of stuff happens + // from time to time, especially in the console if you're just exploring. + assertEquals(2, client.submit("1+1").all().get().get(0).getInt()); + + cluster.close(); + } + + @Test + public void shouldProcessRequestsOutOfOrder() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(); + + final ResultSet rsFive = client.submit("Thread.sleep(5000);'five'"); + final ResultSet rsZero = client.submit("'zero'"); + + final CompletableFuture<List<Result>> futureFive = rsFive.all(); + final CompletableFuture<List<Result>> futureZero = rsZero.all(); + + final long start = System.nanoTime(); + assertFalse(futureFive.isDone()); + assertEquals("zero", futureZero.get().get(0).getString()); + + logger.info("Eval of 'zero' complete: " + TimeUtil.millisSince(start)); + + assertFalse(futureFive.isDone()); + assertEquals("five", futureFive.get(10, TimeUnit.SECONDS).get(0).getString()); + + logger.info("Eval of 'five' complete: " + TimeUtil.millisSince(start)); + } + + @Test + public void shouldProcessSessionRequestsInOrder() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(name.getMethodName()); + + final ResultSet rsFive = client.submit("Thread.sleep(5000);'five'"); + final ResultSet rsZero = client.submit("'zero'"); + + final CompletableFuture<List<Result>> futureFive = rsFive.all(); + final CompletableFuture<List<Result>> futureZero = rsZero.all(); + + final AtomicBoolean hit = new AtomicBoolean(false); + while (!futureFive.isDone()) { + // futureZero can't finish before futureFive - racy business here? + assertThat(futureZero.isDone(), is(false)); + hit.set(true); + } + + // should have entered the loop at least once and thus proven that futureZero didn't return ahead of + // futureFive + assertThat(hit.get(), is(true)); + + assertEquals("zero", futureZero.get().get(0).getString()); + assertEquals("five", futureFive.get(10, TimeUnit.SECONDS).get(0).getString()); + } + + @Test + public void shouldWaitForAllResultsToArrive() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(); + + final AtomicInteger checked = new AtomicInteger(0); + final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); + while (!results.allItemsAvailable()) { + assertTrue(results.getAvailableItemCount() < 10); + checked.incrementAndGet(); + Thread.sleep(100); + } + + assertTrue(checked.get() > 0); + assertEquals(9, results.getAvailableItemCount()); + cluster.close(); + } + + @Test + public void shouldWorkOverNioTransport() throws Exception { + final Cluster cluster = Cluster.build().channelizer(Channelizer.NioChannelizer.class.getName()).create(); + final Client client = cluster.connect(); + + final AtomicInteger checked = new AtomicInteger(0); + final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); + while (!results.allItemsAvailable()) { + assertTrue(results.getAvailableItemCount() < 10); + checked.incrementAndGet(); + Thread.sleep(100); + } + + assertTrue(checked.get() > 0); + assertEquals(9, results.getAvailableItemCount()); + cluster.close(); + } + + @Test + public void shouldStream() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(); + + final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); + final AtomicInteger counter = new AtomicInteger(0); + results.stream().map(i -> i.get(Integer.class) * 2).forEach(i -> assertEquals(counter.incrementAndGet() * 2, Integer.parseInt(i.toString()))); + assertEquals(9, counter.get()); + assertThat(results.allItemsAvailable(), is(true)); + + // cant stream it again + assertThat(results.stream().iterator().hasNext(), is(false)); + + cluster.close(); + } + + @Test + public void shouldIterate() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(); + + final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); + final Iterator<Result> itty = results.iterator(); + final AtomicInteger counter = new AtomicInteger(0); + while (itty.hasNext()) { + counter.incrementAndGet(); + assertEquals(counter.get(), itty.next().getInt()); + } + + assertEquals(9, counter.get()); + assertThat(results.allItemsAvailable(), is(true)); + + // can't stream it again + assertThat(results.iterator().hasNext(), is(false)); + + cluster.close(); + } + + @Test + public void shouldGetSomeThenSomeMore() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(); + + final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); + final CompletableFuture<List<Result>> batch1 = results.some(5); + final CompletableFuture<List<Result>> batch2 = results.some(5); + final CompletableFuture<List<Result>> batchNothingLeft = results.some(5); + + assertEquals(5, batch1.get().size()); + assertEquals(1, batch1.get().get(0).getInt()); + assertEquals(2, batch1.get().get(1).getInt()); + assertEquals(3, batch1.get().get(2).getInt()); + assertEquals(4, batch1.get().get(3).getInt()); + assertEquals(5, batch1.get().get(4).getInt()); + + assertEquals(4, batch2.get().size()); + assertEquals(6, batch2.get().get(0).getInt()); + assertEquals(7, batch2.get().get(1).getInt()); + assertEquals(8, batch2.get().get(2).getInt()); + assertEquals(9, batch2.get().get(3).getInt()); + + assertEquals(0, batchNothingLeft.get().size()); + + cluster.close(); + } + + @Test + public void shouldGetOneThenSomeThenSomeMore() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(); + + final ResultSet results = client.submit("[1,2,3,4,5,6,7,8,9]"); + final Result one = results.one(); + final CompletableFuture<List<Result>> batch1 = results.some(4); + final CompletableFuture<List<Result>> batch2 = results.some(5); + final CompletableFuture<List<Result>> batchNothingLeft = results.some(5); + + assertEquals(1, one.getInt()); + + assertEquals(4, batch1.get().size()); + assertEquals(2, batch1.get().get(0).getInt()); + assertEquals(3, batch1.get().get(1).getInt()); + assertEquals(4, batch1.get().get(2).getInt()); + assertEquals(5, batch1.get().get(3).getInt()); + + assertEquals(4, batch2.get().size()); + assertEquals(6, batch2.get().get(0).getInt()); + assertEquals(7, batch2.get().get(1).getInt()); + assertEquals(8, batch2.get().get(2).getInt()); + assertEquals(9, batch2.get().get(3).getInt()); + + assertEquals(0, batchNothingLeft.get().size()); + + cluster.close(); + } + + @Test + public void shouldAvoidDeadlockOnCallToResultSetDotAll() throws Exception { + + // This test arose from this issue: https://github.org/apache/tinkerpop/tinkerpop3/issues/515 + // + // ResultSet.all returns a CompletableFuture that blocks on the worker pool until isExhausted returns false. + // isExhausted in turn needs a thread on the worker pool to even return. So its totally possible to consume all + // threads on the worker pool waiting for .all to finish such that you can't even get one to wait for + // isExhausted to run. + // + // Note that all() doesn't work as described above anymore. It waits for callback on readComplete rather + // than blocking on isExhausted. + final int workerPoolSizeForDriver = 2; + + // the number of requests 4 times the size of the worker pool as this originally did produce the problem + // described above in the javadoc of the test (though an equivalent number also produced it), but this has + // been tested to much higher multiples and passes. note that the maxWaitForConnection setting is high so + // that the client doesn't timeout waiting for an available connection. obviously this can also be fixed + // by increasing the maxConnectionPoolSize. + final int requests = workerPoolSizeForDriver * 4; + final Cluster cluster = Cluster.build() + .workerPoolSize(workerPoolSizeForDriver) + .maxWaitForConnection(300000) + .create(); + final Client client = cluster.connect(); + + final CountDownLatch latch = new CountDownLatch(requests); + final AtomicReference[] refs = new AtomicReference[requests]; + IntStream.range(0, requests).forEach(ix -> { + refs[ix] = new AtomicReference(); + client.submitAsync("Thread.sleep(5000);[1,2,3,4,5,6,7,8,9]").thenAccept(rs -> + rs.all().thenAccept(refs[ix]::set).thenRun(latch::countDown)); + }); + + // countdown should have reached zero as results should have eventually been all returned and processed + assertTrue(latch.await(20, TimeUnit.SECONDS)); + + final List<Integer> expected = IntStream.range(1, 10).boxed().collect(Collectors.toList()); + IntStream.range(0, requests).forEach(r -> + assertTrue(expected.containsAll(((List<Result>) refs[r].get()).stream().map(resultItem -> new Integer(resultItem.getInt())).collect(Collectors.toList())))); + } + + @Test + public void shouldCloseWithServerDown() throws Exception { + final Cluster cluster = Cluster.open(); + cluster.connect().init(); + + stopServer(); + + cluster.close(); + } + + @Test + public void shouldMarkHostDeadSinceServerIsDown() throws Exception { + final Cluster cluster = Cluster.open(); + assertEquals(0, cluster.availableHosts().size()); + cluster.connect().init(); + assertEquals(1, cluster.availableHosts().size()); + + stopServer(); + + cluster.connect().init(); + assertEquals(0, cluster.availableHosts().size()); + + cluster.close(); + } + + @Test + public void shouldFailWithBadServerSideSerialization() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(); + + final ResultSet results = client.submit("TinkerGraph.open().variables()"); + + try { + results.all().join(); + fail(); + } catch (Exception ex) { + final Throwable inner = ExceptionUtils.getRootCause(ex); + assertTrue(inner instanceof ResponseException); + assertEquals(ResponseStatusCode.SERVER_ERROR_SERIALIZATION, ((ResponseException) inner).getResponseStatusCode()); + } + + // should not die completely just because we had a bad serialization error. that kind of stuff happens + // from time to time, especially in the console if you're just exploring. + assertEquals(2, client.submit("1+1").all().get().get(0).getInt()); + + cluster.close(); + } + + @Test + public void shouldSerializeToStringWhenRequested() throws Exception { + final Map<String, Object> m = new HashMap<>(); + m.put("serializeResultToString", true); + final GryoMessageSerializerV1d0 serializer = new GryoMessageSerializerV1d0(); + serializer.configure(m, null); + + final Cluster cluster = Cluster.build().serializer(serializer).create(); + final Client client = cluster.connect(); + + final ResultSet resultSet = client.submit("TinkerFactory.createClassic()"); + final List<Result> results = resultSet.all().join(); + assertEquals(1, results.size()); + assertEquals("tinkergraph[vertices:6 edges:6]", results.get(0).getString()); + + cluster.close(); + } + + @Test + public void shouldDeserializeWithCustomClasses() throws Exception { + final Map<String, Object> m = new HashMap<>(); + m.put("custom", Arrays.asList(String.format("%s;%s", JsonBuilder.class.getCanonicalName(), JsonBuilderGryoSerializer.class.getCanonicalName()))); + final GryoMessageSerializerV1d0 serializer = new GryoMessageSerializerV1d0(); + serializer.configure(m, null); + + final Cluster cluster = Cluster.build().serializer(serializer).create(); + final Client client = cluster.connect(); + + final List<Result> json = client.submit("b = new JsonBuilder();b.people{person {fname 'stephen'\nlname 'mallette'}};b").all().join(); + assertEquals("{\"people\":{\"person\":{\"fname\":\"stephen\",\"lname\":\"mallette\"}}}", json.get(0).getString()); + cluster.close(); + } + + @Test + public void shouldWorkWithGraphSONSerialization() throws Exception { + final Cluster cluster = Cluster.build("localhost").serializer(Serializers.GRAPHSON_V1D0).create(); + final Client client = cluster.connect(); + + final List<Result> r = client.submit("TinkerFactory.createModern().traversal().V(1)").all().join(); + assertEquals(1, r.size()); + + final Map<String,Object> m = r.get(0).get(Map.class); + assertEquals(4, m.size()); + assertEquals(1, m.get("id")); + assertEquals("person", m.get("label")); + assertEquals("vertex", m.get("type")); + + final Map<String,Object> properties = (Map<String,Object>) m.get("properties"); + assertEquals(2, properties.size()); + + final List<Object> names = (List<Object>) properties.get("name"); + assertEquals(1, names.size()); + + final Map<String,Object> nameProperties = (Map<String,Object>) names.get(0); + assertEquals(2, nameProperties.size()); + assertEquals(0l, nameProperties.get("id")); + assertEquals("marko", nameProperties.get("value")); + + final List<Object> ages = (List<Object>) properties.get("age"); + assertEquals(1, ages.size()); + + final Map<String,Object> ageProperties = (Map<String,Object>) ages.get(0); + assertEquals(2, ageProperties.size()); + assertEquals(1l, ageProperties.get("id")); + assertEquals(29, ageProperties.get("value")); + + cluster.close(); + } + + @Test + @org.junit.Ignore("Can't seem to make this test pass consistently") + public void shouldHandleRequestSentThatNeverReturns() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(); + + final ResultSet results = client.submit("Thread.sleep(10000); 'should-not-ever-get-back-coz-we-killed-the-server'"); + + stopServer(); + + // give the server a chance to kill everything + Thread.sleep(1000); + + try { + results.all().get(10000, TimeUnit.MILLISECONDS); + fail("Server was stopped before the request could execute"); + } catch (TimeoutException toe) { + fail("Should not have tossed a TimeOutException getting the result"); + } catch (Exception ex) { + final Throwable cause = ExceptionUtils.getCause(ex); + assertThat(cause.getMessage(), containsString("rejected from java.util.concurrent.ThreadPoolExecutor")); + } + + cluster.close(); + } + + @Test + public void shouldFailClientSideWithTooLargeAResponse() { + final Cluster cluster = Cluster.build().maxContentLength(1).create(); + final Client client = cluster.connect(); + + try { + final String fatty = IntStream.range(0, 100).mapToObj(String::valueOf).collect(Collectors.joining()); + client.submit("'" + fatty + "'").all().get(); + fail("Should throw an exception."); + } catch (Exception re) { + final Throwable root = ExceptionUtils.getRootCause(re); + assertTrue(root.getMessage().equals("Max frame length of 1 has been exceeded.")); + } finally { + cluster.close(); + } + } + + @Test + public void shouldReturnNiceMessageFromOpSelector() { + final Cluster cluster = Cluster.build().create(); + final Client client = cluster.connect(); + + try { + final Map m = new HashMap<>(); + m.put(null, "a null key will force a throw of OpProcessorException in message validation"); + client.submit("1+1", m).all().get(); + fail("Should throw an exception."); + } catch (Exception re) { + final Throwable root = ExceptionUtils.getRootCause(re); + assertEquals("The [eval] message is using one or more invalid binding keys - they must be of type String and cannot be null", root.getMessage()); + } finally { + cluster.close(); + } + } + + @Test + public void shouldExecuteScriptInSession() throws Exception { + final Cluster cluster = Cluster.build().create(); + final Client client = cluster.connect(name.getMethodName()); + + final ResultSet results1 = client.submit("x = [1,2,3,4,5,6,7,8,9]"); + assertEquals(9, results1.all().get().size()); + + final ResultSet results2 = client.submit("x[0]+1"); + assertEquals(2, results2.all().get().get(0).getInt()); + + final ResultSet results3 = client.submit("x[1]+2"); + assertEquals(4, results3.all().get().get(0).getInt()); + + cluster.close(); + } + + @Test + public void shouldNotThrowNoSuchElementException() throws Exception { + final Cluster cluster = Cluster.open(); + final Client client = cluster.connect(); + + try { + // this should return "nothing" - there should be no exception + assertNull(client.submit("g.V().has('name','kadfjaldjfla')").one()); + } finally { + cluster.close(); + } + } + + @Test + public void shouldCloseSession() throws Exception { + final Cluster cluster = Cluster.build().create(); + final Client client = cluster.connect(name.getMethodName()); + + final ResultSet results1 = client.submit("x = [1,2,3,4,5,6,7,8,9]"); + assertEquals(9, results1.all().get().size()); + final ResultSet results2 = client.submit("x[0]+1"); + assertEquals(2, results2.all().get().get(0).getInt()); + + client.close(); + + try { + client.submit("x[0]+1"); + fail("Should have thrown an exception because the connection is closed"); + } catch (Exception ex) { + final Throwable root = ExceptionUtils.getRootCause(ex); + assertThat(root, instanceOf(ConnectionException.class)); + } + } + + @Test + public void shouldExecuteScriptInSessionAssumingDefaultedImports() throws Exception { + final Cluster cluster = Cluster.build().create(); + final Client client = cluster.connect(name.getMethodName()); + + final ResultSet results1 = client.submit("TinkerFactory.class.name"); + assertEquals(TinkerFactory.class.getName(), results1.all().get().get(0).getString()); + + cluster.close(); + } + + @Test + public void shouldExecuteScriptInSessionOnTransactionalGraph() throws Exception { + assumeNeo4jIsPresent(); + + final Cluster cluster = Cluster.build().create(); + final Client client = cluster.connect(name.getMethodName()); + + final Vertex vertexBeforeTx = client.submit("v=graph.addVertex(\"name\",\"stephen\")").all().get().get(0).getVertex(); + assertEquals("stephen", vertexBeforeTx.values("name").next()); + + final Vertex vertexFromV = client.submit("graph.vertices().next()").all().get().get(0).getVertex(); + assertEquals("stephen", vertexFromV.values("name").next()); + + final Vertex vertexFromBinding = client.submit("v").all().get().get(0).getVertex(); + assertEquals("stephen", vertexFromBinding.values("name").next()); + + final Vertex vertexAfterTx = client.submit("v.property(\"color\",\"blue\"); graph.tx().commit(); v").all().get().get(0).getVertex(); + assertEquals("stephen", vertexAfterTx.values("name").next()); + assertEquals("blue", vertexAfterTx.values("color").next()); + + cluster.close(); + } + + @Test + public void shouldExecuteScriptInSessionOnTransactionalWithManualTransactionsGraph() throws Exception { + assumeNeo4jIsPresent(); + + final Cluster cluster = Cluster.build().create(); + final Client client = cluster.connect(name.getMethodName()); + final Client sessionlessClient = cluster.connect(); + client.submit("graph.tx().onReadWrite(Transaction.READ_WRITE_BEHAVIOR.MANUAL);null").all().get(); + client.submit("graph.tx().open()").all().get(); + + final Vertex vertexBeforeTx = client.submit("v=graph.addVertex(\"name\",\"stephen\")").all().get().get(0).getVertex(); + assertEquals("stephen", vertexBeforeTx.values("name").next()); + + final Vertex vertexFromV = client.submit("graph.vertices().next()").all().get().get(0).getVertex(); + assertEquals("stephen", vertexFromV.values("name").next()); + + final Vertex vertexFromBinding = client.submit("v").all().get().get(0).getVertex(); + assertEquals("stephen", vertexFromBinding.values("name").next()); + + client.submit("v.property(\"color\",\"blue\")").all().get(); + client.submit("graph.tx().commit()").all().get(); + + // Run a sessionless request to change transaction.readWriteConsumer back to AUTO + // The will make the next in session request fail if consumers aren't ThreadLocal + sessionlessClient.submit("graph.vertices().next()").all().get(); + + client.submit("graph.tx().open()").all().get(); + + final Vertex vertexAfterTx = client.submit("graph.vertices().next()").all().get().get(0).getVertex(); + assertEquals("stephen", vertexAfterTx.values("name").next()); + assertEquals("blue", vertexAfterTx.values("color").next()); + + client.submit("graph.tx().rollback()").all().get(); + + cluster.close(); + } + + @Test + public void shouldExecuteInSessionAndSessionlessWithoutOpeningTransaction() throws Exception { + assumeNeo4jIsPresent(); + + final Cluster cluster = Cluster.build().create(); + final Client sessionClient = cluster.connect(name.getMethodName()); + final Client sessionlessClient = cluster.connect(); + + //open transaction in session, then add vertex and commit + sessionClient.submit("graph.tx().open()").all().get(); + final Vertex vertexBeforeTx = sessionClient.submit("v=graph.addVertex(\"name\",\"stephen\")").all().get().get(0).getVertex(); + assertEquals("stephen", vertexBeforeTx.values("name").next()); + sessionClient.submit("graph.tx().commit()").all().get(); + + // check that session transaction is closed + final boolean isOpen = sessionClient.submit("graph.tx().isOpen()").all().get().get(0).getBoolean(); + assertTrue("Transaction should be closed", !isOpen); + + //run a sessionless read + sessionlessClient.submit("graph.traversal().V()").all().get(); + + // check that session transaction is still closed + final boolean isOpenAfterSessionless = sessionClient.submit("graph.tx().isOpen()").all().get().get(0).getBoolean(); + assertTrue("Transaction should stil be closed", !isOpenAfterSessionless); + + } + + @Test + public void shouldExecuteSessionlessScriptOnTransactionalGraph() throws Exception { + assumeNeo4jIsPresent(); + + final Cluster cluster = Cluster.build().create(); + final Client client = cluster.connect(); + + // this line is important because it tests GraphTraversal which has a certain transactional path + final Vertex vertexRequest1 = client.submit("g.addV(\"name\",\"stephen\")").all().get().get(0).getVertex(); + assertEquals("stephen", vertexRequest1.values("name").next()); + + final Vertex vertexRequest2 = client.submit("graph.vertices().next()").all().get().get(0).getVertex(); + assertEquals("stephen", vertexRequest2.values("name").next()); + + // this line is important because it tests the other transactional path + final Vertex vertexRequest3 = client.submit("graph.addVertex(\"name\",\"marko\")").all().get().get(0).getVertex(); + assertEquals("marko", vertexRequest3.values("name").next()); + + assertEquals(2, client.submit("g.V().count()").all().get().get(0).getLong()); + + cluster.close(); + } + + @Test + public void shouldExecuteScriptInSessionWithBindingsSavedOnServerBetweenRequests() throws Exception { + final Cluster cluster = Cluster.build().create(); + final Client client = cluster.connect(name.getMethodName()); + + final Map<String, Object> bindings1 = new HashMap<>(); + bindings1.put("a", 100); + bindings1.put("b", 200); + final ResultSet results1 = client.submit("x = a + b", bindings1); + assertEquals(300, results1.one().getInt()); + + final Map<String, Object> bindings2 = new HashMap<>(); + bindings2.put("b", 100); + final ResultSet results2 = client.submit("x + b + a", bindings2); + assertEquals(500, results2.one().getInt()); + + final Map<String, Object> bindings3 = new HashMap<>(); + bindings3.put("x", 100); + final ResultSet results3 = client.submit("x + b + a + 1", bindings3); + assertEquals(301, results3.one().getInt()); + + final Map<String, Object> bindings4 = new HashMap<>(); + final ResultSet results4 = client.submit("x + b + a + 1", bindings4); + assertEquals(301, results4.one().getInt()); + + cluster.close(); + } + + @Test + public void shouldExecuteScriptsInMultipleSession() throws Exception { + final Cluster cluster = Cluster.build().create(); + final Client client1 = cluster.connect(name.getMethodName() + "1"); + final Client client2 = cluster.connect(name.getMethodName() + "2"); + final Client client3 = cluster.connect(name.getMethodName() + "3"); + + final ResultSet results11 = client1.submit("x = 1"); + final ResultSet results21 = client2.submit("x = 2"); + final ResultSet results31 = client3.submit("x = 3"); + assertEquals(1, results11.all().get().get(0).getInt()); + assertEquals(2, results21.all().get().get(0).getInt()); + assertEquals(3, results31.all().get().get(0).getInt()); + + final ResultSet results12 = client1.submit("x + 100"); + final ResultSet results22 = client2.submit("x * 2"); + final ResultSet results32 = client3.submit("x * 10"); + assertEquals(101, results12.all().get().get(0).getInt()); + assertEquals(4, results22.all().get().get(0).getInt()); + assertEquals(30, results32.all().get().get(0).getInt()); + + cluster.close(); + } + + @Test + public void shouldNotHaveKnowledgeOfBindingsBetweenRequestsWhenSessionless() throws Exception { + final Cluster cluster = Cluster.build().create(); + final Client client1 = cluster.connect(); + final Client client2 = cluster.connect(); + final Client client3 = cluster.connect(); + + final ResultSet results11 = client1.submit("x = 1"); + final ResultSet results21 = client2.submit("x = 2"); + final ResultSet results31 = client3.submit("x = 3"); + assertEquals(1, results11.all().get().get(0).getInt()); + assertEquals(2, results21.all().get().get(0).getInt()); + assertEquals(3, results31.all().get().get(0).getInt()); + + try { + client1.submit("x").all().get(); + fail("The variable 'x' should not be present on the new request."); + } catch (Exception ex) { + final Throwable root = ExceptionUtils.getRootCause(ex); + assertThat(root, IsInstanceOf.instanceOf(ResponseException.class)); + assertThat(root.getMessage(), containsString("No such property: x for class")); + } + + try { + client2.submit("x").all().get(); + fail("The variable 'x' should not be present on the new request."); + } catch (Exception ex) { + final Throwable root = ExceptionUtils.getRootCause(ex); + assertThat(root, IsInstanceOf.instanceOf(ResponseException.class)); + assertThat(root.getMessage(), containsString("No such property: x for class")); + } + + try { + client3.submit("x").all().get(); + fail("The variable 'x' should not be present on the new request."); + } catch (Exception ex) { + final Throwable root = ExceptionUtils.getRootCause(ex); + assertThat(root, IsInstanceOf.instanceOf(ResponseException.class)); + assertThat(root.getMessage(), containsString("No such property: x for class")); + } + + cluster.close(); + } @Test public void shouldBeThreadSafeToUseOneClient() throws Exception { @@ -995,202 +995,202 @@ public class GremlinDriverIntegrateTest extends AbstractGremlinServerIntegration } } -// @Test -// public void shouldRequireAliasedGraphVariablesInStrictTransactionMode() throws Exception { -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(); -// -// try { -// client.submit("1+1").all().get(); -// fail("Should have tossed an exception because strict mode is on and no aliasing was performed"); -// } catch (Exception ex) { -// final Throwable root = ExceptionUtils.getRootCause(ex); -// assertThat(root, instanceOf(ResponseException.class)); -// final ResponseException re = (ResponseException) root; -// assertEquals(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS, re.getResponseStatusCode()); -// } -// -// cluster.close(); -// } -// -// @Test -// public void shouldAliasGraphVariablesInStrictTransactionMode() throws Exception { -// assumeNeo4jIsPresent(); -// -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(); -// -// try { -// client.submit("g.addVertex('name','stephen');").all().get().get(0).getVertex(); -// fail("Should have tossed an exception because \"g\" does not have the addVertex method under default config"); -// } catch (Exception ex) { -// final Throwable root = ExceptionUtils.getRootCause(ex); -// assertThat(root, instanceOf(ResponseException.class)); -// final ResponseException re = (ResponseException) root; -// assertEquals(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS, re.getResponseStatusCode()); -// } -// -// // keep the testing here until "rebind" is completely removed -// final Client reboundLegacy = cluster.connect().rebind("graph"); -// final Vertex vLegacy = reboundLegacy.submit("g.addVertex('name','stephen')").all().get().get(0).getVertex(); -// assertEquals("stephen", vLegacy.value("name")); -// -// final Client rebound = cluster.connect().alias("graph"); -// final Vertex v = rebound.submit("g.addVertex('name','jason')").all().get().get(0).getVertex(); -// assertEquals("jason", v.value("name")); -// -// cluster.close(); -// } -// -// @Test -// public void shouldAliasGraphVariables() throws Exception { -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(); -// -// try { -// client.submit("g.addVertex('name','stephen');").all().get().get(0).getVertex(); -// fail("Should have tossed an exception because \"g\" does not have the addVertex method under default config"); -// } catch (Exception ex) { -// final Throwable root = ExceptionUtils.getRootCause(ex); -// assertThat(root, instanceOf(ResponseException.class)); -// final ResponseException re = (ResponseException) root; -// assertEquals(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION, re.getResponseStatusCode()); -// } -// -// // keep the testing here until "rebind" is completely removed -// final Client reboundLegacy = cluster.connect().rebind("graph"); -// final Vertex vLegacy = reboundLegacy.submit("g.addVertex('name','stephen')").all().get().get(0).getVertex(); -// assertEquals("stephen", vLegacy.value("name")); -// -// final Client rebound = cluster.connect().alias("graph"); -// final Vertex v = rebound.submit("g.addVertex('name','jason')").all().get().get(0).getVertex(); -// assertEquals("jason", v.value("name")); -// -// cluster.close(); -// } -// -// @Test -// public void shouldAliasTraversalSourceVariables() throws Exception { -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(); -// -// try { -// client.submit("g.addV('name','stephen')").all().get().get(0).getVertex(); -// fail("Should have tossed an exception because \"g\" is readonly in this context"); -// } catch (Exception ex) { -// final Throwable root = ExceptionUtils.getRootCause(ex); -// assertThat(root, instanceOf(ResponseException.class)); -// final ResponseException re = (ResponseException) root; -// assertEquals(ResponseStatusCode.SERVER_ERROR, re.getResponseStatusCode()); -// } -// -// // keep the testing here until "rebind" is completely removed -// final Client clientLegacy = client.rebind("g1"); -// final Vertex vLegacy = clientLegacy.submit("g.addV('name','stephen')").all().get().get(0).getVertex(); -// assertEquals("stephen", vLegacy.value("name")); -// -// final Client clientAliased = client.alias("g1"); -// final Vertex v = clientAliased.submit("g.addV('name','jason')").all().get().get(0).getVertex(); -// assertEquals("jason", v.value("name")); -// -// cluster.close(); -// } -// -// @Test -// public void shouldAliasGraphVariablesInSession() throws Exception { -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(name.getMethodName()); -// -// try { -// client.submit("g.addVertex('name','stephen');").all().get().get(0).getVertex(); -// fail("Should have tossed an exception because \"g\" does not have the addVertex method under default config"); -// } catch (Exception ex) { -// final Throwable root = ExceptionUtils.getRootCause(ex); -// assertThat(root, instanceOf(ResponseException.class)); -// final ResponseException re = (ResponseException) root; -// assertEquals(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION, re.getResponseStatusCode()); -// } -// -// // keep the testing here until "rebind" is completely removed -// final Client reboundLegacy = client.rebind("graph"); -// assertEquals("stephen", reboundLegacy.submit("n='stephen'").all().get().get(0).getString()); -// final Vertex vLegacy = reboundLegacy.submit("g.addVertex('name',n)").all().get().get(0).getVertex(); -// assertEquals("stephen", vLegacy.value("name")); -// -// final Client aliased = client.alias("graph"); -// assertEquals("jason", reboundLegacy.submit("n='jason'").all().get().get(0).getString()); -// final Vertex v = aliased.submit("g.addVertex('name',n)").all().get().get(0).getVertex(); -// assertEquals("jason", v.value("name")); -// -// cluster.close(); -// } -// -// @Test -// public void shouldAliasTraversalSourceVariablesInSession() throws Exception { -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(name.getMethodName()); -// -// try { -// client.submit("g.addV('name','stephen')").all().get().get(0).getVertex(); -// fail("Should have tossed an exception because \"g\" is readonly in this context"); -// } catch (Exception ex) { -// final Throwable root = ExceptionUtils.getRootCause(ex); -// assertThat(root, instanceOf(ResponseException.class)); -// final ResponseException re = (ResponseException) root; -// assertEquals(ResponseStatusCode.SERVER_ERROR, re.getResponseStatusCode()); -// } -// -// // keep the testing here until "rebind" is completely removed -// final Client clientLegacy = client.rebind("g1"); -// assertEquals("stephen", clientLegacy.submit("n='stephen'").all().get().get(0).getString()); -// final Vertex vLegacy = clientLegacy.submit("g.addV('name',n)").all().get().get(0).getVertex(); -// assertEquals("stephen", vLegacy.value("name")); -// -// final Client clientAliased = client.alias("g1"); -// assertEquals("jason", clientAliased.submit("n='jason'").all().get().get(0).getString()); -// final Vertex v = clientAliased.submit("g.addV('name',n)").all().get().get(0).getVertex(); -// assertEquals("jason", v.value("name")); -// -// cluster.close(); -// } -// -// @Test -// public void shouldManageTransactionsInSession() throws Exception { -// assumeNeo4jIsPresent(); -// -// final Cluster cluster = Cluster.build().create(); -// final Client client = cluster.connect(); -// final Client sessionWithManagedTx = cluster.connect(name.getMethodName() + "-managed", true); -// final Client sessionWithoutManagedTx = cluster.connect(name.getMethodName() + "-not-managed"); -// -// // this should auto-commit -// final Vertex vStephen = sessionWithManagedTx.submit("v = g.addV('name','stephen').next()").all().get().get(0).getVertex(); -// assertEquals("stephen", vStephen.value("name")); -// -// // the other clients should see that change because of auto-commit -// assertThat(client.submit("g.V().has('name','stephen').hasNext()").all().get().get(0).getBoolean(), is(true)); -// assertThat(sessionWithoutManagedTx.submit("g.V().has('name','stephen').hasNext()").all().get().get(0).getBoolean(), is(true)); -// -// // this should NOT auto-commit -// final Vertex vDaniel = sessionWithoutManagedTx.submit("v = g.addV('name','daniel').next()").all().get().get(0).getVertex(); -// assertEquals("daniel", vDaniel.value("name")); -// -// // the other clients should NOT see that change because of auto-commit -// assertThat(client.submit("g.V().has('name','daniel').hasNext()").all().get().get(0).getBoolean(), is(false)); -// assertThat(sessionWithManagedTx.submit("g.V().has('name','daniel').hasNext()").all().get().get(0).getBoolean(), is(false)); -// -// // but "v" should still be there -// final Vertex vDanielAgain = sessionWithoutManagedTx.submit("v").all().get().get(0).getVertex(); -// assertEquals("daniel", vDanielAgain.value("name")); -// -// // now commit manually -// sessionWithoutManagedTx.submit("g.tx().commit()").all().get(); -// -// // should be there for all now -// assertThat(client.submit("g.V().has('name','daniel').hasNext()").all().get().get(0).getBoolean(), is(true)); -// assertThat(sessionWithManagedTx.submit("g.V().has('name','daniel').hasNext()").all().get().get(0).getBoolean(), is(true)); -// assertThat(sessionWithoutManagedTx.submit("g.V().has('name','daniel').hasNext()").all().get().get(0).getBoolean(), is(true)); -// -// cluster.close(); -// } + @Test + public void shouldRequireAliasedGraphVariablesInStrictTransactionMode() throws Exception { + final Cluster cluster = Cluster.build().create(); + final Client client = cluster.connect(); + + try { + client.submit("1+1").all().get(); + fail("Should have tossed an exception because strict mode is on and no aliasing was performed"); + } catch (Exception ex) { + final Throwable root = ExceptionUtils.getRootCause(ex); + assertThat(root, instanceOf(ResponseException.class)); + final ResponseException re = (ResponseException) root; + assertEquals(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS, re.getResponseStatusCode()); + } + + cluster.close(); + } + + @Test + public void shouldAliasGraphVariablesInStrictTransactionMode() throws Exception { + assumeNeo4jIsPresent(); + + final Cluster cluster = Cluster.build().create(); + final Client client = cluster.connect(); + + try { + client.submit("g.addVertex('name','stephen');").all().get().get(0).getVertex(); + fail("Should have tossed an exception because \"g\" does not have the addVertex method under default config"); + } catch (Exception ex) { + final Throwable root = ExceptionUtils.getRootCause(ex); + assertThat(root, instanceOf(ResponseException.class)); + final ResponseException re = (ResponseException) root; + assertEquals(ResponseStatusCode.REQUEST_ERROR_INVALID_REQUEST_ARGUMENTS, re.getResponseStatusCode()); + } + + // keep the testing here until "rebind" is completely removed + final Client reboundLegacy = cluster.connect().rebind("graph"); + final Vertex vLegacy = reboundLegacy.submit("g.addVertex('name','stephen')").all().get().get(0).getVertex(); + assertEquals("stephen", vLegacy.value("name")); + + final Client rebound = cluster.connect().alias("graph"); + final Vertex v = rebound.submit("g.addVertex('name','jason')").all().get().get(0).getVertex(); + assertEquals("jason", v.value("name")); + + cluster.close(); + } + + @Test + public void shouldAliasGraphVariables() throws Exception { + final Cluster cluster = Cluster.build().create(); + final Client client = cluster.connect(); + + try { + client.submit("g.addVertex('name','stephen');").all().get().get(0).getVertex(); + fail("Should have tossed an exception because \"g\" does not have the addVertex method under default config"); + } catch (Exception ex) { + final Throwable root = ExceptionUtils.getRootCause(ex); + assertThat(root, instanceOf(ResponseException.class)); + final ResponseException re = (ResponseException) root; + assertEquals(ResponseStatusCode.SERVER_ERROR_SCRIPT_EVALUATION, re.getResponseStatusCode()); + } + + // keep the testing here until "rebind" is completely removed + final Client reboundLegacy = cluster.connect().rebind("graph"); + final Vertex vLegacy = reboundLegacy.submit("g.addVertex('name','stephen')").all().get().get(0).getVertex(); + assertEquals("stephen", vLegacy.value("name")); + + final Client rebound = cluster.connect().alias("graph"); + final Vertex v = rebound.submit("g.addVertex('name','jason')").all().get().get(0).getVertex(); + assertEquals("jason", v.value("name")); + + cluster.close(); + <TRUNCATED>