Skip to content

Commit 983cc68

Browse files
author
Divjot Arora
committed
GODRIVER-1931 Run tests against LBs in Evergreen
1 parent 331e1cd commit 983cc68

File tree

14 files changed

+229
-33
lines changed

14 files changed

+229
-33
lines changed

.evergreen/config.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,33 @@ functions:
518518
PKG_CONFIG_PATH=$PKG_CONFIG_PATH \
519519
LD_LIBRARY_PATH=$LD_LIBRARY_PATH
520520
521+
run-load-balancer-tests:
522+
- command: shell.exec
523+
type: test
524+
params:
525+
working_dir: src/go.mongodb.org/mongo-driver
526+
script: |
527+
${PREPARE_SHELL}
528+
529+
if [ ${SSL} = "ssl" ]; then
530+
export MONGO_GO_DRIVER_CA_FILE="$PROJECT_DIRECTORY/data/certificates/ca.pem"
531+
if [ "Windows_NT" = "$OS" ]; then # Magic variable in cygwin
532+
export MONGO_GO_DRIVER_CA_FILE=$(cygpath -m $MONGO_GO_DRIVER_CA_FILE)
533+
fi
534+
fi
535+
536+
export GOFLAGS=-mod=vendor
537+
set +o xtrace
538+
AUTH="${AUTH}" \
539+
SSL="${SSL}" \
540+
MONGODB_URI="${SINGLE_MONGOS_LB_URI}" \
541+
SINGLE_MONGOS_LB_URI="${SINGLE_MONGOS_LB_URI}" \
542+
MULTI_MONGOS_LB_URI="${MULTI_MONGOS_LB_URI}" \
543+
TOPOLOGY="${TOPOLOGY}" \
544+
MONGO_GO_DRIVER_COMPRESSOR=${MONGO_GO_DRIVER_COMPRESSOR} \
545+
BUILD_TAGS="-tags cse" \
546+
make evg-test-load-balancers
547+
521548
run-atlas-data-lake-test:
522549
- command: shell.exec
523550
type: test
@@ -612,6 +639,21 @@ functions:
612639
-v \
613640
--fault revoked
614641
642+
run-load-balancer:
643+
- command: shell.exec
644+
params:
645+
script: |
646+
DRIVERS_TOOLS=${DRIVERS_TOOLS} MONGODB_URI=${MONGODB_URI} bash ${DRIVERS_TOOLS}/.evergreen/run-load-balancer.sh start
647+
- command: expansions.update
648+
params:
649+
file: lb-expansion.yml
650+
651+
stop-load-balancer:
652+
- command: shell.exec
653+
params:
654+
script: |
655+
DRIVERS_TOOLS=${DRIVERS_TOOLS} bash ${DRIVERS_TOOLS}/.evergreen/run-load-balancer.sh stop
656+
615657
add-aws-auth-variables-to-file:
616658
- command: shell.exec
617659
type: test
@@ -866,6 +908,7 @@ post:
866908
files:
867909
- "src/go.mongodb.org/mongo-driver/*.suite"
868910
- func: upload-mo-artifacts
911+
- func: stop-load-balancer
869912
- func: cleanup
870913

871914
tasks:
@@ -1379,6 +1422,28 @@ tasks:
13791422
- func: bootstrap-mongohoused
13801423
- func: run-atlas-data-lake-test
13811424

1425+
- name: test-load-balancer-noauth-nossl
1426+
tags: ["load-balancer"]
1427+
commands:
1428+
- func: bootstrap-mongo-orchestration
1429+
vars:
1430+
TOPOLOGY: "sharded_cluster"
1431+
AUTH: "noauth"
1432+
SSL: "nossl"
1433+
- func: run-load-balancer
1434+
- func: run-load-balancer-tests
1435+
1436+
- name: test-load-balancer-auth-ssl
1437+
tags: ["load-balancer"]
1438+
commands:
1439+
- func: bootstrap-mongo-orchestration
1440+
vars:
1441+
TOPOLOGY: "sharded_cluster"
1442+
AUTH: "auth"
1443+
SSL: "ssl"
1444+
- func: run-load-balancer
1445+
- func: run-load-balancer-tests
1446+
13821447
- name: test-replicaset-noauth-nossl
13831448
tags: ["test", "replicaset"]
13841449
commands:
@@ -1969,6 +2034,12 @@ buildvariants:
19692034
tasks:
19702035
- name: ".versioned-api"
19712036

