You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by xi...@apache.org on 2023/01/11 19:41:15 UTC
[tinkerpop] branch master updated: Adds tests for user agent feature (#1923)
This is an automated email from the ASF dual-hosted git repository.
xiazcy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/master by this push:
new f1df1a670c Adds tests for user agent feature (#1923)
f1df1a670c is described below
commit f1df1a670c9fb2cfcab27df6b8a402437cd900ff
Author: Cole Greer <11...@users.noreply.github.com>
AuthorDate: Wed Jan 11 11:41:09 2023 -0800
Adds tests for user agent feature (#1923)
Adds a test to each GLV which uses gremlin-socket-server to confirm that
the driver is sending the correct user agent. Also adds a test which verifies
that the user agent is not sent if it has been disabled in the driver config.
---
gremlin-dotnet/src/Gremlin.Net/Process/Utils.cs | 3 ++
.../src/Gremlin.Net/Properties/AssemblyInfo.cs | 1 +
.../GremlinClientBehaviorIntegrationTests.cs | 30 +++++++++++-
.../Gremlin.Net.IntegrationTest.csproj | 3 ++
gremlin-go/driver/client_test.go | 55 ++++++++++++++++++++++
.../javascript/gremlin-javascript/test/helper.js | 20 ++++++--
.../test/integration/client-behavior-tests.js | 15 ++++++
gremlin-python/src/main/python/tests/conftest.py | 36 ++++++++++----
.../driver/test_web_socket_client_behavior.py | 26 ++++++++++
.../socket/server/TestWSGremlinInitializer.java | 5 +-
10 files changed, 179 insertions(+), 15 deletions(-)
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Utils.cs b/gremlin-dotnet/src/Gremlin.Net/Process/Utils.cs
index 8e13b2d25a..be76feac9f 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Utils.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Utils.cs
@@ -34,6 +34,9 @@ namespace Gremlin.Net.Process
/// </summary>
internal static class Utils
{
+ /// <summary>
+ /// The user agent which is sent with connection requests if enabled.
+ /// </summary>
public static string UserAgent => _userAgent ??= GenerateUserAgent();
private static string? _userAgent;
diff --git a/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs b/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs
index 4351b0e902..e6c1a7e784 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Properties/AssemblyInfo.cs
@@ -24,4 +24,5 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Gremlin.Net.UnitTest, PublicKey=00240000048000009400000006020000002400005253413100040000010001009bbf7a5b9966d9207d8abb9d3d3e98f5e387b292742cfb791dc657357221c3ac9b38ab6dab89630dc8edb3cde84a107f493d192116a934afa463355eefd58b82fd08dc2616ee6074a74bf5845652864746e285bd04e2e1a87921e8e2c383d1b302e7bee1fd7cdab5fe2bbed8c6677624d63433548d43a873ab5650ed96fb0687")]
+[assembly: InternalsVisibleTo("Gremlin.Net.IntegrationTest, PublicKey=00240000048000009400000006020000002400005253413100040000010001009bbf7a5b9966d9207d8abb9d3d3e98f5e387b292742cfb791dc657357221c3ac9b38ab6dab89630dc8edb3cde84a107f493d192116a934afa463355eefd58b82fd08dc2616ee6074a74bf5845652864746e285bd04e2e1a87921e8e2c383d1b302e7bee1fd7cdab5fe2bbed8c6677624d63433548d43a873ab5650ed96fb0687")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
\ No newline at end of file
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientBehaviorIntegrationTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientBehaviorIntegrationTests.cs
index 6fc4f16fd9..b6354d0409 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientBehaviorIntegrationTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Driver/GremlinClientBehaviorIntegrationTests.cs
@@ -22,7 +22,6 @@
#endregion
using System;
-using System.Linq;
using System.Threading.Tasks;
using Gremlin.Net.Driver;
using Gremlin.Net.Driver.Exceptions;
@@ -68,7 +67,7 @@ namespace Gremlin.Net.IntegrationTest.Driver
var poolSettings = new ConnectionPoolSettings {PoolSize = 1};
var gremlinServer = new GremlinServer(TestHost, Settings.Port);
- var gremlinClient = new GremlinClient(gremlinServer, messageSerializer: Serializer,
+ using var gremlinClient = new GremlinClient(gremlinServer, messageSerializer: Serializer,
connectionPoolSettings: poolSettings, sessionId: sessionId);
Assert.Equal(1, gremlinClient.NrConnections);
@@ -84,5 +83,32 @@ namespace Gremlin.Net.IntegrationTest.Driver
Assert.NotNull(response2);
Assert.Equal(1, gremlinClient.NrConnections);
}
+
+ [Fact]
+ public async Task ShouldIncludeUserAgentInHandshakeRequest()
+ {
+ var gremlinServer = new GremlinServer(TestHost, Settings.Port);
+ using var gremlinClient = new GremlinClient(gremlinServer, messageSerializer: Serializer);
+
+ //verify that the server received the correct user agent during connection setup.
+ var userAgentResponse = await gremlinClient.SubmitWithSingleResultAsync<String>(RequestMessage.Build("1")
+ .OverrideRequestId(Settings.UserAgentRequestId).Create());
+ Assert.Equal(Gremlin.Net.Process.Utils.UserAgent, userAgentResponse);
+ }
+
+ [Fact]
+ public async Task ShouldNotIncludeUserAgentInHandshakeRequestIfDisabled()
+ {
+ var poolSettings = new ConnectionPoolSettings {EnableUserAgentOnConnect = false};
+
+ var gremlinServer = new GremlinServer(TestHost, Settings.Port);
+ using var gremlinClient = new GremlinClient(gremlinServer, messageSerializer: Serializer,
+ connectionPoolSettings: poolSettings);
+
+ //verify that the server did not receive any user agent.
+ var userAgentResponse = await gremlinClient.SubmitWithSingleResultAsync<String>(RequestMessage.Build("1")
+ .OverrideRequestId(Settings.UserAgentRequestId).Create());
+ Assert.Equal("", userAgentResponse);
+ }
}
}
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
index 867672db45..58f670246a 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gremlin.Net.IntegrationTest.csproj
@@ -2,6 +2,9 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
+ <AssemblyOriginatorKeyFile>../../build/tinkerpop.snk</AssemblyOriginatorKeyFile>
+ <SignAssembly>true</SignAssembly>
+ <PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
</PropertyGroup>
<ItemGroup>
<None Update="appsettings.json">
diff --git a/gremlin-go/driver/client_test.go b/gremlin-go/driver/client_test.go
index a09506d787..fdda8eb614 100644
--- a/gremlin-go/driver/client_test.go
+++ b/gremlin-go/driver/client_test.go
@@ -133,6 +133,61 @@ func TestClientAgainstSocketServer(t *testing.T) {
client.Close()
})
+ /**
+ * Tests that client is correctly sending user agent during web socket handshake by having the server return
+ * the captured user agent.
+ */
+ t.Run("Should include user agent in handshake request", func(t *testing.T) {
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ client, err := NewClient(testSocketServerUrl)
+ assert.Nil(t, err)
+ assert.NotNil(t, client)
+
+ resultSet, err := client.Submit("1", map[string]interface{}{"requestId": settings.USER_AGENT_REQUEST_ID})
+ assert.Nil(t, err)
+ assert.NotNil(t, resultSet)
+
+ result, ok, err := resultSet.One()
+ assert.Nil(t, err)
+ assert.True(t, ok)
+ assert.NotNil(t, result)
+
+ userAgentResponse := result.GetString()
+ assert.Equal(t, userAgent, userAgentResponse)
+
+ client.Close()
+ })
+
+ /**
+ * Tests that no user agent (other than the default one provided by gorilla) is sent to server when
+ * that behaviour is disabled.
+ */
+ t.Run("Should not include user agent in handshake request if disabled", func(t *testing.T) {
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ client, err := NewClient(testSocketServerUrl,
+ func(settings *ClientSettings) {
+ settings.EnableUserAgentOnConnect = false
+ })
+ assert.Nil(t, err)
+ assert.NotNil(t, client)
+
+ resultSet, err := client.Submit("1", map[string]interface{}{"requestId": settings.USER_AGENT_REQUEST_ID})
+ assert.Nil(t, err)
+ assert.NotNil(t, resultSet)
+
+ result, ok, err := resultSet.One()
+ assert.Nil(t, err)
+ assert.True(t, ok)
+ assert.NotNil(t, result)
+
+ userAgentResponse := result.GetString()
+ //If the gremlin user agent is disabled, the underlying web socket library reverts to sending its default user agent
+ //during connection requests.
+ assert.Contains(t, userAgentResponse, "Go-http-client/")
+
+ client.Close()
+ })
+
/**
* Note: This test currently fails due to race condition check in go test and is only included for demonstration
* purposes. See https://issues.apache.org/jira/browse/TINKERPOP-2845.
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js
index 60040d0cbf..6232570f68 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/helper.js
@@ -78,11 +78,9 @@ exports.getSessionClient = function getSessionClient(traversalSource) {
});
};
-exports.getGremlinSocketServerClient = function getGremlinSocketServerClient(traversalSource) {
- const settings = exports.getGremlinSocketServerSettings();
- const url = socketServerUrl + settings.PORT + '/gremlin';
+function getMimeTypeFromSocketServerSettings(socketServerSettings) {
let mimeType;
- switch(settings.SERIALIZER) {
+ switch(socketServerSettings.SERIALIZER) {
case "GraphSONV2":
mimeType = 'application/vnd.gremlin-v2.0+json';
break;
@@ -94,9 +92,23 @@ exports.getGremlinSocketServerClient = function getGremlinSocketServerClient(tra
mimeType = 'application/vnd.graphbinary-v1.0';
break;
}
+ return mimeType;
+}
+
+exports.getGremlinSocketServerClient = function getGremlinSocketServerClient(traversalSource) {
+ const settings = exports.getGremlinSocketServerSettings();
+ const url = socketServerUrl + settings.PORT + '/gremlin';
+ let mimeType = getMimeTypeFromSocketServerSettings(settings)
return new Client(url, { traversalSource, mimeType });
};
+exports.getGremlinSocketServerClientNoUserAgent = function getGremlinSocketServerClient(traversalSource) {
+ const settings = exports.getGremlinSocketServerSettings();
+ const url = socketServerUrl + settings.PORT + '/gremlin';
+ let mimeType = getMimeTypeFromSocketServerSettings(settings)
+ return new Client(url, { traversalSource, mimeType, enableUserAgentOnConnect:false });
+};
+
exports.getGremlinSocketServerSettings = function getGremlinSocketServerSettings() {
const settings = yaml.load(fs.readFileSync(sockerServerConfigPath, 'utf8'));
return settings;
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-behavior-tests.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-behavior-tests.js
index 311b809a42..55236e05ad 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-behavior-tests.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/integration/client-behavior-tests.js
@@ -21,6 +21,7 @@
const assert = require('assert');
const helper = require('../helper');
+const {getUserAgent} = require("../../lib/utils");
let client;
let settings;
@@ -49,5 +50,19 @@ describe('Client', function () {
console.log("result received: "+JSON.stringify(result));
assert.ok(result);
});
+ it('should include user agent in handshake request', async function () {
+ let result = await client.submit('1', null, {requestId: settings.USER_AGENT_REQUEST_ID});
+
+ assert.strictEqual(result.first(), getUserAgent());
+ });
+ it('should not include user agent in handshake request if disabled', async function () {
+ let noUserAgentClient = helper.getGremlinSocketServerClientNoUserAgent('gmodern');
+ let result = await noUserAgentClient.submit('1', null,
+ {requestId: settings.USER_AGENT_REQUEST_ID});
+
+ assert.strictEqual(result.first(), "");
+
+ await noUserAgentClient.close();
+ });
});
});
diff --git a/gremlin-python/src/main/python/tests/conftest.py b/gremlin-python/src/main/python/tests/conftest.py
index 224adcb915..9fa82852cf 100644
--- a/gremlin-python/src/main/python/tests/conftest.py
+++ b/gremlin-python/src/main/python/tests/conftest.py
@@ -93,18 +93,38 @@ def client(request):
@pytest.fixture
-def socket_server_client(request, socket_server_settings):
- url = gremlin_socket_server_url.format(socket_server_settings["PORT"])
+def gremlin_socket_server_serializer(socket_server_settings):
if socket_server_settings["SERIALIZER"] == "GraphBinaryV1":
- ser = serializer.GraphBinarySerializersV1()
+ return serializer.GraphBinarySerializersV1()
elif socket_server_settings["SERIALIZER"] == "GraphSONV2":
- ser = serializer.GraphSONSerializersV2d0()
+ return serializer.GraphSONSerializersV2d0()
elif socket_server_settings["SERIALIZER"] == "GraphSONV3":
- ser = serializer.GraphSONSerializersV3d0()
+ return serializer.GraphSONSerializersV3d0()
+ else:
+ return serializer.GraphBinarySerializersV1()
+
+
+@pytest.fixture
+def socket_server_client(request, socket_server_settings, gremlin_socket_server_serializer):
+ url = gremlin_socket_server_url.format(socket_server_settings["PORT"])
+ try:
+ client = Client(url, 'g', pool_size=1, message_serializer=gremlin_socket_server_serializer)
+ except OSError:
+ pytest.skip('Gremlin Socket Server is not running')
else:
- ser = serializer.GraphBinarySerializersV1()
+ def fin():
+ client.close()
+
+ request.addfinalizer(fin)
+ return client
+
+
+@pytest.fixture
+def socket_server_client_no_user_agent(request, socket_server_settings, gremlin_socket_server_serializer):
+ url = gremlin_socket_server_url.format(socket_server_settings["PORT"])
try:
- client = Client(url, 'g', pool_size=1, message_serializer=ser)
+ client = Client(url, 'g', pool_size=1, message_serializer=gremlin_socket_server_serializer,
+ enable_user_agent_on_connect=False)
except OSError:
pytest.skip('Gremlin Socket Server is not running')
else:
@@ -116,7 +136,7 @@ def socket_server_client(request, socket_server_settings):
@pytest.fixture
-def socket_server_settings(request):
+def socket_server_settings():
with open(gremlin_socket_server_config_path, mode="rb") as file:
settings = yaml.safe_load(file)
return settings
diff --git a/gremlin-python/src/main/python/tests/driver/test_web_socket_client_behavior.py b/gremlin-python/src/main/python/tests/driver/test_web_socket_client_behavior.py
index a6ad2c5da9..7a3c1dac53 100644
--- a/gremlin-python/src/main/python/tests/driver/test_web_socket_client_behavior.py
+++ b/gremlin-python/src/main/python/tests/driver/test_web_socket_client_behavior.py
@@ -19,6 +19,11 @@
__author__ = 'Cole Greer (cole@colegreer.ca)'
+import re
+
+from gremlin_python.driver import useragent
+
+
# Note: This test demonstrates different behavior in response to a server sending a close frame than the other GLV's.
# Other GLV's will respond to this by trying to reconnect. This test is also demonstrating incorrect behavior of
# client.is_closed() as it appears unaware that the event loop is dead.
@@ -40,3 +45,24 @@ def test_does_not_create_new_connection_if_closed_by_server(socket_server_client
assert str(err) == "Event loop is closed"
assert not socket_server_client.is_closed()
+
+
+# Tests that client is correctly sending user agent during web socket handshake by having the server return
+# the captured user agent.
+def test_should_include_user_agent_in_handshake_request(socket_server_client, socket_server_settings):
+ user_agent_response = socket_server_client.submit(
+ "1", request_options={'requestId': socket_server_settings["USER_AGENT_REQUEST_ID"]}).one()[0]
+
+ assert user_agent_response == useragent.userAgent
+
+
+# Tests that no user agent (other than the default one provided by aiohttp) is sent to server when that
+# behaviour is disabled.
+def test_should_not_include_user_agent_in_handshake_request_if_disabled(socket_server_client_no_user_agent,
+ socket_server_settings):
+ user_agent_response = socket_server_client_no_user_agent.submit(
+ "1", request_options={'requestId': socket_server_settings["USER_AGENT_REQUEST_ID"]}).one()[0]
+
+ # If the gremlin user agent is disabled, the underlying web socket library reverts to sending its default user agent
+ # during connection requests.
+ assert re.search("^Python/(\d\.)*\d aiohttp/(\d\.)*\d$", user_agent_response)
diff --git a/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/socket/server/TestWSGremlinInitializer.java b/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/socket/server/TestWSGremlinInitializer.java
index f1a8dde2af..2f28799122 100644
--- a/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/socket/server/TestWSGremlinInitializer.java
+++ b/gremlin-tools/gremlin-socket-server/src/main/java/org/apache/tinkerpop/gremlin/socket/server/TestWSGremlinInitializer.java
@@ -162,7 +162,10 @@ public class TestWSGremlinInitializer extends TestChannelizers.TestWebSocketServ
* @throws SerializationException
*/
private ByteBuf returnSimpleBinaryResponse(final UUID requestID, String message) throws SerializationException {
- return SERIALIZER.serializeResponseAsBinary(ResponseMessage.build(requestID).result(message).create(), ByteBufAllocator.DEFAULT);
+ //Need to package message in a list of size 1 as some GLV's serializers require all messages to be in a list
+ final List<String> messageList = new ArrayList<>(1);
+ messageList.add(message);
+ return SERIALIZER.serializeResponseAsBinary(ResponseMessage.build(requestID).result(messageList).create(), ByteBufAllocator.DEFAULT);
}
/**