mongo 2.16.3 → 2.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +1 -1
- data/lib/mongo/auth/aws/request.rb +0 -1
- data/lib/mongo/client.rb +4 -0
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +26 -14
- data/lib/mongo/collection/view/aggregation.rb +62 -17
- data/lib/mongo/collection/view/builder/aggregation.rb +11 -13
- data/lib/mongo/collection/view/builder/map_reduce.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +7 -3
- data/lib/mongo/collection/view/iterable.rb +2 -3
- data/lib/mongo/collection/view/map_reduce.rb +2 -0
- data/lib/mongo/collection/view/readable.rb +24 -1
- data/lib/mongo/collection/view/writable.rb +23 -0
- data/lib/mongo/collection.rb +21 -1
- data/lib/mongo/cursor/kill_spec.rb +19 -2
- data/lib/mongo/cursor.rb +5 -5
- data/lib/mongo/database/view.rb +4 -2
- data/lib/mongo/database.rb +6 -6
- data/lib/mongo/error/snapshot_session_invalid_server_version.rb +31 -0
- data/lib/mongo/error/snapshot_session_transaction_prohibited.rb +30 -0
- data/lib/mongo/error.rb +2 -0
- data/lib/mongo/operation/delete/op_msg.rb +2 -1
- data/lib/mongo/operation/find/builder/command.rb +1 -0
- data/lib/mongo/operation/result.rb +6 -0
- data/lib/mongo/operation/shared/executable.rb +4 -0
- data/lib/mongo/operation/shared/sessions_supported.rb +18 -2
- data/lib/mongo/operation/update/op_msg.rb +2 -1
- data/lib/mongo/server/description/features.rb +3 -1
- data/lib/mongo/server_selector/base.rb +26 -4
- data/lib/mongo/session.rb +19 -0
- data/lib/mongo/socket/ocsp_cache.rb +2 -3
- data/lib/mongo/socket.rb +1 -5
- data/lib/mongo/utils.rb +0 -6
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +1 -1
- data/spec/integration/read_preference_spec.rb +16 -12
- data/spec/mongo/cluster/cursor_reaper_spec.rb +22 -15
- data/spec/mongo/collection/view/aggregation_spec.rb +71 -95
- data/spec/mongo/collection/view/change_stream_spec.rb +1 -1
- data/spec/mongo/collection/view/map_reduce_spec.rb +14 -1
- data/spec/mongo/cursor_spec.rb +3 -2
- data/spec/mongo/operation/read_preference_op_msg_spec.rb +24 -1
- data/spec/mongo/server_selector_spec.rb +136 -15
- data/spec/mongo/socket/ssl_spec.rb +26 -58
- data/spec/mongo/utils_spec.rb +0 -14
- data/spec/runners/crud/verifier.rb +1 -2
- data/spec/runners/unified/assertions.rb +3 -1
- data/spec/runners/unified/crud_operations.rb +77 -23
- data/spec/runners/unified/ddl_operations.rb +29 -1
- data/spec/runners/unified/entity_map.rb +3 -3
- data/spec/runners/unified/support_operations.rb +6 -1
- data/spec/runners/unified/test.rb +15 -3
- data/spec/spec_tests/data/crud_unified/aggregate-let.yml +138 -0
- data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +155 -0
- data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +151 -0
- data/spec/spec_tests/data/crud_unified/deleteMany-let.yml +91 -0
- data/spec/spec_tests/data/crud_unified/deleteOne-let.yml +89 -0
- data/spec/spec_tests/data/crud_unified/find-let.yml +71 -0
- data/spec/spec_tests/data/crud_unified/findOneAndDelete-let.yml +88 -0
- data/spec/spec_tests/data/crud_unified/findOneAndReplace-let.yml +94 -0
- data/spec/spec_tests/data/crud_unified/findOneAndUpdate-let.yml +96 -0
- data/spec/spec_tests/data/crud_unified/updateMany-let.yml +103 -0
- data/spec/spec_tests/data/crud_unified/updateOne-let.yml +98 -0
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Secondary.yml +4 -4
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml +4 -4
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest_tags.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml +5 -5
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags.yml +5 -5
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/Sharded/SmallMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/Single/SmallMaxStaleness.yml +1 -1
- data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -1
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-client-error.yml +69 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-server-error.yml +102 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-unsupported-ops.yml +258 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions.yml +482 -0
- data/spec/spec_tests/sessions_unified_spec.rb +13 -0
- data.tar.gz.sig +0 -0
- metadata +36 -2
- metadata.gz.sig +0 -0
@@ -8,7 +8,9 @@ module Unified
|
|
8
8
|
def find(op)
|
9
9
|
collection = entities.get(:collection, op.use!('object'))
|
10
10
|
use_arguments(op) do |args|
|
11
|
-
opts = {
|
11
|
+
opts = {
|
12
|
+
let: args.use('let'),
|
13
|
+
}
|
12
14
|
if session = args.use('session')
|
13
15
|
opts[:session] = entities.get(:session, session)
|
14
16
|
end
|
@@ -29,7 +31,11 @@ module Unified
|
|
29
31
|
def count_documents(op)
|
30
32
|
collection = entities.get(:collection, op.use!('object'))
|
31
33
|
use_arguments(op) do |args|
|
32
|
-
|
34
|
+
opts = {}
|
35
|
+
if session = args.use('session')
|
36
|
+
opts[:session] = entities.get(:session, session)
|
37
|
+
end
|
38
|
+
collection.find(args.use!('filter')).count_documents(**opts)
|
33
39
|
end
|
34
40
|
end
|
35
41
|
|
@@ -47,7 +53,11 @@ module Unified
|
|
47
53
|
def distinct(op)
|
48
54
|
collection = entities.get(:collection, op.use!('object'))
|
49
55
|
use_arguments(op) do |args|
|
50
|
-
|
56
|
+
opts = {}
|
57
|
+
if session = args.use('session')
|
58
|
+
opts[:session] = entities.get(:session, session)
|
59
|
+
end
|
60
|
+
req = collection.find(args.use!('filter'), **opts).distinct(args.use!('fieldName'), **opts)
|
51
61
|
result = req.to_a
|
52
62
|
end
|
53
63
|
end
|
@@ -57,10 +67,15 @@ module Unified
|
|
57
67
|
use_arguments(op) do |args|
|
58
68
|
filter = args.use!('filter')
|
59
69
|
update = args.use!('update')
|
60
|
-
opts = {
|
70
|
+
opts = {
|
71
|
+
let: args.use('let'),
|
72
|
+
}
|
61
73
|
if return_document = args.use('returnDocument')
|
62
74
|
opts[:return_document] = return_document.downcase.to_sym
|
63
75
|
end
|
76
|
+
if session = args.use('session')
|
77
|
+
opts[:session] = entities.get(:session, session)
|
78
|
+
end
|
64
79
|
collection.find_one_and_update(filter, update, **opts)
|
65
80
|
end
|
66
81
|
end
|
@@ -70,7 +85,13 @@ module Unified
|
|
70
85
|
use_arguments(op) do |args|
|
71
86
|
filter = args.use!('filter')
|
72
87
|
update = args.use!('replacement')
|
73
|
-
|
88
|
+
opts = {
|
89
|
+
let: args.use('let'),
|
90
|
+
}
|
91
|
+
if session = args.use('session')
|
92
|
+
opts[:session] = entities.get(:session, session)
|
93
|
+
end
|
94
|
+
collection.find_one_and_replace(filter, update, **opts)
|
74
95
|
end
|
75
96
|
end
|
76
97
|
|
@@ -78,7 +99,13 @@ module Unified
|
|
78
99
|
collection = entities.get(:collection, op.use!('object'))
|
79
100
|
use_arguments(op) do |args|
|
80
101
|
filter = args.use!('filter')
|
81
|
-
|
102
|
+
opts = {
|
103
|
+
let: args.use('let'),
|
104
|
+
}
|
105
|
+
if session = args.use('session')
|
106
|
+
opts[:session] = entities.get(:session, session)
|
107
|
+
end
|
108
|
+
collection.find_one_and_delete(filter, **opts)
|
82
109
|
end
|
83
110
|
end
|
84
111
|
|
@@ -96,25 +123,37 @@ module Unified
|
|
96
123
|
def insert_many(op)
|
97
124
|
collection = entities.get(:collection, op.use!('object'))
|
98
125
|
use_arguments(op) do |args|
|
99
|
-
|
126
|
+
opts = {}
|
100
127
|
unless (ordered = args.use('ordered')).nil?
|
101
|
-
|
128
|
+
opts[:ordered] = ordered
|
129
|
+
end
|
130
|
+
if session = args.use('session')
|
131
|
+
opts[:session] = entities.get(:session, session)
|
102
132
|
end
|
103
|
-
collection.insert_many(args.use!('documents'), **
|
133
|
+
collection.insert_many(args.use!('documents'), **opts)
|
104
134
|
end
|
105
135
|
end
|
106
136
|
|
107
137
|
def update_one(op)
|
108
138
|
collection = entities.get(:collection, op.use!('object'))
|
109
139
|
use_arguments(op) do |args|
|
110
|
-
|
140
|
+
opts = {
|
141
|
+
let: args.use('let'),
|
142
|
+
}
|
143
|
+
if session = args.use('session')
|
144
|
+
opts[:session] = entities.get(:session, session)
|
145
|
+
end
|
146
|
+
collection.update_one(args.use!('filter'), args.use!('update'), **opts)
|
111
147
|
end
|
112
148
|
end
|
113
149
|
|
114
150
|
def update_many(op)
|
115
151
|
collection = entities.get(:collection, op.use!('object'))
|
116
152
|
use_arguments(op) do |args|
|
117
|
-
|
153
|
+
opts = {
|
154
|
+
let: args.use('let'),
|
155
|
+
}
|
156
|
+
collection.update_many(args.use!('filter'), args.use!('update'), **opts)
|
118
157
|
end
|
119
158
|
end
|
120
159
|
|
@@ -132,14 +171,23 @@ module Unified
|
|
132
171
|
def delete_one(op)
|
133
172
|
collection = entities.get(:collection, op.use!('object'))
|
134
173
|
use_arguments(op) do |args|
|
135
|
-
|
174
|
+
opts = {
|
175
|
+
let: args.use('let'),
|
176
|
+
}
|
177
|
+
if session = args.use('session')
|
178
|
+
opts[:session] = entities.get(:session, session)
|
179
|
+
end
|
180
|
+
collection.delete_one(args.use!('filter'), **opts)
|
136
181
|
end
|
137
182
|
end
|
138
183
|
|
139
184
|
def delete_many(op)
|
140
185
|
collection = entities.get(:collection, op.use!('object'))
|
141
186
|
use_arguments(op) do |args|
|
142
|
-
|
187
|
+
opts = {
|
188
|
+
let: args.use('let'),
|
189
|
+
}
|
190
|
+
collection.delete_many(args.use!('filter'), **opts)
|
143
191
|
end
|
144
192
|
end
|
145
193
|
|
@@ -157,6 +205,22 @@ module Unified
|
|
157
205
|
end
|
158
206
|
end
|
159
207
|
|
208
|
+
def aggregate(op)
|
209
|
+
obj = entities.get_any(op.use!('object'))
|
210
|
+
args = op.use!('arguments')
|
211
|
+
pipeline = args.use!('pipeline')
|
212
|
+
opts = {
|
213
|
+
let: args.use('let'),
|
214
|
+
}
|
215
|
+
if session = args.use('session')
|
216
|
+
opts[:session] = entities.get(:session, session)
|
217
|
+
end
|
218
|
+
unless args.empty?
|
219
|
+
raise NotImplementedError, "Unhandled spec keys: #{args} in #{test_spec}"
|
220
|
+
end
|
221
|
+
obj.aggregate(pipeline, **opts).to_a
|
222
|
+
end
|
223
|
+
|
160
224
|
private
|
161
225
|
|
162
226
|
def convert_bulk_write_spec(spec)
|
@@ -192,15 +256,5 @@ module Unified
|
|
192
256
|
end
|
193
257
|
{Utils.underscore(op) =>out}
|
194
258
|
end
|
195
|
-
|
196
|
-
def aggregate(op)
|
197
|
-
obj = entities.get_any(op.use!('object'))
|
198
|
-
args = op.use!('arguments')
|
199
|
-
pipeline = args.use!('pipeline')
|
200
|
-
unless args.empty?
|
201
|
-
raise NotImplementedError, "Unhandled spec keys: #{test_spec}"
|
202
|
-
end
|
203
|
-
obj.aggregate(pipeline).to_a
|
204
|
-
end
|
205
259
|
end
|
206
260
|
end
|
@@ -7,7 +7,13 @@ module Unified
|
|
7
7
|
|
8
8
|
def list_databases(op)
|
9
9
|
client = entities.get(:client, op.use!('object'))
|
10
|
-
|
10
|
+
use_arguments(op) do |args|
|
11
|
+
opts = {}
|
12
|
+
if session = args.use('session')
|
13
|
+
opts[:session] = entities.get(:session, session)
|
14
|
+
end
|
15
|
+
client.list_databases({}, false, **opts)
|
16
|
+
end
|
11
17
|
end
|
12
18
|
|
13
19
|
def create_collection(op)
|
@@ -28,6 +34,17 @@ module Unified
|
|
28
34
|
end
|
29
35
|
end
|
30
36
|
|
37
|
+
def list_collections(op)
|
38
|
+
database = entities.get(:database, op.use!('object'))
|
39
|
+
use_arguments(op) do |args|
|
40
|
+
opts = {}
|
41
|
+
if session = args.use('session')
|
42
|
+
opts[:session] = entities.get(:session, session)
|
43
|
+
end
|
44
|
+
database.list_collections(**opts)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
31
48
|
def drop_collection(op)
|
32
49
|
database = entities.get(:database, op.use!('object'))
|
33
50
|
use_arguments(op) do |args|
|
@@ -58,6 +75,17 @@ module Unified
|
|
58
75
|
assert_collection_exists(op, false)
|
59
76
|
end
|
60
77
|
|
78
|
+
def list_indexes(op)
|
79
|
+
collection = entities.get(:collection, op.use!('object'))
|
80
|
+
use_arguments(op) do |args|
|
81
|
+
opts = {}
|
82
|
+
if session = args.use('session')
|
83
|
+
opts[:session] = entities.get(:session, session)
|
84
|
+
end
|
85
|
+
collection.indexes(**opts).to_a
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
61
89
|
def create_index(op)
|
62
90
|
collection = entities.get(:collection, op.use!('object'))
|
63
91
|
use_arguments(op) do |args|
|
@@ -3,6 +3,8 @@
|
|
3
3
|
|
4
4
|
module Unified
|
5
5
|
class EntityMap
|
6
|
+
extend Forwardable
|
7
|
+
|
6
8
|
def initialize
|
7
9
|
@map = {}
|
8
10
|
end
|
@@ -35,8 +37,6 @@ module Unified
|
|
35
37
|
raise Error::EntityMissing, "There is no #{id} known"
|
36
38
|
end
|
37
39
|
|
38
|
-
|
39
|
-
@map[type]
|
40
|
-
end
|
40
|
+
def_delegators :@map, :[], :fetch
|
41
41
|
end
|
42
42
|
end
|
@@ -160,13 +160,24 @@ module Unified
|
|
160
160
|
end
|
161
161
|
when 'database'
|
162
162
|
client = entities.get(:client, spec.use!('client'))
|
163
|
-
|
163
|
+
opts = Utils.snakeize_hash(spec.use('databaseOptions') || {})
|
164
|
+
.merge(database: spec.use!('databaseName'))
|
165
|
+
if opts.key?(:read_preference)
|
166
|
+
opts[:read] = opts.delete(:read_preference)
|
167
|
+
if opts[:read].key?(:max_staleness_seconds)
|
168
|
+
opts[:read][:max_staleness] = opts[:read].delete(:max_staleness_seconds)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
client.with(opts).database
|
164
172
|
when 'collection'
|
165
173
|
database = entities.get(:database, spec.use!('database'))
|
166
174
|
# TODO verify
|
167
175
|
opts = Utils.snakeize_hash(spec.use('collectionOptions') || {})
|
168
176
|
if opts.key?(:read_preference)
|
169
177
|
opts[:read] = opts.delete(:read_preference)
|
178
|
+
if opts[:read].key?(:max_staleness_seconds)
|
179
|
+
opts[:read][:max_staleness] = opts[:read].delete(:max_staleness_seconds)
|
180
|
+
end
|
170
181
|
end
|
171
182
|
database[spec.use!('collectionName'), opts]
|
172
183
|
when 'bucket'
|
@@ -195,7 +206,8 @@ module Unified
|
|
195
206
|
def set_initial_data
|
196
207
|
@spec['initialData']&.each do |entity_spec|
|
197
208
|
spec = UsingHash[entity_spec]
|
198
|
-
collection = root_authorized_client.
|
209
|
+
collection = root_authorized_client.with(write_concern: {w: :majority}).
|
210
|
+
use(spec.use!('databaseName'))[spec.use!('collectionName')]
|
199
211
|
collection.drop
|
200
212
|
docs = spec.use!('documents')
|
201
213
|
if docs.any?
|
@@ -268,7 +280,7 @@ module Unified
|
|
268
280
|
end
|
269
281
|
if expected_error = op.use('expectError')
|
270
282
|
begin
|
271
|
-
|
283
|
+
public_send(method_name, op)
|
272
284
|
rescue Mongo::Error, BSON::String::IllegalKey => e
|
273
285
|
if expected_error.use('isClientError')
|
274
286
|
# isClientError doesn't actually mean a client error.
|
@@ -0,0 +1,138 @@
|
|
1
|
+
description: "aggregate-let"
|
2
|
+
|
3
|
+
schemaVersion: "1.4"
|
4
|
+
|
5
|
+
createEntities:
|
6
|
+
- client:
|
7
|
+
id: &client0 client0
|
8
|
+
observeEvents: [ commandStartedEvent ]
|
9
|
+
- database:
|
10
|
+
id: &database0 database0
|
11
|
+
client: *client0
|
12
|
+
databaseName: &database0Name crud-tests
|
13
|
+
- collection:
|
14
|
+
id: &collection0 collection0
|
15
|
+
database: *database0
|
16
|
+
collectionName: &collection0Name coll0
|
17
|
+
- collection:
|
18
|
+
id: &collection1 collection1
|
19
|
+
database: *database0
|
20
|
+
collectionName: &collection1Name coll1
|
21
|
+
|
22
|
+
initialData: &initialData
|
23
|
+
- collectionName: *collection0Name
|
24
|
+
databaseName: *database0Name
|
25
|
+
documents:
|
26
|
+
- { _id: 1 }
|
27
|
+
- collectionName: *collection1Name
|
28
|
+
databaseName: *database0Name
|
29
|
+
documents: [ ]
|
30
|
+
|
31
|
+
tests:
|
32
|
+
- description: "Aggregate with let option"
|
33
|
+
runOnRequirements:
|
34
|
+
- minServerVersion: "5.0"
|
35
|
+
operations:
|
36
|
+
- name: aggregate
|
37
|
+
object: *collection0
|
38
|
+
arguments:
|
39
|
+
pipeline: &pipeline0
|
40
|
+
# $match takes a query expression, so $expr is necessary to utilize
|
41
|
+
# an aggregate expression context and access "let" variables.
|
42
|
+
- $match: { $expr: { $eq: ["$_id", "$$id"] } }
|
43
|
+
- $project: { _id: 0, x: "$$x", y: "$$y", rand: "$$rand" }
|
44
|
+
# Values in "let" must be constant or closed expressions that do not
|
45
|
+
# depend on document values. This test demonstrates a basic constant
|
46
|
+
# value, a value wrapped with $literal (to avoid expression parsing),
|
47
|
+
# and a closed expression (e.g. $rand).
|
48
|
+
let: &let0
|
49
|
+
id: 1
|
50
|
+
x: foo
|
51
|
+
y: { $literal: "$bar" }
|
52
|
+
rand: { $rand: {} }
|
53
|
+
expectResult:
|
54
|
+
- { x: "foo", y: "$bar", rand: { $$type: "double" } }
|
55
|
+
expectEvents:
|
56
|
+
- client: *client0
|
57
|
+
events:
|
58
|
+
- commandStartedEvent:
|
59
|
+
command:
|
60
|
+
aggregate: *collection0Name
|
61
|
+
pipeline: *pipeline0
|
62
|
+
let: *let0
|
63
|
+
|
64
|
+
- description: "Aggregate with let option unsupported (server-side error)"
|
65
|
+
runOnRequirements:
|
66
|
+
- minServerVersion: "2.6.0"
|
67
|
+
maxServerVersion: "4.4.99"
|
68
|
+
operations:
|
69
|
+
- name: aggregate
|
70
|
+
object: *collection0
|
71
|
+
arguments:
|
72
|
+
pipeline: &pipeline1
|
73
|
+
- $match: { _id: 1 }
|
74
|
+
let: &let1
|
75
|
+
x: foo
|
76
|
+
expectError:
|
77
|
+
# Older server versions may not report an error code, but the error
|
78
|
+
# message is consistent between 2.6.x and 4.4.x server versions.
|
79
|
+
errorContains: "unrecognized field 'let'"
|
80
|
+
isClientError: false
|
81
|
+
expectEvents:
|
82
|
+
- client: *client0
|
83
|
+
events:
|
84
|
+
- commandStartedEvent:
|
85
|
+
command:
|
86
|
+
aggregate: *collection0Name
|
87
|
+
pipeline: *pipeline1
|
88
|
+
let: *let1
|
89
|
+
|
90
|
+
- description: "Aggregate to collection with let option"
|
91
|
+
runOnRequirements:
|
92
|
+
- minServerVersion: "5.0"
|
93
|
+
serverless: "forbid"
|
94
|
+
operations:
|
95
|
+
- name: aggregate
|
96
|
+
object: *collection0
|
97
|
+
arguments:
|
98
|
+
pipeline: &pipeline2
|
99
|
+
- $match: { $expr: { $eq: ["$_id", "$$id"] } }
|
100
|
+
- $project: { _id: 1 }
|
101
|
+
- $out: *collection1Name
|
102
|
+
let: &let2
|
103
|
+
id: 1
|
104
|
+
expectEvents:
|
105
|
+
- client: *client0
|
106
|
+
events:
|
107
|
+
- commandStartedEvent:
|
108
|
+
command:
|
109
|
+
aggregate: *collection0Name
|
110
|
+
pipeline: *pipeline2
|
111
|
+
let: *let2
|
112
|
+
outcome:
|
113
|
+
- collectionName: *collection1Name
|
114
|
+
databaseName: *database0Name
|
115
|
+
documents:
|
116
|
+
- { _id: 1 }
|
117
|
+
|
118
|
+
- description: "Aggregate to collection with let option unsupported (server-side error)"
|
119
|
+
runOnRequirements:
|
120
|
+
- minServerVersion: "2.6.0"
|
121
|
+
maxServerVersion: "4.4.99"
|
122
|
+
operations:
|
123
|
+
- name: aggregate
|
124
|
+
object: *collection0
|
125
|
+
arguments:
|
126
|
+
pipeline: *pipeline2
|
127
|
+
let: *let2
|
128
|
+
expectError:
|
129
|
+
errorContains: "unrecognized field 'let'"
|
130
|
+
isClientError: false
|
131
|
+
expectEvents:
|
132
|
+
- client: *client0
|
133
|
+
events:
|
134
|
+
- commandStartedEvent:
|
135
|
+
command:
|
136
|
+
aggregate: *collection0Name
|
137
|
+
pipeline: *pipeline2
|
138
|
+
let: *let2
|
@@ -0,0 +1,155 @@
|
|
1
|
+
description: aggregate-write-readPreference
|
2
|
+
|
3
|
+
schemaVersion: '1.4'
|
4
|
+
|
5
|
+
runOnRequirements:
|
6
|
+
# 3.6+ non-standalone is needed to utilize $readPreference in OP_MSG
|
7
|
+
- minServerVersion: "3.6"
|
8
|
+
topologies: [ replicaset, sharded, load-balanced ]
|
9
|
+
|
10
|
+
_yamlAnchors:
|
11
|
+
readConcern: &readConcern
|
12
|
+
level: &readConcernLevel "local"
|
13
|
+
writeConcern: &writeConcern
|
14
|
+
w: &writeConcernW 1
|
15
|
+
|
16
|
+
createEntities:
|
17
|
+
- client:
|
18
|
+
id: &client0 client0
|
19
|
+
observeEvents:
|
20
|
+
- commandStartedEvent
|
21
|
+
# Used to test that read and write concerns are still inherited
|
22
|
+
uriOptions:
|
23
|
+
readConcernLevel: *readConcernLevel
|
24
|
+
w: *writeConcernW
|
25
|
+
- database:
|
26
|
+
id: &database0 database0
|
27
|
+
client: *client0
|
28
|
+
databaseName: &database0Name db0
|
29
|
+
- collection:
|
30
|
+
id: &collection0 collection0
|
31
|
+
database: *database0
|
32
|
+
collectionName: &collection0Name coll0
|
33
|
+
collectionOptions:
|
34
|
+
readPreference: &readPreference
|
35
|
+
# secondaryPreferred is specified for compatibility with clusters that
|
36
|
+
# may not have a secondary (e.g. each shard is only a primary).
|
37
|
+
mode: secondaryPreferred
|
38
|
+
# maxStalenessSeconds is specified to ensure that drivers forward the
|
39
|
+
# read preference to mongos or a load balancer. That would not be the
|
40
|
+
# case with only secondaryPreferred.
|
41
|
+
maxStalenessSeconds: 600
|
42
|
+
- collection:
|
43
|
+
id: &collection1 collection1
|
44
|
+
database: *database0
|
45
|
+
collectionName: &collection1Name coll1
|
46
|
+
|
47
|
+
initialData:
|
48
|
+
- collectionName: *collection0Name
|
49
|
+
databaseName: *database0Name
|
50
|
+
documents:
|
51
|
+
- { _id: 1, x: 11 }
|
52
|
+
- { _id: 2, x: 22 }
|
53
|
+
- { _id: 3, x: 33 }
|
54
|
+
- collectionName: *collection1Name
|
55
|
+
databaseName: *database0Name
|
56
|
+
documents: []
|
57
|
+
|
58
|
+
tests:
|
59
|
+
- description: "Aggregate with $out includes read preference for 5.0+ server"
|
60
|
+
runOnRequirements:
|
61
|
+
- minServerVersion: "5.0"
|
62
|
+
serverless: "forbid"
|
63
|
+
operations:
|
64
|
+
- object: *collection0
|
65
|
+
name: aggregate
|
66
|
+
arguments:
|
67
|
+
pipeline: &outPipeline
|
68
|
+
- { $match: { _id: { $gt: 1 } } }
|
69
|
+
- { $sort: { x: 1 } }
|
70
|
+
- { $out: *collection1Name }
|
71
|
+
expectEvents:
|
72
|
+
- client: *client0
|
73
|
+
events:
|
74
|
+
- commandStartedEvent:
|
75
|
+
command:
|
76
|
+
aggregate: *collection0Name
|
77
|
+
pipeline: *outPipeline
|
78
|
+
$readPreference: *readPreference
|
79
|
+
readConcern: *readConcern
|
80
|
+
writeConcern: *writeConcern
|
81
|
+
outcome: &outcome
|
82
|
+
- collectionName: *collection1Name
|
83
|
+
databaseName: *database0Name
|
84
|
+
documents:
|
85
|
+
- { _id: 2, x: 22 }
|
86
|
+
- { _id: 3, x: 33 }
|
87
|
+
|
88
|
+
- description: "Aggregate with $out omits read preference for pre-5.0 server"
|
89
|
+
runOnRequirements:
|
90
|
+
# MongoDB 4.2 introduced support for read concerns and write stages.
|
91
|
+
# Pre-4.2 servers may allow a "local" read concern anyway, but some
|
92
|
+
# drivers may avoid inheriting a client-level read concern for pre-4.2.
|
93
|
+
- minServerVersion: "4.2"
|
94
|
+
maxServerVersion: "4.4.99"
|
95
|
+
serverless: "forbid"
|
96
|
+
operations:
|
97
|
+
- object: *collection0
|
98
|
+
name: aggregate
|
99
|
+
arguments:
|
100
|
+
pipeline: *outPipeline
|
101
|
+
expectEvents:
|
102
|
+
- client: *client0
|
103
|
+
events:
|
104
|
+
- commandStartedEvent:
|
105
|
+
command:
|
106
|
+
aggregate: *collection0Name
|
107
|
+
pipeline: *outPipeline
|
108
|
+
$readPreference: { $$exists: false }
|
109
|
+
readConcern: *readConcern
|
110
|
+
writeConcern: *writeConcern
|
111
|
+
outcome: *outcome
|
112
|
+
|
113
|
+
- description: "Aggregate with $merge includes read preference for 5.0+ server"
|
114
|
+
runOnRequirements:
|
115
|
+
- minServerVersion: "5.0"
|
116
|
+
operations:
|
117
|
+
- object: *collection0
|
118
|
+
name: aggregate
|
119
|
+
arguments:
|
120
|
+
pipeline: &mergePipeline
|
121
|
+
- { $match: { _id: { $gt: 1 } } }
|
122
|
+
- { $sort: { x: 1 } }
|
123
|
+
- { $merge: { into: *collection1Name } }
|
124
|
+
expectEvents:
|
125
|
+
- client: *client0
|
126
|
+
events:
|
127
|
+
- commandStartedEvent:
|
128
|
+
command:
|
129
|
+
aggregate: *collection0Name
|
130
|
+
pipeline: *mergePipeline
|
131
|
+
$readPreference: *readPreference
|
132
|
+
readConcern: *readConcern
|
133
|
+
writeConcern: *writeConcern
|
134
|
+
outcome: *outcome
|
135
|
+
|
136
|
+
- description: "Aggregate with $merge omits read preference for pre-5.0 server"
|
137
|
+
runOnRequirements:
|
138
|
+
- minServerVersion: "4.2"
|
139
|
+
maxServerVersion: "4.4.99"
|
140
|
+
operations:
|
141
|
+
- object: *collection0
|
142
|
+
name: aggregate
|
143
|
+
arguments:
|
144
|
+
pipeline: *mergePipeline
|
145
|
+
expectEvents:
|
146
|
+
- client: *client0
|
147
|
+
events:
|
148
|
+
- commandStartedEvent:
|
149
|
+
command:
|
150
|
+
aggregate: *collection0Name
|
151
|
+
pipeline: *mergePipeline
|
152
|
+
$readPreference: { $$exists: false }
|
153
|
+
readConcern: *readConcern
|
154
|
+
writeConcern: *writeConcern
|
155
|
+
outcome: *outcome
|