You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by GitBox <gi...@apache.org> on 2022/03/17 19:59:20 UTC
[GitHub] [tinkerpop] lyndonbauto opened a new pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
lyndonbauto opened a new pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589
This has the changes for Milestone 3 and 4 of the gremlin-go driver. I would like to thank @xiazcy, @simonz-bq, @L0Lmaker, @vkagamlyk, @divijvaidya, and @spmallette for continued help they have all been putting into this.
We have all tests passing in the Cucumber test suite, have integrated the driver into the TinkerPop build infrastructure and have the driver ready for an actual release.
Pull request comments will be added as backlog items for the next milestone, instead of being addressed within this pull request.
This pull request will remain open for at least a week, so the community has a chance to look at it and critique it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r830251848
##########
File path: gremlin-go/driver/graphBinary_test.go
##########
@@ -51,6 +51,11 @@ func readToValue(buff *bytes.Buffer) interface{} {
}
func TestGraphBinaryV1(t *testing.T) {
+ var m = map[interface{}]interface{}{
Review comment:
We are using Go 1.17 since Go 1.18 was released around a month ago. Go 1.18 introduced the any keyword (when they introduced generics).
We discussed upgrading to 1.18, but ultimately decided to stick with 1.17 for the time being for the following reasons:
1. Benefit of upgrade is limited to cleaner code inside our library
2. Users of the library would have to upgrade to Go 1.18 if they were not already on it. This could cause friction in adoption
Obviously open to discussion around upgrading, if you would like to talk more on it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] krlawrence commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
krlawrence commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r830117916
##########
File path: gremlin-go/README.md
##########
@@ -114,15 +156,19 @@ func main() {
Note: The exact import name as well as the module prefix for `NewDriverRemoteConnection` may change in the future.
+### Design Architecture
+
+See [Gremlin-Go Design Overview](design.MD)
+
# Go Gremlin Language Variant
[Apache TinkerPop™][tk] is a graph computing framework for both graph databases (OLTP) and graph analytic systems
(OLAP). [Gremlin][gremlin] is the graph traversal language of TinkerPop. It can be described as a functional,
data-flow language that enables users to succinctly express complex traversals on (or queries of) their application's
property graph.
-Gremlin-Go implements Gremlin within the Go language and can be used on any Go runtime greater than v1.17. One important distinction with Go and Java is that
-the functions are capitalized, as is required to export functions is Go.
+Gremlin-Go implements Gremlin within the Go language and can be used on any Go runtime greater than v1.17. One
+important distinction with Go and Java is that the functions are capitalized, as is required to export functions is Go.
Review comment:
s/is/in
perhaps say "one important difference between Go and Java is that"
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#issuecomment-1072783568
Something that was raised that is worth calling out:
The Godog tests will not currently run through docker. We haven't set up the server to run custom configurations in docker yet, we expect to have this capability in for the next milestone (MS 5).
If you would like to test this yourself, please use the following configuration file:
```
# 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.
host: localhost
port: 8182
evaluationTimeout: 30000
channelizer: org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer
graphs: {
graph: conf/tinkergraph-empty.properties,
classic: conf/tinkergraph-empty.properties,
modern: conf/tinkergraph-empty.properties,
crew: conf/tinkergraph-empty.properties,
grateful: conf/tinkergraph-empty.properties,
sink: conf/tinkergraph-empty.properties
}
scriptEngines: {
gremlin-groovy: {
plugins: { org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {},
org.apache.tinkerpop.gremlin.tinkergraph.jsr223.TinkerGraphGremlinPlugin: {},
org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {classImports: [java.lang.Math], methodImports: [java.lang.Math#*]},
org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin: {files: [scripts/generate-all.groovy]}}}}
serializers:
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3d0] }} # application/json
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1 } # application/vnd.graphbinary-v1.0
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }} # application/vnd.graphbinary-v1.0-stringd
processors:
- { className: org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor, config: { sessionTimeout: 28800000 }}
- { className: org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor, config: { cacheExpirationTime: 600000, cacheMaxSize: 1000 }}
metrics: {
consoleReporter: {enabled: true, interval: 180000},
csvReporter: {enabled: true, interval: 180000, fileName: /tmp/gremlin-server-metrics.csv},
jmxReporter: {enabled: true},
slf4jReporter: {enabled: true, interval: 180000}}
strictTransactionManagement: false
idleConnectionTimeout: 0
keepAliveInterval: 0
maxInitialLineLength: 4096
maxHeaderSize: 8192
maxChunkSize: 8192
maxContentLength: 65536
maxAccumulationBufferComponents: 1024
resultIterationBatchSize: 64
writeBufferLowWaterMark: 32768
writeBufferHighWaterMark: 65536
ssl: {
enabled: false}
```
And make sure you have this generate-all.groovy file as linked in the above config. (Note you must unzip it, it is zipped because GitHub won't allow groovy uploaded directly).
[generate-all.groovy.zip](https://github.com/apache/tinkerpop/files/8307540/generate-all.groovy.zip)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833633406
##########
File path: gremlin-go/driver/gorillaTransporter.go
##########
@@ -20,42 +20,50 @@ under the License.
package gremlingo
import (
+ "crypto/tls"
"net/url"
- "strconv"
+ "time"
"github.com/gorilla/websocket"
)
+const maxFailCount = 3
+
// Transport layer that uses gorilla/websocket: https://github.com/gorilla/websocket
// Gorilla WebSocket is a widely used and stable Go implementation of the WebSocket protocol.
type gorillaTransporter struct {
- host string
- port int
+ url string
connection websocketConn
isClosed bool
+ authInfo *AuthInfo
+ tlsConfig *tls.Config
}
+// Connect used to establish a connection.
func (transporter *gorillaTransporter) Connect() (err error) {
if transporter.connection != nil {
return
}
- u := url.URL{
- Scheme: scheme,
- Host: transporter.host + ":" + strconv.Itoa(transporter.port),
- Path: path,
+ var u *url.URL
+ u, err = url.Parse(transporter.url)
+ if err != nil {
+ return
}
dialer := websocket.DefaultDialer
+ dialer.TLSClientConfig = transporter.tlsConfig
// TODO: make this configurable from client; this currently does nothing since 4096 is the default
dialer.WriteBufferSize = 4096
- conn, _, err := dialer.Dial(u.String(), nil)
+ // Nil is accepted as a valid header, so it can always be passed directly through.
+ conn, _, err := dialer.Dial(u.String(), transporter.authInfo.getHeader())
Review comment:
You can set a timeout in gorilla but currently we are not using it, we found the timeout structure of gorilla to be problematic. It will require a bit more effort and will likely be done in a future milestone.
The reason it is problematic is because if you use it and it expires, the connection becomes unusable - which is okay when we have pooling and recovery set up, but not in our current simple single connection model.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] divijvaidya commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
divijvaidya commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833281982
##########
File path: gremlin-go/driver/connection_test.go
##########
@@ -131,78 +150,389 @@ func readCount(t *testing.T, g *GraphTraversalSource, label string, expected int
assert.Equal(t, int32(expected), count)
}
+func sortAndCompareTwoStringSlices(s1 []string, s2 []string) bool {
+ sort.Strings(s1)
+ sort.Strings(s2)
+ return reflect.DeepEqual(s1, s2)
+}
+
+func readUsingAnonymousTraversal(t *testing.T, g *GraphTraversalSource) {
+ results, err := g.V().Fold().
+ Project(testLabel, personLabel).
+ By(T__.Unfold().HasLabel(testLabel).Count()).
+ By(T__.Unfold().HasLabel(personLabel).Count()).
+ ToList()
+ assert.Nil(t, err)
+ assert.Equal(t, 1, len(results))
+ resultMap := results[0].GetInterface().(map[interface{}]interface{})
+ assert.Equal(t, int64(0), resultMap[testLabel])
+ assert.Equal(t, int64(len(testNames)), resultMap[personLabel])
+}
+
+func readWithNextAndHasNext(t *testing.T, g *GraphTraversalSource) {
+ traversal := g.V().HasLabel(personLabel).Properties(nameKey)
+ var names []string
+ for i := 0; i < len(testNames); i++ {
+ hasN, err := traversal.HasNext()
+ assert.Nil(t, err)
+ assert.True(t, hasN)
+ res, err := traversal.Next()
+ assert.Nil(t, err)
+ assert.NotNil(t, res)
+ vp, err := res.GetVertexProperty()
+ assert.Nil(t, err)
+ names = append(names, vp.Value.(string))
+ }
+ hasN, _ := traversal.HasNext()
+ assert.False(t, hasN)
+ // Check for Next error when no more elements left
+ res, err := traversal.Next()
+ assert.Nil(t, res)
+ assert.NotNil(t, err)
+ assert.True(t, sortAndCompareTwoStringSlices(names, testNames))
+}
+
+func getEnvOrDefaultString(key string, defaultValue string) string {
+ // Missing value is returned as "".
+ value := os.Getenv(key)
+ if len(value) != 0 {
+ return value
+ }
+ return defaultValue
+}
+
+func getEnvOrDefaultBool(key string, defaultValue bool) bool {
+ value := getEnvOrDefaultString(key, "")
+ if len(value) != 0 {
+ boolValue, err := strconv.ParseBool(value)
+ if err == nil {
+ return boolValue
+ }
+ }
+ return defaultValue
+}
+
+func getBasicAuthInfo() *AuthInfo {
+ return BasicAuthInfo(getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_USERNAME", "stephen"),
+ getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_PASSWORD", "password"))
+}
+
+func skipTestsIfNotEnabled(t *testing.T, testSuiteName string, testSuiteEnabled bool) {
+ if !testSuiteEnabled {
+ t.Skip(fmt.Sprintf("Skipping %s because %s tests are not enabled.", t.Name(), testSuiteName))
+ }
+}
+
func TestConnection(t *testing.T) {
+ // Integration test variables.
+ testNoAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthEnable := getEnvOrDefaultBool("RUN_INTEGRATION_TESTS", true)
+ testNoAuthAuthInfo := &AuthInfo{}
+ testNoAuthTlsConfig := &tls.Config{}
+
+ // No authentication integration test with graphs loaded and alias configured server
+ testNoAuthWithAliasUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthWithAliasEnable := getEnvOrDefaultBool("RUN_INTEGRATION_WITH_ALIAS_ TESTS", false)
+ testNoAuthWithAliasAuthInfo := &AuthInfo{}
+ testNoAuthWithAliasTlsConfig := &tls.Config{}
+
+ // Basic authentication integration test variables.
+ testBasicAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_BASIC_AUTH_URL", "wss://localhost:8183/gremlin")
+ testBasicAuthEnable := getEnvOrDefaultBool("RUN_BASIC_AUTH_INTEGRATION_TESTS", false)
+ testBasicAuthAuthInfo := getBasicAuthInfo()
+ testBasicAuthTlsConfig := &tls.Config{InsecureSkipVerify: true}
+
+ t.Run("Test createConnection without valid server", func(t *testing.T) {
+ connection, err := createConnection(invalidHostValidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid port", func(t *testing.T) {
+ connection, err := createConnection(validHostInvalidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid path", func(t *testing.T) {
+ connection, err := createConnection(validHostValidPortInvalidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
t.Run("Test DriverRemoteConnection GraphTraversal", func(t *testing.T) {
- if runIntegration {
- remote, err := NewDriverRemoteConnection(testHost, testPort)
- assert.Nil(t, err)
- assert.NotNil(t, remote)
- g := Traversal_().WithRemote(remote)
-
- // 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)
-
- // Add data and check that the size of the graph is correct.
- addTestData(t, g)
- readCount(t, g, "", len(getTestNames()))
- readCount(t, g, testLabel, 0)
- readCount(t, g, personLabel, len(getTestNames()))
-
- // Read test data out of the graph and check that it is correct.
- readTestDataVertexProperties(t, g)
- 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)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+
+ // Initialize graph
+ g := initializeGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
+
+ // Read test data out of the graph and check that it is correct.
+ readTestDataVertexProperties(t, g)
+ readTestDataValues(t, g)
+
+ // Reset Graph
+ resetGraph(t, g)
})
t.Run("Test createConnection", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ err = connection.close()
+ assert.Nil(t, err)
})
t.Run("Test connection.write()", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- request := makeStringRequest("g.V().count()")
- resultSet, err := connection.write(&request)
- assert.Nil(t, err)
- assert.NotNil(t, resultSet)
- result := resultSet.one()
- assert.NotNil(t, result)
- assert.Equal(t, "[0]", result.GetString())
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ request := makeStringRequest("g.V().count()", "g")
+ resultSet, err := connection.write(&request)
+ assert.Nil(t, err)
+ assert.NotNil(t, resultSet)
+ result, err := resultSet.one()
+ assert.Nil(t, err)
+ assert.NotNil(t, result)
+ err = connection.close()
Review comment:
this should probably be done in this test using defer so that close is always called even if one of the assertions fail in the test. Otherwise, we may leave unclosed connections on the test server.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833670556
##########
File path: gremlin-go/driver/client.go
##########
@@ -20,69 +20,76 @@ under the License.
package gremlingo
import (
+ "crypto/tls"
"golang.org/x/text/language"
)
// ClientSettings is used to modify a Client's settings on initialization.
type ClientSettings struct {
+ TraversalSource string
TransporterType TransporterType
LogVerbosity LogVerbosity
Logger Logger
Language language.Tag
+ AuthInfo *AuthInfo
+ TlsConfig *tls.Config
}
// Client is used to connect and interact with a Gremlin-supported server.
type Client struct {
- host string
- port int
+ url string
+ traversalSource string
logHandler *logHandler
transporterType TransporterType
connection *connection
}
// NewClient creates a Client and configures it with the given parameters.
-func NewClient(host string, port int, configurations ...func(settings *ClientSettings)) (*Client, error) {
+func NewClient(url string, configurations ...func(settings *ClientSettings)) (*Client, error) {
settings := &ClientSettings{
+ TraversalSource: "g",
TransporterType: Gorilla,
LogVerbosity: Info,
Logger: &defaultLogger{},
Language: language.English,
+ AuthInfo: &AuthInfo{},
+ TlsConfig: &tls.Config{},
}
for _, configuration := range configurations {
configuration(settings)
}
logHandler := newLogHandler(settings.Logger, settings.LogVerbosity, settings.Language)
- conn, err := createConnection(host, port, logHandler)
+ conn, err := createConnection(url, settings.AuthInfo, settings.TlsConfig, logHandler)
if err != nil {
return nil, err
Review comment:
Done.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833667939
##########
File path: gremlin-go/driver/connection_test.go
##########
@@ -131,78 +150,389 @@ func readCount(t *testing.T, g *GraphTraversalSource, label string, expected int
assert.Equal(t, int32(expected), count)
}
+func sortAndCompareTwoStringSlices(s1 []string, s2 []string) bool {
+ sort.Strings(s1)
+ sort.Strings(s2)
+ return reflect.DeepEqual(s1, s2)
+}
+
+func readUsingAnonymousTraversal(t *testing.T, g *GraphTraversalSource) {
+ results, err := g.V().Fold().
+ Project(testLabel, personLabel).
+ By(T__.Unfold().HasLabel(testLabel).Count()).
+ By(T__.Unfold().HasLabel(personLabel).Count()).
+ ToList()
+ assert.Nil(t, err)
+ assert.Equal(t, 1, len(results))
+ resultMap := results[0].GetInterface().(map[interface{}]interface{})
+ assert.Equal(t, int64(0), resultMap[testLabel])
+ assert.Equal(t, int64(len(testNames)), resultMap[personLabel])
+}
+
+func readWithNextAndHasNext(t *testing.T, g *GraphTraversalSource) {
+ traversal := g.V().HasLabel(personLabel).Properties(nameKey)
+ var names []string
+ for i := 0; i < len(testNames); i++ {
+ hasN, err := traversal.HasNext()
+ assert.Nil(t, err)
+ assert.True(t, hasN)
+ res, err := traversal.Next()
+ assert.Nil(t, err)
+ assert.NotNil(t, res)
+ vp, err := res.GetVertexProperty()
+ assert.Nil(t, err)
+ names = append(names, vp.Value.(string))
+ }
+ hasN, _ := traversal.HasNext()
+ assert.False(t, hasN)
+ // Check for Next error when no more elements left
+ res, err := traversal.Next()
+ assert.Nil(t, res)
+ assert.NotNil(t, err)
+ assert.True(t, sortAndCompareTwoStringSlices(names, testNames))
+}
+
+func getEnvOrDefaultString(key string, defaultValue string) string {
+ // Missing value is returned as "".
+ value := os.Getenv(key)
+ if len(value) != 0 {
+ return value
+ }
+ return defaultValue
+}
+
+func getEnvOrDefaultBool(key string, defaultValue bool) bool {
+ value := getEnvOrDefaultString(key, "")
+ if len(value) != 0 {
+ boolValue, err := strconv.ParseBool(value)
+ if err == nil {
+ return boolValue
+ }
+ }
+ return defaultValue
+}
+
+func getBasicAuthInfo() *AuthInfo {
+ return BasicAuthInfo(getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_USERNAME", "stephen"),
+ getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_PASSWORD", "password"))
+}
+
+func skipTestsIfNotEnabled(t *testing.T, testSuiteName string, testSuiteEnabled bool) {
+ if !testSuiteEnabled {
+ t.Skip(fmt.Sprintf("Skipping %s because %s tests are not enabled.", t.Name(), testSuiteName))
+ }
+}
+
func TestConnection(t *testing.T) {
+ // Integration test variables.
+ testNoAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthEnable := getEnvOrDefaultBool("RUN_INTEGRATION_TESTS", true)
+ testNoAuthAuthInfo := &AuthInfo{}
+ testNoAuthTlsConfig := &tls.Config{}
+
+ // No authentication integration test with graphs loaded and alias configured server
+ testNoAuthWithAliasUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthWithAliasEnable := getEnvOrDefaultBool("RUN_INTEGRATION_WITH_ALIAS_ TESTS", false)
+ testNoAuthWithAliasAuthInfo := &AuthInfo{}
+ testNoAuthWithAliasTlsConfig := &tls.Config{}
+
+ // Basic authentication integration test variables.
+ testBasicAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_BASIC_AUTH_URL", "wss://localhost:8183/gremlin")
+ testBasicAuthEnable := getEnvOrDefaultBool("RUN_BASIC_AUTH_INTEGRATION_TESTS", false)
+ testBasicAuthAuthInfo := getBasicAuthInfo()
+ testBasicAuthTlsConfig := &tls.Config{InsecureSkipVerify: true}
+
+ t.Run("Test createConnection without valid server", func(t *testing.T) {
+ connection, err := createConnection(invalidHostValidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid port", func(t *testing.T) {
+ connection, err := createConnection(validHostInvalidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid path", func(t *testing.T) {
+ connection, err := createConnection(validHostValidPortInvalidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
t.Run("Test DriverRemoteConnection GraphTraversal", func(t *testing.T) {
- if runIntegration {
- remote, err := NewDriverRemoteConnection(testHost, testPort)
- assert.Nil(t, err)
- assert.NotNil(t, remote)
- g := Traversal_().WithRemote(remote)
-
- // 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)
-
- // Add data and check that the size of the graph is correct.
- addTestData(t, g)
- readCount(t, g, "", len(getTestNames()))
- readCount(t, g, testLabel, 0)
- readCount(t, g, personLabel, len(getTestNames()))
-
- // Read test data out of the graph and check that it is correct.
- readTestDataVertexProperties(t, g)
- 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)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+
+ // Initialize graph
+ g := initializeGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
+
+ // Read test data out of the graph and check that it is correct.
+ readTestDataVertexProperties(t, g)
+ readTestDataValues(t, g)
+
+ // Reset Graph
+ resetGraph(t, g)
})
t.Run("Test createConnection", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ err = connection.close()
+ assert.Nil(t, err)
})
t.Run("Test connection.write()", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- request := makeStringRequest("g.V().count()")
- resultSet, err := connection.write(&request)
- assert.Nil(t, err)
- assert.NotNil(t, resultSet)
- result := resultSet.one()
- assert.NotNil(t, result)
- assert.Equal(t, "[0]", result.GetString())
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ request := makeStringRequest("g.V().count()", "g")
+ resultSet, err := connection.write(&request)
+ assert.Nil(t, err)
+ assert.NotNil(t, resultSet)
+ result, err := resultSet.one()
+ assert.Nil(t, err)
+ assert.NotNil(t, result)
+ err = connection.close()
Review comment:
Done.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] spmallette commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
spmallette commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r829998363
##########
File path: gremlin-go/NOTICE
##########
@@ -0,0 +1,23 @@
+====================================================================================================
Review comment:
Started this thread regarding LICENSE/NOTICE: https://lists.apache.org/thread/kgd52bz7pjc1qc638ktk31ooww5gbp8d
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r830187420
##########
File path: gremlin-go/build/generate.groovy
##########
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+
+import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph
+import org.apache.tinkerpop.gremlin.process.traversal.translator.GolangTranslator
+import org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine
+import org.apache.tinkerpop.gremlin.groovy.jsr223.ast.VarAsBindingASTTransformation
+import org.apache.tinkerpop.gremlin.groovy.jsr223.ast.RepeatASTTransformationCustomizer
+import org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyCustomizer
+import org.codehaus.groovy.control.customizers.CompilationCustomizer
+import org.apache.tinkerpop.gremlin.features.FeatureReader
+
+import javax.script.SimpleBindings
+
+import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal
+
+// file is overwritten on each generation
+radishGremlinFile = new File("${projectBaseDir}/gremlin-go/cucumber/gremlin.go")
+
+// assumes globally unique scenario names for keys with list of Gremlin traversals as they appear
+gremlins = FeatureReader.parse("${projectBaseDir}")
+
+gremlinGroovyScriptEngine = new GremlinGroovyScriptEngine(new GroovyCustomizer() {
+ public CompilationCustomizer create() {
+ return new RepeatASTTransformationCustomizer(new VarAsBindingASTTransformation())
+ }
+})
+translator = GolangTranslator.of('g')
+g = traversal().withEmbedded(EmptyGraph.instance())
+bindings = new SimpleBindings()
+bindings.put('g', g)
+
+radishGremlinFile.withWriter('UTF-8') { Writer writer ->
+ writer.writeLine('/*\n' +
+ 'Licensed to the Apache Software Foundation (ASF) under one\n' +
+ 'or more contributor license agreements. See the NOTICE file\n' +
+ 'distributed with this work for additional information\n' +
+ 'regarding copyright ownership. The ASF licenses this file\n' +
+ 'to you under the Apache License, Version 2.0 (the\n' +
+ '"License"); you may not use this file except in compliance\n' +
+ 'with the License. You may obtain a copy of the License at\n' +
+ '\n' +
+ 'http://www.apache.org/licenses/LICENSE-2.0\n' +
+ '\n' +
+ 'Unless required by applicable law or agreed to in writing,\n' +
+ 'software distributed under the License is distributed on an\n' +
+ '"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n' +
+ 'KIND, either express or implied. See the License for the\n' +
+ 'specific language governing permissions and limitations\n' +
+ 'under the License.\n' +
+ '*/\n')
+
+ writer.writeLine("\n//********************************************************************************")
+ writer.writeLine("//* Do NOT edit this file directly - generated by build/generate.groovy")
+ writer.writeLine("//********************************************************************************\n")
+
+ writer.writeLine(
+ 'package gremlingo\n' +
+ '\n' +
+ 'import (\n' +
+ '\t \"errors\"\n' +
+ '\t \"github.com/lyndonb-bq/tinkerpop/gremlin-go/driver\"\n' +
Review comment:
Ah yes, that was an oversight. I will fix those.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833670955
##########
File path: gremlin-go/driver/client.go
##########
@@ -20,69 +20,76 @@ under the License.
package gremlingo
import (
+ "crypto/tls"
"golang.org/x/text/language"
)
// ClientSettings is used to modify a Client's settings on initialization.
type ClientSettings struct {
+ TraversalSource string
TransporterType TransporterType
LogVerbosity LogVerbosity
Logger Logger
Language language.Tag
+ AuthInfo *AuthInfo
+ TlsConfig *tls.Config
}
// Client is used to connect and interact with a Gremlin-supported server.
type Client struct {
- host string
- port int
+ url string
+ traversalSource string
logHandler *logHandler
transporterType TransporterType
connection *connection
}
// NewClient creates a Client and configures it with the given parameters.
-func NewClient(host string, port int, configurations ...func(settings *ClientSettings)) (*Client, error) {
+func NewClient(url string, configurations ...func(settings *ClientSettings)) (*Client, error) {
settings := &ClientSettings{
+ TraversalSource: "g",
TransporterType: Gorilla,
LogVerbosity: Info,
Logger: &defaultLogger{},
Language: language.English,
+ AuthInfo: &AuthInfo{},
+ TlsConfig: &tls.Config{},
}
for _, configuration := range configurations {
configuration(settings)
}
logHandler := newLogHandler(settings.Logger, settings.LogVerbosity, settings.Language)
- conn, err := createConnection(host, port, logHandler)
+ conn, err := createConnection(url, settings.AuthInfo, settings.TlsConfig, logHandler)
if err != nil {
return nil, err
Review comment:
Done.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#issuecomment-1077018305
See #1594
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] spmallette commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
spmallette commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r829998363
##########
File path: gremlin-go/NOTICE
##########
@@ -0,0 +1,23 @@
+====================================================================================================
Review comment:
Started this thread regarding LICENSE/NOTICE: https://lists.apache.org/thread/kgd52bz7pjc1qc638ktk31ooww5gbp8d
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] spmallette commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
spmallette commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r830102188
##########
File path: gremlin-go/build/generate.groovy
##########
@@ -0,0 +1,167 @@
+/*
Review comment:
I noticed that when i build locally, this script modifies the `gremlin.go` file - the formatting is apparently different from what is being committed. I'm wondering if someone's IDE perhaps formatted the file before commit? I assume we want the format committed that is produced by this file so that it doesn't create unnecessary commits and file contention?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833653717
##########
File path: gremlin-go/driver/connection.go
##########
@@ -66,17 +67,16 @@ func (connection *connection) write(request *request) (ResultSet, error) {
return connection.results[requestID], connection.protocol.write(request)
Review comment:
That is correct. The entire connection is private, we only expose the Client and DriverRemoteConnection, with the connection/protocol/transport layers all private.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833631185
##########
File path: gremlin-go/driver/gorillaTransporter.go
##########
@@ -65,21 +73,30 @@ func (transporter *gorillaTransporter) Write(data []byte) (err error) {
}
err = transporter.connection.WriteMessage(websocket.BinaryMessage, data)
- return err
+ return
+}
+
+func (transporter *gorillaTransporter) getAuthInfo() *AuthInfo {
+ return transporter.authInfo
}
-func (transporter *gorillaTransporter) Read() (bytes []byte, err error) {
+// Read used to read data from the transporter. Opens connection if closed.
+func (transporter *gorillaTransporter) Read() ([]byte, error) {
if transporter.connection == nil {
- err = transporter.Connect()
+ err := transporter.Connect()
Review comment:
The design references gorilla's websocket implementation which references the v13 spec of websockets.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] divijvaidya commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
divijvaidya commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833294695
##########
File path: gremlin-go/driver/connection.go
##########
@@ -66,17 +67,16 @@ func (connection *connection) write(request *request) (ResultSet, error) {
return connection.results[requestID], connection.protocol.write(request)
Review comment:
Correct me if I am wrong but shouldn't the public interfaces for a connection start with a capital? such as Write(), Close() etc.
##########
File path: gremlin-go/driver/connection.go
##########
@@ -66,17 +67,16 @@ func (connection *connection) write(request *request) (ResultSet, error) {
return connection.results[requestID], connection.protocol.write(request)
Review comment:
Instead of `newChannelResultSet`, it should probably be `newConnectionResultSet` to keep names of entities consistent.
##########
File path: gremlin-go/driver/connection.go
##########
@@ -66,17 +67,16 @@ func (connection *connection) write(request *request) (ResultSet, error) {
return connection.results[requestID], connection.protocol.write(request)
}
-func createConnection(host string, port int, logHandler *logHandler) (*connection, error) {
+func createConnection(url string, authInfo *AuthInfo, tlsConfig *tls.Config, logHandler *logHandler) (*connection, error) {
Review comment:
On line number 43 in errorCallBack() method, we are ignoring the error if we fail to close the connection. This may silently lead to leaks.
##########
File path: gremlin-go/driver/connection.go
##########
@@ -66,17 +67,16 @@ func (connection *connection) write(request *request) (ResultSet, error) {
return connection.results[requestID], connection.protocol.write(request)
Review comment:
This method (write()) should validate state of the connection first before executing
##########
File path: gremlin-go/driver/gorillaTransporter.go
##########
@@ -20,42 +20,50 @@ under the License.
package gremlingo
import (
+ "crypto/tls"
"net/url"
- "strconv"
+ "time"
"github.com/gorilla/websocket"
)
+const maxFailCount = 3
+
// Transport layer that uses gorilla/websocket: https://github.com/gorilla/websocket
// Gorilla WebSocket is a widely used and stable Go implementation of the WebSocket protocol.
type gorillaTransporter struct {
- host string
- port int
+ url string
connection websocketConn
isClosed bool
+ authInfo *AuthInfo
+ tlsConfig *tls.Config
}
+// Connect used to establish a connection.
func (transporter *gorillaTransporter) Connect() (err error) {
if transporter.connection != nil {
return
}
- u := url.URL{
- Scheme: scheme,
- Host: transporter.host + ":" + strconv.Itoa(transporter.port),
- Path: path,
+ var u *url.URL
+ u, err = url.Parse(transporter.url)
+ if err != nil {
+ return
}
dialer := websocket.DefaultDialer
+ dialer.TLSClientConfig = transporter.tlsConfig
// TODO: make this configurable from client; this currently does nothing since 4096 is the default
dialer.WriteBufferSize = 4096
- conn, _, err := dialer.Dial(u.String(), nil)
+ // Nil is accepted as a valid header, so it can always be passed directly through.
+ conn, _, err := dialer.Dial(u.String(), transporter.authInfo.getHeader())
Review comment:
is there a timeout here for cases when the server is alive but the connection is taking longer than usual?
##########
File path: gremlin-go/driver/connection_test.go
##########
@@ -131,78 +150,389 @@ func readCount(t *testing.T, g *GraphTraversalSource, label string, expected int
assert.Equal(t, int32(expected), count)
}
+func sortAndCompareTwoStringSlices(s1 []string, s2 []string) bool {
+ sort.Strings(s1)
+ sort.Strings(s2)
+ return reflect.DeepEqual(s1, s2)
+}
+
+func readUsingAnonymousTraversal(t *testing.T, g *GraphTraversalSource) {
+ results, err := g.V().Fold().
+ Project(testLabel, personLabel).
+ By(T__.Unfold().HasLabel(testLabel).Count()).
+ By(T__.Unfold().HasLabel(personLabel).Count()).
+ ToList()
+ assert.Nil(t, err)
+ assert.Equal(t, 1, len(results))
+ resultMap := results[0].GetInterface().(map[interface{}]interface{})
+ assert.Equal(t, int64(0), resultMap[testLabel])
+ assert.Equal(t, int64(len(testNames)), resultMap[personLabel])
+}
+
+func readWithNextAndHasNext(t *testing.T, g *GraphTraversalSource) {
+ traversal := g.V().HasLabel(personLabel).Properties(nameKey)
+ var names []string
+ for i := 0; i < len(testNames); i++ {
+ hasN, err := traversal.HasNext()
+ assert.Nil(t, err)
+ assert.True(t, hasN)
+ res, err := traversal.Next()
+ assert.Nil(t, err)
+ assert.NotNil(t, res)
+ vp, err := res.GetVertexProperty()
+ assert.Nil(t, err)
+ names = append(names, vp.Value.(string))
+ }
+ hasN, _ := traversal.HasNext()
+ assert.False(t, hasN)
+ // Check for Next error when no more elements left
+ res, err := traversal.Next()
+ assert.Nil(t, res)
+ assert.NotNil(t, err)
+ assert.True(t, sortAndCompareTwoStringSlices(names, testNames))
+}
+
+func getEnvOrDefaultString(key string, defaultValue string) string {
+ // Missing value is returned as "".
+ value := os.Getenv(key)
+ if len(value) != 0 {
+ return value
+ }
+ return defaultValue
+}
+
+func getEnvOrDefaultBool(key string, defaultValue bool) bool {
+ value := getEnvOrDefaultString(key, "")
+ if len(value) != 0 {
+ boolValue, err := strconv.ParseBool(value)
+ if err == nil {
+ return boolValue
+ }
+ }
+ return defaultValue
+}
+
+func getBasicAuthInfo() *AuthInfo {
+ return BasicAuthInfo(getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_USERNAME", "stephen"),
+ getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_PASSWORD", "password"))
+}
+
+func skipTestsIfNotEnabled(t *testing.T, testSuiteName string, testSuiteEnabled bool) {
+ if !testSuiteEnabled {
+ t.Skip(fmt.Sprintf("Skipping %s because %s tests are not enabled.", t.Name(), testSuiteName))
+ }
+}
+
func TestConnection(t *testing.T) {
Review comment:
Missing tests for connection:
1. scenario when a connection write() is called after connection close()
2. test that validates that resultSet for a request ID is cleared at some stage.
3. test when a query sends an error e.g. some syntax exception. In such cases, the connection should not disconnect and the error should be propagated as results.
4. scenario when server closes the websocket connection with a close websocket frame
5. scenario when the client closes the connection. Server expects a close websocket frame. Does the gorrila client send that?
##########
File path: gremlin-go/driver/connection_test.go
##########
@@ -131,78 +150,389 @@ func readCount(t *testing.T, g *GraphTraversalSource, label string, expected int
assert.Equal(t, int32(expected), count)
}
+func sortAndCompareTwoStringSlices(s1 []string, s2 []string) bool {
+ sort.Strings(s1)
+ sort.Strings(s2)
+ return reflect.DeepEqual(s1, s2)
+}
+
+func readUsingAnonymousTraversal(t *testing.T, g *GraphTraversalSource) {
+ results, err := g.V().Fold().
+ Project(testLabel, personLabel).
+ By(T__.Unfold().HasLabel(testLabel).Count()).
+ By(T__.Unfold().HasLabel(personLabel).Count()).
+ ToList()
+ assert.Nil(t, err)
+ assert.Equal(t, 1, len(results))
+ resultMap := results[0].GetInterface().(map[interface{}]interface{})
+ assert.Equal(t, int64(0), resultMap[testLabel])
+ assert.Equal(t, int64(len(testNames)), resultMap[personLabel])
+}
+
+func readWithNextAndHasNext(t *testing.T, g *GraphTraversalSource) {
+ traversal := g.V().HasLabel(personLabel).Properties(nameKey)
+ var names []string
+ for i := 0; i < len(testNames); i++ {
+ hasN, err := traversal.HasNext()
+ assert.Nil(t, err)
+ assert.True(t, hasN)
+ res, err := traversal.Next()
+ assert.Nil(t, err)
+ assert.NotNil(t, res)
+ vp, err := res.GetVertexProperty()
+ assert.Nil(t, err)
+ names = append(names, vp.Value.(string))
+ }
+ hasN, _ := traversal.HasNext()
+ assert.False(t, hasN)
+ // Check for Next error when no more elements left
+ res, err := traversal.Next()
+ assert.Nil(t, res)
+ assert.NotNil(t, err)
+ assert.True(t, sortAndCompareTwoStringSlices(names, testNames))
+}
+
+func getEnvOrDefaultString(key string, defaultValue string) string {
+ // Missing value is returned as "".
+ value := os.Getenv(key)
+ if len(value) != 0 {
+ return value
+ }
+ return defaultValue
+}
+
+func getEnvOrDefaultBool(key string, defaultValue bool) bool {
+ value := getEnvOrDefaultString(key, "")
+ if len(value) != 0 {
+ boolValue, err := strconv.ParseBool(value)
+ if err == nil {
+ return boolValue
+ }
+ }
+ return defaultValue
+}
+
+func getBasicAuthInfo() *AuthInfo {
+ return BasicAuthInfo(getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_USERNAME", "stephen"),
+ getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_PASSWORD", "password"))
+}
+
+func skipTestsIfNotEnabled(t *testing.T, testSuiteName string, testSuiteEnabled bool) {
+ if !testSuiteEnabled {
+ t.Skip(fmt.Sprintf("Skipping %s because %s tests are not enabled.", t.Name(), testSuiteName))
+ }
+}
+
func TestConnection(t *testing.T) {
+ // Integration test variables.
+ testNoAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthEnable := getEnvOrDefaultBool("RUN_INTEGRATION_TESTS", true)
+ testNoAuthAuthInfo := &AuthInfo{}
+ testNoAuthTlsConfig := &tls.Config{}
+
+ // No authentication integration test with graphs loaded and alias configured server
+ testNoAuthWithAliasUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthWithAliasEnable := getEnvOrDefaultBool("RUN_INTEGRATION_WITH_ALIAS_ TESTS", false)
+ testNoAuthWithAliasAuthInfo := &AuthInfo{}
+ testNoAuthWithAliasTlsConfig := &tls.Config{}
+
+ // Basic authentication integration test variables.
+ testBasicAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_BASIC_AUTH_URL", "wss://localhost:8183/gremlin")
+ testBasicAuthEnable := getEnvOrDefaultBool("RUN_BASIC_AUTH_INTEGRATION_TESTS", false)
+ testBasicAuthAuthInfo := getBasicAuthInfo()
+ testBasicAuthTlsConfig := &tls.Config{InsecureSkipVerify: true}
+
+ t.Run("Test createConnection without valid server", func(t *testing.T) {
+ connection, err := createConnection(invalidHostValidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid port", func(t *testing.T) {
+ connection, err := createConnection(validHostInvalidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid path", func(t *testing.T) {
+ connection, err := createConnection(validHostValidPortInvalidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
t.Run("Test DriverRemoteConnection GraphTraversal", func(t *testing.T) {
- if runIntegration {
- remote, err := NewDriverRemoteConnection(testHost, testPort)
- assert.Nil(t, err)
- assert.NotNil(t, remote)
- g := Traversal_().WithRemote(remote)
-
- // 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)
-
- // Add data and check that the size of the graph is correct.
- addTestData(t, g)
- readCount(t, g, "", len(getTestNames()))
- readCount(t, g, testLabel, 0)
- readCount(t, g, personLabel, len(getTestNames()))
-
- // Read test data out of the graph and check that it is correct.
- readTestDataVertexProperties(t, g)
- 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)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+
+ // Initialize graph
+ g := initializeGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
+
+ // Read test data out of the graph and check that it is correct.
+ readTestDataVertexProperties(t, g)
+ readTestDataValues(t, g)
+
+ // Reset Graph
+ resetGraph(t, g)
})
t.Run("Test createConnection", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ err = connection.close()
+ assert.Nil(t, err)
})
t.Run("Test connection.write()", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- request := makeStringRequest("g.V().count()")
- resultSet, err := connection.write(&request)
- assert.Nil(t, err)
- assert.NotNil(t, resultSet)
- result := resultSet.one()
- assert.NotNil(t, result)
- assert.Equal(t, "[0]", result.GetString())
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ request := makeStringRequest("g.V().count()", "g")
+ resultSet, err := connection.write(&request)
+ assert.Nil(t, err)
+ assert.NotNil(t, resultSet)
+ result, err := resultSet.one()
+ assert.Nil(t, err)
+ assert.NotNil(t, result)
+ err = connection.close()
+ assert.Nil(t, err)
+ })
+
+ t.Run("Test connection.close() failure", func(t *testing.T) {
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ err = connection.close()
+ assert.Nil(t, err)
+ err = connection.close()
+ assert.NotNil(t, err)
+ err = connection.close()
+ assert.NotNil(t, err)
})
t.Run("Test client.submit()", func(t *testing.T) {
Review comment:
This should go in client_test.go file.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833683741
##########
File path: gremlin-go/driver/client.go
##########
@@ -20,69 +20,76 @@ under the License.
package gremlingo
import (
+ "crypto/tls"
"golang.org/x/text/language"
)
// ClientSettings is used to modify a Client's settings on initialization.
type ClientSettings struct {
+ TraversalSource string
TransporterType TransporterType
LogVerbosity LogVerbosity
Logger Logger
Language language.Tag
+ AuthInfo *AuthInfo
+ TlsConfig *tls.Config
}
// Client is used to connect and interact with a Gremlin-supported server.
type Client struct {
- host string
- port int
+ url string
+ traversalSource string
logHandler *logHandler
transporterType TransporterType
connection *connection
}
// NewClient creates a Client and configures it with the given parameters.
Review comment:
Done.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] divijvaidya commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
divijvaidya commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833261372
##########
File path: gremlin-go/driver/client.go
##########
@@ -20,69 +20,76 @@ under the License.
package gremlingo
import (
+ "crypto/tls"
"golang.org/x/text/language"
)
// ClientSettings is used to modify a Client's settings on initialization.
type ClientSettings struct {
+ TraversalSource string
TransporterType TransporterType
LogVerbosity LogVerbosity
Logger Logger
Language language.Tag
+ AuthInfo *AuthInfo
+ TlsConfig *tls.Config
}
// Client is used to connect and interact with a Gremlin-supported server.
type Client struct {
- host string
- port int
+ url string
+ traversalSource string
logHandler *logHandler
transporterType TransporterType
connection *connection
}
// NewClient creates a Client and configures it with the given parameters.
-func NewClient(host string, port int, configurations ...func(settings *ClientSettings)) (*Client, error) {
+func NewClient(url string, configurations ...func(settings *ClientSettings)) (*Client, error) {
settings := &ClientSettings{
+ TraversalSource: "g",
TransporterType: Gorilla,
LogVerbosity: Info,
Logger: &defaultLogger{},
Language: language.English,
+ AuthInfo: &AuthInfo{},
+ TlsConfig: &tls.Config{},
}
for _, configuration := range configurations {
configuration(settings)
}
logHandler := newLogHandler(settings.Logger, settings.LogVerbosity, settings.Language)
- conn, err := createConnection(host, port, logHandler)
+ conn, err := createConnection(url, settings.AuthInfo, settings.TlsConfig, logHandler)
if err != nil {
return nil, err
Review comment:
please wrap the error with additional details since the underlying error may not have information which are only available here such as the url, transporter type used to connect etc.
##########
File path: gremlin-go/driver/connection.go
##########
@@ -66,17 +67,16 @@ func (connection *connection) write(request *request) (ResultSet, error) {
return connection.results[requestID], connection.protocol.write(request)
}
-func createConnection(host string, port int, logHandler *logHandler) (*connection, error) {
+func createConnection(url string, authInfo *AuthInfo, tlsConfig *tls.Config, logHandler *logHandler) (*connection, error) {
Review comment:
Please add documentation in this class. The documentation should call out that a connection should be cleanly closed and should also document it's lifecycle states.
##########
File path: gremlin-go/driver/connection_test.go
##########
@@ -131,78 +150,389 @@ func readCount(t *testing.T, g *GraphTraversalSource, label string, expected int
assert.Equal(t, int32(expected), count)
}
+func sortAndCompareTwoStringSlices(s1 []string, s2 []string) bool {
+ sort.Strings(s1)
+ sort.Strings(s2)
+ return reflect.DeepEqual(s1, s2)
+}
+
+func readUsingAnonymousTraversal(t *testing.T, g *GraphTraversalSource) {
+ results, err := g.V().Fold().
+ Project(testLabel, personLabel).
+ By(T__.Unfold().HasLabel(testLabel).Count()).
+ By(T__.Unfold().HasLabel(personLabel).Count()).
+ ToList()
+ assert.Nil(t, err)
+ assert.Equal(t, 1, len(results))
+ resultMap := results[0].GetInterface().(map[interface{}]interface{})
+ assert.Equal(t, int64(0), resultMap[testLabel])
+ assert.Equal(t, int64(len(testNames)), resultMap[personLabel])
+}
+
+func readWithNextAndHasNext(t *testing.T, g *GraphTraversalSource) {
+ traversal := g.V().HasLabel(personLabel).Properties(nameKey)
+ var names []string
+ for i := 0; i < len(testNames); i++ {
+ hasN, err := traversal.HasNext()
+ assert.Nil(t, err)
+ assert.True(t, hasN)
+ res, err := traversal.Next()
+ assert.Nil(t, err)
+ assert.NotNil(t, res)
+ vp, err := res.GetVertexProperty()
+ assert.Nil(t, err)
+ names = append(names, vp.Value.(string))
+ }
+ hasN, _ := traversal.HasNext()
+ assert.False(t, hasN)
+ // Check for Next error when no more elements left
+ res, err := traversal.Next()
+ assert.Nil(t, res)
+ assert.NotNil(t, err)
+ assert.True(t, sortAndCompareTwoStringSlices(names, testNames))
+}
+
+func getEnvOrDefaultString(key string, defaultValue string) string {
+ // Missing value is returned as "".
+ value := os.Getenv(key)
+ if len(value) != 0 {
+ return value
+ }
+ return defaultValue
+}
+
+func getEnvOrDefaultBool(key string, defaultValue bool) bool {
+ value := getEnvOrDefaultString(key, "")
+ if len(value) != 0 {
+ boolValue, err := strconv.ParseBool(value)
+ if err == nil {
+ return boolValue
+ }
+ }
+ return defaultValue
+}
+
+func getBasicAuthInfo() *AuthInfo {
+ return BasicAuthInfo(getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_USERNAME", "stephen"),
+ getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_PASSWORD", "password"))
+}
+
+func skipTestsIfNotEnabled(t *testing.T, testSuiteName string, testSuiteEnabled bool) {
+ if !testSuiteEnabled {
+ t.Skip(fmt.Sprintf("Skipping %s because %s tests are not enabled.", t.Name(), testSuiteName))
+ }
+}
+
func TestConnection(t *testing.T) {
+ // Integration test variables.
+ testNoAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthEnable := getEnvOrDefaultBool("RUN_INTEGRATION_TESTS", true)
+ testNoAuthAuthInfo := &AuthInfo{}
+ testNoAuthTlsConfig := &tls.Config{}
+
+ // No authentication integration test with graphs loaded and alias configured server
+ testNoAuthWithAliasUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthWithAliasEnable := getEnvOrDefaultBool("RUN_INTEGRATION_WITH_ALIAS_ TESTS", false)
+ testNoAuthWithAliasAuthInfo := &AuthInfo{}
+ testNoAuthWithAliasTlsConfig := &tls.Config{}
+
+ // Basic authentication integration test variables.
+ testBasicAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_BASIC_AUTH_URL", "wss://localhost:8183/gremlin")
+ testBasicAuthEnable := getEnvOrDefaultBool("RUN_BASIC_AUTH_INTEGRATION_TESTS", false)
+ testBasicAuthAuthInfo := getBasicAuthInfo()
+ testBasicAuthTlsConfig := &tls.Config{InsecureSkipVerify: true}
+
+ t.Run("Test createConnection without valid server", func(t *testing.T) {
+ connection, err := createConnection(invalidHostValidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid port", func(t *testing.T) {
+ connection, err := createConnection(validHostInvalidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid path", func(t *testing.T) {
+ connection, err := createConnection(validHostValidPortInvalidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
t.Run("Test DriverRemoteConnection GraphTraversal", func(t *testing.T) {
- if runIntegration {
- remote, err := NewDriverRemoteConnection(testHost, testPort)
- assert.Nil(t, err)
- assert.NotNil(t, remote)
- g := Traversal_().WithRemote(remote)
-
- // 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)
-
- // Add data and check that the size of the graph is correct.
- addTestData(t, g)
- readCount(t, g, "", len(getTestNames()))
- readCount(t, g, testLabel, 0)
- readCount(t, g, personLabel, len(getTestNames()))
-
- // Read test data out of the graph and check that it is correct.
- readTestDataVertexProperties(t, g)
- 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)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+
+ // Initialize graph
+ g := initializeGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
+
+ // Read test data out of the graph and check that it is correct.
+ readTestDataVertexProperties(t, g)
+ readTestDataValues(t, g)
+
+ // Reset Graph
+ resetGraph(t, g)
})
t.Run("Test createConnection", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ err = connection.close()
+ assert.Nil(t, err)
})
t.Run("Test connection.write()", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- request := makeStringRequest("g.V().count()")
- resultSet, err := connection.write(&request)
- assert.Nil(t, err)
- assert.NotNil(t, resultSet)
- result := resultSet.one()
- assert.NotNil(t, result)
- assert.Equal(t, "[0]", result.GetString())
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ request := makeStringRequest("g.V().count()", "g")
+ resultSet, err := connection.write(&request)
+ assert.Nil(t, err)
+ assert.NotNil(t, resultSet)
+ result, err := resultSet.one()
+ assert.Nil(t, err)
+ assert.NotNil(t, result)
+ err = connection.close()
+ assert.Nil(t, err)
+ })
+
+ t.Run("Test connection.close() failure", func(t *testing.T) {
Review comment:
1. please assert connection state
2. where is the failure during close in this test?
##########
File path: gremlin-go/driver/connection.go
##########
@@ -66,17 +67,16 @@ func (connection *connection) write(request *request) (ResultSet, error) {
return connection.results[requestID], connection.protocol.write(request)
Review comment:
When are we removing the result set for a request ID? Would it always keep on growing for long lasting connections?
##########
File path: gremlin-go/driver/client.go
##########
@@ -20,69 +20,76 @@ under the License.
package gremlingo
import (
+ "crypto/tls"
"golang.org/x/text/language"
)
// ClientSettings is used to modify a Client's settings on initialization.
type ClientSettings struct {
+ TraversalSource string
TransporterType TransporterType
LogVerbosity LogVerbosity
Logger Logger
Language language.Tag
+ AuthInfo *AuthInfo
+ TlsConfig *tls.Config
}
// Client is used to connect and interact with a Gremlin-supported server.
type Client struct {
- host string
- port int
+ url string
+ traversalSource string
logHandler *logHandler
transporterType TransporterType
connection *connection
}
// NewClient creates a Client and configures it with the given parameters.
-func NewClient(host string, port int, configurations ...func(settings *ClientSettings)) (*Client, error) {
+func NewClient(url string, configurations ...func(settings *ClientSettings)) (*Client, error) {
settings := &ClientSettings{
+ TraversalSource: "g",
TransporterType: Gorilla,
LogVerbosity: Info,
Logger: &defaultLogger{},
Language: language.English,
+ AuthInfo: &AuthInfo{},
+ TlsConfig: &tls.Config{},
}
for _, configuration := range configurations {
configuration(settings)
}
logHandler := newLogHandler(settings.Logger, settings.LogVerbosity, settings.Language)
- conn, err := createConnection(host, port, logHandler)
+ conn, err := createConnection(url, settings.AuthInfo, settings.TlsConfig, logHandler)
if err != nil {
return nil, err
}
client := &Client{
- host: host,
- port: port,
+ url: url,
+ traversalSource: "g",
logHandler: logHandler,
transporterType: settings.TransporterType,
connection: conn,
}
return client, nil
}
-// Close closes the client via connection
+// Close closes the client via connection.
Review comment:
Please document whether this API is idempotent or not. Ideally, a close API call should be idempotent. You can achieve this by adding a lifecycle state variable with client which goes from INITIALIZED -> CLOSING -> CLOSED. If close() API is called when the client is not in INITIALIZED state, then it should be a no-op.
##########
File path: gremlin-go/driver/client.go
##########
@@ -20,69 +20,76 @@ under the License.
package gremlingo
import (
+ "crypto/tls"
"golang.org/x/text/language"
)
// ClientSettings is used to modify a Client's settings on initialization.
type ClientSettings struct {
+ TraversalSource string
TransporterType TransporterType
LogVerbosity LogVerbosity
Logger Logger
Language language.Tag
+ AuthInfo *AuthInfo
+ TlsConfig *tls.Config
}
// Client is used to connect and interact with a Gremlin-supported server.
type Client struct {
- host string
- port int
+ url string
+ traversalSource string
logHandler *logHandler
transporterType TransporterType
connection *connection
}
// NewClient creates a Client and configures it with the given parameters.
-func NewClient(host string, port int, configurations ...func(settings *ClientSettings)) (*Client, error) {
+func NewClient(url string, configurations ...func(settings *ClientSettings)) (*Client, error) {
settings := &ClientSettings{
+ TraversalSource: "g",
TransporterType: Gorilla,
LogVerbosity: Info,
Logger: &defaultLogger{},
Language: language.English,
+ AuthInfo: &AuthInfo{},
+ TlsConfig: &tls.Config{},
}
for _, configuration := range configurations {
configuration(settings)
}
logHandler := newLogHandler(settings.Logger, settings.LogVerbosity, settings.Language)
- conn, err := createConnection(host, port, logHandler)
+ conn, err := createConnection(url, settings.AuthInfo, settings.TlsConfig, logHandler)
if err != nil {
return nil, err
Review comment:
please wrap the error with additional details since the underlying error may not have information which are only available here such as the url, transporter type used to connect etc.
##########
File path: gremlin-go/driver/gorillaTransporter.go
##########
@@ -65,21 +73,30 @@ func (transporter *gorillaTransporter) Write(data []byte) (err error) {
}
err = transporter.connection.WriteMessage(websocket.BinaryMessage, data)
- return err
+ return
+}
+
+func (transporter *gorillaTransporter) getAuthInfo() *AuthInfo {
+ return transporter.authInfo
}
-func (transporter *gorillaTransporter) Read() (bytes []byte, err error) {
+// Read used to read data from the transporter. Opens connection if closed.
+func (transporter *gorillaTransporter) Read() ([]byte, error) {
if transporter.connection == nil {
- err = transporter.Connect()
+ err := transporter.Connect()
Review comment:
there should be some place where we say that we support websocket V13 in the gorilla configuration.
##########
File path: gremlin-go/driver/protocol.go
##########
@@ -123,13 +123,34 @@ func responseHandler(resultSets map[string]ResultSet, response response, log *lo
// Add data to the ResultSet.
resultSets[responseIDString].addResult(&Result{data})
log.logger.Logf(Info, "Partial %v===>%v", response.responseStatus, data)
- } else if statusCode == http.StatusProxyAuthRequired {
- // TODO AN-989: Implement authentication (including handshaking).
- resultSets[responseIDString].Close()
- return errors.New("authentication is not currently supported")
+ } else if statusCode == http.StatusProxyAuthRequired || statusCode == 151 {
Review comment:
please move 151 into a constant with a descriptive name
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833689649
##########
File path: gremlin-go/driver/connection.go
##########
@@ -66,17 +67,16 @@ func (connection *connection) write(request *request) (ResultSet, error) {
return connection.results[requestID], connection.protocol.write(request)
}
-func createConnection(host string, port int, logHandler *logHandler) (*connection, error) {
+func createConnection(url string, authInfo *AuthInfo, tlsConfig *tls.Config, logHandler *logHandler) (*connection, error) {
Review comment:
Added documentation and logging for error so that it will be noticed.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833640299
##########
File path: gremlin-go/driver/connection.go
##########
@@ -66,17 +67,16 @@ func (connection *connection) write(request *request) (ResultSet, error) {
return connection.results[requestID], connection.protocol.write(request)
Review comment:
ResultSet is an interface and the implementation in channelResultSet, this is because it uses a channel under the hood. The reason for the naming is because it makes a channel based result set, I like it this way because if we wanted to we could change to a slice based ResultSet and it would be newSliceResultSet.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833820296
##########
File path: gremlin-go/driver/client.go
##########
@@ -20,69 +20,76 @@ under the License.
package gremlingo
import (
+ "crypto/tls"
"golang.org/x/text/language"
)
// ClientSettings is used to modify a Client's settings on initialization.
type ClientSettings struct {
+ TraversalSource string
TransporterType TransporterType
LogVerbosity LogVerbosity
Logger Logger
Language language.Tag
+ AuthInfo *AuthInfo
+ TlsConfig *tls.Config
}
// Client is used to connect and interact with a Gremlin-supported server.
type Client struct {
- host string
- port int
+ url string
+ traversalSource string
logHandler *logHandler
transporterType TransporterType
connection *connection
}
// NewClient creates a Client and configures it with the given parameters.
-func NewClient(host string, port int, configurations ...func(settings *ClientSettings)) (*Client, error) {
+func NewClient(url string, configurations ...func(settings *ClientSettings)) (*Client, error) {
settings := &ClientSettings{
+ TraversalSource: "g",
TransporterType: Gorilla,
LogVerbosity: Info,
Logger: &defaultLogger{},
Language: language.English,
+ AuthInfo: &AuthInfo{},
+ TlsConfig: &tls.Config{},
}
for _, configuration := range configurations {
configuration(settings)
}
logHandler := newLogHandler(settings.Logger, settings.LogVerbosity, settings.Language)
- conn, err := createConnection(host, port, logHandler)
+ conn, err := createConnection(url, settings.AuthInfo, settings.TlsConfig, logHandler)
if err != nil {
return nil, err
}
client := &Client{
- host: host,
- port: port,
+ url: url,
+ traversalSource: "g",
logHandler: logHandler,
transporterType: settings.TransporterType,
connection: conn,
}
return client, nil
}
-// Close closes the client via connection
+// Close closes the client via connection.
Review comment:
TODO.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] divijvaidya commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
divijvaidya commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833258897
##########
File path: gremlin-go/driver/client.go
##########
@@ -20,69 +20,76 @@ under the License.
package gremlingo
import (
+ "crypto/tls"
"golang.org/x/text/language"
)
// ClientSettings is used to modify a Client's settings on initialization.
type ClientSettings struct {
+ TraversalSource string
TransporterType TransporterType
LogVerbosity LogVerbosity
Logger Logger
Language language.Tag
+ AuthInfo *AuthInfo
+ TlsConfig *tls.Config
}
// Client is used to connect and interact with a Gremlin-supported server.
type Client struct {
- host string
- port int
+ url string
+ traversalSource string
logHandler *logHandler
transporterType TransporterType
connection *connection
}
// NewClient creates a Client and configures it with the given parameters.
Review comment:
A webSocket connection is also created in initialization of a client. Please add this to the documentation. Customers need to know at what stage is a network connection established with the server.
Please also document that a client should be properly closed else it may leak connections to the server.
##########
File path: gremlin-go/driver/connection_test.go
##########
@@ -131,78 +150,389 @@ func readCount(t *testing.T, g *GraphTraversalSource, label string, expected int
assert.Equal(t, int32(expected), count)
}
+func sortAndCompareTwoStringSlices(s1 []string, s2 []string) bool {
+ sort.Strings(s1)
+ sort.Strings(s2)
+ return reflect.DeepEqual(s1, s2)
+}
+
+func readUsingAnonymousTraversal(t *testing.T, g *GraphTraversalSource) {
+ results, err := g.V().Fold().
+ Project(testLabel, personLabel).
+ By(T__.Unfold().HasLabel(testLabel).Count()).
+ By(T__.Unfold().HasLabel(personLabel).Count()).
+ ToList()
+ assert.Nil(t, err)
+ assert.Equal(t, 1, len(results))
+ resultMap := results[0].GetInterface().(map[interface{}]interface{})
+ assert.Equal(t, int64(0), resultMap[testLabel])
+ assert.Equal(t, int64(len(testNames)), resultMap[personLabel])
+}
+
+func readWithNextAndHasNext(t *testing.T, g *GraphTraversalSource) {
+ traversal := g.V().HasLabel(personLabel).Properties(nameKey)
+ var names []string
+ for i := 0; i < len(testNames); i++ {
+ hasN, err := traversal.HasNext()
+ assert.Nil(t, err)
+ assert.True(t, hasN)
+ res, err := traversal.Next()
+ assert.Nil(t, err)
+ assert.NotNil(t, res)
+ vp, err := res.GetVertexProperty()
+ assert.Nil(t, err)
+ names = append(names, vp.Value.(string))
+ }
+ hasN, _ := traversal.HasNext()
+ assert.False(t, hasN)
+ // Check for Next error when no more elements left
+ res, err := traversal.Next()
+ assert.Nil(t, res)
+ assert.NotNil(t, err)
+ assert.True(t, sortAndCompareTwoStringSlices(names, testNames))
+}
+
+func getEnvOrDefaultString(key string, defaultValue string) string {
+ // Missing value is returned as "".
+ value := os.Getenv(key)
+ if len(value) != 0 {
+ return value
+ }
+ return defaultValue
+}
+
+func getEnvOrDefaultBool(key string, defaultValue bool) bool {
+ value := getEnvOrDefaultString(key, "")
+ if len(value) != 0 {
+ boolValue, err := strconv.ParseBool(value)
+ if err == nil {
+ return boolValue
+ }
+ }
+ return defaultValue
+}
+
+func getBasicAuthInfo() *AuthInfo {
+ return BasicAuthInfo(getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_USERNAME", "stephen"),
+ getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_PASSWORD", "password"))
+}
+
+func skipTestsIfNotEnabled(t *testing.T, testSuiteName string, testSuiteEnabled bool) {
+ if !testSuiteEnabled {
+ t.Skip(fmt.Sprintf("Skipping %s because %s tests are not enabled.", t.Name(), testSuiteName))
+ }
+}
+
func TestConnection(t *testing.T) {
+ // Integration test variables.
+ testNoAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthEnable := getEnvOrDefaultBool("RUN_INTEGRATION_TESTS", true)
+ testNoAuthAuthInfo := &AuthInfo{}
+ testNoAuthTlsConfig := &tls.Config{}
+
+ // No authentication integration test with graphs loaded and alias configured server
+ testNoAuthWithAliasUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthWithAliasEnable := getEnvOrDefaultBool("RUN_INTEGRATION_WITH_ALIAS_ TESTS", false)
+ testNoAuthWithAliasAuthInfo := &AuthInfo{}
+ testNoAuthWithAliasTlsConfig := &tls.Config{}
+
+ // Basic authentication integration test variables.
+ testBasicAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_BASIC_AUTH_URL", "wss://localhost:8183/gremlin")
+ testBasicAuthEnable := getEnvOrDefaultBool("RUN_BASIC_AUTH_INTEGRATION_TESTS", false)
+ testBasicAuthAuthInfo := getBasicAuthInfo()
+ testBasicAuthTlsConfig := &tls.Config{InsecureSkipVerify: true}
+
+ t.Run("Test createConnection without valid server", func(t *testing.T) {
+ connection, err := createConnection(invalidHostValidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid port", func(t *testing.T) {
+ connection, err := createConnection(validHostInvalidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid path", func(t *testing.T) {
+ connection, err := createConnection(validHostValidPortInvalidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
t.Run("Test DriverRemoteConnection GraphTraversal", func(t *testing.T) {
- if runIntegration {
- remote, err := NewDriverRemoteConnection(testHost, testPort)
- assert.Nil(t, err)
- assert.NotNil(t, remote)
- g := Traversal_().WithRemote(remote)
-
- // 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)
-
- // Add data and check that the size of the graph is correct.
- addTestData(t, g)
- readCount(t, g, "", len(getTestNames()))
- readCount(t, g, testLabel, 0)
- readCount(t, g, personLabel, len(getTestNames()))
-
- // Read test data out of the graph and check that it is correct.
- readTestDataVertexProperties(t, g)
- 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)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+
+ // Initialize graph
+ g := initializeGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
+
+ // Read test data out of the graph and check that it is correct.
+ readTestDataVertexProperties(t, g)
+ readTestDataValues(t, g)
+
+ // Reset Graph
+ resetGraph(t, g)
})
t.Run("Test createConnection", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ err = connection.close()
+ assert.Nil(t, err)
})
t.Run("Test connection.write()", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- request := makeStringRequest("g.V().count()")
- resultSet, err := connection.write(&request)
- assert.Nil(t, err)
- assert.NotNil(t, resultSet)
- result := resultSet.one()
- assert.NotNil(t, result)
- assert.Equal(t, "[0]", result.GetString())
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
Review comment:
please assert state of connection here
<same for other tests>
##########
File path: gremlin-go/driver/connection.go
##########
@@ -66,17 +67,16 @@ func (connection *connection) write(request *request) (ResultSet, error) {
return connection.results[requestID], connection.protocol.write(request)
Review comment:
Why do we need `errorCallback()` function? It seems like we are closing the connection on error (which is fine). Can we validate the state first? What if user had called connection.Close() when connection was in flight, in that case, close() will be called twice.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833665090
##########
File path: gremlin-go/driver/connection_test.go
##########
@@ -131,78 +150,389 @@ func readCount(t *testing.T, g *GraphTraversalSource, label string, expected int
assert.Equal(t, int32(expected), count)
}
+func sortAndCompareTwoStringSlices(s1 []string, s2 []string) bool {
+ sort.Strings(s1)
+ sort.Strings(s2)
+ return reflect.DeepEqual(s1, s2)
+}
+
+func readUsingAnonymousTraversal(t *testing.T, g *GraphTraversalSource) {
+ results, err := g.V().Fold().
+ Project(testLabel, personLabel).
+ By(T__.Unfold().HasLabel(testLabel).Count()).
+ By(T__.Unfold().HasLabel(personLabel).Count()).
+ ToList()
+ assert.Nil(t, err)
+ assert.Equal(t, 1, len(results))
+ resultMap := results[0].GetInterface().(map[interface{}]interface{})
+ assert.Equal(t, int64(0), resultMap[testLabel])
+ assert.Equal(t, int64(len(testNames)), resultMap[personLabel])
+}
+
+func readWithNextAndHasNext(t *testing.T, g *GraphTraversalSource) {
+ traversal := g.V().HasLabel(personLabel).Properties(nameKey)
+ var names []string
+ for i := 0; i < len(testNames); i++ {
+ hasN, err := traversal.HasNext()
+ assert.Nil(t, err)
+ assert.True(t, hasN)
+ res, err := traversal.Next()
+ assert.Nil(t, err)
+ assert.NotNil(t, res)
+ vp, err := res.GetVertexProperty()
+ assert.Nil(t, err)
+ names = append(names, vp.Value.(string))
+ }
+ hasN, _ := traversal.HasNext()
+ assert.False(t, hasN)
+ // Check for Next error when no more elements left
+ res, err := traversal.Next()
+ assert.Nil(t, res)
+ assert.NotNil(t, err)
+ assert.True(t, sortAndCompareTwoStringSlices(names, testNames))
+}
+
+func getEnvOrDefaultString(key string, defaultValue string) string {
+ // Missing value is returned as "".
+ value := os.Getenv(key)
+ if len(value) != 0 {
+ return value
+ }
+ return defaultValue
+}
+
+func getEnvOrDefaultBool(key string, defaultValue bool) bool {
+ value := getEnvOrDefaultString(key, "")
+ if len(value) != 0 {
+ boolValue, err := strconv.ParseBool(value)
+ if err == nil {
+ return boolValue
+ }
+ }
+ return defaultValue
+}
+
+func getBasicAuthInfo() *AuthInfo {
+ return BasicAuthInfo(getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_USERNAME", "stephen"),
+ getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_PASSWORD", "password"))
+}
+
+func skipTestsIfNotEnabled(t *testing.T, testSuiteName string, testSuiteEnabled bool) {
+ if !testSuiteEnabled {
+ t.Skip(fmt.Sprintf("Skipping %s because %s tests are not enabled.", t.Name(), testSuiteName))
+ }
+}
+
func TestConnection(t *testing.T) {
+ // Integration test variables.
+ testNoAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthEnable := getEnvOrDefaultBool("RUN_INTEGRATION_TESTS", true)
+ testNoAuthAuthInfo := &AuthInfo{}
+ testNoAuthTlsConfig := &tls.Config{}
+
+ // No authentication integration test with graphs loaded and alias configured server
+ testNoAuthWithAliasUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthWithAliasEnable := getEnvOrDefaultBool("RUN_INTEGRATION_WITH_ALIAS_ TESTS", false)
+ testNoAuthWithAliasAuthInfo := &AuthInfo{}
+ testNoAuthWithAliasTlsConfig := &tls.Config{}
+
+ // Basic authentication integration test variables.
+ testBasicAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_BASIC_AUTH_URL", "wss://localhost:8183/gremlin")
+ testBasicAuthEnable := getEnvOrDefaultBool("RUN_BASIC_AUTH_INTEGRATION_TESTS", false)
+ testBasicAuthAuthInfo := getBasicAuthInfo()
+ testBasicAuthTlsConfig := &tls.Config{InsecureSkipVerify: true}
+
+ t.Run("Test createConnection without valid server", func(t *testing.T) {
+ connection, err := createConnection(invalidHostValidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid port", func(t *testing.T) {
+ connection, err := createConnection(validHostInvalidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid path", func(t *testing.T) {
+ connection, err := createConnection(validHostValidPortInvalidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
t.Run("Test DriverRemoteConnection GraphTraversal", func(t *testing.T) {
- if runIntegration {
- remote, err := NewDriverRemoteConnection(testHost, testPort)
- assert.Nil(t, err)
- assert.NotNil(t, remote)
- g := Traversal_().WithRemote(remote)
-
- // 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)
-
- // Add data and check that the size of the graph is correct.
- addTestData(t, g)
- readCount(t, g, "", len(getTestNames()))
- readCount(t, g, testLabel, 0)
- readCount(t, g, personLabel, len(getTestNames()))
-
- // Read test data out of the graph and check that it is correct.
- readTestDataVertexProperties(t, g)
- 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)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+
+ // Initialize graph
+ g := initializeGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
+
+ // Read test data out of the graph and check that it is correct.
+ readTestDataVertexProperties(t, g)
+ readTestDataValues(t, g)
+
+ // Reset Graph
+ resetGraph(t, g)
})
t.Run("Test createConnection", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ err = connection.close()
+ assert.Nil(t, err)
})
t.Run("Test connection.write()", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- request := makeStringRequest("g.V().count()")
- resultSet, err := connection.write(&request)
- assert.Nil(t, err)
- assert.NotNil(t, resultSet)
- result := resultSet.one()
- assert.NotNil(t, result)
- assert.Equal(t, "[0]", result.GetString())
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ request := makeStringRequest("g.V().count()", "g")
+ resultSet, err := connection.write(&request)
+ assert.Nil(t, err)
+ assert.NotNil(t, resultSet)
+ result, err := resultSet.one()
+ assert.Nil(t, err)
+ assert.NotNil(t, result)
+ err = connection.close()
+ assert.Nil(t, err)
+ })
+
+ t.Run("Test connection.close() failure", func(t *testing.T) {
Review comment:
1. Will add assert
2. Failure is `assert.NotNil(t, err)`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833668315
##########
File path: gremlin-go/driver/connection_test.go
##########
@@ -131,78 +150,389 @@ func readCount(t *testing.T, g *GraphTraversalSource, label string, expected int
assert.Equal(t, int32(expected), count)
}
+func sortAndCompareTwoStringSlices(s1 []string, s2 []string) bool {
+ sort.Strings(s1)
+ sort.Strings(s2)
+ return reflect.DeepEqual(s1, s2)
+}
+
+func readUsingAnonymousTraversal(t *testing.T, g *GraphTraversalSource) {
+ results, err := g.V().Fold().
+ Project(testLabel, personLabel).
+ By(T__.Unfold().HasLabel(testLabel).Count()).
+ By(T__.Unfold().HasLabel(personLabel).Count()).
+ ToList()
+ assert.Nil(t, err)
+ assert.Equal(t, 1, len(results))
+ resultMap := results[0].GetInterface().(map[interface{}]interface{})
+ assert.Equal(t, int64(0), resultMap[testLabel])
+ assert.Equal(t, int64(len(testNames)), resultMap[personLabel])
+}
+
+func readWithNextAndHasNext(t *testing.T, g *GraphTraversalSource) {
+ traversal := g.V().HasLabel(personLabel).Properties(nameKey)
+ var names []string
+ for i := 0; i < len(testNames); i++ {
+ hasN, err := traversal.HasNext()
+ assert.Nil(t, err)
+ assert.True(t, hasN)
+ res, err := traversal.Next()
+ assert.Nil(t, err)
+ assert.NotNil(t, res)
+ vp, err := res.GetVertexProperty()
+ assert.Nil(t, err)
+ names = append(names, vp.Value.(string))
+ }
+ hasN, _ := traversal.HasNext()
+ assert.False(t, hasN)
+ // Check for Next error when no more elements left
+ res, err := traversal.Next()
+ assert.Nil(t, res)
+ assert.NotNil(t, err)
+ assert.True(t, sortAndCompareTwoStringSlices(names, testNames))
+}
+
+func getEnvOrDefaultString(key string, defaultValue string) string {
+ // Missing value is returned as "".
+ value := os.Getenv(key)
+ if len(value) != 0 {
+ return value
+ }
+ return defaultValue
+}
+
+func getEnvOrDefaultBool(key string, defaultValue bool) bool {
+ value := getEnvOrDefaultString(key, "")
+ if len(value) != 0 {
+ boolValue, err := strconv.ParseBool(value)
+ if err == nil {
+ return boolValue
+ }
+ }
+ return defaultValue
+}
+
+func getBasicAuthInfo() *AuthInfo {
+ return BasicAuthInfo(getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_USERNAME", "stephen"),
+ getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_PASSWORD", "password"))
+}
+
+func skipTestsIfNotEnabled(t *testing.T, testSuiteName string, testSuiteEnabled bool) {
+ if !testSuiteEnabled {
+ t.Skip(fmt.Sprintf("Skipping %s because %s tests are not enabled.", t.Name(), testSuiteName))
+ }
+}
+
func TestConnection(t *testing.T) {
+ // Integration test variables.
+ testNoAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthEnable := getEnvOrDefaultBool("RUN_INTEGRATION_TESTS", true)
+ testNoAuthAuthInfo := &AuthInfo{}
+ testNoAuthTlsConfig := &tls.Config{}
+
+ // No authentication integration test with graphs loaded and alias configured server
+ testNoAuthWithAliasUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthWithAliasEnable := getEnvOrDefaultBool("RUN_INTEGRATION_WITH_ALIAS_ TESTS", false)
+ testNoAuthWithAliasAuthInfo := &AuthInfo{}
+ testNoAuthWithAliasTlsConfig := &tls.Config{}
+
+ // Basic authentication integration test variables.
+ testBasicAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_BASIC_AUTH_URL", "wss://localhost:8183/gremlin")
+ testBasicAuthEnable := getEnvOrDefaultBool("RUN_BASIC_AUTH_INTEGRATION_TESTS", false)
+ testBasicAuthAuthInfo := getBasicAuthInfo()
+ testBasicAuthTlsConfig := &tls.Config{InsecureSkipVerify: true}
+
+ t.Run("Test createConnection without valid server", func(t *testing.T) {
+ connection, err := createConnection(invalidHostValidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid port", func(t *testing.T) {
+ connection, err := createConnection(validHostInvalidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid path", func(t *testing.T) {
+ connection, err := createConnection(validHostValidPortInvalidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
t.Run("Test DriverRemoteConnection GraphTraversal", func(t *testing.T) {
- if runIntegration {
- remote, err := NewDriverRemoteConnection(testHost, testPort)
- assert.Nil(t, err)
- assert.NotNil(t, remote)
- g := Traversal_().WithRemote(remote)
-
- // 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)
-
- // Add data and check that the size of the graph is correct.
- addTestData(t, g)
- readCount(t, g, "", len(getTestNames()))
- readCount(t, g, testLabel, 0)
- readCount(t, g, personLabel, len(getTestNames()))
-
- // Read test data out of the graph and check that it is correct.
- readTestDataVertexProperties(t, g)
- 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)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+
+ // Initialize graph
+ g := initializeGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
+
+ // Read test data out of the graph and check that it is correct.
+ readTestDataVertexProperties(t, g)
+ readTestDataValues(t, g)
+
+ // Reset Graph
+ resetGraph(t, g)
})
t.Run("Test createConnection", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ err = connection.close()
+ assert.Nil(t, err)
})
t.Run("Test connection.write()", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- request := makeStringRequest("g.V().count()")
- resultSet, err := connection.write(&request)
- assert.Nil(t, err)
- assert.NotNil(t, resultSet)
- result := resultSet.one()
- assert.NotNil(t, result)
- assert.Equal(t, "[0]", result.GetString())
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
Review comment:
Done.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] spmallette commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
spmallette commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r830099849
##########
File path: gremlin-go/build/generate.groovy
##########
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+
+import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph
+import org.apache.tinkerpop.gremlin.process.traversal.translator.GolangTranslator
+import org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine
+import org.apache.tinkerpop.gremlin.groovy.jsr223.ast.VarAsBindingASTTransformation
+import org.apache.tinkerpop.gremlin.groovy.jsr223.ast.RepeatASTTransformationCustomizer
+import org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyCustomizer
+import org.codehaus.groovy.control.customizers.CompilationCustomizer
+import org.apache.tinkerpop.gremlin.features.FeatureReader
+
+import javax.script.SimpleBindings
+
+import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal
+
+// file is overwritten on each generation
+radishGremlinFile = new File("${projectBaseDir}/gremlin-go/cucumber/gremlin.go")
+
+// assumes globally unique scenario names for keys with list of Gremlin traversals as they appear
+gremlins = FeatureReader.parse("${projectBaseDir}")
+
+gremlinGroovyScriptEngine = new GremlinGroovyScriptEngine(new GroovyCustomizer() {
+ public CompilationCustomizer create() {
+ return new RepeatASTTransformationCustomizer(new VarAsBindingASTTransformation())
+ }
+})
+translator = GolangTranslator.of('g')
+g = traversal().withEmbedded(EmptyGraph.instance())
+bindings = new SimpleBindings()
+bindings.put('g', g)
+
+radishGremlinFile.withWriter('UTF-8') { Writer writer ->
+ writer.writeLine('/*\n' +
+ 'Licensed to the Apache Software Foundation (ASF) under one\n' +
+ 'or more contributor license agreements. See the NOTICE file\n' +
+ 'distributed with this work for additional information\n' +
+ 'regarding copyright ownership. The ASF licenses this file\n' +
+ 'to you under the Apache License, Version 2.0 (the\n' +
+ '"License"); you may not use this file except in compliance\n' +
+ 'with the License. You may obtain a copy of the License at\n' +
+ '\n' +
+ 'http://www.apache.org/licenses/LICENSE-2.0\n' +
+ '\n' +
+ 'Unless required by applicable law or agreed to in writing,\n' +
+ 'software distributed under the License is distributed on an\n' +
+ '"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n' +
+ 'KIND, either express or implied. See the License for the\n' +
+ 'specific language governing permissions and limitations\n' +
+ 'under the License.\n' +
+ '*/\n')
+
+ writer.writeLine("\n//********************************************************************************")
+ writer.writeLine("//* Do NOT edit this file directly - generated by build/generate.groovy")
+ writer.writeLine("//********************************************************************************\n")
+
+ writer.writeLine(
+ 'package gremlingo\n' +
+ '\n' +
+ 'import (\n' +
+ '\t \"errors\"\n' +
+ '\t \"github.com/lyndonb-bq/tinkerpop/gremlin-go/driver\"\n' +
Review comment:
i note that there are number of places that reference the "lyndonb-bq" repo. i assume those should all be changed now?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r830187861
##########
File path: gremlin-go/build/generate.groovy
##########
@@ -0,0 +1,167 @@
+/*
Review comment:
Yeah I think IntelliJ auto formats it if you commit through IntelliJ. I will fix this.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833820028
##########
File path: gremlin-go/driver/connection_test.go
##########
@@ -131,78 +150,389 @@ func readCount(t *testing.T, g *GraphTraversalSource, label string, expected int
assert.Equal(t, int32(expected), count)
}
+func sortAndCompareTwoStringSlices(s1 []string, s2 []string) bool {
+ sort.Strings(s1)
+ sort.Strings(s2)
+ return reflect.DeepEqual(s1, s2)
+}
+
+func readUsingAnonymousTraversal(t *testing.T, g *GraphTraversalSource) {
+ results, err := g.V().Fold().
+ Project(testLabel, personLabel).
+ By(T__.Unfold().HasLabel(testLabel).Count()).
+ By(T__.Unfold().HasLabel(personLabel).Count()).
+ ToList()
+ assert.Nil(t, err)
+ assert.Equal(t, 1, len(results))
+ resultMap := results[0].GetInterface().(map[interface{}]interface{})
+ assert.Equal(t, int64(0), resultMap[testLabel])
+ assert.Equal(t, int64(len(testNames)), resultMap[personLabel])
+}
+
+func readWithNextAndHasNext(t *testing.T, g *GraphTraversalSource) {
+ traversal := g.V().HasLabel(personLabel).Properties(nameKey)
+ var names []string
+ for i := 0; i < len(testNames); i++ {
+ hasN, err := traversal.HasNext()
+ assert.Nil(t, err)
+ assert.True(t, hasN)
+ res, err := traversal.Next()
+ assert.Nil(t, err)
+ assert.NotNil(t, res)
+ vp, err := res.GetVertexProperty()
+ assert.Nil(t, err)
+ names = append(names, vp.Value.(string))
+ }
+ hasN, _ := traversal.HasNext()
+ assert.False(t, hasN)
+ // Check for Next error when no more elements left
+ res, err := traversal.Next()
+ assert.Nil(t, res)
+ assert.NotNil(t, err)
+ assert.True(t, sortAndCompareTwoStringSlices(names, testNames))
+}
+
+func getEnvOrDefaultString(key string, defaultValue string) string {
+ // Missing value is returned as "".
+ value := os.Getenv(key)
+ if len(value) != 0 {
+ return value
+ }
+ return defaultValue
+}
+
+func getEnvOrDefaultBool(key string, defaultValue bool) bool {
+ value := getEnvOrDefaultString(key, "")
+ if len(value) != 0 {
+ boolValue, err := strconv.ParseBool(value)
+ if err == nil {
+ return boolValue
+ }
+ }
+ return defaultValue
+}
+
+func getBasicAuthInfo() *AuthInfo {
+ return BasicAuthInfo(getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_USERNAME", "stephen"),
+ getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_PASSWORD", "password"))
+}
+
+func skipTestsIfNotEnabled(t *testing.T, testSuiteName string, testSuiteEnabled bool) {
+ if !testSuiteEnabled {
+ t.Skip(fmt.Sprintf("Skipping %s because %s tests are not enabled.", t.Name(), testSuiteName))
+ }
+}
+
func TestConnection(t *testing.T) {
Review comment:
1. Done
2. Done
3. TODO
4. TODO
5. I looked in Python and in Java and this looks like it is only for sessions. We do not support sessions yet, do I need them for this?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833654411
##########
File path: gremlin-go/driver/connection.go
##########
@@ -66,17 +67,16 @@ func (connection *connection) write(request *request) (ResultSet, error) {
return connection.results[requestID], connection.protocol.write(request)
Review comment:
Fixed
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] krlawrence commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
krlawrence commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r830142638
##########
File path: gremlin-go/driver/graphBinary_test.go
##########
@@ -51,6 +51,11 @@ func readToValue(buff *bytes.Buffer) interface{} {
}
func TestGraphBinaryV1(t *testing.T) {
+ var m = map[interface{}]interface{}{
Review comment:
Just a general question/comment - I believe the empty interface `interface{}` has been recently deprecated in favor of `any` . At some point we may want to make that change.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r830252543
##########
File path: gremlin-go/README.md
##########
@@ -114,15 +156,19 @@ func main() {
Note: The exact import name as well as the module prefix for `NewDriverRemoteConnection` may change in the future.
+### Design Architecture
+
+See [Gremlin-Go Design Overview](design.MD)
+
# Go Gremlin Language Variant
[Apache TinkerPop™][tk] is a graph computing framework for both graph databases (OLTP) and graph analytic systems
(OLAP). [Gremlin][gremlin] is the graph traversal language of TinkerPop. It can be described as a functional,
data-flow language that enables users to succinctly express complex traversals on (or queries of) their application's
property graph.
-Gremlin-Go implements Gremlin within the Go language and can be used on any Go runtime greater than v1.17. One important distinction with Go and Java is that
-the functions are capitalized, as is required to export functions is Go.
+Gremlin-Go implements Gremlin within the Go language and can be used on any Go runtime greater than v1.17. One
+important distinction with Go and Java is that the functions are capitalized, as is required to export functions is Go.
Review comment:
Will update, thanks!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833637113
##########
File path: gremlin-go/driver/connection.go
##########
@@ -66,17 +67,16 @@ func (connection *connection) write(request *request) (ResultSet, error) {
return connection.results[requestID], connection.protocol.write(request)
Review comment:
Yes, we identified this issue as a (form of) memory leak. This will be corrected.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r833666164
##########
File path: gremlin-go/driver/connection_test.go
##########
@@ -131,78 +150,389 @@ func readCount(t *testing.T, g *GraphTraversalSource, label string, expected int
assert.Equal(t, int32(expected), count)
}
+func sortAndCompareTwoStringSlices(s1 []string, s2 []string) bool {
+ sort.Strings(s1)
+ sort.Strings(s2)
+ return reflect.DeepEqual(s1, s2)
+}
+
+func readUsingAnonymousTraversal(t *testing.T, g *GraphTraversalSource) {
+ results, err := g.V().Fold().
+ Project(testLabel, personLabel).
+ By(T__.Unfold().HasLabel(testLabel).Count()).
+ By(T__.Unfold().HasLabel(personLabel).Count()).
+ ToList()
+ assert.Nil(t, err)
+ assert.Equal(t, 1, len(results))
+ resultMap := results[0].GetInterface().(map[interface{}]interface{})
+ assert.Equal(t, int64(0), resultMap[testLabel])
+ assert.Equal(t, int64(len(testNames)), resultMap[personLabel])
+}
+
+func readWithNextAndHasNext(t *testing.T, g *GraphTraversalSource) {
+ traversal := g.V().HasLabel(personLabel).Properties(nameKey)
+ var names []string
+ for i := 0; i < len(testNames); i++ {
+ hasN, err := traversal.HasNext()
+ assert.Nil(t, err)
+ assert.True(t, hasN)
+ res, err := traversal.Next()
+ assert.Nil(t, err)
+ assert.NotNil(t, res)
+ vp, err := res.GetVertexProperty()
+ assert.Nil(t, err)
+ names = append(names, vp.Value.(string))
+ }
+ hasN, _ := traversal.HasNext()
+ assert.False(t, hasN)
+ // Check for Next error when no more elements left
+ res, err := traversal.Next()
+ assert.Nil(t, res)
+ assert.NotNil(t, err)
+ assert.True(t, sortAndCompareTwoStringSlices(names, testNames))
+}
+
+func getEnvOrDefaultString(key string, defaultValue string) string {
+ // Missing value is returned as "".
+ value := os.Getenv(key)
+ if len(value) != 0 {
+ return value
+ }
+ return defaultValue
+}
+
+func getEnvOrDefaultBool(key string, defaultValue bool) bool {
+ value := getEnvOrDefaultString(key, "")
+ if len(value) != 0 {
+ boolValue, err := strconv.ParseBool(value)
+ if err == nil {
+ return boolValue
+ }
+ }
+ return defaultValue
+}
+
+func getBasicAuthInfo() *AuthInfo {
+ return BasicAuthInfo(getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_USERNAME", "stephen"),
+ getEnvOrDefaultString("GREMLIN_GO_BASIC_AUTH_PASSWORD", "password"))
+}
+
+func skipTestsIfNotEnabled(t *testing.T, testSuiteName string, testSuiteEnabled bool) {
+ if !testSuiteEnabled {
+ t.Skip(fmt.Sprintf("Skipping %s because %s tests are not enabled.", t.Name(), testSuiteName))
+ }
+}
+
func TestConnection(t *testing.T) {
+ // Integration test variables.
+ testNoAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthEnable := getEnvOrDefaultBool("RUN_INTEGRATION_TESTS", true)
+ testNoAuthAuthInfo := &AuthInfo{}
+ testNoAuthTlsConfig := &tls.Config{}
+
+ // No authentication integration test with graphs loaded and alias configured server
+ testNoAuthWithAliasUrl := getEnvOrDefaultString("GREMLIN_SERVER_URL", "ws://localhost:8182/gremlin")
+ testNoAuthWithAliasEnable := getEnvOrDefaultBool("RUN_INTEGRATION_WITH_ALIAS_ TESTS", false)
+ testNoAuthWithAliasAuthInfo := &AuthInfo{}
+ testNoAuthWithAliasTlsConfig := &tls.Config{}
+
+ // Basic authentication integration test variables.
+ testBasicAuthUrl := getEnvOrDefaultString("GREMLIN_SERVER_BASIC_AUTH_URL", "wss://localhost:8183/gremlin")
+ testBasicAuthEnable := getEnvOrDefaultBool("RUN_BASIC_AUTH_INTEGRATION_TESTS", false)
+ testBasicAuthAuthInfo := getBasicAuthInfo()
+ testBasicAuthTlsConfig := &tls.Config{InsecureSkipVerify: true}
+
+ t.Run("Test createConnection without valid server", func(t *testing.T) {
+ connection, err := createConnection(invalidHostValidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid port", func(t *testing.T) {
+ connection, err := createConnection(validHostInvalidPortValidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
+ t.Run("Test createConnection without valid path", func(t *testing.T) {
+ connection, err := createConnection(validHostValidPortInvalidPath, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.NotNil(t, err)
+ assert.Nil(t, connection)
+ })
+
t.Run("Test DriverRemoteConnection GraphTraversal", func(t *testing.T) {
- if runIntegration {
- remote, err := NewDriverRemoteConnection(testHost, testPort)
- assert.Nil(t, err)
- assert.NotNil(t, remote)
- g := Traversal_().WithRemote(remote)
-
- // 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)
-
- // Add data and check that the size of the graph is correct.
- addTestData(t, g)
- readCount(t, g, "", len(getTestNames()))
- readCount(t, g, testLabel, 0)
- readCount(t, g, personLabel, len(getTestNames()))
-
- // Read test data out of the graph and check that it is correct.
- readTestDataVertexProperties(t, g)
- 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)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+
+ // Initialize graph
+ g := initializeGraph(t, testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig)
+
+ // Read test data out of the graph and check that it is correct.
+ readTestDataVertexProperties(t, g)
+ readTestDataValues(t, g)
+
+ // Reset Graph
+ resetGraph(t, g)
})
t.Run("Test createConnection", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ err = connection.close()
+ assert.Nil(t, err)
})
t.Run("Test connection.write()", func(t *testing.T) {
- if runIntegration {
- connection, err := createConnection(testHost, testPort, newLogHandler(&defaultLogger{}, Info, language.English))
- assert.Nil(t, err)
- assert.NotNil(t, connection)
- request := makeStringRequest("g.V().count()")
- resultSet, err := connection.write(&request)
- assert.Nil(t, err)
- assert.NotNil(t, resultSet)
- result := resultSet.one()
- assert.NotNil(t, result)
- assert.Equal(t, "[0]", result.GetString())
- err = connection.close()
- assert.Nil(t, err)
- }
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ assert.NotNil(t, connection)
+ request := makeStringRequest("g.V().count()", "g")
+ resultSet, err := connection.write(&request)
+ assert.Nil(t, err)
+ assert.NotNil(t, resultSet)
+ result, err := resultSet.one()
+ assert.Nil(t, err)
+ assert.NotNil(t, result)
+ err = connection.close()
+ assert.Nil(t, err)
+ })
+
+ t.Run("Test connection.close() failure", func(t *testing.T) {
+ skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
+ connection, err := createConnection(testNoAuthUrl, testNoAuthAuthInfo, testNoAuthTlsConfig, newLogHandler(&defaultLogger{}, Info, language.English))
+ assert.Nil(t, err)
+ err = connection.close()
+ assert.Nil(t, err)
+ err = connection.close()
+ assert.NotNil(t, err)
+ err = connection.close()
+ assert.NotNil(t, err)
})
t.Run("Test client.submit()", func(t *testing.T) {
Review comment:
Done.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] krlawrence commented on a change in pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
krlawrence commented on a change in pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#discussion_r830117916
##########
File path: gremlin-go/README.md
##########
@@ -114,15 +156,19 @@ func main() {
Note: The exact import name as well as the module prefix for `NewDriverRemoteConnection` may change in the future.
+### Design Architecture
+
+See [Gremlin-Go Design Overview](design.MD)
+
# Go Gremlin Language Variant
[Apache TinkerPop™][tk] is a graph computing framework for both graph databases (OLTP) and graph analytic systems
(OLAP). [Gremlin][gremlin] is the graph traversal language of TinkerPop. It can be described as a functional,
data-flow language that enables users to succinctly express complex traversals on (or queries of) their application's
property graph.
-Gremlin-Go implements Gremlin within the Go language and can be used on any Go runtime greater than v1.17. One important distinction with Go and Java is that
-the functions are capitalized, as is required to export functions is Go.
+Gremlin-Go implements Gremlin within the Go language and can be used on any Go runtime greater than v1.17. One
+important distinction with Go and Java is that the functions are capitalized, as is required to export functions is Go.
Review comment:
s/is/in -> "functions in Go"
perhaps say "one important difference between Go and Java is that"
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto merged pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto merged pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [tinkerpop] lyndonbauto commented on pull request #1589: Gremlin Go MS3 and MS4 - Release Ready - Cucumber Suite Passes
Posted by GitBox <gi...@apache.org>.
lyndonbauto commented on pull request #1589:
URL: https://github.com/apache/tinkerpop/pull/1589#issuecomment-1077018119
New pull request for gremlin-go branch against 3.5-dev is coming up. With that in mind I am going to close this pull request.
The comments which were not addressed in this pull request have been migrated to that pull request's description.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@tinkerpop.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org