From da163390f192c2f82963b563e3758dc3489e58f3 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Wed, 16 Apr 2025 18:30:05 -0400 Subject: [PATCH 1/6] GODRIVER-3037 Support internal-only options. --- mongo/options/internaloptions.go | 38 ++++++++++++++ mongo/options/internaloptions_test.go | 73 +++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 mongo/options/internaloptions.go create mode 100644 mongo/options/internaloptions_test.go diff --git a/mongo/options/internaloptions.go b/mongo/options/internaloptions.go new file mode 100644 index 0000000000..cb58536699 --- /dev/null +++ b/mongo/options/internaloptions.go @@ -0,0 +1,38 @@ +// Copyright (C) MongoDB, Inc. 2025-present. +// +// Licensed 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 + +package options + +import ( + "fmt" + + "go.mongodb.org/mongo-driver/v2/x/mongo/driver" +) + +// Deprecated: SetInternalClientOptions sets internal only options for ClientOptions. It may be changed +// or removed in any release. +func SetInternalClientOptions(opts *ClientOptions, custom map[string]any) (*ClientOptions, error) { + const typeErr = "unexpected type for %s" + for k, v := range custom { + switch k { + case "crypt": + c, ok := v.(driver.Crypt) + if !ok { + return nil, fmt.Errorf(typeErr, k) + } + opts.Crypt = c + case "deployment": + d, ok := v.(driver.Deployment) + if !ok { + return nil, fmt.Errorf(typeErr, k) + } + opts.Deployment = d + default: + return nil, fmt.Errorf("unsupported option: %s", k) + } + } + return opts, nil +} diff --git a/mongo/options/internaloptions_test.go b/mongo/options/internaloptions_test.go new file mode 100644 index 0000000000..b0d23d0f46 --- /dev/null +++ b/mongo/options/internaloptions_test.go @@ -0,0 +1,73 @@ +// Copyright (C) MongoDB, Inc. 2025-present. +// +// Licensed 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 + +package options + +import ( + "testing" + + "go.mongodb.org/mongo-driver/v2/internal/require" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/drivertest" +) + +func TestSetClientOptions(t *testing.T) { + t.Parallel() + + t.Run("set Crypt with driver.Crypt", func(t *testing.T) { + t.Parallel() + + opts := &ClientOptions{} + c := driver.NewCrypt(&driver.CryptOptions{}) + opts, err := SetInternalClientOptions(opts, map[string]any{ + "crypt": c, + }) + require.NoError(t, err) + require.Equal(t, c, opts.Crypt) + }) + + t.Run("set Crypt with driver.Deployment", func(t *testing.T) { + t.Parallel() + + opts := &ClientOptions{} + _, err := SetInternalClientOptions(opts, map[string]any{ + "crypt": &drivertest.MockDeployment{}, + }) + require.EqualError(t, err, "unexpected type for crypt") + }) + + t.Run("set Deployment with driver.Deployment", func(t *testing.T) { + t.Parallel() + + opts := &ClientOptions{} + d := &drivertest.MockDeployment{} + opts, err := SetInternalClientOptions(opts, map[string]any{ + "deployment": d, + }) + require.NoError(t, err) + require.Equal(t, d, opts.Deployment) + }) + + t.Run("set Deployment with driver.Crypt", func(t *testing.T) { + t.Parallel() + + opts := &ClientOptions{} + _, err := SetInternalClientOptions(opts, map[string]any{ + "deployment": driver.NewCrypt(&driver.CryptOptions{}), + }) + require.EqualError(t, err, "unexpected type for deployment") + }) + + t.Run("set unsupported option", func(t *testing.T) { + t.Parallel() + + opts := &ClientOptions{} + _, err := SetInternalClientOptions(opts, map[string]any{ + "unsupported": "unsupported", + }) + require.EqualError(t, err, "unsupported option: unsupported") + }) +} From dbd783757d9b1c368089032fc6ff5928b293cd9f Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Wed, 16 Apr 2025 18:40:56 -0400 Subject: [PATCH 2/6] update comment --- mongo/options/internaloptions.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mongo/options/internaloptions.go b/mongo/options/internaloptions.go index cb58536699..d69f7e187f 100644 --- a/mongo/options/internaloptions.go +++ b/mongo/options/internaloptions.go @@ -12,8 +12,9 @@ import ( "go.mongodb.org/mongo-driver/v2/x/mongo/driver" ) -// Deprecated: SetInternalClientOptions sets internal only options for ClientOptions. It may be changed -// or removed in any release. +// SetInternalClientOptions sets internal options for ClientOptions. +// +// Deprecated: This function is for internal use only. It may be changed or removed in any release. func SetInternalClientOptions(opts *ClientOptions, custom map[string]any) (*ClientOptions, error) { const typeErr = "unexpected type for %s" for k, v := range custom { From 81b9815d55f7972d1a26f81281e7d5595ff55418 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Mon, 21 Apr 2025 17:06:04 -0400 Subject: [PATCH 3/6] GODRIVER-3429 Revert internal-only "AuthenticateToAnything". --- internal/options/options.go | 32 +++++++++ mongo/options/clientoptions.go | 7 ++ mongo/options/internaloptions.go | 39 ----------- mongo/options/internaloptions_test.go | 73 --------------------- x/mongo/driver/options/options.go | 45 +++++++++++++ x/mongo/driver/topology/topology_options.go | 10 +++ 6 files changed, 94 insertions(+), 112 deletions(-) create mode 100644 internal/options/options.go delete mode 100644 mongo/options/internaloptions.go delete mode 100644 mongo/options/internaloptions_test.go create mode 100644 x/mongo/driver/options/options.go diff --git a/internal/options/options.go b/internal/options/options.go new file mode 100644 index 0000000000..91308f5745 --- /dev/null +++ b/internal/options/options.go @@ -0,0 +1,32 @@ +// Copyright (C) MongoDB, Inc. 2025-present. +// +// Licensed 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 + +package options + +// Options stores internal options. +type Options struct { + values map[string]any +} + +// WithValue sets an option value with the associated key. +func WithValue(opts Options, key string, option any) Options { + if opts.values == nil { + opts.values = make(map[string]any) + } + opts.values[key] = option + return opts +} + +// Value returns the value associated with the options for key. +func Value(opts Options, key string) any { + if opts.values == nil { + return nil + } + if val, ok := opts.values[key]; ok { + return val + } + return nil +} diff --git a/mongo/options/clientoptions.go b/mongo/options/clientoptions.go index 925325c6c5..2aa94f8960 100644 --- a/mongo/options/clientoptions.go +++ b/mongo/options/clientoptions.go @@ -26,6 +26,7 @@ import ( "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/event" "go.mongodb.org/mongo-driver/v2/internal/httputil" + "go.mongodb.org/mongo-driver/v2/internal/options" "go.mongodb.org/mongo-driver/v2/mongo/readconcern" "go.mongodb.org/mongo-driver/v2/mongo/readpref" "go.mongodb.org/mongo-driver/v2/mongo/writeconcern" @@ -295,6 +296,12 @@ type ClientOptions struct { // release. Deployment driver.Deployment + // Custom specifies internal options for the new Client. + // + // Deprecated: This option is for internal use only and should not be set. It may be changed or removed in any + // release. + Custom options.Options + connString *connstring.ConnString err error } diff --git a/mongo/options/internaloptions.go b/mongo/options/internaloptions.go deleted file mode 100644 index d69f7e187f..0000000000 --- a/mongo/options/internaloptions.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) MongoDB, Inc. 2025-present. -// -// Licensed 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 - -package options - -import ( - "fmt" - - "go.mongodb.org/mongo-driver/v2/x/mongo/driver" -) - -// SetInternalClientOptions sets internal options for ClientOptions. -// -// Deprecated: This function is for internal use only. It may be changed or removed in any release. -func SetInternalClientOptions(opts *ClientOptions, custom map[string]any) (*ClientOptions, error) { - const typeErr = "unexpected type for %s" - for k, v := range custom { - switch k { - case "crypt": - c, ok := v.(driver.Crypt) - if !ok { - return nil, fmt.Errorf(typeErr, k) - } - opts.Crypt = c - case "deployment": - d, ok := v.(driver.Deployment) - if !ok { - return nil, fmt.Errorf(typeErr, k) - } - opts.Deployment = d - default: - return nil, fmt.Errorf("unsupported option: %s", k) - } - } - return opts, nil -} diff --git a/mongo/options/internaloptions_test.go b/mongo/options/internaloptions_test.go deleted file mode 100644 index b0d23d0f46..0000000000 --- a/mongo/options/internaloptions_test.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (C) MongoDB, Inc. 2025-present. -// -// Licensed 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 - -package options - -import ( - "testing" - - "go.mongodb.org/mongo-driver/v2/internal/require" - "go.mongodb.org/mongo-driver/v2/x/mongo/driver" - "go.mongodb.org/mongo-driver/v2/x/mongo/driver/drivertest" -) - -func TestSetClientOptions(t *testing.T) { - t.Parallel() - - t.Run("set Crypt with driver.Crypt", func(t *testing.T) { - t.Parallel() - - opts := &ClientOptions{} - c := driver.NewCrypt(&driver.CryptOptions{}) - opts, err := SetInternalClientOptions(opts, map[string]any{ - "crypt": c, - }) - require.NoError(t, err) - require.Equal(t, c, opts.Crypt) - }) - - t.Run("set Crypt with driver.Deployment", func(t *testing.T) { - t.Parallel() - - opts := &ClientOptions{} - _, err := SetInternalClientOptions(opts, map[string]any{ - "crypt": &drivertest.MockDeployment{}, - }) - require.EqualError(t, err, "unexpected type for crypt") - }) - - t.Run("set Deployment with driver.Deployment", func(t *testing.T) { - t.Parallel() - - opts := &ClientOptions{} - d := &drivertest.MockDeployment{} - opts, err := SetInternalClientOptions(opts, map[string]any{ - "deployment": d, - }) - require.NoError(t, err) - require.Equal(t, d, opts.Deployment) - }) - - t.Run("set Deployment with driver.Crypt", func(t *testing.T) { - t.Parallel() - - opts := &ClientOptions{} - _, err := SetInternalClientOptions(opts, map[string]any{ - "deployment": driver.NewCrypt(&driver.CryptOptions{}), - }) - require.EqualError(t, err, "unexpected type for deployment") - }) - - t.Run("set unsupported option", func(t *testing.T) { - t.Parallel() - - opts := &ClientOptions{} - _, err := SetInternalClientOptions(opts, map[string]any{ - "unsupported": "unsupported", - }) - require.EqualError(t, err, "unsupported option: unsupported") - }) -} diff --git a/x/mongo/driver/options/options.go b/x/mongo/driver/options/options.go new file mode 100644 index 0000000000..464085a903 --- /dev/null +++ b/x/mongo/driver/options/options.go @@ -0,0 +1,45 @@ +// Copyright (C) MongoDB, Inc. 2025-present. +// +// Licensed 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 + +package options + +import ( + "fmt" + + internalOptions "go.mongodb.org/mongo-driver/v2/internal/options" + "go.mongodb.org/mongo-driver/v2/mongo/options" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver" +) + +// SetInternalClientOptions sets internal options for ClientOptions. +// +// Deprecated: This function is for internal use only. It may be changed or removed in any release. +func SetInternalClientOptions(opts *options.ClientOptions, key string, option any) error { + const typeErr = "unexpected type for %s" + switch key { + case "crypt": + c, ok := option.(driver.Crypt) + if !ok { + return fmt.Errorf(typeErr, key) + } + opts.Crypt = c + case "deployment": + d, ok := option.(driver.Deployment) + if !ok { + return fmt.Errorf(typeErr, key) + } + opts.Deployment = d + case "authenticateToAnything": + b, ok := option.(bool) + if !ok { + return fmt.Errorf(typeErr, key) + } + opts.Custom = internalOptions.WithValue(opts.Custom, key, b) + default: + return fmt.Errorf("unsupported option: %s", key) + } + return nil +} diff --git a/x/mongo/driver/topology/topology_options.go b/x/mongo/driver/topology/topology_options.go index aefa74c56a..0f0138e566 100644 --- a/x/mongo/driver/topology/topology_options.go +++ b/x/mongo/driver/topology/topology_options.go @@ -15,9 +15,11 @@ import ( "go.mongodb.org/mongo-driver/v2/event" "go.mongodb.org/mongo-driver/v2/internal/logger" + internalOptions "go.mongodb.org/mongo-driver/v2/internal/options" "go.mongodb.org/mongo-driver/v2/mongo/options" "go.mongodb.org/mongo-driver/v2/x/mongo/driver" "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description" "go.mongodb.org/mongo-driver/v2/x/mongo/driver/ocsp" "go.mongodb.org/mongo-driver/v2/x/mongo/driver/operation" "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session" @@ -270,6 +272,14 @@ func NewConfigFromOptionsWithAuthenticator(opts *options.ClientOptions, clock *s // Required for SASL mechanism negotiation during handshake handshakeOpts.DBUser = opts.Auth.AuthSource + "." + opts.Auth.Username } + if a := internalOptions.Value(opts.Custom, "authenticateToAnything"); a != nil { + if v, ok := a.(bool); ok && v { + // Authenticate arbiters + handshakeOpts.PerformAuthentication = func(_ description.Server) bool { + return true + } + } + } handshaker = func(driver.Handshaker) driver.Handshaker { return auth.Handshaker(nil, handshakeOpts) From 16f8f2852431c65df9bc03c2b6be4f482408516a Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Mon, 21 Apr 2025 18:11:10 -0400 Subject: [PATCH 4/6] fix test --- internal/options/options.go | 13 +++++++++++++ mongo/options/clientoptions_test.go | 3 +++ 2 files changed, 16 insertions(+) diff --git a/internal/options/options.go b/internal/options/options.go index 91308f5745..8d5f47f422 100644 --- a/internal/options/options.go +++ b/internal/options/options.go @@ -30,3 +30,16 @@ func Value(opts Options, key string) any { } return nil } + +// Equal compares two Options instances for equality. +func Equal(opts1, opts2 Options) bool { + if len(opts1.values) != len(opts2.values) { + return false + } + for key, val1 := range opts1.values { + if val2, ok := opts2.values[key]; !ok || val1 != val2 { + return false + } + } + return true +} diff --git a/mongo/options/clientoptions_test.go b/mongo/options/clientoptions_test.go index 907584d5f0..a8a00122e0 100644 --- a/mongo/options/clientoptions_test.go +++ b/mongo/options/clientoptions_test.go @@ -27,6 +27,7 @@ import ( "go.mongodb.org/mongo-driver/v2/event" "go.mongodb.org/mongo-driver/v2/internal/assert" "go.mongodb.org/mongo-driver/v2/internal/httputil" + "go.mongodb.org/mongo-driver/v2/internal/options" "go.mongodb.org/mongo-driver/v2/internal/ptrutil" "go.mongodb.org/mongo-driver/v2/mongo/readconcern" "go.mongodb.org/mongo-driver/v2/mongo/readpref" @@ -156,6 +157,7 @@ func TestClientOptions(t *testing.T) { cmp.Comparer(func(r1, r2 *bson.Registry) bool { return r1 == r2 }), cmp.Comparer(func(cfg1, cfg2 *tls.Config) bool { return cfg1 == cfg2 }), cmp.Comparer(func(fp1, fp2 *event.PoolMonitor) bool { return fp1 == fp2 }), + cmp.Comparer(options.Equal), cmp.AllowUnexported(ClientOptions{}), cmpopts.IgnoreFields(http.Client{}, "Transport"), ); diff != "" { @@ -1253,6 +1255,7 @@ func TestApplyURI(t *testing.T) { cmp.Comparer(func(r1, r2 *bson.Registry) bool { return r1 == r2 }), cmp.Comparer(compareTLSConfig), cmp.Comparer(compareErrors), + cmp.Comparer(options.Equal), cmpopts.SortSlices(stringLess), cmpopts.IgnoreFields(connstring.ConnString{}, "SSLClientCertificateKeyPassword"), cmpopts.IgnoreFields(http.Client{}, "Transport"), From 66b8813b732966914a6551c04d36e1d7aa552f79 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Thu, 24 Apr 2025 18:38:22 -0400 Subject: [PATCH 5/6] add tests --- x/mongo/driver/auth/auth_test.go | 59 +++++++++++++++ x/mongo/driver/options/options_test.go | 64 ++++++++++++++++ .../driver/topology/topology_options_test.go | 73 +++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 x/mongo/driver/options/options_test.go diff --git a/x/mongo/driver/auth/auth_test.go b/x/mongo/driver/auth/auth_test.go index 4736144e59..27aa38741f 100644 --- a/x/mongo/driver/auth/auth_test.go +++ b/x/mongo/driver/auth/auth_test.go @@ -7,13 +7,19 @@ package auth_test import ( + "context" + "fmt" "net/http" "testing" "github.com/google/go-cmp/cmp" "go.mongodb.org/mongo-driver/v2/internal/require" "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver" "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/drivertest" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet" "go.mongodb.org/mongo-driver/v2/x/mongo/driver/wiremessage" ) @@ -101,3 +107,56 @@ func compareResponses(t *testing.T, wm []byte, expectedPayload bsoncore.Document t.Errorf("Payloads don't match. got %v; want %v", actualPayload, expectedPayload) } } + +type testAuthenticator struct{} + +func (a *testAuthenticator) Auth(context.Context, *driver.AuthConfig) error { + return fmt.Errorf("test error") +} + +func (a *testAuthenticator) Reauth(context.Context, *driver.AuthConfig) error { + return nil +} + +func TestPerformAuthentication(t *testing.T) { + t.Parallel() + + cases := []struct { + name string + needToPerform bool + assert func(*testing.T, error) + }{ + { + name: "positive", + needToPerform: true, + assert: func(t *testing.T, err error) { + require.EqualError(t, err, "auth error: test error") + }, + }, + { + name: "negative", + needToPerform: false, + assert: func(t *testing.T, err error) { + require.NoError(t, err) + }, + }, + } + mnetconn := mnet.NewConnection(&drivertest.ChannelConn{}) + for _, tc := range cases { + tc := tc + + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + handshaker := auth.Handshaker(nil, &auth.HandshakeOptions{ + Authenticator: &testAuthenticator{}, + PerformAuthentication: func(description.Server) bool { + return tc.needToPerform + }, + }) + + err := handshaker.FinishHandshake(context.Background(), mnetconn) + tc.assert(t, err) + }) + } +} diff --git a/x/mongo/driver/options/options_test.go b/x/mongo/driver/options/options_test.go new file mode 100644 index 0000000000..8c383e79ee --- /dev/null +++ b/x/mongo/driver/options/options_test.go @@ -0,0 +1,64 @@ +// Copyright (C) MongoDB, Inc. 2025-present. +// +// Licensed 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 + +package options + +import ( + "testing" + + internalOptions "go.mongodb.org/mongo-driver/v2/internal/options" + "go.mongodb.org/mongo-driver/v2/internal/require" + "go.mongodb.org/mongo-driver/v2/mongo/options" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/drivertest" +) + +func TestSetInternalClientOptions(t *testing.T) { + t.Parallel() + + cases := []struct { + key string + value any + }{ + { + key: "authenticateToAnything", + value: true, + }, + } + for _, tc := range cases { + tc := tc + + t.Run(tc.key, func(t *testing.T) { + t.Parallel() + + opts := options.Client() + err := SetInternalClientOptions(opts, tc.key, tc.value) + require.NoError(t, err, "error setting %s: %v", tc.key, err) + v := internalOptions.Value(opts.Custom, tc.key) + require.Equal(t, tc.value, v, "expected %v, got %v", tc.value, v) + }) + } + + t.Run("crypt", func(t *testing.T) { + t.Parallel() + + c := driver.NewCrypt(&driver.CryptOptions{}) + opts := options.Client() + err := SetInternalClientOptions(opts, "crypt", c) + require.NoError(t, err, "error setting crypt: %v", err) + require.Equal(t, c, opts.Crypt, "expected %v, got %v", c, opts.Crypt) + }) + + t.Run("deployment", func(t *testing.T) { + t.Parallel() + + d := &drivertest.MockDeployment{} + opts := options.Client() + err := SetInternalClientOptions(opts, "deployment", d) + require.NoError(t, err, "error setting deployment: %v", err) + require.Equal(t, d, opts.Deployment, "expected %v, got %v", d, opts.Deployment) + }) +} diff --git a/x/mongo/driver/topology/topology_options_test.go b/x/mongo/driver/topology/topology_options_test.go index 759ab9aa4a..4646721744 100644 --- a/x/mongo/driver/topology/topology_options_test.go +++ b/x/mongo/driver/topology/topology_options_test.go @@ -7,6 +7,7 @@ package topology import ( + "context" "fmt" "net/url" "reflect" @@ -17,6 +18,10 @@ import ( "go.mongodb.org/mongo-driver/v2/internal/require" "go.mongodb.org/mongo-driver/v2/mongo/options" "go.mongodb.org/mongo-driver/v2/x/mongo/driver" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/description" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/drivertest" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/mnet" + xoptions "go.mongodb.org/mongo-driver/v2/x/mongo/driver/options" ) func TestDirectConnectionFromConnString(t *testing.T) { @@ -85,6 +90,74 @@ func TestLoadBalancedFromConnString(t *testing.T) { } } +type testAuthenticator struct{} + +func (a *testAuthenticator) Auth(context.Context, *driver.AuthConfig) error { + return fmt.Errorf("test error") +} + +func (a *testAuthenticator) Reauth(context.Context, *driver.AuthConfig) error { + return nil +} + +func TestAuthenticateToAnything(t *testing.T) { + t.Parallel() + + cases := []struct { + name string + set func(*options.ClientOptions) error + assert func(*testing.T, error) + }{ + { + name: "default", + set: func(*options.ClientOptions) error { return nil }, + assert: func(t *testing.T, err error) { + require.NoError(t, err) + }, + }, + { + name: "positive", + set: func(opt *options.ClientOptions) error { + return xoptions.SetInternalClientOptions(opt, "authenticateToAnything", true) + }, + assert: func(t *testing.T, err error) { + require.EqualError(t, err, "auth error: test error") + }, + }, + { + name: "negative", + set: func(opt *options.ClientOptions) error { + return xoptions.SetInternalClientOptions(opt, "authenticateToAnything", false) + }, + assert: func(t *testing.T, err error) { + require.NoError(t, err) + }, + }, + } + + describer := &drivertest.ChannelConn{ + Desc: description.Server{Kind: description.ServerKindRSArbiter}, + } + for _, tc := range cases { + tc := tc + + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + opt := options.Client().SetAuth(options.Credential{Username: "foo", Password: "bar"}) + err := tc.set(opt) + require.NoError(t, err, "error setting authenticateToAnything: %v", err) + cfg, err := NewConfigFromOptionsWithAuthenticator(opt, nil, &testAuthenticator{}) + require.NoError(t, err, "error constructing topology config: %v", err) + + srvrCfg := newServerConfig(defaultConnectionTimeout, cfg.ServerOpts...) + connCfg := newConnectionConfig(srvrCfg.connectionOpts...) + err = connCfg.handshaker.FinishHandshake(context.TODO(), &mnet.Connection{Describer: describer}) + tc.assert(t, err) + }) + } +} + func TestTopologyNewConfig(t *testing.T) { t.Run("default ServerSelectionTimeout", func(t *testing.T) { cfg, err := NewConfig(options.Client(), nil) From 466b4d002591e77da5ba5f91d5d98b44f60ae275 Mon Sep 17 00:00:00 2001 From: Qingyang Hu Date: Fri, 25 Apr 2025 14:41:05 -0400 Subject: [PATCH 6/6] update tests --- x/mongo/driver/options/options_test.go | 31 +++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/x/mongo/driver/options/options_test.go b/x/mongo/driver/options/options_test.go index 8c383e79ee..0cbab93444 100644 --- a/x/mongo/driver/options/options_test.go +++ b/x/mongo/driver/options/options_test.go @@ -7,6 +7,7 @@ package options import ( + "fmt" "testing" internalOptions "go.mongodb.org/mongo-driver/v2/internal/options" @@ -31,7 +32,7 @@ func TestSetInternalClientOptions(t *testing.T) { for _, tc := range cases { tc := tc - t.Run(tc.key, func(t *testing.T) { + t.Run(fmt.Sprintf("set %s", tc.key), func(t *testing.T) { t.Parallel() opts := options.Client() @@ -42,7 +43,7 @@ func TestSetInternalClientOptions(t *testing.T) { }) } - t.Run("crypt", func(t *testing.T) { + t.Run("set crypt", func(t *testing.T) { t.Parallel() c := driver.NewCrypt(&driver.CryptOptions{}) @@ -52,7 +53,15 @@ func TestSetInternalClientOptions(t *testing.T) { require.Equal(t, c, opts.Crypt, "expected %v, got %v", c, opts.Crypt) }) - t.Run("deployment", func(t *testing.T) { + t.Run("set crypt - wrong type", func(t *testing.T) { + t.Parallel() + + opts := options.Client() + err := SetInternalClientOptions(opts, "crypt", &drivertest.MockDeployment{}) + require.EqualError(t, err, "unexpected type for crypt") + }) + + t.Run("set deployment", func(t *testing.T) { t.Parallel() d := &drivertest.MockDeployment{} @@ -61,4 +70,20 @@ func TestSetInternalClientOptions(t *testing.T) { require.NoError(t, err, "error setting deployment: %v", err) require.Equal(t, d, opts.Deployment, "expected %v, got %v", d, opts.Deployment) }) + + t.Run("set deployment - wrong type", func(t *testing.T) { + t.Parallel() + + opts := options.Client() + err := SetInternalClientOptions(opts, "deployment", driver.NewCrypt(&driver.CryptOptions{})) + require.EqualError(t, err, "unexpected type for deployment") + }) + + t.Run("set unsupported option", func(t *testing.T) { + t.Parallel() + + opts := options.Client() + err := SetInternalClientOptions(opts, "unsupported", "unsupported") + require.EqualError(t, err, "unsupported option: unsupported") + }) }