2037+
- matrix_name: "load-balancer-test"
2038+
matrix_spec: { version: ["latest"], os-ssl-40: ["ubuntu1804-64-go-1-15"] }
2039+
display_name: "Load Balancer Version ${os-ssl-40}"
2040+
tasks:
2041+
- name: ".load-balancer"
2042+
19722043
- matrix_name: "kms-tls-test"
19732044
matrix_spec: { version: ["latest"], os-ssl-40: ["ubuntu1804-64-go-1-15"] }
19742045
display_name: "KMS TLS ${version} ${os-ssl-40}"

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,14 @@ evg-test-versioned-api:
165165
go test -exec "env PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH)" $(BUILD_TAGS) -v -timeout $(TEST_TIMEOUT)s $$TEST_PKG >> test.suite ; \
166166
done
167167

168+
.PHONY: evg-test-load-balancers
169+
evg-test-load-balancers:
170+
go test $(BUILD_TAGS) ./mongo/integration -run TestUnifiedSpecs/retryable-reads -v -timeout $(TEST_TIMEOUT)s >> test.suite
171+
go test $(BUILD_TAGS) ./mongo/integration -run TestRetryableWritesSpec -v -timeout $(TEST_TIMEOUT)s >> test.suite
172+
go test $(BUILD_TAGS) ./mongo/integration -run TestChangeStreamSpec -v -timeout $(TEST_TIMEOUT)s >> test.suite
173+
go test $(BULID_TAGS) ./mongo/integration -run TestInitialDNSSeedlistDiscoverySpec/load_balanced -v -timeout $(TEST_TIMEOUT)s >> test.suite
174+
go test $(BUILD_TAGS) ./mongo/integration/unified -run TestUnifiedSpec -v -timeout $(TEST_TIMEOUT)s >> test.suite
175+
168176
.PHONY: evg-test-kms
169177
evg-test-kms:
170178
go test -exec "env PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH)" $(BUILD_TAGS) -v -timeout $(TEST_TIMEOUT)s ./mongo/integration -run TestClientSideEncryptionProse/kms_tls_tests >> test.suite

internal/const.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,8 @@ package internal // import "go.mongodb.org/mongo-driver/internal"
88

99
// Version is the current version of the driver.
1010
var Version = "local build"
11+
12+
// SetServiceID enables a mode in which the driver mocks server support for returning a "serviceId" field in "hello"
13+
// command responses by using the value of "topologyVersion.processId". This is used for testing load balancer
14+
// support until an upstream service can support running behind a load balancer.
15+
var SetServiceID = false

mongo/description/server.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,10 @@ func NewServer(addr address.Address, response bson.Raw) Server {
266266
desc.LastError = err
267267
return desc
268268
}
269+
270+
if internal.SetServiceID {
271+
desc.ServiceID = &desc.TopologyVersion.ProcessID
272+
}
269273
}
270274
}
271275

mongo/integration/main_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,22 @@ package integration
99
import (
1010
"log"
1111
"os"
12+
"strings"
1213
"testing"
1314

15+
"go.mongodb.org/mongo-driver/internal"
1416
"go.mongodb.org/mongo-driver/mongo/integration/mtest"
1517
)
1618

