mongo 2.5.0.beta → 2.5.0
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.tar.gz.sig +0 -0
- data/lib/mongo/address.rb +1 -1
- data/lib/mongo/address/unix.rb +1 -1
- data/lib/mongo/auth/user.rb +0 -5
- data/lib/mongo/auth/user/view.rb +4 -4
- data/lib/mongo/bulk_write.rb +60 -32
- data/lib/mongo/client.rb +44 -8
- data/lib/mongo/cluster.rb +14 -12
- data/lib/mongo/cluster/periodic_executor.rb +106 -0
- data/lib/mongo/cluster/{cursor_reaper.rb → reapers/cursor_reaper.rb} +5 -37
- data/lib/mongo/cluster/reapers/socket_reaper.rb +59 -0
- data/lib/mongo/collection.rb +9 -6
- data/lib/mongo/collection/view.rb +2 -2
- data/lib/mongo/collection/view/builder/aggregation.rb +2 -1
- data/lib/mongo/collection/view/builder/find_command.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +14 -1
- data/lib/mongo/collection/view/map_reduce.rb +30 -13
- data/lib/mongo/collection/view/readable.rb +5 -5
- data/lib/mongo/collection/view/writable.rb +98 -51
- data/lib/mongo/error.rb +3 -0
- data/lib/mongo/error/invalid_txt_record.rb +27 -0
- data/lib/mongo/error/invalid_uri.rb +7 -6
- data/lib/mongo/error/mismatched_domain.rb +27 -0
- data/lib/mongo/error/no_srv_records.rb +26 -0
- data/lib/mongo/error/unsupported_features.rb +0 -18
- data/lib/mongo/index/view.rb +2 -2
- data/lib/mongo/operation.rb +1 -0
- data/lib/mongo/operation/causally_consistent.rb +33 -0
- data/lib/mongo/operation/commands.rb +2 -1
- data/lib/mongo/operation/commands/aggregate.rb +2 -7
- data/lib/mongo/operation/commands/count.rb +27 -0
- data/lib/mongo/operation/commands/distinct.rb +27 -0
- data/lib/mongo/operation/commands/find.rb +3 -1
- data/lib/mongo/operation/commands/map_reduce.rb +1 -0
- data/lib/mongo/operation/commands/parallel_scan.rb +1 -0
- data/lib/mongo/operation/specifiable.rb +12 -0
- data/lib/mongo/operation/uses_command_op_msg.rb +36 -5
- data/lib/mongo/operation/write.rb +0 -5
- data/lib/mongo/operation/write/bulk/bulkable.rb +4 -8
- data/lib/mongo/operation/write/bulk/mergable.rb +2 -0
- data/lib/mongo/operation/write/command/create_index.rb +19 -0
- data/lib/mongo/operation/write/command/create_user.rb +19 -0
- data/lib/mongo/operation/write/command/delete.rb +1 -2
- data/lib/mongo/operation/write/command/drop_index.rb +19 -0
- data/lib/mongo/operation/write/command/insert.rb +1 -2
- data/lib/mongo/operation/write/command/remove_user.rb +19 -0
- data/lib/mongo/operation/write/command/update.rb +1 -2
- data/lib/mongo/operation/write/command/update_user.rb +19 -0
- data/lib/mongo/operation/write/write_command_enabled.rb +1 -3
- data/lib/mongo/protocol/compressed.rb +2 -1
- data/lib/mongo/protocol/serializers.rb +6 -6
- data/lib/mongo/retryable.rb +48 -5
- data/lib/mongo/server.rb +15 -0
- data/lib/mongo/server/connection.rb +21 -1
- data/lib/mongo/server/connection_pool.rb +3 -0
- data/lib/mongo/server/connection_pool/queue.rb +50 -5
- data/lib/mongo/server/description.rb +11 -3
- data/lib/mongo/server/description/features.rb +26 -7
- data/lib/mongo/session.rb +133 -6
- data/lib/mongo/session/server_session.rb +30 -0
- data/lib/mongo/session/session_pool.rb +20 -20
- data/lib/mongo/uri.rb +88 -44
- data/lib/mongo/uri/srv_protocol.rb +158 -0
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo/write_concern/normalizable.rb +12 -0
- data/mongo.gemspec +1 -2
- data/spec/mongo/address_spec.rb +12 -0
- data/spec/mongo/auth/user/view_spec.rb +1 -5
- data/spec/mongo/bulk_write_spec.rb +232 -401
- data/spec/mongo/change_stream_examples_spec.rb +150 -0
- data/spec/mongo/client_spec.rb +142 -2
- data/spec/mongo/cluster/cursor_reaper_spec.rb +0 -70
- data/spec/mongo/cluster/socket_reaper_spec.rb +32 -0
- data/spec/mongo/cluster_spec.rb +11 -7
- data/spec/mongo/collection/view/aggregation_spec.rb +46 -1
- data/spec/mongo/collection/view/builder/find_command_spec.rb +15 -0
- data/spec/mongo/collection/view/change_stream_spec.rb +79 -12
- data/spec/mongo/collection/view/map_reduce_spec.rb +120 -4
- data/spec/mongo/collection/view/readable_spec.rb +23 -5
- data/spec/mongo/collection_spec.rb +292 -102
- data/spec/mongo/command_monitoring_spec.rb +26 -32
- data/spec/mongo/crud_spec.rb +1 -1
- data/spec/mongo/cursor_spec.rb +2 -3
- data/spec/mongo/database_spec.rb +30 -14
- data/spec/mongo/dns_seedlist_discovery_spec.rb +94 -0
- data/spec/mongo/grid/fs_bucket_spec.rb +1 -1
- data/spec/mongo/grid/stream/write_spec.rb +1 -1
- data/spec/mongo/index/view_spec.rb +8 -46
- data/spec/mongo/operation/write/bulk/delete_spec.rb +2 -2
- data/spec/mongo/operation/write/bulk/insert_spec.rb +2 -10
- data/spec/mongo/operation/write/{create_index_spec.rb → command/create_index_spec.rb} +2 -6
- data/spec/mongo/operation/write/command/delete_spec.rb +35 -7
- data/spec/mongo/operation/write/{drop_index_spec.rb → command/drop_index_spec.rb} +1 -1
- data/spec/mongo/operation/write/command/insert_spec.rb +37 -6
- data/spec/mongo/operation/write/{remove_user_spec.rb → command/remove_user_spec.rb} +2 -6
- data/spec/mongo/operation/write/command/update_spec.rb +34 -7
- data/spec/mongo/operation/write/{update_user_spec.rb → command/update_user_spec.rb} +1 -1
- data/spec/mongo/operation/write/create_user_spec.rb +1 -1
- data/spec/mongo/operation/write/delete_spec.rb +1 -1
- data/spec/mongo/operation/write/insert_spec.rb +2 -10
- data/spec/mongo/operation/write/update_spec.rb +3 -15
- data/spec/mongo/retryable_spec.rb +1 -1
- data/spec/mongo/retryable_writes_spec.rb +815 -0
- data/spec/mongo/server/connection_pool/queue_spec.rb +35 -2
- data/spec/mongo/server/connection_pool_spec.rb +234 -1
- data/spec/mongo/server/connection_spec.rb +10 -6
- data/spec/mongo/server/description/features_spec.rb +51 -37
- data/spec/mongo/server/description_spec.rb +6 -3
- data/spec/mongo/server_spec.rb +87 -0
- data/spec/mongo/session/server_session_spec.rb +43 -0
- data/spec/mongo/session/session_pool_spec.rb +63 -27
- data/spec/mongo/session_spec.rb +247 -0
- data/spec/mongo/shell_examples_spec.rb +2 -2
- data/spec/mongo/uri/srv_protocol_spec.rb +933 -0
- data/spec/mongo/uri_spec.rb +42 -3
- data/spec/mongo/write_concern/acknowledged_spec.rb +11 -0
- data/spec/mongo/write_concern/unacknowledged_spec.rb +11 -0
- data/spec/spec_helper.rb +11 -25
- data/spec/support/authorization.rb +2 -1
- data/spec/support/connection_string.rb +8 -4
- data/spec/support/crud.rb +38 -24
- data/spec/support/crud/write.rb +30 -3
- data/spec/support/crud_tests/read/aggregate-out.yml +21 -0
- data/spec/support/crud_tests/write/bulkWrite-arrayFilters.yml +44 -0
- data/spec/support/crud_tests/write/findOneAndUpdate-arrayFilters.yml +1 -1
- data/spec/support/crud_tests/write/insertMany.yml +1 -3
- data/spec/support/crud_tests/write/replaceOne.yml +1 -1
- data/spec/support/crud_tests/write/updateMany-arrayFilters.yml +1 -1
- data/spec/support/crud_tests/write/updateOne-arrayFilters.yml +1 -1
- data/spec/support/dns_seedlist_discovery_tests/longer-parent-in-return.yml +11 -0
- data/spec/support/dns_seedlist_discovery_tests/misformatted-option.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/no-results.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/not-enough-parts.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/one-result-default-port.yml +10 -0
- data/spec/support/dns_seedlist_discovery_tests/one-txt-record-multiple-strings.yml +10 -0
- data/spec/support/dns_seedlist_discovery_tests/one-txt-record.yml +11 -0
- data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch1.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch2.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch3.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch4.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch5.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/returned-parent-too-short.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/returned-parent-wrong.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/two-results-default-port.yml +11 -0
- data/spec/support/dns_seedlist_discovery_tests/two-results-nonstandard-port.yml +11 -0
- data/spec/support/dns_seedlist_discovery_tests/two-txt-records.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/txt-record-not-allowed-option.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/txt-record-with-overridden-ssl-option.yml +11 -0
- data/spec/support/dns_seedlist_discovery_tests/txt-record-with-overridden-uri-option.yml +11 -0
- data/spec/support/dns_seedlist_discovery_tests/txt-record-with-unallowed-option.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/uri-with-port.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/uri-with-two-hosts.yml +5 -0
- data/spec/support/retryable_writes_tests/bulkWrite.yml +305 -0
- data/spec/support/retryable_writes_tests/deleteOne.yml +51 -0
- data/spec/support/retryable_writes_tests/findOneAndDelete.yml +52 -0
- data/spec/support/retryable_writes_tests/findOneAndReplace.yml +57 -0
- data/spec/support/retryable_writes_tests/findOneAndUpdate.yml +56 -0
- data/spec/support/retryable_writes_tests/insertMany.yml +72 -0
- data/spec/support/retryable_writes_tests/insertOne.yml +55 -0
- data/spec/support/retryable_writes_tests/replaceOne.yml +60 -0
- data/spec/support/retryable_writes_tests/updateOne.yml +120 -0
- data/spec/support/shared/session.rb +525 -24
- metadata +437 -350
- metadata.gz.sig +0 -0
- data/lib/mongo/operation/commands/user_query.rb +0 -72
- data/lib/mongo/operation/write/create_index.rb +0 -67
- data/lib/mongo/operation/write/create_user.rb +0 -50
- data/lib/mongo/operation/write/drop_index.rb +0 -63
- data/lib/mongo/operation/write/remove_user.rb +0 -48
- data/lib/mongo/operation/write/update_user.rb +0 -50
@@ -1,6 +1,6 @@
|
|
1
1
|
shared_examples 'an operation using a session' do
|
2
2
|
|
3
|
-
describe 'operation execution', if:
|
3
|
+
describe 'operation execution', if: test_sessions? do
|
4
4
|
|
5
5
|
context 'when the session is created from the same client used for the operation' do
|
6
6
|
|
@@ -17,7 +17,7 @@ shared_examples 'an operation using a session' do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
let!(:before_operation_time) do
|
20
|
-
(session.
|
20
|
+
(session.operation_time || 0)
|
21
21
|
end
|
22
22
|
|
23
23
|
let!(:operation_result) do
|
@@ -33,7 +33,7 @@ shared_examples 'an operation using a session' do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'updates the operation time value' do
|
36
|
-
expect(session.
|
36
|
+
expect(session.operation_time).not_to eq(before_operation_time)
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'does not close the session when the operation completes' do
|
@@ -44,11 +44,7 @@ shared_examples 'an operation using a session' do
|
|
44
44
|
context 'when a session from another client is provided' do
|
45
45
|
|
46
46
|
let(:session) do
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
let(:client) do
|
51
|
-
authorized_client.with(read: { mode: :secondary })
|
47
|
+
authorized_client.with(read: { mode: :secondary }).start_session
|
52
48
|
end
|
53
49
|
|
54
50
|
let(:operation_result) do
|
@@ -87,17 +83,18 @@ end
|
|
87
83
|
|
88
84
|
shared_examples 'a failed operation using a session' do
|
89
85
|
|
90
|
-
context 'when the operation fails', if:
|
86
|
+
context 'when the operation fails', if: test_sessions? do
|
91
87
|
|
92
88
|
let!(:before_last_use) do
|
93
89
|
session.instance_variable_get(:@server_session).last_use
|
94
90
|
end
|
95
91
|
|
96
92
|
let!(:before_operation_time) do
|
97
|
-
(session.
|
93
|
+
(session.operation_time || 0)
|
98
94
|
end
|
99
95
|
|
100
96
|
let!(:operation_result) do
|
97
|
+
sleep 0.2
|
101
98
|
begin; failed_operation; rescue => e; e; end
|
102
99
|
end
|
103
100
|
|
@@ -115,7 +112,451 @@ shared_examples 'a failed operation using a session' do
|
|
115
112
|
end
|
116
113
|
|
117
114
|
it 'updates the operation time value' do
|
118
|
-
expect(session.
|
115
|
+
expect(session.operation_time).not_to eq(before_operation_time)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
shared_examples 'a causally consistent client session with an unacknowledged write' do
|
121
|
+
|
122
|
+
context 'when an unacknowledged write is executed in the context of a causally consistent session', if: sessions_enabled? do
|
123
|
+
|
124
|
+
let(:session) do
|
125
|
+
client.start_session(causal_consistency: true)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'does not update the operation time of the session' do
|
129
|
+
operation
|
130
|
+
expect(session.operation_time).to be_nil
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
shared_examples 'an operation supporting causally consistent reads' do
|
136
|
+
|
137
|
+
let(:client) do
|
138
|
+
authorized_client.with(heartbeat_frequency: 100).tap do |cl|
|
139
|
+
cl.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
let(:subscriber) do
|
144
|
+
EventSubscriber.new
|
145
|
+
end
|
146
|
+
|
147
|
+
after do
|
148
|
+
client.close
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'when connected to a standalone', if: sessions_enabled? && standalone? do
|
152
|
+
|
153
|
+
context 'when the collection specifies a read concern' do
|
154
|
+
|
155
|
+
let(:collection) do
|
156
|
+
client[TEST_COLL, read_concern: { level: 'majority' }]
|
157
|
+
end
|
158
|
+
|
159
|
+
context 'when the session has causal_consistency set to true' do
|
160
|
+
|
161
|
+
let(:session) do
|
162
|
+
client.start_session(causal_consistency: true)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'does not add the afterClusterTime to the read concern in the command' do
|
166
|
+
expect(command['readConcern']['afterClusterTime']).to be_nil
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'when the session has causal_consistency set to false' do
|
171
|
+
|
172
|
+
let(:session) do
|
173
|
+
client.start_session(causal_consistency: false)
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'does not add the afterClusterTime to the read concern in the command' do
|
177
|
+
expect(command['readConcern']['afterClusterTime']).to be_nil
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context 'when the session has causal_consistency not set' do
|
182
|
+
|
183
|
+
let(:session) do
|
184
|
+
client.start_session
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'does not add the afterClusterTime to the read concern in the command' do
|
188
|
+
expect(command['readConcern']['afterClusterTime']).to be_nil
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'when the collection does not specify a read concern' do
|
194
|
+
|
195
|
+
let(:collection) do
|
196
|
+
client[TEST_COLL]
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'when the session has causal_consistency set to true' do
|
200
|
+
|
201
|
+
let(:session) do
|
202
|
+
client.start_session(causal_consistency: true)
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'does not include the read concern in the command' do
|
206
|
+
expect(command['readConcern']).to be_nil
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context 'when the session has causal_consistency set to false' do
|
211
|
+
|
212
|
+
let(:session) do
|
213
|
+
client.start_session(causal_consistency: false)
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'does not include the read concern in the command' do
|
217
|
+
expect(command['readConcern']).to be_nil
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context 'when the session has causal_consistency not set' do
|
222
|
+
|
223
|
+
let(:session) do
|
224
|
+
client.start_session
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'does not include the read concern in the command' do
|
228
|
+
expect(command['readConcern']).to be_nil
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
context 'when connected to replica set or sharded cluster', if: test_sessions? do
|
235
|
+
|
236
|
+
context 'when the collection specifies a read concern' do
|
237
|
+
|
238
|
+
let(:collection) do
|
239
|
+
client[TEST_COLL, read_concern: { level: 'majority' }]
|
240
|
+
end
|
241
|
+
|
242
|
+
context 'when the session has causal_consistency set to true' do
|
243
|
+
|
244
|
+
let(:session) do
|
245
|
+
client.start_session(causal_consistency: true)
|
246
|
+
end
|
247
|
+
|
248
|
+
context 'when the session has an operation time' do
|
249
|
+
|
250
|
+
before do
|
251
|
+
client.database.command({ ping: 1 }, session: session)
|
252
|
+
end
|
253
|
+
|
254
|
+
let!(:operation_time) do
|
255
|
+
session.operation_time
|
256
|
+
end
|
257
|
+
|
258
|
+
let(:expected_read_concern) do
|
259
|
+
BSON::Document.new(level: 'majority', afterClusterTime: operation_time)
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'merges the afterClusterTime with the read concern in the command' do
|
263
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
context 'when the session does not have an operation time' do
|
268
|
+
|
269
|
+
let(:expected_read_concern) do
|
270
|
+
BSON::Document.new(level: 'majority')
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'leaves the read concern document unchanged' do
|
274
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
context 'when the operation time is advanced' do
|
279
|
+
|
280
|
+
before do
|
281
|
+
session.advance_operation_time(operation_time)
|
282
|
+
end
|
283
|
+
|
284
|
+
let(:operation_time) do
|
285
|
+
BSON::Timestamp.new(0, 1)
|
286
|
+
end
|
287
|
+
|
288
|
+
let(:expected_read_concern) do
|
289
|
+
BSON::Document.new(level: 'majority', afterClusterTime: operation_time)
|
290
|
+
end
|
291
|
+
|
292
|
+
it 'merges the afterClusterTime with the new operation time and read concern in the command' do
|
293
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
context 'when the session has causal_consistency set to false' do
|
299
|
+
|
300
|
+
let(:session) do
|
301
|
+
client.start_session(causal_consistency: false)
|
302
|
+
end
|
303
|
+
|
304
|
+
context 'when the session does not have an operation time' do
|
305
|
+
|
306
|
+
let(:expected_read_concern) do
|
307
|
+
BSON::Document.new(level: 'majority')
|
308
|
+
end
|
309
|
+
|
310
|
+
it 'leaves the read concern document unchanged' do
|
311
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
context 'when the session has an operation time' do
|
316
|
+
|
317
|
+
before do
|
318
|
+
client.database.command({ ping: 1 }, session: session)
|
319
|
+
end
|
320
|
+
|
321
|
+
let(:expected_read_concern) do
|
322
|
+
BSON::Document.new(level: 'majority')
|
323
|
+
end
|
324
|
+
|
325
|
+
it 'leaves the read concern document unchanged' do
|
326
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
context 'when the operation time is advanced' do
|
331
|
+
|
332
|
+
before do
|
333
|
+
session.advance_operation_time(operation_time)
|
334
|
+
end
|
335
|
+
|
336
|
+
let(:operation_time) do
|
337
|
+
BSON::Timestamp.new(0, 1)
|
338
|
+
end
|
339
|
+
|
340
|
+
let(:expected_read_concern) do
|
341
|
+
BSON::Document.new(level: 'majority')
|
342
|
+
end
|
343
|
+
|
344
|
+
it 'leaves the read concern document unchanged' do
|
345
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
context 'when the session has causal_consistency not set' do
|
351
|
+
|
352
|
+
let(:session) do
|
353
|
+
client.start_session
|
354
|
+
end
|
355
|
+
|
356
|
+
context 'when the session does not have an operation time' do
|
357
|
+
|
358
|
+
let(:expected_read_concern) do
|
359
|
+
BSON::Document.new(level: 'majority')
|
360
|
+
end
|
361
|
+
|
362
|
+
it 'leaves the read concern document unchanged' do
|
363
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
context 'when the session has an operation time' do
|
368
|
+
|
369
|
+
before do
|
370
|
+
client.database.command({ ping: 1 }, session: session)
|
371
|
+
end
|
372
|
+
|
373
|
+
let!(:operation_time) do
|
374
|
+
session.operation_time
|
375
|
+
end
|
376
|
+
|
377
|
+
let(:expected_read_concern) do
|
378
|
+
BSON::Document.new(level: 'majority', afterClusterTime: operation_time)
|
379
|
+
end
|
380
|
+
|
381
|
+
it 'merges the afterClusterTime with the new operation time and read concern in the command' do
|
382
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
context 'when the operation time is advanced' do
|
387
|
+
|
388
|
+
before do
|
389
|
+
session.advance_operation_time(operation_time)
|
390
|
+
end
|
391
|
+
|
392
|
+
let(:operation_time) do
|
393
|
+
BSON::Timestamp.new(0, 1)
|
394
|
+
end
|
395
|
+
|
396
|
+
let(:expected_read_concern) do
|
397
|
+
BSON::Document.new(level: 'majority', afterClusterTime: operation_time)
|
398
|
+
end
|
399
|
+
|
400
|
+
it 'merges the afterClusterTime with the new operation time and read concern in the command' do
|
401
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
context 'when the collection does not specify a read concern' do
|
408
|
+
|
409
|
+
let(:collection) do
|
410
|
+
client[TEST_COLL]
|
411
|
+
end
|
412
|
+
|
413
|
+
context 'when the session has causal_consistency set to true' do
|
414
|
+
|
415
|
+
let(:session) do
|
416
|
+
client.start_session(causal_consistency: true)
|
417
|
+
end
|
418
|
+
|
419
|
+
context 'when the session does not have an operation time' do
|
420
|
+
|
421
|
+
it 'does not include the read concern in the command' do
|
422
|
+
expect(command['readConcern']).to be_nil
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
context 'when the session has an operation time' do
|
427
|
+
|
428
|
+
before do
|
429
|
+
client.database.command({ ping: 1 }, session: session)
|
430
|
+
end
|
431
|
+
|
432
|
+
let!(:operation_time) do
|
433
|
+
session.operation_time
|
434
|
+
end
|
435
|
+
|
436
|
+
let(:expected_read_concern) do
|
437
|
+
BSON::Document.new(afterClusterTime: operation_time)
|
438
|
+
end
|
439
|
+
|
440
|
+
it 'merges the afterClusterTime with the read concern in the command' do
|
441
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
context 'when the operation time is advanced' do
|
446
|
+
|
447
|
+
before do
|
448
|
+
session.advance_operation_time(operation_time)
|
449
|
+
end
|
450
|
+
|
451
|
+
let(:operation_time) do
|
452
|
+
BSON::Timestamp.new(0, 1)
|
453
|
+
end
|
454
|
+
|
455
|
+
let(:expected_read_concern) do
|
456
|
+
BSON::Document.new(afterClusterTime: operation_time)
|
457
|
+
end
|
458
|
+
|
459
|
+
it 'merges the afterClusterTime with the new operation time in the command' do
|
460
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
context 'when the session has causal_consistency set to false' do
|
466
|
+
|
467
|
+
let(:session) do
|
468
|
+
client.start_session(causal_consistency: false)
|
469
|
+
end
|
470
|
+
|
471
|
+
context 'when the session does not have an operation time' do
|
472
|
+
|
473
|
+
it 'does not include the read concern in the command' do
|
474
|
+
expect(command['readConcern']).to be_nil
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
context 'when the session has an operation time' do
|
479
|
+
|
480
|
+
before do
|
481
|
+
client.database.command({ ping: 1 }, session: session)
|
482
|
+
end
|
483
|
+
|
484
|
+
it 'does not include the read concern in the command' do
|
485
|
+
expect(command['readConcern']).to be_nil
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
context 'when the operation time is advanced' do
|
490
|
+
|
491
|
+
before do
|
492
|
+
session.advance_operation_time(operation_time)
|
493
|
+
end
|
494
|
+
|
495
|
+
let(:operation_time) do
|
496
|
+
BSON::Timestamp.new(0, 1)
|
497
|
+
end
|
498
|
+
|
499
|
+
let(:expected_read_concern) do
|
500
|
+
BSON::Document.new(afterClusterTime: operation_time)
|
501
|
+
end
|
502
|
+
|
503
|
+
it 'does not include the read concern in the command' do
|
504
|
+
expect(command['readConcern']).to be_nil
|
505
|
+
end
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
context 'when the session has causal_consistency not set' do
|
510
|
+
|
511
|
+
let(:session) do
|
512
|
+
client.start_session
|
513
|
+
end
|
514
|
+
|
515
|
+
context 'when the session does not have an operation time' do
|
516
|
+
|
517
|
+
it 'does not include the read concern in the command' do
|
518
|
+
expect(command['readConcern']).to be_nil
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
context 'when the session has an operation time' do
|
523
|
+
|
524
|
+
before do
|
525
|
+
client.database.command({ ping: 1 }, session: session)
|
526
|
+
end
|
527
|
+
|
528
|
+
let!(:operation_time) do
|
529
|
+
session.operation_time
|
530
|
+
end
|
531
|
+
|
532
|
+
let(:expected_read_concern) do
|
533
|
+
BSON::Document.new(afterClusterTime: operation_time)
|
534
|
+
end
|
535
|
+
|
536
|
+
it 'merges the afterClusterTime with the read concern in the command' do
|
537
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
538
|
+
end
|
539
|
+
end
|
540
|
+
|
541
|
+
context 'when the operation time is advanced' do
|
542
|
+
|
543
|
+
before do
|
544
|
+
session.advance_operation_time(operation_time)
|
545
|
+
end
|
546
|
+
|
547
|
+
let(:operation_time) do
|
548
|
+
BSON::Timestamp.new(0, 1)
|
549
|
+
end
|
550
|
+
|
551
|
+
let(:expected_read_concern) do
|
552
|
+
BSON::Document.new(afterClusterTime: operation_time)
|
553
|
+
end
|
554
|
+
|
555
|
+
it 'merges the afterClusterTime with the new operation time in the command' do
|
556
|
+
expect(command['readConcern']).to eq(expected_read_concern)
|
557
|
+
end
|
558
|
+
end
|
559
|
+
end
|
119
560
|
end
|
120
561
|
end
|
121
562
|
end
|
@@ -126,6 +567,10 @@ shared_examples 'an operation updating cluster time' do
|
|
126
567
|
client.cluster
|
127
568
|
end
|
128
569
|
|
570
|
+
let(:session) do
|
571
|
+
client.start_session
|
572
|
+
end
|
573
|
+
|
129
574
|
let(:client) do
|
130
575
|
authorized_client.with(heartbeat_frequency: 100).tap do |cl|
|
131
576
|
cl.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
@@ -144,32 +589,40 @@ shared_examples 'an operation updating cluster time' do
|
|
144
589
|
|
145
590
|
context 'when the server is version 3.6' do
|
146
591
|
|
147
|
-
context 'when the
|
592
|
+
context 'when the cluster is sharded or a replica set', if: test_sessions? do
|
148
593
|
|
149
594
|
let!(:reply_cluster_time) do
|
150
|
-
|
595
|
+
operation_with_session
|
151
596
|
subscriber.succeeded_events[-1].reply['$clusterTime']
|
152
597
|
end
|
153
598
|
|
154
599
|
it 'updates the cluster time of the cluster' do
|
155
600
|
expect(cluster.cluster_time).to eq(reply_cluster_time)
|
156
601
|
end
|
602
|
+
|
603
|
+
it 'updates the cluster time of the session' do
|
604
|
+
expect(session.cluster_time).to eq(reply_cluster_time)
|
605
|
+
end
|
157
606
|
end
|
158
607
|
|
159
|
-
context 'when the server is
|
608
|
+
context 'when the server is a standalone', if: (standalone? && sessions_enabled?) do
|
160
609
|
|
161
610
|
let(:before_cluster_time) do
|
162
611
|
client.cluster.cluster_time
|
163
612
|
end
|
164
613
|
|
165
614
|
let!(:reply_cluster_time) do
|
166
|
-
|
615
|
+
operation_with_session
|
167
616
|
subscriber.succeeded_events[-1].reply['$clusterTime']
|
168
617
|
end
|
169
618
|
|
170
619
|
it 'does not update the cluster time of the cluster' do
|
171
620
|
expect(before_cluster_time).to eq(before_cluster_time)
|
172
621
|
end
|
622
|
+
|
623
|
+
it 'does not update the cluster time of the session' do
|
624
|
+
expect(session.cluster_time).to be_nil
|
625
|
+
end
|
173
626
|
end
|
174
627
|
end
|
175
628
|
|
@@ -193,28 +646,76 @@ shared_examples 'an operation updating cluster time' do
|
|
193
646
|
context 'when the command is run twice' do
|
194
647
|
|
195
648
|
let!(:reply_cluster_time) do
|
196
|
-
|
649
|
+
operation_with_session
|
197
650
|
subscriber.succeeded_events[-1].reply['$clusterTime']
|
198
651
|
end
|
199
652
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
653
|
+
context 'when the cluster is sharded or a replica set', if: test_sessions? do
|
654
|
+
|
655
|
+
context 'when the session cluster time is advanced' do
|
656
|
+
|
657
|
+
before do
|
658
|
+
session.advance_cluster_time(advanced_cluster_time)
|
659
|
+
end
|
660
|
+
|
661
|
+
let(:second_command_cluster_time) do
|
662
|
+
second_operation
|
663
|
+
subscriber.started_events[-1].command['$clusterTime']
|
664
|
+
end
|
204
665
|
|
205
|
-
|
666
|
+
context 'when the advanced cluster time is greater than the existing cluster time' do
|
206
667
|
|
207
|
-
|
208
|
-
|
668
|
+
let(:advanced_cluster_time) do
|
669
|
+
new_timestamp = BSON::Timestamp.new(reply_cluster_time[Mongo::Cluster::CLUSTER_TIME].seconds,
|
670
|
+
reply_cluster_time[Mongo::Cluster::CLUSTER_TIME].increment + 1)
|
671
|
+
new_cluster_time = reply_cluster_time.dup
|
672
|
+
new_cluster_time.merge(Mongo::Cluster::CLUSTER_TIME => new_timestamp)
|
673
|
+
end
|
674
|
+
|
675
|
+
it 'includes the advanced cluster time in the second command' do
|
676
|
+
expect(second_command_cluster_time).to eq(advanced_cluster_time)
|
677
|
+
end
|
678
|
+
end
|
679
|
+
|
680
|
+
context 'when the advanced cluster time is not greater than the existing cluster time' do
|
681
|
+
|
682
|
+
let(:advanced_cluster_time) do
|
683
|
+
new_timestamp = BSON::Timestamp.new(reply_cluster_time[Mongo::Cluster::CLUSTER_TIME].seconds,
|
684
|
+
reply_cluster_time[Mongo::Cluster::CLUSTER_TIME].increment - 1)
|
685
|
+
new_cluster_time = reply_cluster_time.dup
|
686
|
+
new_cluster_time.merge(Mongo::Cluster::CLUSTER_TIME => new_timestamp)
|
687
|
+
end
|
688
|
+
|
689
|
+
it 'does not advance the cluster time' do
|
690
|
+
expect(second_command_cluster_time).to eq(reply_cluster_time)
|
691
|
+
end
|
692
|
+
end
|
693
|
+
end
|
694
|
+
|
695
|
+
context 'when the session cluster time is not advanced' do
|
696
|
+
|
697
|
+
let(:second_command_cluster_time) do
|
698
|
+
second_operation
|
699
|
+
subscriber.started_events[-1].command['$clusterTime']
|
700
|
+
end
|
701
|
+
|
702
|
+
it 'includes the received cluster time in the second command' do
|
703
|
+
expect(second_command_cluster_time).to eq(reply_cluster_time)
|
704
|
+
end
|
209
705
|
end
|
210
706
|
end
|
211
707
|
|
212
|
-
context 'when the server is
|
708
|
+
context 'when the server is a standalone', if: (standalone? && sessions_enabled?) do
|
213
709
|
|
214
710
|
let(:before_cluster_time) do
|
215
711
|
client.cluster.cluster_time
|
216
712
|
end
|
217
713
|
|
714
|
+
let(:second_command_cluster_time) do
|
715
|
+
second_operation
|
716
|
+
subscriber.started_events[-1].command['$clusterTime']
|
717
|
+
end
|
718
|
+
|
218
719
|
it 'does not update the cluster time of the cluster' do
|
219
720
|
second_command_cluster_time
|
220
721
|
expect(before_cluster_time).to eq(before_cluster_time)
|