From fed988015532b63d38133895bb3a1a2c6614fd2c Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Fri, 21 Nov 2025 16:48:28 -0700 Subject: [PATCH 01/16] Run golangci-lint CLI migration --- .golangci.yml | 222 ++++++++++++++++++++++++------------------- etc/golangci-lint.sh | 2 +- 2 files changed, 126 insertions(+), 98 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index b3c66c4d7d..4285d6cef4 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,17 +1,11 @@ -run: - timeout: 5m - +version: "2" linters: - disable-all: true - # TODO(GODRIVER-2156): Enable all commented-out linters. + default: none enable: - errcheck - # - errorlint - - exportloopref - gocritic - - goimports - - gosimple - - gosec + # TODO(GODRIVER-3712): Enable gosec in golangci-lint version 2.6.2 + #- gosec - govet - ineffassign - makezero @@ -21,95 +15,129 @@ linters: - prealloc - revive - staticcheck - - typecheck - - unused - unconvert - unparam + - unused + settings: + errcheck: + exclude-functions: + - .errcheck-excludes + govet: + disable: + - cgocall + - composites + paralleltest: + # Ignore missing calls to `t.Parallel()` and only report incorrect uses of + # `t.Parallel()`. + ignore-missing: true + staticcheck: + checks: + - all + # Disable deprecation warnings for now. + - -SA1012 + # Disable "do not pass a nil Context" to allow testing nil contexts in + # tests. + - -SA1019 + exclusions: + generated: lax + rules: + # Ignore some linters for example code that is intentionally simplified. + - linters: + - errcheck + - revive + path: examples/ + # Disable "unused" linter for code files that depend on the + # "mongocrypt.MongoCrypt" type because the linter build doesn't work + # correctly with CGO enabled. As a result, all calls to a + # "mongocrypt.MongoCrypt" API appear to always panic (see + # mongocrypt_not_enabled.go), leading to confusing messages about unused + # code. + - linters: + - unused + path: x/mongo/driver/crypt.go|mongo/(crypt_retrievers|mongocryptd).go + # Ignore "TLS MinVersion too low", "TLS InsecureSkipVerify set true", and + # "Use of weak random number generator (math/rand instead of crypto/rand)" + # in tests. Disable gosec entirely for test files to reduce noise. + - linters: + - gosec + path: _test\.go + # Ignore missing comments for exported variable/function/type for code in + # the "internal" and "benchmark" directories. + - path: (internal\/|benchmark\/) + text: exported (.+) should have comment( \(or a comment on this block\))? or be unexported + # Ignore missing package comments for directories that aren't frequently + # used by external users. + - path: (internal\/|benchmark\/|x\/|cmd\/|mongo\/integration\/) + text: should have a package comment -linters-settings: - errcheck: - exclude-functions: .errcheck-excludes - govet: - disable: - - cgocall - - composites - paralleltest: - # Ignore missing calls to `t.Parallel()` and only report incorrect uses of `t.Parallel()`. - ignore-missing: true - staticcheck: - checks: [ - "all", - "-SA1019", # Disable deprecation warnings for now. - "-SA1012", # Disable "do not pass a nil Context" to allow testing nil contexts in tests. - ] - -issues: - exclude-dirs-use-default: false - exclude-dirs: - - (^|/)testdata($|/) - - (^|/)etc($|/) - # Disable all linters for copied third-party code. - - internal/rand - - internal/aws - - internal/assert - exclude-use-default: false - exclude: - # Add all default excluded issues except issues related to exported types/functions not having - # comments; we want those warnings. The defaults are copied from the "--exclude-use-default" - # documentation on https://golangci-lint.run/usage/configuration/#command-line-options - ## Defaults ## - # EXC0001 errcheck: Almost all programs ignore errors on these functions and in most cases it's ok - - Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv). is not checked - # EXC0003 golint: False positive when tests are defined in package 'test' - - func name will be used as test\.Test.* by other packages, and that stutters; consider calling this - # EXC0004 govet: Common false positives - - (possible misuse of unsafe.Pointer|should have signature) - # EXC0005 staticcheck: Developers tend to write in C-style with an explicit 'break' in a 'switch', so it's ok to ignore - - ineffective break statement. Did you mean to break out of the outer loop - # EXC0006 gosec: Too many false-positives on 'unsafe' usage - - Use of unsafe calls should be audited - # EXC0007 gosec: Too many false-positives for parametrized shell calls - - Subprocess launch(ed with variable|ing should be audited) - # EXC0008 gosec: Duplicated errcheck checks - - (G104|G307) - # EXC0009 gosec: Too many issues in popular repos - - (Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less) - # EXC0010 gosec: False positive is triggered by 'src, err := ioutil.ReadFile(filename)' - - Potential file inclusion via variable - ## End Defaults ## + # Add all default excluded issues except issues related to exported + # types/functions not having comments; we want those warnings. The + # defaults are copied from the "--exclude-use-default" documentation on + # https://golangci-lint.run/usage/configuration/#command-line-options + # + ## Defaults ## + # + # EXC0001 errcheck: Almost all programs ignore errors on these functions + # and in most cases it's ok + - path: (.+)\.go$ + text: Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*print(f|ln)?|os\.(Un)?Setenv). is not checked + # EXC0003 golint: False positive when tests are defined in package 'test' + - path: (.+)\.go$ + text: func name will be used as test\.Test.* by other packages, and that stutters; consider calling this + # EXC0004 govet: Common false positives + - path: (.+)\.go$ + text: (possible misuse of unsafe.Pointer|should have signature) + # EXC0005 staticcheck: Developers tend to write in C-style with an explicit 'break' in a 'switch', so it's ok to ignore + - path: (.+)\.go$ + text: ineffective break statement. Did you mean to break out of the outer loop + # EXC0006 gosec: Too many false-positives on 'unsafe' usage + - path: (.+)\.go$ + text: Use of unsafe calls should be audited + # EXC0007 gosec: Too many false-positives for parametrized shell calls + - path: (.+)\.go$ + text: Subprocess launch(ed with variable|ing should be audited) + # EXC0008 gosec: Duplicated errcheck checks + - path: (.+)\.go$ + text: (G104|G307) + # EXC0009 gosec: Too many issues in popular repos + - path: (.+)\.go$ + text: (Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less) + # EXC0010 gosec: False positive is triggered by + # 'src, err := ioutil.ReadFile(filename)' + - path: (.+)\.go$ + text: Potential file inclusion via variable + ## End Defaults ## - # Ignore capitalization warning for this weird field name. - - "var-naming: struct field CqCssWxW should be CqCSSWxW" - # Ignore warnings for common "wiremessage.Read..." usage because the safest way to use that API - # is by assigning possibly unused returned byte buffers. - - "SA4006: this value of `wm` is never used" - - "SA4006: this value of `rem` is never used" - - "ineffectual assignment to wm" - - "ineffectual assignment to rem" + # Ignore capitalization warning for this weird field name. + - path: (.+)\.go$ + text: "var-naming: struct field CqCssWxW should be CqCSSWxW" - exclude-rules: - # Ignore some linters for example code that is intentionally simplified. - - path: examples/ - linters: - - revive - - errcheck - # Disable "unused" linter for code files that depend on the "mongocrypt.MongoCrypt" type because - # the linter build doesn't work correctly with CGO enabled. As a result, all calls to a - # "mongocrypt.MongoCrypt" API appear to always panic (see mongocrypt_not_enabled.go), leading - # to confusing messages about unused code. - - path: x/mongo/driver/crypt.go|mongo/(crypt_retrievers|mongocryptd).go - linters: - - unused - # Ignore "TLS MinVersion too low", "TLS InsecureSkipVerify set true", and "Use of weak random - # number generator (math/rand instead of crypto/rand)" in tests. - - path: _test\.go - text: G401|G402|G404 - linters: - - gosec - # Ignore missing comments for exported variable/function/type for code in the "internal" and - # "benchmark" directories. - - path: (internal\/|benchmark\/) - text: exported (.+) should have comment( \(or a comment on this block\))? or be unexported - # Ignore missing package comments for directories that aren't frequently used by external users. - - path: (internal\/|benchmark\/|x\/|cmd\/|mongo\/integration\/) - text: should have a package comment + # Ignore warnings for common "wiremessage.Read..." usage because the + # safest way to use that API is by assigning possibly unused returned byte + # buffers. + - path: (.+)\.go$ + text: "SA4006: this value of `wm` is never used" + - path: (.+)\.go$ + text: "SA4006: this value of `rem` is never used" + - path: (.+)\.go$ + text: ineffectual assignment to wm + - path: (.+)\.go$ + text: ineffectual assignment to rem + paths: + - (^|/)testdata($|/) + - (^|/)etc($|/) + # Disable all linters for copied third-party code. + - internal/rand + - internal/aws + - internal/assert +formatters: + enable: + - goimports + exclusions: + generated: lax + paths: + - (^|/)testdata($|/) + - (^|/)etc($|/) + - internal/rand + - internal/aws + - internal/assert diff --git a/etc/golangci-lint.sh b/etc/golangci-lint.sh index 9951455d4e..de4e9b88c9 100755 --- a/etc/golangci-lint.sh +++ b/etc/golangci-lint.sh @@ -3,7 +3,7 @@ set -ex # Keep this in sync with go version used in static-analysis Evergreen build variant. GO_VERSION=1.25.0 -GOLANGCI_LINT_VERSION=1.60.1 +GOLANGCI_LINT_VERSION=2.6.2 # Unset the cross-compiler overrides while downloading binaries. GOOS_ORIG=${GOOS:-} From 65aa74e4af2f743a5bc684227ec625fc0159cad6 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 14:52:54 -0700 Subject: [PATCH 02/16] Run golangci-lint CLI fix --- bson/mgoregistry.go | 2 +- internal/credproviders/static_provider.go | 2 +- internal/errutil/join_go1.19.go | 1 - internal/errutil/join_go1.20.go | 1 - .../client_side_encryption_prose_test.go | 1 - .../client_side_encryption_spec_test.go | 1 - .../client_side_encryption_test.go | 1 - internal/integration/csot_cse_prose_test.go | 1 - internal/integration/cursor_test.go | 5 +---- internal/integration/errors_test.go | 1 - internal/integration/mtest/csfle_enabled.go | 1 - .../integration/mtest/csfle_not_enabled.go | 1 - .../integration/sdam_error_handling_test.go | 1 - internal/integration/unified/client_entity.go | 2 +- .../integration/unified/event_verification.go | 8 ++++---- internal/integration/unified_spec_test.go | 4 ++-- internal/israce/norace.go | 1 - internal/israce/race.go | 1 - mongo/change_stream.go | 2 +- mongo/client_encryption_test.go | 1 - mongo/collection.go | 2 +- mongo/gridfs_upload_stream.go | 5 +---- mongo/read_write_concern_spec_test.go | 6 +++--- x/mongo/driver/auth/gssapi.go | 2 -- x/mongo/driver/auth/gssapi_not_enabled.go | 1 - x/mongo/driver/auth/gssapi_not_supported.go | 1 - x/mongo/driver/auth/gssapi_test.go | 1 - .../driver/connstring/connstring_spec_test.go | 2 +- x/mongo/driver/integration/main_test.go | 2 +- x/mongo/driver/mongocrypt/binary.go | 1 - x/mongo/driver/mongocrypt/binary_test.go | 1 - x/mongo/driver/mongocrypt/errors.go | 1 - .../driver/mongocrypt/errors_not_enabled.go | 1 - x/mongo/driver/mongocrypt/mongocrypt.go | 1 - .../driver/mongocrypt/mongocrypt_context.go | 1 - .../mongocrypt_context_not_enabled.go | 1 - .../mongocrypt/mongocrypt_kms_context.go | 1 - .../mongocrypt_kms_context_not_enabled.go | 1 - .../mongocrypt/mongocrypt_not_enabled.go | 1 - x/mongo/driver/mongocrypt/mongocrypt_test.go | 1 - x/mongo/driver/ocsp/ocsp_test.go | 1 - x/mongo/driver/operation.go | 20 +++++++++---------- x/mongo/driver/operation/hello.go | 2 +- x/mongo/driver/session/client_session.go | 18 +++++++++-------- x/mongo/driver/topology/CMAP_spec_test.go | 6 ++---- x/mongo/driver/topology/fsm.go | 6 +++--- x/mongo/driver/topology/server_test.go | 1 - .../topology/tls_connection_source_1_16.go | 1 - .../topology/tls_connection_source_1_17.go | 1 - x/mongo/driver/topology/topology.go | 2 +- .../driver/topology/topology_errors_test.go | 1 - 51 files changed, 44 insertions(+), 86 deletions(-) diff --git a/bson/mgoregistry.go b/bson/mgoregistry.go index 6aa74f292c..db0871525e 100644 --- a/bson/mgoregistry.go +++ b/bson/mgoregistry.go @@ -201,7 +201,7 @@ func getterEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) erro return vw.WriteNull() } vv := reflect.ValueOf(x) - encoder, err := ec.Registry.LookupEncoder(vv.Type()) + encoder, err := ec.LookupEncoder(vv.Type()) if err != nil { return err } diff --git a/internal/credproviders/static_provider.go b/internal/credproviders/static_provider.go index bbb0e8033a..a99b223f02 100644 --- a/internal/credproviders/static_provider.go +++ b/internal/credproviders/static_provider.go @@ -45,7 +45,7 @@ func verify(v credentials.Value) error { func (s *StaticProvider) Retrieve() (credentials.Value, error) { if !s.verified { s.err = verify(s.Value) - s.Value.ProviderName = staticProviderName + s.ProviderName = staticProviderName s.verified = true } return s.Value, s.err diff --git a/internal/errutil/join_go1.19.go b/internal/errutil/join_go1.19.go index 569a0216b5..becdf9774c 100644 --- a/internal/errutil/join_go1.19.go +++ b/internal/errutil/join_go1.19.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build !go1.20 -// +build !go1.20 package errutil diff --git a/internal/errutil/join_go1.20.go b/internal/errutil/join_go1.20.go index 69b9ad2231..831991c793 100644 --- a/internal/errutil/join_go1.20.go +++ b/internal/errutil/join_go1.20.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build go1.20 -// +build go1.20 package errutil diff --git a/internal/integration/client_side_encryption_prose_test.go b/internal/integration/client_side_encryption_prose_test.go index 18d55c4cf5..d2f84a1c2b 100644 --- a/internal/integration/client_side_encryption_prose_test.go +++ b/internal/integration/client_side_encryption_prose_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package integration diff --git a/internal/integration/client_side_encryption_spec_test.go b/internal/integration/client_side_encryption_spec_test.go index 369f631a7b..d61d486ac7 100644 --- a/internal/integration/client_side_encryption_spec_test.go +++ b/internal/integration/client_side_encryption_spec_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package integration diff --git a/internal/integration/client_side_encryption_test.go b/internal/integration/client_side_encryption_test.go index 6be3b1c6e3..bb1dba65d2 100644 --- a/internal/integration/client_side_encryption_test.go +++ b/internal/integration/client_side_encryption_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package integration diff --git a/internal/integration/csot_cse_prose_test.go b/internal/integration/csot_cse_prose_test.go index 960db3e2a5..b3dfe8094a 100644 --- a/internal/integration/csot_cse_prose_test.go +++ b/internal/integration/csot_cse_prose_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package integration diff --git a/internal/integration/cursor_test.go b/internal/integration/cursor_test.go index 94acd222c5..500058bf6b 100644 --- a/internal/integration/cursor_test.go +++ b/internal/integration/cursor_test.go @@ -215,10 +215,7 @@ func TestCursor_RemainingBatchLength(t *testing.T) { defer cursor.Close(context.Background()) mt.ClearEvents() - for { - if cursor.TryNext(context.Background()) { - break - } + for !cursor.TryNext(context.Background()) { assert.Nil(mt, cursor.Err(), "cursor error: %v", err) assert.Equal(mt, diff --git a/internal/integration/errors_test.go b/internal/integration/errors_test.go index a33b8df93a..2d12ace87a 100644 --- a/internal/integration/errors_test.go +++ b/internal/integration/errors_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build go1.13 -// +build go1.13 package integration diff --git a/internal/integration/mtest/csfle_enabled.go b/internal/integration/mtest/csfle_enabled.go index 588e9ad6de..ba940400eb 100644 --- a/internal/integration/mtest/csfle_enabled.go +++ b/internal/integration/mtest/csfle_enabled.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package mtest diff --git a/internal/integration/mtest/csfle_not_enabled.go b/internal/integration/mtest/csfle_not_enabled.go index 289cf5ce6d..f7c3565fcf 100644 --- a/internal/integration/mtest/csfle_not_enabled.go +++ b/internal/integration/mtest/csfle_not_enabled.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build !cse -// +build !cse package mtest diff --git a/internal/integration/sdam_error_handling_test.go b/internal/integration/sdam_error_handling_test.go index 737cb67830..d9aa5f2846 100644 --- a/internal/integration/sdam_error_handling_test.go +++ b/internal/integration/sdam_error_handling_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build go1.13 -// +build go1.13 package integration diff --git a/internal/integration/unified/client_entity.go b/internal/integration/unified/client_entity.go index bc981793df..8f9df3d1c6 100644 --- a/internal/integration/unified/client_entity.go +++ b/internal/integration/unified/client_entity.go @@ -261,7 +261,7 @@ func (c *clientEntity) disconnect(ctx context.Context) error { return nil } - if err := c.Client.Disconnect(ctx); err != nil { + if err := c.Disconnect(ctx); err != nil { return err } diff --git a/internal/integration/unified/event_verification.go b/internal/integration/unified/event_verification.go index 0521f0653e..46a88fab79 100644 --- a/internal/integration/unified/event_verification.go +++ b/internal/integration/unified/event_verification.go @@ -429,22 +429,22 @@ func stringifyEventsForClient(client *clientEntity) string { str.WriteString("\n\nStarted Events\n\n") for _, evt := range client.startedEvents() { - str.WriteString(fmt.Sprintf("[%s] %s\n", evt.ConnectionID, evt.Command)) + fmt.Fprintf(str, "[%s] %s\n", evt.ConnectionID, evt.Command) } str.WriteString("\nSucceeded Events\n\n") for _, evt := range client.succeededEvents() { - str.WriteString(fmt.Sprintf("[%s] CommandName: %s, Reply: %s\n", evt.ConnectionID, evt.CommandName, evt.Reply)) + fmt.Fprintf(str, "[%s] CommandName: %s, Reply: %s\n", evt.ConnectionID, evt.CommandName, evt.Reply) } str.WriteString("\nFailed Events\n\n") for _, evt := range client.failedEvents() { - str.WriteString(fmt.Sprintf("[%s] CommandName: %s, Failure: %s\n", evt.ConnectionID, evt.CommandName, evt.Failure)) + fmt.Fprintf(str, "[%s] CommandName: %s, Failure: %s\n", evt.ConnectionID, evt.CommandName, evt.Failure) } str.WriteString("\nPool Events\n\n") for _, evt := range client.poolEvents() { - str.WriteString(fmt.Sprintf("[%s] Event Type: %q\n", evt.Address, evt.Type)) + fmt.Fprintf(str, "[%s] Event Type: %q\n", evt.Address, evt.Type) } return str.String() diff --git a/internal/integration/unified_spec_test.go b/internal/integration/unified_spec_test.go index 99906d448c..af4495cb76 100644 --- a/internal/integration/unified_spec_test.go +++ b/internal/integration/unified_spec_test.go @@ -69,7 +69,7 @@ func decodeTestData(dc bson.DecodeContext, vr bson.ValueReader, val reflect.Valu switch vr.Type() { case bson.TypeArray: docsVal := val.FieldByName("Documents") - decoder, err := dc.Registry.LookupDecoder(docsVal.Type()) + decoder, err := dc.LookupDecoder(docsVal.Type()) if err != nil { return err } @@ -77,7 +77,7 @@ func decodeTestData(dc bson.DecodeContext, vr bson.ValueReader, val reflect.Valu return decoder.DecodeValue(dc, vr, docsVal) case bson.TypeEmbeddedDocument: gridfsDataVal := val.FieldByName("GridFSData") - decoder, err := dc.Registry.LookupDecoder(gridfsDataVal.Type()) + decoder, err := dc.LookupDecoder(gridfsDataVal.Type()) if err != nil { return err } diff --git a/internal/israce/norace.go b/internal/israce/norace.go index 5c4422a678..b5d9662b1f 100644 --- a/internal/israce/norace.go +++ b/internal/israce/norace.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build !race -// +build !race // Package israce reports if the Go race detector is enabled. package israce diff --git a/internal/israce/race.go b/internal/israce/race.go index bd252147e7..c24e4d1d7f 100644 --- a/internal/israce/race.go +++ b/internal/israce/race.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build race -// +build race // Package israce reports if the Go race detector is enabled. package israce diff --git a/mongo/change_stream.go b/mongo/change_stream.go index d5ad8058ec..53ade7b20d 100644 --- a/mongo/change_stream.go +++ b/mongo/change_stream.go @@ -403,7 +403,7 @@ func (cs *ChangeStream) storeResumeToken() error { func (cs *ChangeStream) buildPipelineSlice(pipeline any) error { val := reflect.ValueOf(pipeline) - if !val.IsValid() || !(val.Kind() == reflect.Slice) { + if !val.IsValid() || (val.Kind() != reflect.Slice) { cs.err = errors.New("can only marshal slices and arrays into aggregation pipelines, but got invalid") return cs.err } diff --git a/mongo/client_encryption_test.go b/mongo/client_encryption_test.go index 1c49b3f707..ea967a0f0f 100644 --- a/mongo/client_encryption_test.go +++ b/mongo/client_encryption_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package mongo diff --git a/mongo/collection.go b/mongo/collection.go index af1960d970..18cb0f475d 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -1023,7 +1023,7 @@ func aggregate(a aggregateParams, opts ...options.Lister[options.AggregateOption op.AllowDiskUse(*args.AllowDiskUse) } // ignore batchSize of 0 with $out - if args.BatchSize != nil && !(*args.BatchSize == 0 && hasOutputStage) { + if args.BatchSize != nil && (*args.BatchSize != 0 || !hasOutputStage) { op.BatchSize(*args.BatchSize) cursorOpts.BatchSize = *args.BatchSize } diff --git a/mongo/gridfs_upload_stream.go b/mongo/gridfs_upload_stream.go index ba7883d978..7f34c9168d 100644 --- a/mongo/gridfs_upload_stream.go +++ b/mongo/gridfs_upload_stream.go @@ -99,10 +99,7 @@ func (us *GridFSUploadStream) Write(p []byte) (int, error) { } origLen := len(p) - for { - if len(p) == 0 { - break - } + for len(p) != 0 { n := copy(us.buffer[us.bufferIndex:], p) // copy as much as possible p = p[n:] diff --git a/mongo/read_write_concern_spec_test.go b/mongo/read_write_concern_spec_test.go index 5118cc511d..05b3f5b689 100644 --- a/mongo/read_write_concern_spec_test.go +++ b/mongo/read_write_concern_spec_test.go @@ -246,16 +246,16 @@ func writeConcernFromRaw(t *testing.T, wcRaw bson.Raw) writeConcern { switch val.Type { case bson.TypeInt32: w := int(val.Int32()) - wc.WriteConcern.W = w + wc.W = w case bson.TypeString: - wc.WriteConcern.W = val.StringValue() + wc.W = val.StringValue() default: t.Fatalf("unexpected type for w: %v", val.Type) } case "journal": wc.jSet = true j := val.Boolean() - wc.WriteConcern.Journal = &j + wc.Journal = &j case "wtimeoutMS": // Do nothing, this field is deprecated t.Skip("the wtimeoutMS write concern option is not supported") default: diff --git a/x/mongo/driver/auth/gssapi.go b/x/mongo/driver/auth/gssapi.go index 0ae7571d23..5f915efdd4 100644 --- a/x/mongo/driver/auth/gssapi.go +++ b/x/mongo/driver/auth/gssapi.go @@ -5,8 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build gssapi && (windows || linux || darwin) -// +build gssapi -// +build windows linux darwin package auth diff --git a/x/mongo/driver/auth/gssapi_not_enabled.go b/x/mongo/driver/auth/gssapi_not_enabled.go index e50553c7a1..2f45412100 100644 --- a/x/mongo/driver/auth/gssapi_not_enabled.go +++ b/x/mongo/driver/auth/gssapi_not_enabled.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build !gssapi -// +build !gssapi package auth diff --git a/x/mongo/driver/auth/gssapi_not_supported.go b/x/mongo/driver/auth/gssapi_not_supported.go index 12046ff67c..b53f2df31b 100644 --- a/x/mongo/driver/auth/gssapi_not_supported.go +++ b/x/mongo/driver/auth/gssapi_not_supported.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build gssapi && !windows && !linux && !darwin -// +build gssapi,!windows,!linux,!darwin package auth diff --git a/x/mongo/driver/auth/gssapi_test.go b/x/mongo/driver/auth/gssapi_test.go index eedfe428e9..8a89c54678 100644 --- a/x/mongo/driver/auth/gssapi_test.go +++ b/x/mongo/driver/auth/gssapi_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build gssapi -// +build gssapi package auth diff --git a/x/mongo/driver/connstring/connstring_spec_test.go b/x/mongo/driver/connstring/connstring_spec_test.go index b6243a471e..21aff46b64 100644 --- a/x/mongo/driver/connstring/connstring_spec_test.go +++ b/x/mongo/driver/connstring/connstring_spec_test.go @@ -112,7 +112,7 @@ func runTest(t *testing.T, test testCase, warningsError bool) { // URI options, but don't with some of the older things, we do a switch on the filename // here. We are trying to not break existing user applications that have unrecognized // options. - if test.Valid && !(test.Warning && warningsError) { + if test.Valid && (!test.Warning || !warningsError) { require.NoError(t, err) } else { require.Error(t, err) diff --git a/x/mongo/driver/integration/main_test.go b/x/mongo/driver/integration/main_test.go index f1c24bfd0d..97f85de244 100644 --- a/x/mongo/driver/integration/main_test.go +++ b/x/mongo/driver/integration/main_test.go @@ -133,7 +133,7 @@ func dropCollection(t *testing.T, dbname, colname string) { err := operation.NewCommand(bsoncore.BuildDocument(nil, bsoncore.AppendStringElement(nil, "drop", colname))). Database(dbname).ServerSelector(&serverselector.Write{}).Deployment(integtest.Topology(t)). Execute(context.Background()) - if de, ok := err.(driver.Error); err != nil && !(ok && de.NamespaceNotFound()) { + if de, ok := err.(driver.Error); err != nil && (!ok || !de.NamespaceNotFound()) { require.NoError(t, err) } } diff --git a/x/mongo/driver/mongocrypt/binary.go b/x/mongo/driver/mongocrypt/binary.go index 4e4b51d74b..116b2b5e1a 100644 --- a/x/mongo/driver/mongocrypt/binary.go +++ b/x/mongo/driver/mongocrypt/binary.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package mongocrypt diff --git a/x/mongo/driver/mongocrypt/binary_test.go b/x/mongo/driver/mongocrypt/binary_test.go index 6f122745d4..c6c86455dc 100644 --- a/x/mongo/driver/mongocrypt/binary_test.go +++ b/x/mongo/driver/mongocrypt/binary_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package mongocrypt diff --git a/x/mongo/driver/mongocrypt/errors.go b/x/mongo/driver/mongocrypt/errors.go index 3401e73849..d80bacfe12 100644 --- a/x/mongo/driver/mongocrypt/errors.go +++ b/x/mongo/driver/mongocrypt/errors.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package mongocrypt diff --git a/x/mongo/driver/mongocrypt/errors_not_enabled.go b/x/mongo/driver/mongocrypt/errors_not_enabled.go index 706a0f9e75..970de44625 100644 --- a/x/mongo/driver/mongocrypt/errors_not_enabled.go +++ b/x/mongo/driver/mongocrypt/errors_not_enabled.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build !cse -// +build !cse package mongocrypt diff --git a/x/mongo/driver/mongocrypt/mongocrypt.go b/x/mongo/driver/mongocrypt/mongocrypt.go index 91b950c371..c2c47a6334 100644 --- a/x/mongo/driver/mongocrypt/mongocrypt.go +++ b/x/mongo/driver/mongocrypt/mongocrypt.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package mongocrypt diff --git a/x/mongo/driver/mongocrypt/mongocrypt_context.go b/x/mongo/driver/mongocrypt/mongocrypt_context.go index 5a34516533..b7f2c325b7 100644 --- a/x/mongo/driver/mongocrypt/mongocrypt_context.go +++ b/x/mongo/driver/mongocrypt/mongocrypt_context.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package mongocrypt diff --git a/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go b/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go index a04272781b..14bc764d18 100644 --- a/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go +++ b/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build !cse -// +build !cse package mongocrypt diff --git a/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go b/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go index 49baa37f2e..fb3c354331 100644 --- a/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go +++ b/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package mongocrypt diff --git a/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go b/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go index 7968897648..acb24e4b07 100644 --- a/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go +++ b/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build !cse -// +build !cse package mongocrypt diff --git a/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go b/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go index 6e21e64917..1b78b05ccd 100644 --- a/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go +++ b/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build !cse -// +build !cse // Package mongocrypt is intended for internal use only. It is made available to // facilitate use cases that require access to internal MongoDB driver diff --git a/x/mongo/driver/mongocrypt/mongocrypt_test.go b/x/mongo/driver/mongocrypt/mongocrypt_test.go index 964991d537..3a1369d38c 100644 --- a/x/mongo/driver/mongocrypt/mongocrypt_test.go +++ b/x/mongo/driver/mongocrypt/mongocrypt_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build cse -// +build cse package mongocrypt diff --git a/x/mongo/driver/ocsp/ocsp_test.go b/x/mongo/driver/ocsp/ocsp_test.go index 58a89315bb..0137865a2c 100644 --- a/x/mongo/driver/ocsp/ocsp_test.go +++ b/x/mongo/driver/ocsp/ocsp_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build go1.13 -// +build go1.13 package ocsp diff --git a/x/mongo/driver/operation.go b/x/mongo/driver/operation.go index 3e720eba63..ac2d5f69e1 100644 --- a/x/mongo/driver/operation.go +++ b/x/mongo/driver/operation.go @@ -475,7 +475,7 @@ func (op Operation) getServerAndConnection( server, err := op.selectServer(ctx, requestID, deprioritized) if err != nil { if op.Client != nil && - !(op.Client.Committing || op.Client.Aborting) && op.Client.TransactionRunning() { + (!op.Client.Committing && !op.Client.Aborting) && op.Client.TransactionRunning() { err = Error{ Message: err.Error(), Labels: []string{TransientTransactionError}, @@ -792,7 +792,7 @@ func (op Operation) Execute(ctx context.Context) error { serverConnID: startedInfo.serverConnID, redacted: startedInfo.redacted, serviceID: startedInfo.serviceID, - serverAddress: desc.Server.Addr, + serverAddress: desc.Addr, } startedTime := time.Now() @@ -845,7 +845,7 @@ func (op Operation) Execute(ctx context.Context) error { retryableErr := tt.Retryable(connDesc.Kind, connDesc.WireVersion) preRetryWriteLabelVersion := connDesc.WireVersion != nil && connDesc.WireVersion.Max < 9 inTransaction := op.Client != nil && - !(op.Client.Committing || op.Client.Aborting) && op.Client.TransactionRunning() + (!op.Client.Committing && !op.Client.Aborting) && op.Client.TransactionRunning() // If retry is enabled and the operation isn't in a transaction, add a RetryableWriteError label for // retryable errors from pre-4.4 servers if retryableErr && preRetryWriteLabelVersion && retryEnabled && !inTransaction { @@ -961,7 +961,7 @@ func (op Operation) Execute(ctx context.Context) error { retryableErr = tt.RetryableWrite(connDesc.WireVersion) preRetryWriteLabelVersion := connDesc.WireVersion != nil && connDesc.WireVersion.Max < 9 inTransaction := op.Client != nil && - !(op.Client.Committing || op.Client.Aborting) && op.Client.TransactionRunning() + (!op.Client.Committing && !op.Client.Aborting) && op.Client.TransactionRunning() // If retryWrites is enabled and the operation isn't in a transaction, add a RetryableWriteError label // for network errors and retryable errors from pre-4.4 servers if retryEnabled && !inTransaction && @@ -1081,7 +1081,7 @@ func (op Operation) retryable(desc description.Server) bool { return true } if retryWritesSupported(desc) && - op.Client != nil && !(op.Client.TransactionInProgress() || op.Client.TransactionStarting()) && + op.Client != nil && (!op.Client.TransactionInProgress() && !op.Client.TransactionStarting()) && op.WriteConcern.Acknowledged() { return true } @@ -1089,7 +1089,7 @@ func (op Operation) retryable(desc description.Server) bool { if op.Client != nil && (op.Client.Committing || op.Client.Aborting) { return true } - if op.Client == nil || !(op.Client.TransactionInProgress() || op.Client.TransactionStarting()) { + if op.Client == nil || (!op.Client.TransactionInProgress() && !op.Client.TransactionStarting()) { return true } } @@ -1335,10 +1335,8 @@ func (op Operation) createMsgWireMessage( if err != nil { return dst, nil, err } - retryWrite := false - if op.retryable(conn.Description()) && op.RetryMode != nil && op.RetryMode.Enabled() { - retryWrite = true - } + retryWrite := op.retryable(conn.Description()) && op.RetryMode != nil && op.RetryMode.Enabled() + dst, err = op.addSession(dst, desc, retryWrite) if err != nil { return dst, nil, err @@ -1842,7 +1840,7 @@ func (op Operation) createReadPref(desc description.SelectedServer, isOpQuery bo // TODO if supplied readPreference was "overwritten" with primary in description.selectForReplicaSet. if desc.Server.Kind == description.ServerKindStandalone || (isOpQuery && desc.Server.Kind != description.ServerKindMongos) || - op.Type == Write || (op.IsOutputAggregate && desc.Server.WireVersion.Max < 13) { + op.Type == Write || (op.IsOutputAggregate && desc.WireVersion.Max < 13) { // Don't send read preference for: // 1. all standalones // 2. non-mongos when using OP_QUERY diff --git a/x/mongo/driver/operation/hello.go b/x/mongo/driver/operation/hello.go index dd232f0623..41ccfd8ac8 100644 --- a/x/mongo/driver/operation/hello.go +++ b/x/mongo/driver/operation/hello.go @@ -576,7 +576,7 @@ func (h *Hello) handshakeCommand(dst []byte, desc description.SelectedServer) ([ func (h *Hello) command(dst []byte, desc description.SelectedServer) ([]byte, error) { // Use "hello" if topology is LoadBalanced, API version is declared or server // has responded with "helloOk". Otherwise, use legacy hello. - if h.loadBalanced || h.serverAPI != nil || desc.Server.HelloOK { + if h.loadBalanced || h.serverAPI != nil || desc.HelloOK { dst = bsoncore.AppendInt32Element(dst, "hello", 1) } else { dst = bsoncore.AppendInt32Element(dst, handshake.LegacyHello, 1) diff --git a/x/mongo/driver/session/client_session.go b/x/mongo/driver/session/client_session.go index cd89b707b4..616f71bc29 100644 --- a/x/mongo/driver/session/client_session.go +++ b/x/mongo/driver/session/client_session.go @@ -422,9 +422,10 @@ func (c *Client) StartTransaction(opts *TransactionOptions) error { // CheckCommitTransaction checks to see if allowed to commit transaction and returns // an error if not allowed. func (c *Client) CheckCommitTransaction() error { - if c.TransactionState == None { + switch c.TransactionState { + case None: return ErrNoTransactStarted - } else if c.TransactionState == Aborted { + case Aborted: return ErrCommitAfterAbort } return nil @@ -462,12 +463,12 @@ func (c *Client) UpdateCommitTransactionWriteConcern() { // CheckAbortTransaction checks to see if allowed to abort transaction and returns // an error if not allowed. func (c *Client) CheckAbortTransaction() error { - switch { - case c.TransactionState == None: + switch c.TransactionState { + case None: return ErrNoTransactStarted - case c.TransactionState == Committed: + case Committed: return ErrAbortAfterCommit - case c.TransactionState == Aborted: + case Aborted: return ErrAbortTwice } return nil @@ -506,13 +507,14 @@ func (c *Client) ApplyCommand(desc description.Server) error { // Do not change state if committing after already committed return nil } - if c.TransactionState == Starting { + switch c.TransactionState { + case Starting: c.TransactionState = InProgress // If this is in a transaction and the server is a mongos, pin it if desc.Kind == description.ServerKindMongos { c.PinnedServerAddr = &desc.Addr } - } else if c.TransactionState == Committed || c.TransactionState == Aborted { + case Committed, Aborted: c.TransactionState = None return c.clearTransactionOpts() } diff --git a/x/mongo/driver/topology/CMAP_spec_test.go b/x/mongo/driver/topology/CMAP_spec_test.go index a0579ff552..29f6276375 100644 --- a/x/mongo/driver/topology/CMAP_spec_test.go +++ b/x/mongo/driver/topology/CMAP_spec_test.go @@ -427,10 +427,8 @@ func runOperationInThread(t *testing.T, operation map[string]any, testInfo *test t.Fatalf("unable to find thread to wait for: %v", threadName) } - for { - if atomic.LoadInt32(&thread.JobsCompleted) == atomic.LoadInt32(&thread.JobsAssigned) { - break - } + for atomic.LoadInt32(&thread.JobsCompleted) != atomic.LoadInt32(&thread.JobsAssigned) { + } case "waitForEvent": var targetCount int diff --git a/x/mongo/driver/topology/fsm.go b/x/mongo/driver/topology/fsm.go index 26e2fc320b..7e96b3c341 100644 --- a/x/mongo/driver/topology/fsm.go +++ b/x/mongo/driver/topology/fsm.go @@ -125,7 +125,7 @@ func (f *fsm) apply(s description.Server) (description.Topology, description.Ser SetName: f.SetName, } - f.Topology.SessionTimeoutMinutes = serverTimeoutMinutes + f.SessionTimeoutMinutes = serverTimeoutMinutes if _, ok := f.findServer(s.Addr); !ok { return f.Topology, s @@ -157,7 +157,7 @@ func (f *fsm) apply(s description.Server) (description.Topology, description.Ser SupportedWireVersions.Min, MinSupportedMongoDBVersion, ) - f.Topology.CompatibilityErr = f.compatibilityErr + f.CompatibilityErr = f.compatibilityErr return f.Topology, s } @@ -169,7 +169,7 @@ func (f *fsm) apply(s description.Server) (description.Topology, description.Ser server.WireVersion.Min, SupportedWireVersions.Max, ) - f.Topology.CompatibilityErr = f.compatibilityErr + f.CompatibilityErr = f.compatibilityErr return f.Topology, s } } diff --git a/x/mongo/driver/topology/server_test.go b/x/mongo/driver/topology/server_test.go index ae3009573b..7626ff1920 100644 --- a/x/mongo/driver/topology/server_test.go +++ b/x/mongo/driver/topology/server_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build go1.13 -// +build go1.13 package topology diff --git a/x/mongo/driver/topology/tls_connection_source_1_16.go b/x/mongo/driver/topology/tls_connection_source_1_16.go index 387f2ec04d..dad53d010d 100644 --- a/x/mongo/driver/topology/tls_connection_source_1_16.go +++ b/x/mongo/driver/topology/tls_connection_source_1_16.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build !go1.17 -// +build !go1.17 package topology diff --git a/x/mongo/driver/topology/tls_connection_source_1_17.go b/x/mongo/driver/topology/tls_connection_source_1_17.go index c9822e0609..8306c6c437 100644 --- a/x/mongo/driver/topology/tls_connection_source_1_17.go +++ b/x/mongo/driver/topology/tls_connection_source_1_17.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build go1.17 -// +build go1.17 package topology diff --git a/x/mongo/driver/topology/topology.go b/x/mongo/driver/topology/topology.go index 5343934ccf..a4ce875837 100644 --- a/x/mongo/driver/topology/topology.go +++ b/x/mongo/driver/topology/topology.go @@ -772,7 +772,7 @@ func (t *Topology) pollSRVRecords(hosts string) { return } topoKind := t.Description().Kind - if !(topoKind == description.Unknown || topoKind == description.TopologyKindSharded) { + if topoKind != description.Unknown && topoKind != description.TopologyKindSharded { break } diff --git a/x/mongo/driver/topology/topology_errors_test.go b/x/mongo/driver/topology/topology_errors_test.go index 3b4306e606..0fd45da036 100644 --- a/x/mongo/driver/topology/topology_errors_test.go +++ b/x/mongo/driver/topology/topology_errors_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build go1.13 -// +build go1.13 package topology From 12b4c37eb8aa4c37c4e37959bc57bd537a964ca6 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 14:54:12 -0700 Subject: [PATCH 03/16] errcheck: fix issues in topology package --- x/mongo/driver/topology/connection.go | 33 ++++++++++++------- .../driver/topology/connection_errors_test.go | 4 +-- x/mongo/driver/topology/pool_test.go | 3 +- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/x/mongo/driver/topology/connection.go b/x/mongo/driver/topology/connection.go index b1bf1d13f1..65ec4e3c6b 100644 --- a/x/mongo/driver/topology/connection.go +++ b/x/mongo/driver/topology/connection.go @@ -226,7 +226,6 @@ func (c *connection) connect(ctx context.Context) (err error) { HTTPClient: c.config.httpClient, } tlsNc, err := configureTLS(ctx, c.config.tlsConnectionSource, c.nc, c.addr, tlsConfig, ocspOpts) - if err != nil { return ConnectionError{Wrapped: err, init: true, message: fmt.Sprintf("failed to configure TLS for %s", c.addr)} } @@ -365,7 +364,8 @@ func (c *connection) writeWireMessage(ctx context.Context, wm []byte) error { err = c.write(ctx, wm) if err != nil { - c.close() + _ = c.close() + return ConnectionError{ ConnectionID: c.id, Wrapped: transformNetworkError(ctx, err, contextDeadlineUsed), @@ -412,7 +412,7 @@ func (c *connection) readWireMessage(ctx context.Context) ([]byte, error) { if c.awaitRemainingBytes == nil { // If the connection was not marked as awaiting response, close the // connection because we don't know what the connection state is. - c.close() + _ = c.close() } message := errMsg return nil, ConnectionError{ @@ -586,15 +586,17 @@ func (c *connection) SetOIDCTokenGenID(genID uint64) { // *connection to a Handshaker. type initConnection struct{ *connection } -var _ mnet.ReadWriteCloser = initConnection{} -var _ mnet.Describer = initConnection{} -var _ mnet.Streamer = initConnection{} +var ( + _ mnet.ReadWriteCloser = initConnection{} + _ mnet.Describer = initConnection{} + _ mnet.Streamer = initConnection{} +) func (c initConnection) Description() description.Server { if c.connection == nil { return description.Server{} } - return c.connection.desc + return c.desc } func (c initConnection) Close() error { return nil } func (c initConnection) ID() string { return c.id } @@ -606,18 +608,23 @@ func (c initConnection) LocalAddress() address.Address { } return address.Address(c.nc.LocalAddr().String()) } + func (c initConnection) Write(ctx context.Context, wm []byte) error { return c.writeWireMessage(ctx, wm) } + func (c initConnection) Read(ctx context.Context) ([]byte, error) { return c.readWireMessage(ctx) } + func (c initConnection) SetStreaming(streaming bool) { c.setStreaming(streaming) } + func (c initConnection) CurrentlyStreaming() bool { return c.getCurrentlyStreaming() } + func (c initConnection) SupportsStreaming() bool { return c.canStream } @@ -639,11 +646,13 @@ type Connection struct { mu sync.RWMutex } -var _ mnet.ReadWriteCloser = (*Connection)(nil) -var _ mnet.Describer = (*Connection)(nil) -var _ mnet.Compressor = (*Connection)(nil) -var _ mnet.Pinner = (*Connection)(nil) -var _ driver.Expirable = (*Connection)(nil) +var ( + _ mnet.ReadWriteCloser = (*Connection)(nil) + _ mnet.Describer = (*Connection)(nil) + _ mnet.Compressor = (*Connection)(nil) + _ mnet.Pinner = (*Connection)(nil) + _ driver.Expirable = (*Connection)(nil) +) // WriteWireMessage handles writing a wire message to the underlying connection. func (c *Connection) Write(ctx context.Context, wm []byte) error { diff --git a/x/mongo/driver/topology/connection_errors_test.go b/x/mongo/driver/topology/connection_errors_test.go index 0a7259035d..b9984b6788 100644 --- a/x/mongo/driver/topology/connection_errors_test.go +++ b/x/mongo/driver/topology/connection_errors_test.go @@ -5,7 +5,6 @@ // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 //go:build go1.13 -// +build go1.13 package topology @@ -16,6 +15,7 @@ import ( "testing" "go.mongodb.org/mongo-driver/v2/internal/assert" + "go.mongodb.org/mongo-driver/v2/internal/require" "go.mongodb.org/mongo-driver/v2/mongo/address" "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth" ) @@ -43,7 +43,7 @@ func TestConnectionErrors(t *testing.T) { }) }), ) - defer conn.close() + defer func() { require.NoError(t, conn.close()) }() ctx, cancel := context.WithCancel(context.Background()) cancel() diff --git a/x/mongo/driver/topology/pool_test.go b/x/mongo/driver/topology/pool_test.go index 17e803ea49..8cdfb79df8 100644 --- a/x/mongo/driver/topology/pool_test.go +++ b/x/mongo/driver/topology/pool_test.go @@ -788,7 +788,8 @@ func TestPool_checkOut(t *testing.T) { // checkOut() completes is within 100ms. var start time.Time go func() { - c.close() + require.NoError(t, c.close()) + start = time.Now() err := p.checkIn(c) require.NoError(t, err) From 0fc5be63ae2215eba019c73ea9c55210aa2e3c8b Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:14:58 -0700 Subject: [PATCH 04/16] revive: fix unexported-return in bsoncore --- x/bsonx/bsoncore/bsoncore.go | 4 ++-- x/bsonx/bsoncore/value.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/x/bsonx/bsoncore/bsoncore.go b/x/bsonx/bsoncore/bsoncore.go index 13219ee547..6936056a45 100644 --- a/x/bsonx/bsoncore/bsoncore.go +++ b/x/bsonx/bsoncore/bsoncore.go @@ -350,7 +350,7 @@ func AppendObjectIDElement(dst []byte, key string, oid objectID) []byte { // ReadObjectID will read an ObjectID from src. If there are not enough bytes it // will return false. -func ReadObjectID(src []byte) (objectID, []byte, bool) { +func ReadObjectID(src []byte) ([12]byte, []byte, bool) { var oid objectID idLen := cap(oid) if len(src) < idLen { @@ -461,7 +461,7 @@ func AppendDBPointerElement(dst []byte, key, ns string, oid objectID) []byte { // ReadDBPointer will read a ns and oid from src. If there are not enough bytes it // will return false. -func ReadDBPointer(src []byte) (ns string, oid objectID, rem []byte, ok bool) { +func ReadDBPointer(src []byte) (ns string, oid [12]byte, rem []byte, ok bool) { ns, rem, ok = readstring(src) if !ok { return "", objectID{}, src, false diff --git a/x/bsonx/bsoncore/value.go b/x/bsonx/bsoncore/value.go index fec33029e0..4dbf44ed49 100644 --- a/x/bsonx/bsoncore/value.go +++ b/x/bsonx/bsoncore/value.go @@ -522,7 +522,7 @@ func (v Value) BinaryOK() (subtype byte, data []byte, ok bool) { // ObjectID returns the BSON objectid value the Value represents. It panics if the value is a BSON // type other than objectid. -func (v Value) ObjectID() objectID { +func (v Value) ObjectID() [12]byte { if v.Type != TypeObjectID { panic(ElementTypeError{"bsoncore.Value.ObjectID", v.Type}) } @@ -535,7 +535,7 @@ func (v Value) ObjectID() objectID { // ObjectIDOK is the same as ObjectID, except it returns a boolean instead of // panicking. -func (v Value) ObjectIDOK() (objectID, bool) { +func (v Value) ObjectIDOK() ([12]byte, bool) { if v.Type != TypeObjectID { return objectID{}, false } @@ -652,7 +652,7 @@ func (v Value) RegexOK() (pattern, options string, ok bool) { // DBPointer returns the BSON dbpointer value the Value represents. It panics if the value is a BSON // type other than DBPointer. -func (v Value) DBPointer() (string, objectID) { +func (v Value) DBPointer() (string, [12]byte) { if v.Type != TypeDBPointer { panic(ElementTypeError{"bsoncore.Value.DBPointer", v.Type}) } @@ -665,7 +665,7 @@ func (v Value) DBPointer() (string, objectID) { // DBPointerOK is the same as DBPoitner, except that it returns a boolean // instead of panicking. -func (v Value) DBPointerOK() (string, objectID, bool) { +func (v Value) DBPointerOK() (string, [12]byte, bool) { if v.Type != TypeDBPointer { return "", objectID{}, false } From cf9786f8a5f105fed7d83c0c54f0f31cd988797e Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:15:39 -0700 Subject: [PATCH 05/16] revive: fix warnings in topology --- x/mongo/driver/topology/CMAP_spec_test.go | 6 ++++-- x/mongo/driver/topology/diff.go | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/x/mongo/driver/topology/CMAP_spec_test.go b/x/mongo/driver/topology/CMAP_spec_test.go index 29f6276375..a0579ff552 100644 --- a/x/mongo/driver/topology/CMAP_spec_test.go +++ b/x/mongo/driver/topology/CMAP_spec_test.go @@ -427,8 +427,10 @@ func runOperationInThread(t *testing.T, operation map[string]any, testInfo *test t.Fatalf("unable to find thread to wait for: %v", threadName) } - for atomic.LoadInt32(&thread.JobsCompleted) != atomic.LoadInt32(&thread.JobsAssigned) { - + for { + if atomic.LoadInt32(&thread.JobsCompleted) == atomic.LoadInt32(&thread.JobsAssigned) { + break + } } case "waitForEvent": var targetCount int diff --git a/x/mongo/driver/topology/diff.go b/x/mongo/driver/topology/diff.go index bd1b1d1c6f..eddd334ee8 100644 --- a/x/mongo/driver/topology/diff.go +++ b/x/mongo/driver/topology/diff.go @@ -45,15 +45,15 @@ type topologyDiff struct { } // diffTopology compares the two topology descriptions and returns the difference. -func diffTopology(old, new description.Topology) topologyDiff { +func diffTopology(oldtopo, newtopo description.Topology) topologyDiff { var diff topologyDiff oldServers := make(map[string]bool) - for _, s := range old.Servers { + for _, s := range oldtopo.Servers { oldServers[s.Addr.String()] = true } - for _, s := range new.Servers { + for _, s := range newtopo.Servers { addr := s.Addr.String() if oldServers[addr] { delete(oldServers, addr) @@ -62,7 +62,7 @@ func diffTopology(old, new description.Topology) topologyDiff { } } - for _, s := range old.Servers { + for _, s := range oldtopo.Servers { addr := s.Addr.String() if oldServers[addr] { diff.Removed = append(diff.Removed, s) From f4bfb7618d6df858c14e9ed4c92f0e4c54bc274e Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:29:31 -0700 Subject: [PATCH 06/16] staticcheck: fix warnings in bson --- bson/map_codec.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bson/map_codec.go b/bson/map_codec.go index 4f33484b2f..36d2f6ae26 100644 --- a/bson/map_codec.go +++ b/bson/map_codec.go @@ -79,7 +79,6 @@ func (mc *mapCodec) EncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Va // true if the provided key exists, this is mainly used for inline maps in the // struct codec. func (mc *mapCodec) encodeMapElements(ec EncodeContext, dw DocumentWriter, val reflect.Value, collisionFn func(string) bool) error { - elemType := val.Type().Elem() encoder, err := ec.LookupEncoder(elemType) if err != nil && elemType.Kind() != reflect.Interface { @@ -237,8 +236,10 @@ func (mc *mapCodec) encodeKey(val reflect.Value, encodeKeysWithStringer bool) (s return "", fmt.Errorf("unsupported key type: %v", val.Type()) } -var keyUnmarshalerType = reflect.TypeOf((*KeyUnmarshaler)(nil)).Elem() -var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() +var ( + keyUnmarshalerType = reflect.TypeOf((*KeyUnmarshaler)(nil)).Elem() + textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() +) func (mc *mapCodec) decodeKey(key string, keyType reflect.Type) (reflect.Value, error) { keyVal := reflect.ValueOf(key) @@ -278,7 +279,7 @@ func (mc *mapCodec) decodeKey(key string, keyType reflect.Type) (reflect.Value, if mc.encodeKeysWithStringer { parsed, err := strconv.ParseFloat(key, 64) if err != nil { - return keyVal, fmt.Errorf("Map key is defined to be a decimal type (%v) but got error %w", keyType.Kind(), err) + return keyVal, fmt.Errorf("map key is defined to be a decimal type (%v) but got error %w", keyType.Kind(), err) } keyVal = reflect.ValueOf(parsed) break From 7d6f0d3dacb08da5fa31b9a5e100e7afa1eab1d5 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:29:48 -0700 Subject: [PATCH 07/16] staticcheck: fix warnings in internal/docexamples --- internal/docexamples/examples.go | 48 ++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/internal/docexamples/examples.go b/internal/docexamples/examples.go index 75364c0f25..8d37cfcc65 100644 --- a/internal/docexamples/examples.go +++ b/internal/docexamples/examples.go @@ -273,11 +273,13 @@ func QueryToplevelFieldsExamples(t *testing.T, db *mongo.Database) { cursor, err := coll.Find( context.TODO(), bson.D{ - {"$or", + { + "$or", bson.A{ bson.D{{"status", "A"}}, bson.D{{"qty", bson.D{{"$lt", 30}}}}, - }}, + }, + }, }) // End Example 12 @@ -304,7 +306,6 @@ func QueryToplevelFieldsExamples(t *testing.T, db *mongo.Database) { assert.NoError(t, err) requireCursorLength(t, cursor, 2) } - } // QueryEmbeddedDocumentsExamples contains examples for querying embedded document fields. @@ -466,7 +467,6 @@ func QueryEmbeddedDocumentsExamples(t *testing.T, db *mongo.Database) { assert.NoError(t, err) requireCursorLength(t, cursor, 1) } - } // QueryArraysExamples contains examples for querying array fields. @@ -653,7 +653,6 @@ func QueryArraysExamples(t *testing.T, db *mongo.Database) { assert.NoError(t, err) requireCursorLength(t, cursor, 1) } - } // QueryArrayEmbeddedDocumentsExamples contains examples for querying fields with arrays and embedded documents. @@ -1628,7 +1627,6 @@ func UpdateExamples(t *testing.T, db *mongo.Database) { assert.NoError(t, cursor.Err()) } - } // DeleteExamples contains examples of delete operations. @@ -2100,10 +2098,14 @@ func ChangeStreamExamples(t *testing.T, db *mongo.Database) { { // Start Changestream Example 4 - pipeline := mongo.Pipeline{bson.D{{"$match", bson.D{{"$or", - bson.A{ - bson.D{{"fullDocument.username", "alice"}}, - bson.D{{"operationType", "delete"}}}}}, + pipeline := mongo.Pipeline{bson.D{{ + "$match", bson.D{{ + "$or", + bson.A{ + bson.D{{"fullDocument.username", "alice"}}, + bson.D{{"operationType", "delete"}}, + }, + }}, }}} cs, err := coll.Watch(ctx, pipeline) assert.NoError(t, err) @@ -2503,8 +2505,10 @@ func AggregationExamples(t *testing.T, db *mongo.Database) { { {"$lookup", bson.D{ {"from", "air_airlines"}, - {"let", bson.D{ - {"constituents", "$airlines"}}, + { + "let", bson.D{ + {"constituents", "$airlines"}, + }, }, {"pipeline", bson.A{bson.D{ {"$match", bson.D{ @@ -2586,7 +2590,6 @@ func CausalConsistencyExamples(client *mongo.Client) error { return nil }) - if err != nil { return err } @@ -2615,7 +2618,6 @@ func CausalConsistencyExamples(client *mongo.Client) error { session2.AdvanceOperationTime(operationTime) // Run a find on session2, which should find all the writes from session1 cursor, err := coll.Find(ctx, bson.D{{"end", nil}}) - if err != nil { return err } @@ -2627,7 +2629,6 @@ func CausalConsistencyExamples(client *mongo.Client) error { return cursor.Err() }) - if err != nil { return err } @@ -3064,11 +3065,16 @@ func snapshotQueryRetailExample(mt *mtest.T) error { // Count the total daily sales const totalDailySalesOutput = "totalDailySales" cursor, err := db.Collection("sales").Aggregate(ctx, mongo.Pipeline{ - bson.D{{"$match", - bson.D{{"$expr", - bson.D{{"$gt", - bson.A{"$saleDate", - bson.D{{"$dateSubtract", + bson.D{{ + "$match", + bson.D{{ + "$expr", + bson.D{{ + "$gt", + bson.A{ + "$saleDate", + bson.D{{ + "$dateSubtract", bson.D{ {"startDate", "$$NOW"}, {"unit", "day"}, @@ -3105,7 +3111,7 @@ func snapshotQueryRetailExample(mt *mtest.T) error { return nil } -// SnapshotQuery examples runs examples of using sessions with Snapshot enabled. +// SnapshotQueryExamples runs examples of using sessions with Snapshot enabled. // These appear at https://www.mongodb.com/docs/manual/tutorial/long-running-queries/. func SnapshotQueryExamples(mt *mtest.T) { insertSnapshotQueryTestData(mt) From 1f76895518729b889edbe0d4e663a530a618be0e Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:30:14 -0700 Subject: [PATCH 08/16] staticcheck: fix warnings in internal/integration --- .../integration/causal_consistency_test.go | 8 ++++---- internal/integration/client_test.go | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/internal/integration/causal_consistency_test.go b/internal/integration/causal_consistency_test.go index f4817334da..8f2ecc63a7 100644 --- a/internal/integration/causal_consistency_test.go +++ b/internal/integration/causal_consistency_test.go @@ -65,10 +65,10 @@ func TestCausalConsistency_Supported(t *testing.T) { evt := mt.GetSucceededEvent() assert.Equal(mt, "find", evt.CommandName, "expected 'find' event, got '%v'", evt.CommandName) serverT, serverI := evt.Reply.Lookup("operationTime").Timestamp() - serverTs := &bson.Timestamp{serverT, serverI} - sessionTs := sess.OperationTime() - assert.NotNil(mt, sessionTs, "expected session operation time, got nil") - assert.True(mt, serverTs.Equal(*sessionTs), "expected operation time %v, got %v", serverTs, sessionTs) + serverTS := &bson.Timestamp{serverT, serverI} + sessionTS := sess.OperationTime() + assert.NotNil(mt, sessionTS, "expected session operation time, got nil") + assert.True(mt, serverTS.Equal(*sessionTS), "expected operation time %v, got %v", serverTS, sessionTS) }) mt.RunOpts("operation time sent", noClientOpts, func(mt *mtest.T) { // findOne followed by another read operation should include operationTime returned by server for the first diff --git a/internal/integration/client_test.go b/internal/integration/client_test.go index b51ea5bd10..622c740da9 100644 --- a/internal/integration/client_test.go +++ b/internal/integration/client_test.go @@ -73,8 +73,10 @@ type slowConnDialer struct { delay time.Duration } -var slowConnDialerDelay = 300 * time.Millisecond -var reducedHeartbeatInterval = 500 * time.Millisecond +var ( + slowConnDialerDelay = 300 * time.Millisecond + reducedHeartbeatInterval = 500 * time.Millisecond +) func newSlowConnDialer(delay time.Duration) *slowConnDialer { return &slowConnDialer{ @@ -228,7 +230,7 @@ func TestClient(t *testing.T) { testCases := []struct { name string filter bson.D - hasTestDb bool + hasTestDB bool minServerVersion string }{ {"empty", bson.D{}, true, ""}, @@ -247,12 +249,12 @@ func TestClient(t *testing.T) { var found bool for _, db := range res.Databases { - if db.Name == mtest.TestDb { + if db.Name == mtest.TestDB { found = true break } } - assert.Equal(mt, tc.hasTestDb, found, "expected to find test db: %v, found: %v", tc.hasTestDb, found) + assert.Equal(mt, tc.hasTestDB, found, "expected to find test db: %v, found: %v", tc.hasTestDB, found) }) } }) @@ -279,7 +281,7 @@ func TestClient(t *testing.T) { testCases := []struct { name string filter bson.D - hasTestDb bool + hasTestDB bool minServerVersion string }{ {"no filter", bson.D{}, true, ""}, @@ -298,12 +300,12 @@ func TestClient(t *testing.T) { var found bool for _, db := range dbs { - if db == mtest.TestDb { + if db == mtest.TestDB { found = true break } } - assert.Equal(mt, tc.hasTestDb, found, "expected to find test db: %v, found: %v", tc.hasTestDb, found) + assert.Equal(mt, tc.hasTestDB, found, "expected to find test db: %v, found: %v", tc.hasTestDB, found) }) } }) From 8d9c12f0e8b6ae7b27a2ae62e865f6beb5968e4b Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:30:32 -0700 Subject: [PATCH 09/16] staticcheck: fix warnings in internal/integration/mtest --- internal/integration/mtest/mongotest.go | 6 +++--- internal/integration/mtest/received_message.go | 4 ++-- internal/integration/mtest/sent_message.go | 4 ++-- internal/integration/mtest/setup.go | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/internal/integration/mtest/mongotest.go b/internal/integration/mtest/mongotest.go index 3924b58604..04cfe16696 100644 --- a/internal/integration/mtest/mongotest.go +++ b/internal/integration/mtest/mongotest.go @@ -115,7 +115,7 @@ func newT(wrapped *testing.T, opts ...*Options) *T { t.collName = t.Name() } if t.dbName == "" { - t.dbName = TestDb + t.dbName = TestDB } t.collName = sanitizeCollectionName(t.dbName, t.collName) @@ -600,7 +600,7 @@ func (t *T) createTestClient() { } // Setup command monitor - var customMonitor = clientOpts.Monitor + customMonitor := clientOpts.Monitor clientOpts.SetMonitor(&event.CommandMonitor{ Started: func(ctx context.Context, cse *event.CommandStartedEvent) { if customMonitor != nil && customMonitor.Started != nil { @@ -800,7 +800,7 @@ func verifyRunOnBlockConstraint(rob RunOnBlock) error { // TODO(GODRIVER-3486): Once auto encryption is supported by the unified test // format,this check should be removed. if rob.CSFLEEnabled() && rob.CSFLE.Options != nil { - return fmt.Errorf("Auto encryption required (GODRIVER-3486)") + return fmt.Errorf("auto encryption required (GODRIVER-3486)") } if rob.CSFLEEnabled() && !IsCSFLEEnabled() { diff --git a/internal/integration/mtest/received_message.go b/internal/integration/mtest/received_message.go index 91807a691d..926e3220b2 100644 --- a/internal/integration/mtest/received_message.go +++ b/internal/integration/mtest/received_message.go @@ -74,7 +74,7 @@ func parseOpReply(wm []byte) (*ReceivedMessage, error) { } var replyDocuments []bsoncore.Document - replyDocuments, wm, ok = wiremessage.ReadReplyDocuments(wm) + replyDocuments, _, ok = wiremessage.ReadReplyDocuments(wm) if !ok { return nil, errors.New("failed to read reply documents") } @@ -100,7 +100,7 @@ func parseReceivedOpMsg(wm []byte) (*ReceivedMessage, error) { return nil, fmt.Errorf("error verifying section type for response document: %w", err) } - response, wm, ok := wiremessage.ReadMsgSectionSingleDocument(wm) + response, _, ok := wiremessage.ReadMsgSectionSingleDocument(wm) if !ok { return nil, errors.New("failed to read response document") } diff --git a/internal/integration/mtest/sent_message.go b/internal/integration/mtest/sent_message.go index 5be6cee7e0..f2a00c49bd 100644 --- a/internal/integration/mtest/sent_message.go +++ b/internal/integration/mtest/sent_message.go @@ -64,7 +64,7 @@ func parseOpQuery(wm []byte) (*SentMessage, error) { return nil, errors.New("failed to read number to return") } - query, wm, ok := wiremessage.ReadQueryQuery(wm) + query, _, ok := wiremessage.ReadQueryQuery(wm) if !ok { return nil, errors.New("failed to read query") } @@ -163,7 +163,7 @@ func parseSentOpMsg(wm []byte) (*SentMessage, error) { } var data []byte - _, data, wm, ok = wiremessage.ReadMsgSectionRawDocumentSequence(wm) + _, data, _, ok = wiremessage.ReadMsgSectionRawDocumentSequence(wm) if !ok { return nil, errors.New("failed to read document sequence") } diff --git a/internal/integration/mtest/setup.go b/internal/integration/mtest/setup.go index d4f181f8c7..fb566bcc0a 100644 --- a/internal/integration/mtest/setup.go +++ b/internal/integration/mtest/setup.go @@ -29,8 +29,8 @@ import ( ) const ( - // TestDb specifies the name of default test database. - TestDb = "test" + // TestDB specifies the name of default test database. + TestDB = "test" ) // testContext holds the global context for the integration tests. The testContext members should only be initialized @@ -236,7 +236,7 @@ func Setup(setupOpts ...*SetupOptions) error { func Teardown() error { // Dropping the test database causes an error against Atlas Data Lake. if !testContext.dataLake { - if err := testContext.client.Database(TestDb).Drop(context.Background()); err != nil { + if err := testContext.client.Database(TestDB).Drop(context.Background()); err != nil { return fmt.Errorf("error dropping test database: %w", err) } } @@ -251,7 +251,7 @@ func Teardown() error { func getServerVersion() (string, error) { var serverStatus bson.Raw - err := testContext.client.Database(TestDb).RunCommand( + err := testContext.client.Database(TestDB).RunCommand( context.Background(), bson.D{{"buildInfo", 1}}, ).Decode(&serverStatus) From 5105861ffe36a47bfd0e5e48d00029854533d06a Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:30:59 -0700 Subject: [PATCH 10/16] staticcheck: fix warnings in internal/integration/unified --- internal/integration/unified/collection_data.go | 2 +- .../integration/unified/collection_operation_execution.go | 4 ++-- internal/integration/unified/testrunner_operation.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/integration/unified/collection_data.go b/internal/integration/unified/collection_data.go index 02ceb3f147..d9480aa28d 100644 --- a/internal/integration/unified/collection_data.go +++ b/internal/integration/unified/collection_data.go @@ -88,7 +88,7 @@ func (c *collectionData) verifyContents(ctx context.Context) error { cursor, err := coll.Find(ctx, bson.D{}, options.Find().SetSort(bson.M{"_id": 1})) if err != nil { - return fmt.Errorf("Find error: %w", err) + return fmt.Errorf("find error: %w", err) } defer cursor.Close(ctx) diff --git a/internal/integration/unified/collection_operation_execution.go b/internal/integration/unified/collection_operation_execution.go index 1e03f0eaed..62e9081c08 100644 --- a/internal/integration/unified/collection_operation_execution.go +++ b/internal/integration/unified/collection_operation_execution.go @@ -1581,8 +1581,8 @@ func createFindCursor(ctx context.Context, operation *operation) (*cursorResult, opts.SetCursorType(options.NonTailable) } case "maxAwaitTimeMS": - maxAwaitTimeMS := time.Duration(val.Int32()) * time.Millisecond - opts.SetMaxAwaitTime(maxAwaitTimeMS) + maxAwaitTime := time.Duration(val.Int32()) * time.Millisecond + opts.SetMaxAwaitTime(maxAwaitTime) case "rawData": err = xoptions.SetInternalFindOptions(opts, key, val.Boolean()) if err != nil { diff --git a/internal/integration/unified/testrunner_operation.go b/internal/integration/unified/testrunner_operation.go index bb1f9ecac6..71bc76d6eb 100644 --- a/internal/integration/unified/testrunner_operation.go +++ b/internal/integration/unified/testrunner_operation.go @@ -235,12 +235,12 @@ func executeTestRunnerOperation(ctx context.Context, op *operation, loopDone <-c } return nil case "wait": - waitMS, err := convertValueToMilliseconds(args.Lookup("ms")) + waitDur, err := convertValueToMilliseconds(args.Lookup("ms")) if err != nil { return err } - time.Sleep(waitMS) + time.Sleep(waitDur) return nil case "runOnThread": From 80668468a332c5bff81b6e50f74275321dd40166 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:31:04 -0700 Subject: [PATCH 11/16] staticcheck: fix warnings in mongo --- mongo/collection_test.go | 8 ++++---- mongo/database.go | 16 +++++++--------- mongo/database_test.go | 10 +++++----- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/mongo/collection_test.go b/mongo/collection_test.go index e20d97dd61..5779fca1b9 100644 --- a/mongo/collection_test.go +++ b/mongo/collection_test.go @@ -25,11 +25,11 @@ import ( ) const ( - testDbName = "unitTestDb" + testDBName = "unitTestDB" ) func setupColl(name string, opts ...options.Lister[options.CollectionOptions]) *Collection { - db := setupDb(testDbName) + db := setupDB(testDBName) return db.Collection(name, opts...) } @@ -72,7 +72,7 @@ func TestCollection(t *testing.T) { rcLocal := readconcern.Local() wc1 := &writeconcern.WriteConcern{W: 10} - db := setupDb("foo", options.Database().SetReadPreference(rpPrimary).SetReadConcern(rcLocal)) + db := setupDB("foo", options.Database().SetReadPreference(rpPrimary).SetReadConcern(rcLocal)) coll := db.Collection("bar", options.Collection().SetWriteConcern(wc1)) expected := &Collection{ readPreference: rpPrimary, @@ -143,7 +143,7 @@ func TestCollection(t *testing.T) { t.Run("database accessor", func(t *testing.T) { coll := setupColl("bar") dbName := coll.Database().Name() - assert.Equal(t, testDbName, dbName, "expected db name %v, got %v", testDbName, dbName) + assert.Equal(t, testDBName, dbName, "expected db name %v, got %v", testDBName, dbName) }) t.Run("nil document error", func(t *testing.T) { coll := setupColl("foo") diff --git a/mongo/database.go b/mongo/database.go index 7064929ed6..6531caf86a 100644 --- a/mongo/database.go +++ b/mongo/database.go @@ -29,9 +29,7 @@ import ( "go.mongodb.org/mongo-driver/v2/x/mongo/driver/session" ) -var ( - defaultRunCmdOpts = []options.Lister[options.RunCmdOptions]{options.RunCmd().SetReadPreference(readpref.Primary())} -) +var defaultRunCmdOpts = []options.Lister[options.RunCmdOptions]{options.RunCmd().SetReadPreference(readpref.Primary())} // Database is a handle to a MongoDB database. It is safe for concurrent use by multiple goroutines. type Database struct { @@ -576,8 +574,8 @@ func (db *Database) ListCollectionNames( // The opts parameter can be used to specify options for change stream creation (see the options.ChangeStreamOptions // documentation). func (db *Database) Watch(ctx context.Context, pipeline any, - opts ...options.Lister[options.ChangeStreamOptions]) (*ChangeStream, error) { - + opts ...options.Lister[options.ChangeStreamOptions], +) (*ChangeStream, error) { csConfig := changeStreamConfig{ readConcern: db.readConcern, readPreference: db.readPreference, @@ -700,7 +698,7 @@ func (db *Database) createCollectionWithEncryptedFields( defer conn.Close() wireVersionRange := conn.Description().WireVersion if wireVersionRange.Max < QEv2WireVersion { - return fmt.Errorf("Driver support of Queryable Encryption is incompatible with server. Upgrade server to use Queryable Encryption. Got maxWireVersion %v but need maxWireVersion >= %v", wireVersionRange.Max, QEv2WireVersion) + return fmt.Errorf("driver support of Queryable Encryption is incompatible with server. Upgrade server to use Queryable Encryption. Got maxWireVersion %v but need maxWireVersion >= %v", wireVersionRange.Max, QEv2WireVersion) } } @@ -897,8 +895,8 @@ func (db *Database) createCollectionOperation( // See https://www.mongodb.com/docs/manual/core/views/ for more information // about views. func (db *Database) CreateView(ctx context.Context, viewName, viewOn string, pipeline any, - opts ...options.Lister[options.CreateViewOptions]) error { - + opts ...options.Lister[options.CreateViewOptions], +) error { pipelineArray, _, err := marshalAggregatePipeline(pipeline, db.bsonOpts, db.registry) if err != nil { return err @@ -979,7 +977,7 @@ func (db *Database) GridFSBucket(opts ...options.Lister[options.BucketOptions]) b.rp = bo.ReadPreference } - var collOpts = options.Collection().SetWriteConcern(b.wc).SetReadConcern(b.rc).SetReadPreference(b.rp) + collOpts := options.Collection().SetWriteConcern(b.wc).SetReadConcern(b.rc).SetReadPreference(b.rp) b.chunksColl = db.Collection(b.name+".chunks", collOpts) b.filesColl = db.Collection(b.name+".files", collOpts) diff --git a/mongo/database_test.go b/mongo/database_test.go index bce78d197e..da5ab7225f 100644 --- a/mongo/database_test.go +++ b/mongo/database_test.go @@ -22,7 +22,7 @@ import ( "go.mongodb.org/mongo-driver/v2/x/mongo/driver/topology" ) -func setupDb(name string, opts ...options.Lister[options.DatabaseOptions]) *Database { +func setupDB(name string, opts ...options.Lister[options.DatabaseOptions]) *Database { client := setupClient() return client.Database(name, opts...) } @@ -42,7 +42,7 @@ func compareDbs(t *testing.T, expected, got *Database) { func TestDatabase(t *testing.T) { t.Run("initialize", func(t *testing.T) { name := "foo" - db := setupDb(name) + db := setupDB(name) assert.Equal(t, name, db.Name(), "expected db name %v, got %v", name, db.Name()) assert.NotNil(t, db.Client(), "expected valid client, got nil") }) @@ -64,7 +64,7 @@ func TestDatabase(t *testing.T) { writeConcern: wc2, registry: reg, } - got := setupDb("foo", opts) + got := setupDB("foo", opts) compareDbs(t, expected, got) }) t.Run("inherit", func(t *testing.T) { @@ -85,7 +85,7 @@ func TestDatabase(t *testing.T) { }) }) t.Run("replaceErrors for disconnected topology", func(t *testing.T) { - db := setupDb("foo") + db := setupDB("foo") topo, ok := db.client.deployment.(*topology.Topology) require.True(t, ok, "client deployment is not a topology") @@ -138,7 +138,7 @@ func TestDatabase(t *testing.T) { }) }) t.Run("nil document error", func(t *testing.T) { - db := setupDb("foo") + db := setupDB("foo") err := db.RunCommand(bgCtx, nil).Err() assert.True(t, errors.Is(err, ErrNilDocument), "expected error %v, got %v", ErrNilDocument, err) From a0d646ae6c2153d7129c08ab97e339afe2cc8ab0 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:31:07 -0700 Subject: [PATCH 12/16] staticcheck: fix warnings in x/mongo/driver/auth --- x/mongo/driver/auth/aws_conv.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/mongo/driver/auth/aws_conv.go b/x/mongo/driver/auth/aws_conv.go index f6bb370c4d..06dd04376c 100644 --- a/x/mongo/driver/auth/aws_conv.go +++ b/x/mongo/driver/auth/aws_conv.go @@ -68,7 +68,7 @@ func (ac *awsConversation) Step(challenge []byte) (response []byte, err error) { ac.state = clientDone ac.valid = true default: - response, err = nil, errors.New("Conversation already completed") + response, err = nil, errors.New("conversation already completed") } return } From b9c10fa22b91dbdecd8ced87651c5402e24e08bc Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:31:13 -0700 Subject: [PATCH 13/16] staticcheck: fix warnings in x/mongo/driver/dns --- .../initial_dns_seedlist_discovery_prose_test.go | 6 +++--- x/mongo/driver/dns/dns.go | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/x/mongo/driver/connstring/initial_dns_seedlist_discovery_prose_test.go b/x/mongo/driver/connstring/initial_dns_seedlist_discovery_prose_test.go index ecd9eccc17..894e4d484d 100644 --- a/x/mongo/driver/connstring/initial_dns_seedlist_discovery_prose_test.go +++ b/x/mongo/driver/connstring/initial_dns_seedlist_discovery_prose_test.go @@ -69,7 +69,7 @@ func TestInitialDNSSeedlistDiscoveryProse(t *testing.T) { t.Parallel() _, err := newTestParser(c.record).parse(c.uri) - assert.ErrorContains(t, err, "Domain suffix from SRV record not matched input domain") + assert.ErrorContains(t, err, "domain suffix from SRV record not matched input domain") }) } }) @@ -91,7 +91,7 @@ func TestInitialDNSSeedlistDiscoveryProse(t *testing.T) { _, err := newTestParser(c.record).parse(c.uri) expected := fmt.Sprintf( - "Server record (%d levels) should have more domain levels than parent URI (%d levels)", + "server record (%d levels) should have more domain levels than parent URI (%d levels)", c.labels, c.labels, ) assert.ErrorContains(t, err, expected) @@ -115,7 +115,7 @@ func TestInitialDNSSeedlistDiscoveryProse(t *testing.T) { t.Parallel() _, err := newTestParser(c.record).parse(c.uri) - assert.ErrorContains(t, err, "Domain suffix from SRV record not matched input domain") + assert.ErrorContains(t, err, "domain suffix from SRV record not matched input domain") }) } }) diff --git a/x/mongo/driver/dns/dns.go b/x/mongo/driver/dns/dns.go index 2d599db6de..1252dc5f87 100644 --- a/x/mongo/driver/dns/dns.go +++ b/x/mongo/driver/dns/dns.go @@ -114,10 +114,10 @@ func validateSRVResult(recordFromSRV, inputHostName string) error { separatedInputDomain := strings.Split(strings.ToLower(inputHostName), ".") separatedRecord := strings.Split(strings.ToLower(recordFromSRV), ".") if l := len(separatedInputDomain); l < 3 && len(separatedRecord) <= l { - return fmt.Errorf("Server record (%d levels) should have more domain levels than parent URI (%d levels)", l, len(separatedRecord)) + return fmt.Errorf("server record (%d levels) should have more domain levels than parent URI (%d levels)", l, len(separatedRecord)) } if len(separatedRecord) < len(separatedInputDomain) { - return errors.New("Domain suffix from SRV record not matched input domain") + return errors.New("domain suffix from SRV record not matched input domain") } inputDomainSuffix := separatedInputDomain @@ -129,7 +129,7 @@ func validateSRVResult(recordFromSRV, inputHostName string) error { recordDomainSuffix := separatedRecord[domainSuffixOffset:] for ix, label := range inputDomainSuffix { if label != recordDomainSuffix[ix] { - return errors.New("Domain suffix from SRV record not matched input domain") + return errors.New("domain suffix from SRV record not matched input domain") } } return nil @@ -145,11 +145,11 @@ func validateTXTResult(paramsFromTXT []string) error { for _, param := range paramsFromTXT { kv := strings.SplitN(param, "=", 2) if len(kv) != 2 { - return errors.New("Invalid TXT record") + return errors.New("invalid TXT record") } key := strings.ToLower(kv[0]) if _, ok := allowedTXTOptions[key]; !ok { - return fmt.Errorf("Cannot specify option '%s' in TXT record", kv[0]) + return fmt.Errorf("cannot specify option '%s' in TXT record", kv[0]) } } return nil From 7ed6928b942fed34e33ef21e7aa3bb7cb2c447eb Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:31:17 -0700 Subject: [PATCH 14/16] staticcheck: fix warnings in x/mongo/driver/drivertest --- x/mongo/driver/drivertest/channel_conn.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x/mongo/driver/drivertest/channel_conn.go b/x/mongo/driver/drivertest/channel_conn.go index 4e1f2c78c5..1803741d02 100644 --- a/x/mongo/driver/drivertest/channel_conn.go +++ b/x/mongo/driver/drivertest/channel_conn.go @@ -36,7 +36,7 @@ func (c *ChannelConn) OIDCTokenGenID() uint64 { // (which is always 0) func (c *ChannelConn) SetOIDCTokenGenID(uint64) {} -// WriteWireMessage implements the driver.Connection interface. +// Write implements the driver.Connection interface. func (c *ChannelConn) Write(ctx context.Context, wm []byte) error { // Copy wm in case it came from a buffer pool. b := make([]byte, len(wm)) @@ -51,7 +51,7 @@ func (c *ChannelConn) Write(ctx context.Context, wm []byte) error { return c.WriteErr } -// ReadWireMessage implements the driver.Connection interface. +// Read implements the driver.Connection interface. func (c *ChannelConn) Read(ctx context.Context) ([]byte, error) { var wm []byte var err error @@ -133,7 +133,7 @@ func GetCommandFromQueryWireMessage(wm []byte) (bsoncore.Document, error) { } var query bsoncore.Document - query, wm, ok = wiremessage.ReadQueryQuery(wm) + query, _, ok = wiremessage.ReadQueryQuery(wm) if !ok { return nil, errors.New("could not read query") } @@ -157,7 +157,7 @@ func GetCommandFromMsgWireMessage(wm []byte) (bsoncore.Document, error) { return nil, errors.New("could not read section type") } - cmdDoc, wm, ok := wiremessage.ReadMsgSectionSingleDocument(wm) + cmdDoc, _, ok := wiremessage.ReadMsgSectionSingleDocument(wm) if !ok { return nil, errors.New("could not read command document") } From f6d223dacc264cbcde8909be0f4827177cdbae95 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:31:21 -0700 Subject: [PATCH 15/16] staticcheck: fix warnings in x/mongo/driver --- x/mongo/driver/operation_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/x/mongo/driver/operation_test.go b/x/mongo/driver/operation_test.go index 8fe1dafd03..302a506616 100644 --- a/x/mongo/driver/operation_test.go +++ b/x/mongo/driver/operation_test.go @@ -386,7 +386,8 @@ func TestOperation(t *testing.T) { rpWithTags := bsoncore.BuildDocumentFromElements(nil, bsoncore.AppendStringElement(nil, "mode", "secondaryPreferred"), bsoncore.BuildArrayElement(nil, "tags", - bsoncore.Value{Type: bsoncore.TypeEmbeddedDocument, + bsoncore.Value{ + Type: bsoncore.TypeEmbeddedDocument, Data: bsoncore.BuildDocumentFromElements(nil, bsoncore.AppendStringElement(nil, "disk", "ssd"), bsoncore.AppendStringElement(nil, "use", "reporting"), @@ -408,7 +409,8 @@ func TestOperation(t *testing.T) { rpWithAllOptions := bsoncore.BuildDocumentFromElements(nil, bsoncore.AppendStringElement(nil, "mode", "secondaryPreferred"), bsoncore.BuildArrayElement(nil, "tags", - bsoncore.Value{Type: bsoncore.TypeEmbeddedDocument, + bsoncore.Value{ + Type: bsoncore.TypeEmbeddedDocument, Data: bsoncore.BuildDocumentFromElements(nil, bsoncore.AppendStringElement(nil, "disk", "ssd"), bsoncore.AppendStringElement(nil, "use", "reporting"), @@ -695,7 +697,7 @@ func assertExhaustAllowedSet(t *testing.T, wm []byte, expected bool) { if !ok { t.Fatal("could not read wm header") } - flags, wm, ok := wiremessage.ReadMsgFlags(wm) + flags, _, ok := wiremessage.ReadMsgFlags(wm) if !ok { t.Fatal("could not read wm flags") } From 423b421a5d5edb247665929c2630c29c54dd0dd0 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Wed, 26 Nov 2025 15:31:26 -0700 Subject: [PATCH 16/16] staticcheck: fix warnings in x/mongo/driver/topology --- x/mongo/driver/topology/CMAP_spec_test.go | 1 + x/mongo/driver/topology/connection.go | 6 +++--- x/mongo/driver/topology/server_test.go | 4 ++-- x/mongo/driver/topology/topology.go | 6 ++---- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/x/mongo/driver/topology/CMAP_spec_test.go b/x/mongo/driver/topology/CMAP_spec_test.go index a0579ff552..fd4b018359 100644 --- a/x/mongo/driver/topology/CMAP_spec_test.go +++ b/x/mongo/driver/topology/CMAP_spec_test.go @@ -428,6 +428,7 @@ func runOperationInThread(t *testing.T, operation map[string]any, testInfo *test } for { + // nolint:staticcheck // QF1006: staticcheck solution onflicts with revive if atomic.LoadInt32(&thread.JobsCompleted) == atomic.LoadInt32(&thread.JobsAssigned) { break } diff --git a/x/mongo/driver/topology/connection.go b/x/mongo/driver/topology/connection.go index 65ec4e3c6b..d857c945cf 100644 --- a/x/mongo/driver/topology/connection.go +++ b/x/mongo/driver/topology/connection.go @@ -654,7 +654,7 @@ var ( _ driver.Expirable = (*Connection)(nil) ) -// WriteWireMessage handles writing a wire message to the underlying connection. +// Write handles writing a wire message to the underlying connection. func (c *Connection) Write(ctx context.Context, wm []byte) error { c.mu.RLock() defer c.mu.RUnlock() @@ -664,8 +664,8 @@ func (c *Connection) Write(ctx context.Context, wm []byte) error { return c.connection.writeWireMessage(ctx, wm) } -// ReadWireMessage handles reading a wire message from the underlying connection. The dst parameter -// will be overwritten with the new wire message. +// Read handles reading a wire message from the underlying connection. The dst +// parameter will be overwritten with the new wire message. func (c *Connection) Read(ctx context.Context) ([]byte, error) { c.mu.RLock() defer c.mu.RUnlock() diff --git a/x/mongo/driver/topology/server_test.go b/x/mongo/driver/topology/server_test.go index 7626ff1920..c6a68189f9 100644 --- a/x/mongo/driver/topology/server_test.go +++ b/x/mongo/driver/topology/server_test.go @@ -365,7 +365,7 @@ func TestServerConnectionTimeout(t *testing.T) { } func TestServer(t *testing.T) { - var serverTestTable = []struct { + serverTestTable := []struct { name string connectionError bool networkError bool @@ -1280,7 +1280,7 @@ func includesClientMetadata(t *testing.T, wm []byte) bool { t.Fatal("could not read numberToReturn") } var query bsoncore.Document - query, wm, ok = wiremessage.ReadQueryQuery(wm) + query, _, ok = wiremessage.ReadQueryQuery(wm) if !ok { t.Fatal("could not read query") } diff --git a/x/mongo/driver/topology/topology.go b/x/mongo/driver/topology/topology.go index a4ce875837..5504595a66 100644 --- a/x/mongo/driver/topology/topology.go +++ b/x/mongo/driver/topology/topology.go @@ -549,10 +549,10 @@ func (t *Topology) SelectServer(ctx context.Context, ss description.ServerSelect // try again if there are no servers available if mustLogServerSelection(t, logger.LevelInfo) { elapsed := time.Since(startTime) - remainingTimeMS := t.cfg.ServerSelectionTimeout - elapsed + remainingTime := t.cfg.ServerSelectionTimeout - elapsed logServerSelection(ctx, t, logger.LevelInfo, logger.ServerSelectionWaiting, ss, - logger.KeyRemainingTimeMS, remainingTimeMS.Milliseconds()) + logger.KeyRemainingTimeMS, remainingTime.Milliseconds()) } continue @@ -687,7 +687,6 @@ func (t *Topology) selectServerFromSubscription( subscriptionCh <-chan description.Topology, srvSelector description.ServerSelector, ) ([]description.Server, error) { - current := t.Description() for { select { @@ -713,7 +712,6 @@ func (t *Topology) selectServerFromDescription( desc description.Topology, srvSelector description.ServerSelector, ) ([]description.Server, error) { - // Unlike selectServerFromSubscription, this code path does not check ctx.Done or selectionState.timeoutChan because // selecting a server from a description is not a blocking operation.