1719
func TestMain(m *testing.M) {
20+
// If the cluster is behind a load balancer, enable the SetServiceID flag to mock server-side LB support.
21+
if strings.Contains(os.Getenv("MONGODB_URI"), "loadBalanced=true") {
22+
internal.SetServiceID = true
23+
defer func() {
24+
internal.SetServiceID = false
25+
}()
26+
}
27+
1828
if err := mtest.Setup(); err != nil {
1929
log.Fatal(err)
2030
}

mongo/integration/mtest/global_state.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ func ClusterURI() string {
3535
return testContext.connString.Original
3636
}
3737

38+
// SingleMongosLoadBalancerURI returns the URI for a load balancer fronting a single mongos. This will only be set
39+
// if the cluster is load balanced.
40+
func SingleMongosLoadBalancerURI() string {
41+
return testContext.singleMongosLoadBalancerURI
42+
}
43+
44+
// MultiMongosLoadBalancerURI returns the URI for a load balancer fronting multiple mongoses. This will only be set
45+
// if the cluster is load balanced.
46+
func MultiMongosLoadBalancerURI() string {
47+
return testContext.multiMongosLoadBalancerURI
48+
}
49+
3850
// ClusterConnString returns the parsed ConnString for the cluster.
3951
func ClusterConnString() connstring.ConnString {
4052
return testContext.connString

mongo/integration/mtest/setup.go

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,17 @@ var testContext struct {
4343
// shardedReplicaSet will be true if we're connected to a sharded cluster and each shard is backed by a replica set.
4444
// We track this as a separate boolean rather than setting topoKind to ShardedReplicaSet because a general
4545
// "Sharded" constraint in a test should match both Sharded and ShardedReplicaSet.
46-
shardedReplicaSet bool
47-
client *mongo.Client // client used for setup and teardown
48-
serverVersion string
49-
authEnabled bool
50-
sslEnabled bool
51-
enterpriseServer bool
52-
dataLake bool
53-
requireAPIVersion bool
54-
serverParameters bson.Raw
46+
shardedReplicaSet bool
47+
client *mongo.Client // client used for setup and teardown
48+
serverVersion string
49+
authEnabled bool
50+
sslEnabled bool
51+
enterpriseServer bool
52+
dataLake bool
53+
requireAPIVersion bool
54+
serverParameters bson.Raw
55+
singleMongosLoadBalancerURI string
56+
multiMongosLoadBalancerURI string
5557
}
5658

5759
func setupClient(cs connstring.ConnString, opts *options.ClientOptions) (*mongo.Client, error) {
@@ -75,7 +77,7 @@ func Setup(setupOpts ...*SetupOptions) error {
7577
case opts.URI != nil:
7678
testContext.connString, err = connstring.ParseAndValidate(*opts.URI)
7779
default:
78-
testContext.connString, err = getConnString()
80+
testContext.connString, err = getClusterConnString()
7981
}
8082
if err != nil {
8183
return fmt.Errorf("error getting connection string: %v", err)
@@ -186,6 +188,20 @@ func Setup(setupOpts ...*SetupOptions) error {
186188
}
187189
}
188190

191+
if testContext.topoKind == LoadBalanced {
192+
singleMongosURI := os.Getenv("SINGLE_MONGOS_LB_URI")
193+
if singleMongosURI == "" {
194+
return errors.New("SINGLE_MONGOS_LB_URI must be set when running against load balanced clusters")
195+
}
196+
testContext.singleMongosLoadBalancerURI = addNecessaryParamsToURI(singleMongosURI)
197+
198+
multiMongosURI := os.Getenv("MULTI_MONGOS_LB_URI")
199+
if multiMongosURI == "" {
200+
return errors.New("MULTI_MONGOS_LB_URI must be set when running against load balanced clusters")
201+
}
202+
testContext.multiMongosLoadBalancerURI = addNecessaryParamsToURI(multiMongosURI)
203+
}
204+
189205
testContext.authEnabled = os.Getenv("AUTH") == "auth"
190206
testContext.sslEnabled = os.Getenv("SSL") == "ssl"
191207
biRes, err := testContext.client.Database("admin").RunCommand(Background, bson.D{{"buildInfo", 1}}).DecodeBytes()
@@ -292,17 +308,21 @@ func addCompressors(uri string) string {
292308
return addOptions(uri, "compressors=", comp)
293309
}
294310

295-
// ConnString gets the globally configured connection string.
296-
func getConnString() (connstring.ConnString, error) {
311+
// getClusterConnString gets the globally configured connection string.
312+
func getClusterConnString() (connstring.ConnString, error) {
297313
uri := os.Getenv("MONGODB_URI")
298314
if uri == "" {
299315
uri = "mongodb://localhost:27017"
300316
}
301-
uri = addTLSConfig(uri)
302-
uri = addCompressors(uri)
317+
uri = addNecessaryParamsToURI(uri)
303318
return connstring.ParseAndValidate(uri)
304319
}
305320

321+
func addNecessaryParamsToURI(uri string) string {
322+
uri = addTLSConfig(uri)
323+
return addCompressors(uri)
324+
}
325+
306326
// CompareServerVersions compares two version number strings (i.e. positive integers separated by
307327
// periods). Comparisons are done to the lesser precision of the two versions. For example, 3.2 is
308328
// considered equal to 3.2.11, whereas 3.2.0 is considered less than 3.2.11.

mongo/integration/unified/client_entity.go

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ package unified
99
import (
1010
"context"
1111
"fmt"
12-
"os"
1312
"sync/atomic"
1413
"time"
1514

@@ -57,10 +56,7 @@ func newClientEntity(ctx context.Context, em *EntityMap, entityOptions *entityOp
5756

5857
// Construct a ClientOptions instance by first applying the cluster URI and then the URIOptions map to ensure that
5958
// the options specified in the test file take precedence.
60-
uri, err := getURIForClient(entityOptions)
61-
if err != nil {
62-
return nil, err
63-
}
59+
uri := getURIForClient(entityOptions)
6460
clientOpts := options.Client().ApplyURI(uri)
6561
if entityOptions.URIOptions != nil {
6662
if err := setClientOptionsFromURIOptions(clientOpts, entityOptions.URIOptions); err != nil {
@@ -126,26 +122,19 @@ func newClientEntity(ctx context.Context, em *EntityMap, entityOptions *entityOp
126122
return entity, nil
127123
}
128124

129-
func getURIForClient(opts *entityOptions) (string, error) {
125+
func getURIForClient(opts *entityOptions) string {
130126
if mtest.ClusterTopologyKind() != mtest.LoadBalanced {
131-
return mtest.ClusterURI(), nil
127+
return mtest.ClusterURI()
132128
}
133129

134-
// For load-balanced deployments, UseMultipleMongoses is used to determine the load balancer URI. If set to
135-
// false, the LB fronts a single server. If unset or explicitly true, the LB fronts multiple mongos servers.
136-
var uriEnvVar string
130+
// For load-balanced deployments, UseMultipleMongoses is used to determine the load balancer URI. If set to false,
131+
// the LB fronts a single server. If unset or explicitly true, the LB fronts multiple mongos servers.
137132
switch {
138133
case opts.UseMultipleMongoses != nil && !*opts.UseMultipleMongoses:
139-
uriEnvVar = "SINGLE_MONGOS_LB_URI"
134+
return mtest.SingleMongosLoadBalancerURI()
140135
default:
141-
uriEnvVar = "MULTI_MONGOS_LB_URI"
142-
}
143-
144-
uri := os.Getenv(uriEnvVar)
145-
if uri == "" {
146-
return "", fmt.Errorf("expected load balancer URI to be in environment variable %q, but is not set", uriEnvVar)
136+
return mtest.MultiMongosLoadBalancerURI()
147137
}
148-
return uri, nil
149138
}
150139

151140
func (c *clientEntity) stopListeningForEvents() {
@@ -344,8 +333,14 @@ func setClientOptionsFromURIOptions(clientOpts *options.ClientOptions, uriOpts b
344333

345334
for key, value := range uriOpts {
346335
switch key {
336+
case "appname":
337+
clientOpts.SetAppName(value.(string))
347338
case "heartbeatFrequencyMS":
348339
clientOpts.SetHeartbeatInterval(time.Duration(value.(int32)) * time.Millisecond)
340+
case "loadBalanced":
341+
clientOpts.SetLoadBalanced(value.(bool))
342+
case "maxPoolSize":
343+
clientOpts.SetMaxPoolSize(uint64(value.(int32)))
349344
case "readConcernLevel":
350345
clientOpts.SetReadConcern(readconcern.New(readconcern.Level(value.(string))))
351346
case "retryReads":
@@ -355,6 +350,8 @@ func setClientOptionsFromURIOptions(clientOpts *options.ClientOptions, uriOpts b
355350
case "w":
356351
wc.W = value
357352
wcSet = true
353+
case "waitQueueTimeoutMS":
354+
return newSkipTestError("the waitQueueTimeoutMS client option is not supported")
358355
default:
359356
return fmt.Errorf("unrecognized URI option %s", key)
360357
}

mongo/integration/unified/collection_operation_execution.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,38 @@ func executeInsertOne(ctx context.Context, operation *operation) (*operationResu
748748
return newDocumentResult(raw, err), nil
749749
}
750750

751+
func executeListIndexes(ctx context.Context, operation *operation) (*operationResult, error) {
752+
coll, err := entities(ctx).collection(operation.Object)
753+
if err != nil {
754+
return nil, err
755+
}
756+
757+
opts := options.ListIndexes()
758+
elems, _ := operation.Arguments.Elements()
759+
for _, elem := range elems {
760+
key := elem.Key()
761+
val := elem.Value()
762+
763+
switch key {
764+
case "batchSize":
765+
opts.SetBatchSize(val.Int32())
766+
default:
767+
return nil, fmt.Errorf("unrecognized listIndexes option: %q", key)
768+
}
769+
}
770+
771+
cursor, err := coll.Indexes().List(ctx, opts)
772+
if err != nil {
773+
return newErrorResult(err), nil
774+
}
775+
776+
var docs []bson.Raw
777+
if err := cursor.All(ctx, &docs); err != nil {
778+
return newErrorResult(err), nil
779+
}
780+
return newCursorResult(docs), nil
781+
}
782+
751783
func executeReplaceOne(ctx context.Context, operation *operation) (*operationResult, error) {
752784
coll, err := entities(ctx).collection(operation.Object)
753785
if err != nil {

mongo/integration/unified/database_operation_execution.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func executeListCollections(ctx context.Context, operation *operation) (*operati
8989
defer cursor.Close(ctx)
9090

9191
var docs []bson.Raw
92-
if err := cursor.All(ctx, &cursor); err != nil {
92+
if err := cursor.All(ctx, &docs); err != nil {
9393
return newErrorResult(err), nil
9494
}
9595
return newCursorResult(docs), nil

0 commit comments

Comments
 (0)