Skip to content

Commit

Permalink
improve integration tests (#80)
Browse files Browse the repository at this point in the history
Improved integration tests
  • Loading branch information
vkagamlyk authored Apr 20, 2022
1 parent aa55146 commit 67db228
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 46 deletions.
21 changes: 16 additions & 5 deletions gremlin-go/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,34 @@
# specific language governing permissions and limitations
# under the License.

ARG GREMLIN_SERVER_VERSION=${version:-3.5.4}
FROM tinkerpop/gremlin-server:${GREMLIN_SERVER_VERSION}-SNAPSHOT
ARG GREMLIN_SERVER_VERSION
FROM tinkerpop/gremlin-server:${GREMLIN_SERVER_VERSION:-3.5.4-SNAPSHOT}

USER root
RUN mkdir -p /opt
WORKDIR /opt
COPY gremlin-server/src/test /opt/test/
COPY gremlin-go/docker/generate-all.groovy /opt/test/scripts/
COPY gremlin-go/docker/docker-entrypoint.sh gremlin-go/docker/*.yaml /opt/
RUN chmod 755 /opt/docker-entrypoint.sh

# Setting to 3.5.3 does gives error even when using outside of Docker.
ENV NEO4J_VERSION=${version:-3.5.2}
# Installing dos2unix to avoid errors in running the entrypoint script on Windows machines where their
# carriage return is \r\n instead of the \n needed for linux/unix containers
RUN apk update && apk add dos2unix
RUN dos2unix /opt/docker-entrypoint.sh && apk del dos2unix

ARG NEO4J_VERSION
# Installs Neo4j libraries to this image so that we can test variants with transactions,
# but only only port 45940 is configured with the neo4j graph as the neo4j-empty.properties
# is statically pointing at a temp directory and that space can only be accessed by one
# graph at a time.
RUN /opt/gremlin-server/bin/gremlin-server.sh install org.apache.tinkerpop neo4j-gremlin $NEO4J_VERSION
RUN /opt/gremlin-server/bin/gremlin-server.sh install org.apache.tinkerpop neo4j-gremlin ${NEO4J_VERSION:-3.5.4}

# Gremlin server and neo4j versions are set to 3.5.4 by default, to change their versions, add args under the
# docker-compose build step, e.g.:
# args:
# GREMLIN_SERVER_VERSION: 3.5.x-SNAPSHOT
# NEO4J_VERSION: 3.5.x

EXPOSE 45940 45941

Expand Down
4 changes: 3 additions & 1 deletion gremlin-go/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ services:
build:
context: ../
dockerfile: gremlin-go/Dockerfile
args:
NEO4J_VERSION: 3.5.3
ports:
- "45940:45940"
- "45941:45941"
Expand All @@ -45,6 +47,6 @@ services:
working_dir: /go_app
command: >
bash -c "go install github.com/haveyoudebuggedit/gotestfmt/v2/cmd/gotestfmt@latest
&& go test -p 1 -v -json ./... -race -covermode=atomic -coverprofile=\"coverage.out\" -coverpkg=./... | gotestfmt"
&& go test -v -json ./... -race -covermode=atomic -coverprofile=\"coverage.out\" -coverpkg=./... | gotestfmt"
depends_on:
- gremlin-test-server
79 changes: 79 additions & 0 deletions gremlin-go/docker/generate-all.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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.
*/

// An example of an initialization script that can be configured to run in Gremlin Server.
// Functions defined here will go into global cache and will not be removed from there
// unless there is a reset of the ScriptEngine.
def addItUp(x, y) { x + y }

// an init script that returns a Map allows explicit setting of global bindings.
def globals = [:]

// Generates the modern graph into an "empty" TinkerGraph via LifeCycleHook.
// Note that the name of the key in the "global" map is unimportant.
globals << [hook : [
onStartUp: { ctx ->
// a wild bit of trickery here. the process tests use an INTEGER id manager when LoadGraphWith is used. this
// closure provides a way to to manually override the various id managers for TinkerGraph - the graph on which
// all of these remote tests are executed - so that the tests will pass nicely. an alternative might have been
// to have a special test TinkerGraph config for setting up the id manager properly, but based on how we do
// things now, that test config would have been mixed in with release artifacts and there would have been ugly
// exclusions to make packaging work properly.
allowSetOfIdManager = { graph, idManagerFieldName ->
java.lang.reflect.Field idManagerField = graph.class.getDeclaredField(idManagerFieldName)
idManagerField.setAccessible(true)
java.lang.reflect.Field modifiersField = java.lang.reflect.Field.class.getDeclaredField("modifiers")
modifiersField.setAccessible(true)
modifiersField.setInt(idManagerField, modifiersField.getModifiers() & ~java.lang.reflect.Modifier.FINAL)

idManagerField.set(graph, TinkerGraph.DefaultIdManager.INTEGER)
}

[classic, modern, crew, sink, grateful, test].each{
allowSetOfIdManager(it, "vertexIdManager")
allowSetOfIdManager(it, "edgeIdManager")
allowSetOfIdManager(it, "vertexPropertyIdManager")
}
TinkerFactory.generateClassic(classic)
TinkerFactory.generateModern(modern)
TinkerFactory.generateTheCrew(crew)
TinkerFactory.generateGratefulDead(grateful)
TinkerFactory.generateKitchenSink(sink)
TinkerFactory.generateModern(test)
}
] as LifeCycleHook]

// add default TraversalSource instances for each graph instance
globals << [gclassic : traversal().withEmbedded(classic).withStrategies(ReferenceElementStrategy)]
globals << [gmodern : traversal().withEmbedded(modern).withStrategies(ReferenceElementStrategy)]
globals << [gtest : traversal().withEmbedded(test).withStrategies(ReferenceElementStrategy)]
globals << [g : traversal().withEmbedded(graph).withStrategies(ReferenceElementStrategy)]
globals << [gcrew : traversal().withEmbedded(crew).withStrategies(ReferenceElementStrategy)]
globals << [ggraph : traversal().withEmbedded(graph).withStrategies(ReferenceElementStrategy)]
globals << [ggrateful : traversal().withEmbedded(grateful).withStrategies(ReferenceElementStrategy)]
globals << [gsink : traversal().withEmbedded(sink).withStrategies(ReferenceElementStrategy)]

// dynamically detect existence of gtx as it may or may not be present depending on the -DincludeNeo4j
// and the configuration of the particular server instance. with docker/gremlin-server.sh the neo4j
// "tx" configuration is already present and will therefore be enabled.
def dynamicGtx = context.getBindings(javax.script.ScriptContext.GLOBAL_SCOPE)["tx"]
if (dynamicGtx != null)
globals << [gtx : traversal().withEmbedded(dynamicGtx).withStrategies(ReferenceElementStrategy)]

globals
1 change: 1 addition & 0 deletions gremlin-go/docker/gremlin-server-integration-secure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ port: 45941
evaluationTimeout: 30000
graphs: {
graph: conf/tinkergraph-empty.properties,
test: conf/tinkergraph-empty.properties,
classic: conf/tinkergraph-empty.properties,
modern: conf/tinkergraph-empty.properties,
crew: conf/tinkergraph-empty.properties,
Expand Down
1 change: 1 addition & 0 deletions gremlin-go/docker/gremlin-server-integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ port: 45940
evaluationTimeout: 30000
graphs: {
graph: conf/tinkergraph-empty.properties,
test: conf/tinkergraph-empty.properties,
classic: conf/tinkergraph-empty.properties,
modern: conf/tinkergraph-empty.properties,
crew: conf/tinkergraph-empty.properties,
Expand Down
52 changes: 12 additions & 40 deletions gremlin-go/driver/connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,16 @@ const integrationTestSuiteName = "integration"
const basicAuthIntegrationTestSuite = "basic authentication integration"
const validHostInvalidPortValidPath = "ws://localhost:12341253/gremlin"
const invalidHostValidPortValidPath = "ws://invalidhost:8182/gremlin"
const validHostValidPortInvalidPath = "ws://localhost:8182/invalid"
const testServerModernGraphAlias = "gmodern"
const testServerGraphAlias = "gtest"
const manualTestSuiteName = "manual"
const nonRoutableIPForConnectionTimeout = "ws://10.255.255.1/"

// transaction is enabled on the same port as no auth url
const noAuthUrl = "ws://localhost:45940/gremlin"
const basicAuthNoSsl = "ws://localhost:45941/gremlin"
const basicAuthWithSsl = "wss://localhost:45941/gremlin"

var testNames = []string{"Lyndon", "Yang", "Simon", "Rithin", "Alexey", "Valentyn"}
var mu sync.Mutex

func newDefaultConnectionSettings() *connectionSettings {
return &connectionSettings{
Expand Down Expand Up @@ -90,16 +88,23 @@ func addTestData(t *testing.T, g *GraphTraversalSource) {
assert.Nil(t, <-promise)
}

func initializeGraph(t *testing.T, url string, auth *AuthInfo, tls *tls.Config) *GraphTraversalSource {
func getTestGraph(t *testing.T, url string, auth *AuthInfo, tls *tls.Config) *GraphTraversalSource {
remote, err := NewDriverRemoteConnection(url,
func(settings *DriverRemoteConnectionSettings) {
settings.TlsConfig = tls
settings.AuthInfo = auth
settings.TraversalSource = testServerGraphAlias
})
assert.Nil(t, err)
assert.NotNil(t, remote)
g := Traversal_().WithRemote(remote)

return g
}

func initializeGraph(t *testing.T, url string, auth *AuthInfo, tls *tls.Config) *GraphTraversalSource {
g := getTestGraph(t, url, auth, tls)

// Drop the graph and check that it is empty.
dropGraph(t, g)
readCount(t, g, "", 0)
Expand Down Expand Up @@ -325,9 +330,6 @@ func TestConnection(t *testing.T) {
})

t.Run("Test DriverRemoteConnection GraphTraversal", func(t *testing.T) {
mu.Lock()
defer mu.Unlock()

skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)

// Initialize graph
Expand Down Expand Up @@ -628,9 +630,6 @@ func TestConnection(t *testing.T) {
})

t.Run("Test DriverRemoteConnection GraphTraversal", func(t *testing.T) {
mu.Lock()
defer mu.Unlock()

skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)

// Initialize graph
Expand All @@ -642,16 +641,10 @@ func TestConnection(t *testing.T) {
readTestDataValues(t, g)

// Drop the graph and check that it is empty.
dropGraph(t, g)
readCount(t, g, "", 0)
readCount(t, g, testLabel, 0)
readCount(t, g, personLabel, 0)
resetGraph(t, g)
})

t.Run("Test Traversal. Next and HasNext", func(t *testing.T) {
mu.Lock()
defer mu.Unlock()

skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)

// Initialize graph
Expand All @@ -663,13 +656,10 @@ func TestConnection(t *testing.T) {
})

t.Run("Test DriverRemoteConnection GraphTraversal With Label", func(t *testing.T) {
mu.Lock()
defer mu.Unlock()

skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)

// Initialize graph
g := initializeGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
g := getTestGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
defer g.remoteConnection.Close()

// Drop the graph.
Expand Down Expand Up @@ -711,9 +701,6 @@ func TestConnection(t *testing.T) {
})

t.Run("Test DriverRemoteConnection GraphTraversal P", func(t *testing.T) {
mu.Lock()
defer mu.Unlock()

skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)

// Initialize graph
Expand All @@ -730,9 +717,6 @@ func TestConnection(t *testing.T) {
})

t.Run("Test DriverRemoteConnection Next and HasNext", func(t *testing.T) {
mu.Lock()
defer mu.Unlock()

skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)

// Initialize graph
Expand All @@ -759,9 +743,6 @@ func TestConnection(t *testing.T) {
})

t.Run("Test anonymousTraversal", func(t *testing.T) {
mu.Lock()
defer mu.Unlock()

skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)

// Initialize graph
Expand All @@ -771,10 +752,7 @@ func TestConnection(t *testing.T) {
readUsingAnonymousTraversal(t, g)

// Drop the graph and check that it is empty.
dropGraph(t, g)
readCount(t, g, "", 0)
readCount(t, g, testLabel, 0)
readCount(t, g, personLabel, 0)
resetGraph(t, g)
})

t.Run("Test Traversal.ToList fail", func(t *testing.T) {
Expand Down Expand Up @@ -820,9 +798,6 @@ func TestConnection(t *testing.T) {
})

t.Run("Test DriverRemoteConnection GraphTraversal WithSack", func(t *testing.T) {
mu.Lock()
defer mu.Unlock()

skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)

// Initialize graph
Expand Down Expand Up @@ -997,9 +972,6 @@ func TestConnection(t *testing.T) {
})

t.Run("Test DriverRemoteConnection Invalid GraphTraversal", func(t *testing.T) {
mu.Lock()
defer mu.Unlock()

skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)

// Initialize graph
Expand Down

0 comments on commit 67db228

Please sign in to comment.