Skip to content

Restore ClientBehaviorTests in all GLVs#3436

Open
Cole-Greer wants to merge 3 commits into
masterfrom
gremlinSocketServer
Open

Restore ClientBehaviorTests in all GLVs#3436
Cole-Greer wants to merge 3 commits into
masterfrom
gremlinSocketServer

Conversation

@Cole-Greer
Copy link
Copy Markdown
Contributor

@Cole-Greer Cole-Greer commented May 29, 2026

Summary

The 3.8-dev branch had a set of WebSocket behavioral tests (WebSocketClientBehaviorIntegrateTest + a gremlin-socket-server) that validated driver resilience under adverse network conditions — dropped connections, mid-stream failures, slow responses, etc. These were lost in the switch from WebSockets to HTTP.
This PR recreates that coverage for the HTTP/GraphBinary-V4 stack and extends it to all GLVs.

Because requestId was removed from the wire protocol in 4.x, the old UUID-based dispatch mechanism is no longer possible. The test server now dispatches on the Gremlin query string instead (e.g. client.submit("server_close_connection")), which requires no protocol changes and works identically across every GLV.

What's included

Lightweight HTTP test server (gremlin-tools/gremlin-socket-server)

  • Replaced the dead WebSocket artifacts with an HTTP/Netty test server (TestHttpServerInitializer, TestHttpGremlinHandler) that deserializes GraphBinary V4 requests and dispatches behavior off the gremlin string.
  • Cleaned up legacy code: removed TestHandlers, the UUID-based SocketServerSettings and its YAML config; renamed SimpleSocketServer → SimpleTestServer; introduced a constants-only SocketServerConstants.
  • Scenarios: single vertex, close-before-response, vertex-then-close, error-after-delay, partial-content-close, malformed response, no response, slow drip-feed, and empty body.

Java driver tests — ClientBehaviorIntegrateTest (13 tests) covering connection drops, server errors, malformed/empty/partial responses, slow streaming, timeouts, connection-pool self-healing, and concurrent mixed good/bad requests, with specific exception-type and message assertions.

All GLVs — equivalent ClientBehavior suites for Python, .NET, Go, and JavaScript, each with a constants file and a gremlin-socket-server service added to its docker-compose. Tests gracefully skip when the server isn't reachable.

Testing

All suites were run through their Docker test harnesses:

GLV Result Skipped scenarios
Java 13 passing none
.NET passing server-downtime recovery
Python 11 passing, 1 skip server-downtime recovery
Go 10 passing, 2 skips server-downtime recovery; no-response timeout
JavaScript passing, 2 skips server-downtime recovery; no-response timeout

Skip rationale:

  • server-downtime recovery — requires stopping and restarting the server container mid-test, only feasible from the Java in-process test that controls the server lifecycle directly.
  • no-response timeout (Go, JS) — these drivers lack a client-side request/read timeout, so a non-responsive server hangs indefinitely; left as followup tasks.

Audit findings (follow-up tasks)

Running the same scenarios across every GLV surfaced several driver behavior gaps. Alignment is left out of scope of this PR:

  • Go: no client-side request/read timeout — a server that never responds hangs the client indefinitely (no-response test skipped). Java/.NET/Python all time out cleanly.
  • JavaScript: no client-side request timeout — same indefinite hang on a non-responsive server.
  • Go: empty response body returns an empty success result instead of an error — a silent data-loss risk; other GLVs raise.
  • Python: half-closed connection not evicted after an empty body — same-client recovery fails with Cannot write to closing transport (other failure modes recover fine).
  • Python/JS: low-level transport errors not wrapped — users see raw aiohttp/socket errors rather than an actionable Gremlin-aware message like Java's "Connection to server closed unexpectedly…".
  • Java: empty response body yields a bare EOFException — no message explaining the empty body; should be wrapped with context.

VOTE +1

Replace the old WebSocket behavioral test infrastructure with an HTTP
equivalent. The lightweight test server in gremlin-socket-server dispatches
on the Gremlin query string to simulate adversarial network conditions.

Server changes:
- Remove dead WebSocket artifacts (TestHandlers, test-ws-gremlin.yaml)
- Replace SocketServerSettings with SocketServerConstants (pure constants)
- Rename SimpleSocketServer to SimpleTestServer
- Add TestHttpServerInitializer and TestHttpGremlinHandler
- Scenarios: single vertex, close connection, vertex-then-close,
  error after delay, partial content close, malformed response,
  no response, slow drip-feed, empty body

Test changes:
- Add ClientBehaviorIntegrateTest in gremlin-driver with 13 tests
- Add test-scoped dependency on gremlin-socket-server in gremlin-driver
Add ClientBehaviorIntegrationTests for each GLV against the shared
gremlin-socket-server HTTP test server. Each GLV has 12 test scenarios
matching the Java ClientBehaviorIntegrateTest (server downtime recovery
is skipped since GLVs cannot stop/restart the Docker container).

Docker changes:
- Add gremlin-socket-server service to all 4 GLV docker-compose files
- Set GREMLIN_SOCKET_SERVER_URL env var for test containers
- Remove old conf volume mounts (.NET, JS)

Python:
- Add socket_server_constants.py and test_client_behavior.py
- Remove old test_web_socket_client_behavior.py

.NET:
- Add SocketServerConstants.cs and ClientBehaviorIntegrationTests.cs
- Remove old SocketServerSettings.cs and YamlDotNet dependency

Go:
- Add socket_server_constants_test.go and client_behavior_test.go

JavaScript:
- Add socket-server-constants.js and client-behavior-tests.js
@Cole-Greer Cole-Greer force-pushed the gremlinSocketServer branch from c952954 to 69e97ab Compare May 29, 2026 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant