From 19bca928125066c185730ad82613843b77823437 Mon Sep 17 00:00:00 2001 From: Kirill Stepanishin Date: Fri, 10 Oct 2025 12:00:21 -0700 Subject: [PATCH] Integrate JavaScript examples into CI build - Added example execution to gremlin-js-integration-tests container in docker-compose.yml - Made server URLs and vertex labels configurable via environment variables - Use specialized labels to isolate test data - Build fails if any example fails to execute --- .../gremlin-javascript/basic-gremlin.js | 15 +++++++++------ glv-examples/gremlin-javascript/connections.js | 18 +++++++++--------- .../gremlin-javascript/modern-traversals.js | 4 +++- .../examples/node/basic-gremlin.js | 15 +++++++++------ .../examples/node/connections.js | 18 +++++++++--------- .../examples/node/modern-traversals.js | 7 ++++++- .../gremlin-javascript/docker-compose.yml | 12 +++++++++++- 7 files changed, 56 insertions(+), 33 deletions(-) diff --git a/glv-examples/gremlin-javascript/basic-gremlin.js b/glv-examples/gremlin-javascript/basic-gremlin.js index 77e7f3b7d9f..c804a0f82dc 100644 --- a/glv-examples/gremlin-javascript/basic-gremlin.js +++ b/glv-examples/gremlin-javascript/basic-gremlin.js @@ -21,14 +21,17 @@ const gremlin = require('gremlin'); const traversal = gremlin.process.AnonymousTraversalSource.traversal; const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection; +const serverUrl = 'ws://localhost:8182/gremlin'; +const vertexLabel = 'person'; + async function main() { - const dc = new DriverRemoteConnection('ws://localhost:8182/gremlin'); + const dc = new DriverRemoteConnection(serverUrl); const g = traversal().withRemote(dc); // Basic Gremlin: adding and retrieving data - const v1 = await g.addV('person').property('name','marko').next(); - const v2 = await g.addV('person').property('name','stephen').next(); - const v3 = await g.addV('person').property('name','vadas').next(); + const v1 = await g.addV(vertexLabel).property('name','marko').next(); + const v2 = await g.addV(vertexLabel).property('name','stephen').next(); + const v3 = await g.addV(vertexLabel).property('name','vadas').next(); // Be sure to use a terminating step like next() or iterate() so that the traversal "executes" // Iterate() does not return any data and is used to just generate side-effects (i.e. write data to the database) @@ -36,11 +39,11 @@ async function main() { await g.V(v1.value).addE('knows').to(v3.value).property('weight',0.75).iterate(); // Retrieve the data from the "marko" vertex - const marko = await g.V().has('person','name','marko').values('name').toList(); + const marko = await g.V().has(vertexLabel,'name','marko').values('name').toList(); console.log("name: " + marko[0]); // Find the "marko" vertex and then traverse to the people he "knows" and return their data - const peopleMarkoKnows = await g.V().has('person','name','marko').out('knows').values('name').toList(); + const peopleMarkoKnows = await g.V().has(vertexLabel,'name','marko').out('knows').values('name').toList(); peopleMarkoKnows.forEach((person) => { console.log("marko knows " + person); }); diff --git a/glv-examples/gremlin-javascript/connections.js b/glv-examples/gremlin-javascript/connections.js index 183f6404f6e..c6d5c189655 100644 --- a/glv-examples/gremlin-javascript/connections.js +++ b/glv-examples/gremlin-javascript/connections.js @@ -22,6 +22,9 @@ const traversal = gremlin.process.AnonymousTraversalSource.traversal; const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection; const serializer = gremlin.structure.io.graphserializer; +const serverUrl = 'ws://localhost:8182/gremlin'; +const vertexLabel = 'connection'; + async function main() { await withRemote(); await withConfigs(); @@ -29,15 +32,12 @@ async function main() { async function withRemote() { // Connecting to the server - const dc = new DriverRemoteConnection('ws://localhost:8182/gremlin'); + const dc = new DriverRemoteConnection(serverUrl); const g = traversal().withRemote(dc); - // Drop existing vertices - await g.V().drop().iterate(); - // Simple query to verify connection - const v = await g.addV().iterate(); - const count = await g.V().count().next(); + const v = await g.addV(vertexLabel).iterate(); + const count = await g.V().hasLabel(vertexLabel).count().next(); console.log("Vertex count: " + count.value); // Cleanup @@ -46,7 +46,7 @@ async function withRemote() { async function withConfigs() { // Connecting and customizing configurations - const dc = new DriverRemoteConnection('ws://localhost:8182/gremlin', { + const dc = new DriverRemoteConnection(serverUrl, { mimeType: 'application/vnd.gremlin-v3.0+json', reader: serializer, writer: serializer, @@ -55,8 +55,8 @@ async function withConfigs() { }); const g = traversal().withRemote(dc); - const v = await g.addV().iterate(); - const count = await g.V().count().next(); + const v = await g.addV(vertexLabel).iterate(); + const count = await g.V().hasLabel(vertexLabel).count().next(); console.log("Vertex count: " + count.value); await dc.close(); diff --git a/glv-examples/gremlin-javascript/modern-traversals.js b/glv-examples/gremlin-javascript/modern-traversals.js index 66b039fca38..565dc521357 100644 --- a/glv-examples/gremlin-javascript/modern-traversals.js +++ b/glv-examples/gremlin-javascript/modern-traversals.js @@ -24,13 +24,15 @@ const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection; const p = gremlin.process.P; const t = gremlin.process.t; +const serverUrl = 'ws://localhost:8182/gremlin'; + async function main() { /* This example requires the Modern toy graph to be preloaded upon launching the Gremlin server. For details, see https://tinkerpop.apache.org/docs/current/reference/#gremlin-server-docker-image and use conf/gremlin-server-modern.yaml. */ - const dc = new DriverRemoteConnection('ws://localhost:8182/gremlin'); + const dc = new DriverRemoteConnection(serverUrl); const g = traversal().withRemote(dc); const e1 = await g.V(1).bothE().toList(); // (1) diff --git a/gremlin-javascript/examples/node/basic-gremlin.js b/gremlin-javascript/examples/node/basic-gremlin.js index 77e7f3b7d9f..98a5c33285d 100644 --- a/gremlin-javascript/examples/node/basic-gremlin.js +++ b/gremlin-javascript/examples/node/basic-gremlin.js @@ -21,14 +21,17 @@ const gremlin = require('gremlin'); const traversal = gremlin.process.AnonymousTraversalSource.traversal; const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection; +const serverUrl = process.env.GREMLIN_SERVER_URL || 'ws://localhost:8182/gremlin'; +const vertexLabel = process.env.VERTEX_LABEL || 'person'; + async function main() { - const dc = new DriverRemoteConnection('ws://localhost:8182/gremlin'); + const dc = new DriverRemoteConnection(serverUrl); const g = traversal().withRemote(dc); // Basic Gremlin: adding and retrieving data - const v1 = await g.addV('person').property('name','marko').next(); - const v2 = await g.addV('person').property('name','stephen').next(); - const v3 = await g.addV('person').property('name','vadas').next(); + const v1 = await g.addV(vertexLabel).property('name','marko').next(); + const v2 = await g.addV(vertexLabel).property('name','stephen').next(); + const v3 = await g.addV(vertexLabel).property('name','vadas').next(); // Be sure to use a terminating step like next() or iterate() so that the traversal "executes" // Iterate() does not return any data and is used to just generate side-effects (i.e. write data to the database) @@ -36,11 +39,11 @@ async function main() { await g.V(v1.value).addE('knows').to(v3.value).property('weight',0.75).iterate(); // Retrieve the data from the "marko" vertex - const marko = await g.V().has('person','name','marko').values('name').toList(); + const marko = await g.V().has(vertexLabel,'name','marko').values('name').toList(); console.log("name: " + marko[0]); // Find the "marko" vertex and then traverse to the people he "knows" and return their data - const peopleMarkoKnows = await g.V().has('person','name','marko').out('knows').values('name').toList(); + const peopleMarkoKnows = await g.V().has(vertexLabel,'name','marko').out('knows').values('name').toList(); peopleMarkoKnows.forEach((person) => { console.log("marko knows " + person); }); diff --git a/gremlin-javascript/examples/node/connections.js b/gremlin-javascript/examples/node/connections.js index 183f6404f6e..95c7b87e70d 100644 --- a/gremlin-javascript/examples/node/connections.js +++ b/gremlin-javascript/examples/node/connections.js @@ -22,6 +22,9 @@ const traversal = gremlin.process.AnonymousTraversalSource.traversal; const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection; const serializer = gremlin.structure.io.graphserializer; +const serverUrl = process.env.GREMLIN_SERVER_URL || 'ws://localhost:8182/gremlin'; +const vertexLabel = process.env.VERTEX_LABEL || 'connection'; + async function main() { await withRemote(); await withConfigs(); @@ -29,15 +32,12 @@ async function main() { async function withRemote() { // Connecting to the server - const dc = new DriverRemoteConnection('ws://localhost:8182/gremlin'); + const dc = new DriverRemoteConnection(serverUrl); const g = traversal().withRemote(dc); - // Drop existing vertices - await g.V().drop().iterate(); - // Simple query to verify connection - const v = await g.addV().iterate(); - const count = await g.V().count().next(); + const v = await g.addV(vertexLabel).iterate(); + const count = await g.V().hasLabel(vertexLabel).count().next(); console.log("Vertex count: " + count.value); // Cleanup @@ -46,7 +46,7 @@ async function withRemote() { async function withConfigs() { // Connecting and customizing configurations - const dc = new DriverRemoteConnection('ws://localhost:8182/gremlin', { + const dc = new DriverRemoteConnection(serverUrl, { mimeType: 'application/vnd.gremlin-v3.0+json', reader: serializer, writer: serializer, @@ -55,8 +55,8 @@ async function withConfigs() { }); const g = traversal().withRemote(dc); - const v = await g.addV().iterate(); - const count = await g.V().count().next(); + const v = await g.addV(vertexLabel).iterate(); + const count = await g.V().hasLabel(vertexLabel).count().next(); console.log("Vertex count: " + count.value); await dc.close(); diff --git a/gremlin-javascript/examples/node/modern-traversals.js b/gremlin-javascript/examples/node/modern-traversals.js index 66b039fca38..6c740489721 100644 --- a/gremlin-javascript/examples/node/modern-traversals.js +++ b/gremlin-javascript/examples/node/modern-traversals.js @@ -24,13 +24,18 @@ const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection; const p = gremlin.process.P; const t = gremlin.process.t; +const serverUrl = process.env.GREMLIN_SERVER_URL || 'ws://localhost:8182/gremlin'; + async function main() { /* This example requires the Modern toy graph to be preloaded upon launching the Gremlin server. For details, see https://tinkerpop.apache.org/docs/current/reference/#gremlin-server-docker-image and use conf/gremlin-server-modern.yaml. */ - const dc = new DriverRemoteConnection('ws://localhost:8182/gremlin'); + + // Use gmodern in CI environment, default connection locally + const options = process.env.DOCKER_ENVIRONMENT ? { traversalSource: 'gmodern' } : {}; + const dc = new DriverRemoteConnection(serverUrl, options); const g = traversal().withRemote(dc); const e1 = await g.V(1).bothE().toList(); // (1) diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/docker-compose.yml b/gremlin-javascript/src/main/javascript/gremlin-javascript/docker-compose.yml index 4d07ec7f19e..99965f99d31 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/docker-compose.yml +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/docker-compose.yml @@ -49,12 +49,22 @@ services: - ../../../../../gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features:/gremlin-test - ../../../../../docker/gremlin-test-server:/js_app/gremlin-test-server - ../../../../../gremlin-tools/gremlin-socket-server/conf:/js_app/gremlin-socket-server/conf/ + - ../../../..:/gremlin-javascript environment: - DOCKER_ENVIRONMENT=true + - GREMLIN_SERVER_URL=ws://gremlin-server-test-js:45940/gremlin + - VERTEX_LABEL=javascript-example working_dir: /js_app command: > bash -c "npm config set cache /tmp --global - && npm ci && npm run test && npm run features-docker" + && npm ci && npm run test && npm run features-docker + && echo 'Running examples' + && cd /gremlin-javascript/src/main/javascript/gremlin-javascript && npm ci + && cd /gremlin-javascript/examples/node && npm ci + && node basic-gremlin.js + && node connections.js + && node modern-traversals.js + && echo 'All examples completed successfully'" depends_on: gremlin-server-test-js: condition: service_healthy