| #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.Collections.ObjectModel; |
| using System.Threading.Tasks; |
| using Gremlin.Net.Driver; |
| using Gremlin.Net.Driver.Remote; |
| using Gremlin.Net.Process.Traversal; |
| using Gremlin.Net.Structure; |
| using Gremlin.Net.Structure.IO.GraphBinary4; |
| using Microsoft.Extensions.Logging; |
| using NSubstitute; |
| using Xunit; |
| |
| namespace Gremlin.Net.IntegrationTest.Driver; |
| |
| public class DriverRemoteConnectionTests |
| { |
| private static readonly string TestHost = ConfigProvider.Configuration["TestServerIpAddress"]!; |
| private static readonly int TestPort = Convert.ToInt32(ConfigProvider.Configuration["TestServerPort"]); |
| |
| [Fact] |
| public async Task ShouldLogWithProvidedLoggerFactory() |
| { |
| var loggerFactory = Substitute.For<ILoggerFactory>(); |
| var logger = Substitute.For<ILogger>(); |
| logger.IsEnabled(Arg.Any<LogLevel>()).Returns(true); |
| loggerFactory.CreateLogger(Arg.Any<string>()).Returns(logger); |
| using var driverRemoteConnection = new DriverRemoteConnection(TestHost, TestPort, loggerFactory: loggerFactory); |
| var gremlinLangToLog = SomeValidGremlinLang; |
| |
| await driverRemoteConnection.SubmitAsync<object, object>(gremlinLangToLog); |
| |
| logger.VerifyMessageWasLogged(LogLevel.Debug, gremlinLangToLog.ToString()); |
| } |
| |
| [Fact] |
| public async Task ShouldNotLogForDisabledLogLevel() |
| { |
| var loggerFactory = Substitute.For<ILoggerFactory>(); |
| var logger = Substitute.For<ILogger>(); |
| logger.IsEnabled(Arg.Any<LogLevel>()).Returns(false); |
| loggerFactory.CreateLogger(Arg.Any<string>()).Returns(logger); |
| using var driverRemoteConnection = new DriverRemoteConnection(TestHost, TestPort, loggerFactory: loggerFactory); |
| |
| await driverRemoteConnection.SubmitAsync<object, object>(SomeValidGremlinLang); |
| |
| logger.VerifyNothingWasLogged(); |
| } |
| |
| [Fact] |
| public async Task ShouldLogWithLoggerFactoryFromGremlinClient() |
| { |
| var loggerFactory = Substitute.For<ILoggerFactory>(); |
| var logger = Substitute.For<ILogger>(); |
| logger.IsEnabled(Arg.Any<LogLevel>()).Returns(true); |
| loggerFactory.CreateLogger(Arg.Any<string>()).Returns(logger); |
| using var gremlinClient = |
| new GremlinClient(new GremlinServer(TestHost, TestPort), loggerFactory: loggerFactory); |
| var driverRemoteConnection = new DriverRemoteConnection(gremlinClient); |
| var gremlinLangToLog = SomeValidGremlinLang; |
| |
| await driverRemoteConnection.SubmitAsync<object, object>(SomeValidGremlinLang); |
| |
| logger.VerifyMessageWasLogged(LogLevel.Debug, gremlinLangToLog.ToString()); |
| } |
| |
| private static GremlinLang SomeValidGremlinLang |
| { |
| get |
| { |
| var gremlinLang = new GremlinLang(); |
| gremlinLang.AddStep("inject", 1, 2); |
| return gremlinLang; |
| } |
| } |
| |
| [Fact] |
| public void ShouldRoundTripPdtViaTraversalApi() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using var gremlinClient = new GremlinClient(gremlinServer); |
| using var connection = new DriverRemoteConnection(gremlinClient, "gmodern"); |
| var g = AnonymousTraversalSource.Traversal().With(connection); |
| |
| var pdt = new CompositePDT("TestPoint", |
| new Dictionary<string, object?> { { "x", 1 }, { "y", 2 } }); |
| |
| var results = g.Inject<object>(pdt).ToList(); |
| |
| Assert.Single(results); |
| var result = Assert.IsType<CompositePDT>(results[0]); |
| Assert.Equal("TestPoint", result.Name); |
| Assert.Equal(1, result.Fields["x"]); |
| Assert.Equal(2, result.Fields["y"]); |
| } |
| |
| [Fact] |
| public void ShouldRoundTripTypedObjectViaRegistry() |
| { |
| var registry = new PDTRegistry(); |
| registry.Register(new TestPointAdapter()); |
| |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using var gremlinClient = new GremlinClient(gremlinServer, pdtRegistry: registry); |
| using var connection = new DriverRemoteConnection(gremlinClient, "gmodern", pdtRegistry: registry); |
| var g = AnonymousTraversalSource.Traversal().With(connection); |
| |
| var point = new TestPointClass { X = 5, Y = 10 }; |
| |
| var results = g.Inject<object>(point).ToList(); |
| |
| Assert.Single(results); |
| var result = Assert.IsType<TestPointClass>(results[0]); |
| Assert.Equal(5, result.X); |
| Assert.Equal(10, result.Y); |
| } |
| |
| [Fact] |
| public void ShouldRoundTripAnnotatedClass() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using var gremlinClient = new GremlinClient(gremlinServer); |
| using var connection = new DriverRemoteConnection(gremlinClient, "gmodern"); |
| var g = AnonymousTraversalSource.Traversal().With(connection); |
| |
| var point = new AnnotatedTestPoint { X = 3, Y = 7 }; |
| |
| var results = g.Inject<object>(point).ToList(); |
| |
| Assert.Single(results); |
| var result = Assert.IsType<AnnotatedTestPoint>(results[0]); |
| Assert.Equal(3, result.X); |
| Assert.Equal(7, result.Y); |
| } |
| |
| [Fact] |
| public void ShouldRoundTripPrimitivePdtViaTraversalApi() |
| { |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using var gremlinClient = new GremlinClient(gremlinServer); |
| using var connection = new DriverRemoteConnection(gremlinClient, "gmodern"); |
| var g = AnonymousTraversalSource.Traversal().With(connection); |
| |
| var pdt = new PrimitivePDT("TestToken", "abc123"); |
| |
| var results = g.Inject<object>(pdt).ToList(); |
| |
| Assert.Single(results); |
| var result = Assert.IsType<PrimitivePDT>(results[0]); |
| Assert.Equal("TestToken", result.Name); |
| Assert.Equal("abc123", result.Value); |
| } |
| |
| [Fact] |
| public void ShouldRoundTripPrimitiveTypedObjectViaRegistry() |
| { |
| var registry = new PDTRegistry(); |
| registry.RegisterPrimitive(new TestUint32Adapter()); |
| |
| var gremlinServer = new GremlinServer(TestHost, TestPort); |
| using var gremlinClient = new GremlinClient(gremlinServer, pdtRegistry: registry); |
| using var connection = new DriverRemoteConnection(gremlinClient, "gmodern", pdtRegistry: registry); |
| var g = AnonymousTraversalSource.Traversal().With(connection); |
| |
| var val = 42u; |
| |
| var results = g.Inject<object>(val).ToList(); |
| |
| Assert.Single(results); |
| Assert.IsType<uint>(results[0]); |
| Assert.Equal(42u, (uint)results[0]); |
| } |
| |
| #region Test helpers |
| |
| private class TestPointClass |
| { |
| public int X { get; set; } |
| public int Y { get; set; } |
| } |
| |
| private class TestPointAdapter : IProviderDefinedTypeAdapter<TestPointClass> |
| { |
| public string TypeName => "TestPoint"; |
| |
| public TestPointClass FromFields(IReadOnlyDictionary<string, object?> fields) |
| { |
| return new TestPointClass |
| { |
| X = Convert.ToInt32(fields["x"]), |
| Y = Convert.ToInt32(fields["y"]) |
| }; |
| } |
| |
| public IReadOnlyDictionary<string, object?> ToFields(TestPointClass obj) |
| { |
| return new ReadOnlyDictionary<string, object?>( |
| new Dictionary<string, object?> { { "x", obj.X }, { "y", obj.Y } }); |
| } |
| } |
| |
| [ProviderDefined(Name = "TestPoint")] |
| private class AnnotatedTestPoint |
| { |
| public int X { get; set; } |
| public int Y { get; set; } |
| } |
| |
| private class TestUint32Adapter : IPrimitivePdtAdapter<uint> |
| { |
| public string TypeName => "TestToken"; |
| public uint FromString(string value) => uint.Parse(value); |
| public string ToString(uint obj) => obj.ToString(); |
| } |
| |
| #endregion |
| } |