| #region License |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| #endregion |
| |
| using System; |
| using System.Collections.Generic; |
| using System.Net.WebSockets; |
| using System.Threading.Tasks; |
| using Gremlin.Net.Driver; |
| using Gremlin.Net.Driver.Exceptions; |
| using Gremlin.Net.Driver.Messages; |
| using Gremlin.Net.IntegrationTest.Util; |
| using Newtonsoft.Json.Linq; |
| using Xunit; |
| |
| namespace Gremlin.Net.IntegrationTest.Driver |
| { |
| public class GremlinClientTests |
| { |
| private readonly RequestMessageProvider _requestMessageProvider = new RequestMessageProvider(); |
| private static readonly string TestHost = ConfigProvider.Configuration["TestServerIpAddress"]; |
| private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestServerPort"]); |
| |
| [Theory] |
| [InlineData("'justAString'", "justAString")] |
| [InlineData("'Hello' + 'World'", "HelloWorld")] |
| public async Task ShouldSendScriptForEvaluationAndReturnCorrectResult(string requestMsg, string expectedResponse) |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using (var gremlinClient = new GremlinClient(gremlinServer)) |
| { |
| var response = await gremlinClient.SubmitWithSingleResultAsync<string>(requestMsg); |
| |
| Assert.Equal(expectedResponse, response); |
| } |
| } |
| |
| [Fact] |
| public async Task ShouldHandleBigResponse() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using (var gremlinClient = new GremlinClient(gremlinServer)) |
| { |
| var responseMsgSize = 5000; |
| var requestMsg = $"'1'*{responseMsgSize}"; |
| |
| var response = await gremlinClient.SubmitWithSingleResultAsync<string>(requestMsg); |
| |
| Assert.Equal(responseMsgSize, response.Length); |
| } |
| } |
| |
| [Fact] |
| public async Task ShouldReturnResultWithoutDeserializingItForJTokenType() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using (var gremlinClient = new GremlinClient(gremlinServer)) |
| { |
| var gremlinScript = "'someString'"; |
| |
| var response = await gremlinClient.SubmitWithSingleResultAsync<JToken>(gremlinScript); |
| |
| //Expected: |
| /* { |
| "@type": "g:List", |
| "@value": [ |
| "someString" |
| ] |
| }*/ |
| |
| Assert.IsType<JObject>(response); |
| Assert.Equal("g:List", response["@type"]); |
| |
| var jArray = response["@value"] as JArray; |
| Assert.NotNull(jArray); |
| Assert.Equal(1, jArray.Count); |
| Assert.Equal("someString", (jArray[0] as JValue)?.Value); |
| } |
| } |
| |
| [Fact] |
| public async Task ShouldHandleResponseWithoutContent() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using (var gremlinClient = new GremlinClient(gremlinServer)) |
| { |
| var gremlinScript = "g.V().has(propertyKey, propertyValue);"; |
| var bindings = new Dictionary<string, object> |
| { |
| {"propertyKey", "name"}, |
| {"propertyValue", "unknownTestName"} |
| }; |
| |
| var response = |
| await gremlinClient.SubmitWithSingleResultAsync<object>(gremlinScript, bindings); |
| |
| Assert.Null(response); |
| } |
| } |
| |
| [Fact] |
| public async Task ShouldThrowExceptionForInvalidScript() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using (var gremlinClient = new GremlinClient(gremlinServer)) |
| { |
| var requestMsg = "invalid"; |
| |
| var exception = |
| await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync(requestMsg)); |
| |
| Assert.Equal(typeof(ResponseException), exception.GetType()); |
| Assert.Contains($"ScriptEvaluationError: No such property: {requestMsg}", |
| exception.Message); |
| } |
| } |
| |
| [Fact] |
| public async Task ShouldReassembleResponseBatches() |
| { |
| const int batchSize = 2; |
| var expectedResult = new List<int> {1, 2, 3, 4, 5}; |
| var requestScript = $"{nameof(expectedResult)}"; |
| var bindings = new Dictionary<string, object> {{nameof(expectedResult), expectedResult}}; |
| var requestMessage = |
| RequestMessage.Build(Tokens.OpsEval) |
| .AddArgument(Tokens.ArgsBatchSize, batchSize) |
| .AddArgument(Tokens.ArgsGremlin, requestScript) |
| .AddArgument(Tokens.ArgsBindings, bindings) |
| .Create(); |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using (var gremlinClient = new GremlinClient(gremlinServer)) |
| { |
| var response = await gremlinClient.SubmitAsync<int>(requestMessage); |
| |
| Assert.Equal(expectedResult, response); |
| } |
| } |
| |
| [Fact] |
| public async Task ShouldCorrectlyAssignResponsesToRequests() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using (var gremlinClient = new GremlinClient(gremlinServer)) |
| { |
| var sleepTime = 100; |
| var expectedFirstResult = 1; |
| var gremlinScript = _requestMessageProvider.GetSleepGremlinScript(sleepTime); |
| gremlinScript += $"{expectedFirstResult}"; |
| var firstRequestMsg = RequestMessage.Build(Tokens.OpsEval) |
| .AddArgument(Tokens.ArgsGremlin, gremlinScript).Create(); |
| var expectedSecondResponse = 2; |
| var secondScript = $"{expectedSecondResponse}"; |
| |
| var firstResponseTask = gremlinClient.SubmitWithSingleResultAsync<int>(firstRequestMsg); |
| var secondResponseTask = gremlinClient.SubmitWithSingleResultAsync<int>(secondScript); |
| |
| var secondResponse = await secondResponseTask; |
| Assert.Equal(expectedSecondResponse, secondResponse); |
| var firstResponse = await firstResponseTask; |
| Assert.Equal(expectedFirstResult, firstResponse); |
| } |
| } |
| |
| [Fact] |
| public async Task ShouldReturnEnumerableResult() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using (var gremlinClient = new GremlinClient(gremlinServer)) |
| { |
| var expectedResult = new List<int> {1, 2, 3, 4, 5}; |
| var requestMsg = $"{nameof(expectedResult)}"; |
| var bindings = new Dictionary<string, object> {{nameof(expectedResult), expectedResult}}; |
| |
| var response = await gremlinClient.SubmitAsync<int>(requestMsg, bindings); |
| |
| Assert.Equal(expectedResult, response); |
| } |
| } |
| |
| [Fact] |
| public async Task ShouldThrowOnExecutionOfSimpleInvalidScript() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using (var gremlinClient = new GremlinClient(gremlinServer)) |
| { |
| var invalidRequestScript = "invalid"; |
| |
| await Assert.ThrowsAsync<ResponseException>(() => gremlinClient.SubmitAsync(invalidRequestScript)); |
| } |
| } |
| |
| [Fact] |
| public async Task ShouldHandleSimpleScriptWithoutErrors() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using (var gremlinClient = new GremlinClient(gremlinServer)) |
| { |
| var requestMsg = _requestMessageProvider.GetDummyMessage(); |
| |
| await gremlinClient.SubmitAsync(requestMsg); |
| } |
| } |
| |
| [Fact] |
| public async Task ShouldUseBindingsForScript() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using (var gremlinClient = new GremlinClient(gremlinServer)) |
| { |
| var requestMsg = "a + b"; |
| var a = 1; |
| var b = 2; |
| var bindings = new Dictionary<string, object> {{"a", a}, {"b", b}}; |
| |
| var response = |
| await gremlinClient.SubmitWithSingleResultAsync<int>(requestMsg, bindings); |
| |
| Assert.Equal(a + b, response); |
| } |
| } |
| |
| [Fact] |
| public async Task ShouldConfigureWebSocketOptionsAsSpecified() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| ClientWebSocketOptions optionsSet = null; |
| var expectedKeepAliveInterval = TimeSpan.FromMilliseconds(11); |
| var webSocketConfiguration = |
| new Action<ClientWebSocketOptions>(options => |
| { |
| options.UseDefaultCredentials = false; |
| options.KeepAliveInterval = expectedKeepAliveInterval; |
| optionsSet = options; |
| }); |
| using (var gremlinClient = new GremlinClient(gremlinServer, webSocketConfiguration: webSocketConfiguration)) |
| { |
| // send dummy message to create at least one connection |
| await gremlinClient.SubmitAsync(_requestMessageProvider.GetDummyMessage()); |
| |
| Assert.NotNull(optionsSet); |
| Assert.False(optionsSet.UseDefaultCredentials); |
| Assert.Equal(expectedKeepAliveInterval, optionsSet.KeepAliveInterval); |
| } |
| } |
| |
| [Fact] |
| public async Task ShouldSaveVariableBetweenRequestsInSession() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| var sessionId = Guid.NewGuid().ToString(); |
| using (var gremlinClient = new GremlinClient(gremlinServer, sessionId: sessionId)) |
| { |
| await gremlinClient.SubmitAsync<int>("x = 1"); |
| |
| var expectedResult = new List<int> {3}; |
| var response = await gremlinClient.SubmitAsync<int>("x + 2"); |
| |
| Assert.Equal(expectedResult, response); |
| } |
| |
| using (var gremlinClient = new GremlinClient(gremlinServer, sessionId: sessionId)) |
| { |
| try |
| { |
| await gremlinClient.SubmitAsync<int>("x"); |
| Assert.True(false, "The 'x' variable should not exist after session close"); |
| } |
| catch (Exception ignored) |
| { |
| // do nothing |
| } |
| } |
| } |
| } |
| } |