Skip to content

Commit c0763b3

Browse files
Merge branch 'master' into GODRIVER-3086
2 parents 1abe21b + 50cf0c2 commit c0763b3

File tree

265 files changed

+19458
-3781
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

265 files changed

+19458
-3781
lines changed

.evergreen/config.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,14 @@ functions:
388388
TASKFILE_TARGET: test-short
389389
args: [*task-runner, run-docker]
390390

391+
run-goleak-test:
392+
- command: subprocess.exec
393+
type: test
394+
params:
395+
binary: "bash"
396+
include_expansions_in_env: ["MONGODB_URI"]
397+
args: [*task-runner, test-goleak]
398+
391399
run-ocsp-server:
392400
- command: subprocess.exec
393401
params:
@@ -1100,6 +1108,26 @@ tasks:
11001108
- func: bootstrap-mongo-orchestration
11011109
- func: run-docker-test
11021110

1111+
- name: test-goroutine-leaks-replicaset
1112+
tags: ["goleak"]
1113+
commands:
1114+
- func: bootstrap-mongo-orchestration
1115+
vars:
1116+
TOPOLOGY: "replica_set"
1117+
AUTH: "noauth"
1118+
SSL: "nossl"
1119+
- func: run-goleak-test
1120+
1121+
- name: test-goroutine-leaks-sharded
1122+
tags: ["goleak"]
1123+
commands:
1124+
- func: bootstrap-mongo-orchestration
1125+
vars:
1126+
TOPOLOGY: "sharded_cluster"
1127+
AUTH: "noauth"
1128+
SSL: "nossl"
1129+
- func: run-goleak-test
1130+
11031131
- name: test-load-balancer-noauth-nossl
11041132
tags: ["load-balancer"]
11051133
commands:
@@ -2056,6 +2084,16 @@ buildvariants:
20562084
tasks:
20572085
- name: "test-docker-runner"
20582086

2087+
- name: goroutine-leaks-test
2088+
tags: ["pullrequest"]
2089+
display_name: "Goroutine Leaks Test"
2090+
run_on:
2091+
- ubuntu2204-large
2092+
expansions:
2093+
GO_DIST: "/opt/golang/go1.22"
2094+
tasks:
2095+
- name: ".goleak"
2096+
20592097
- matrix_name: "tests-rhel-36-with-zlib-support"
20602098
tags: ["pullrequest"]
20612099
matrix_spec: { version: ["3.6"], os-ssl-32: ["rhel87-64"] }

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Dockerfile for Go Driver local development.
22

33
# Build libmongocrypt in a separate build stage.
4-
FROM ubuntu:20.04 as libmongocrypt
4+
FROM artifactory.corp.mongodb.com/dockerhub/ubuntu:20.04 as libmongocrypt
55

66
RUN apt-get -qq update && \
77
apt-get -qqy install --no-install-recommends \
@@ -17,7 +17,7 @@ RUN cd /root && bash ./install-libmongocrypt.sh
1717

1818

1919
# Copy in the files from the libmongocrypt build stage.
20-
FROM ubuntu:20.04
20+
FROM artifactory.corp.mongodb.com/dockerhub/ubuntu:20.04
2121

2222
# Install common deps.
2323
RUN export DEBIAN_FRONTEND=noninteractive && \

Taskfile.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ tasks:
105105

106106
test-gcpkms: bash etc/run-gcpkms-test.sh
107107

108+
test-goleak: bash etc/run-goleak-test.sh
109+
108110
### Local FaaS tasks. ###
109111
build-faas-awslambda:
110112
requires:

bson/decoder.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func (d *Decoder) SetRegistry(r *Registry) {
8787
d.dc.Registry = r
8888
}
8989

90-
// DefaultDocumentM causes the Decoder to always unmarshal documents into the primitive.M type. This
90+
// DefaultDocumentM causes the Decoder to always unmarshal documents into the bson.M type. This
9191
// behavior is restricted to data typed as "interface{}" or "map[string]interface{}".
9292
func (d *Decoder) DefaultDocumentM() {
9393
d.dc.defaultDocumentType = reflect.TypeOf(M{})
@@ -101,7 +101,7 @@ func (d *Decoder) AllowTruncatingDoubles() {
101101
}
102102

103103
// BinaryAsSlice causes the Decoder to unmarshal BSON binary field values that are the "Generic" or
104-
// "Old" BSON binary subtype as a Go byte slice instead of a primitive.Binary.
104+
// "Old" BSON binary subtype as a Go byte slice instead of a bson.Binary.
105105
func (d *Decoder) BinaryAsSlice() {
106106
d.dc.binaryAsSlice = true
107107
}

bson/decoder_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,8 @@ func TestDecoderConfiguration(t *testing.T) {
647647

648648
var got objectIDTest
649649
err := dec.Decode(&got)
650-
assert.EqualError(t, err, "error decoding key id: decoding an object ID to a non-hexadecimal string representation is not supported")
650+
const want = "error decoding key id: decoding an object ID into a string is not supported by default (set Decoder.ObjectIDAsHexString to enable decoding as a hexadecimal string)"
651+
assert.EqualError(t, err, want)
651652
})
652653
t.Run("DefaultDocumentM top-level", func(t *testing.T) {
653654
t.Parallel()

bson/default_value_decoders.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,12 @@ func valueUnmarshalerDecodeValue(_ DecodeContext, vr ValueReader, val reflect.Va
11661166
return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val}
11671167
}
11681168

1169+
if vr.Type() == TypeNull {
1170+
val.Set(reflect.Zero(val.Type()))
1171+
1172+
return vr.ReadNull()
1173+
}
1174+
11691175
if val.Kind() == reflect.Ptr && val.IsNil() {
11701176
if !val.CanSet() {
11711177
return ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val}

bson/doc.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,20 @@
4747
// 5. BSON boolean unmarshals to a bool.
4848
// 6. BSON embedded document unmarshals to the parent type (i.e. D for a D, M for an M).
4949
// 7. BSON array unmarshals to a bson.A.
50-
// 8. BSON ObjectId unmarshals to a primitive.ObjectID.
51-
// 9. BSON datetime unmarshals to a primitive.DateTime.
52-
// 10. BSON binary unmarshals to a primitive.Binary.
53-
// 11. BSON regular expression unmarshals to a primitive.Regex.
54-
// 12. BSON JavaScript unmarshals to a primitive.JavaScript.
55-
// 13. BSON code with scope unmarshals to a primitive.CodeWithScope.
56-
// 14. BSON timestamp unmarshals to an primitive.Timestamp.
57-
// 15. BSON 128-bit decimal unmarshals to an primitive.Decimal128.
58-
// 16. BSON min key unmarshals to an primitive.MinKey.
59-
// 17. BSON max key unmarshals to an primitive.MaxKey.
60-
// 18. BSON undefined unmarshals to a primitive.Undefined.
50+
// 8. BSON ObjectId unmarshals to a bson.ObjectID.
51+
// 9. BSON datetime unmarshals to a bson.DateTime.
52+
// 10. BSON binary unmarshals to a bson.Binary.
53+
// 11. BSON regular expression unmarshals to a bson.Regex.
54+
// 12. BSON JavaScript unmarshals to a bson.JavaScript.
55+
// 13. BSON code with scope unmarshals to a bson.CodeWithScope.
56+
// 14. BSON timestamp unmarshals to an bson.Timestamp.
57+
// 15. BSON 128-bit decimal unmarshals to an bson.Decimal128.
58+
// 16. BSON min key unmarshals to an bson.MinKey.
59+
// 17. BSON max key unmarshals to an bson.MaxKey.
60+
// 18. BSON undefined unmarshals to a bson.Undefined.
6161
// 19. BSON null unmarshals to nil.
62-
// 20. BSON DBPointer unmarshals to a primitive.DBPointer.
63-
// 21. BSON symbol unmarshals to a primitive.Symbol.
62+
// 20. BSON DBPointer unmarshals to a bson.DBPointer.
63+
// 21. BSON symbol unmarshals to a bson.Symbol.
6464
//
6565
// The above mappings also apply when marshaling a D or M to BSON. Some other useful marshaling mappings are:
6666
//

bson/marshal.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,10 @@ func MarshalValue(val interface{}) (Type, []byte, error) {
133133
return 0, nil, err
134134
}
135135
typ := sw.Next(2)
136-
return Type(typ[0]), sw.Bytes(), nil
136+
clone := append([]byte{}, sw.Bytes()...) // Don't hand out a shared reference to byte buffer bytes
137+
// and fully copy the data. The byte buffer is (potentially) reused
138+
// and handing out only a reference to the bytes may lead to race-conditions with the buffer.
139+
return Type(typ[0]), clone, nil
137140
}
138141

139142
// MarshalExtJSON returns the extended JSON encoding of val.

bson/marshal_value_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"testing"
1212

1313
"go.mongodb.org/mongo-driver/v2/internal/assert"
14+
"go.mongodb.org/mongo-driver/v2/internal/require"
1415
)
1516

1617
func TestMarshalValue(t *testing.T) {
@@ -33,6 +34,25 @@ func TestMarshalValue(t *testing.T) {
3334
})
3435
}
3536
})
37+
38+
t.Run("returns distinct address ranges", func(t *testing.T) {
39+
// Call MarshalValue in a loop with the same large value (make sure to
40+
// trigger the buffer pooling, which currently doesn't happen for very
41+
// small values). Compare the previous and current BSON byte slices and
42+
// make sure they always have distinct memory ranges.
43+
//
44+
// Don't run this test in parallel to maximize the chance that we get
45+
// the same pooled buffer for most/all calls.
46+
largeVal := strings.Repeat("1234567890", 100_000)
47+
var prev []byte
48+
for i := 0; i < 20; i++ {
49+
_, b, err := MarshalValue(largeVal)
50+
require.NoError(t, err)
51+
52+
assert.DifferentAddressRanges(t, b, prev)
53+
prev = b
54+
}
55+
})
3656
}
3757

3858
func compareMarshalValueResults(t *testing.T, tc marshalValueTestCase, gotType Type, gotBytes []byte) {

bson/primitive.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func (d DateTime) MarshalJSON() ([]byte, error) {
6060
return d.Time().UTC().MarshalJSON()
6161
}
6262

63-
// UnmarshalJSON creates a primitive.DateTime from a JSON string.
63+
// UnmarshalJSON creates a bson.DateTime from a JSON string.
6464
func (d *DateTime) UnmarshalJSON(data []byte) error {
6565
// Ignore "null" so that we can distinguish between a "null" value and
6666
// valid value that is the zero time (as reported by time.Time.IsZero).

0 commit comments

Comments
 (0)