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
@@ -14,7 +14,7 @@ describe Mongo::Server::Description do
|
|
14
14
|
'arbiters' => [
|
15
15
|
'127.0.0.1:27120'
|
16
16
|
],
|
17
|
-
'primary' =>
|
17
|
+
'primary' => authorized_primary.address.to_s,
|
18
18
|
'tags' => { 'rack' => 'a' },
|
19
19
|
'me' => '127.0.0.1:27019',
|
20
20
|
'maxBsonObjectSize' => 16777216,
|
@@ -25,12 +25,14 @@ describe Mongo::Server::Description do
|
|
25
25
|
'localTime' => Time.now,
|
26
26
|
'lastWrite' => { 'lastWriteDate' => Time.now },
|
27
27
|
'logicalSessionTimeoutMinutes' => 7,
|
28
|
+
'operationTime' => 1,
|
29
|
+
'$clusterTime' => 1,
|
28
30
|
'ok' => 1
|
29
31
|
}
|
30
32
|
end
|
31
33
|
|
32
34
|
let(:address) do
|
33
|
-
Mongo::Address.new(
|
35
|
+
Mongo::Address.new(authorized_primary.address.to_s)
|
34
36
|
end
|
35
37
|
|
36
38
|
let(:monitoring) do
|
@@ -868,7 +870,8 @@ describe Mongo::Server::Description do
|
|
868
870
|
described_class.new(address, replica.merge(
|
869
871
|
'localTime' => 1,
|
870
872
|
'lastWrite' => { 'lastWriteDate' => 1 },
|
871
|
-
'operationTime' =>
|
873
|
+
'operationTime' => 2,
|
874
|
+
'$clusterTime' => 2
|
872
875
|
))
|
873
876
|
end
|
874
877
|
|
data/spec/mongo/server_spec.rb
CHANGED
@@ -201,4 +201,91 @@ describe Mongo::Server do
|
|
201
201
|
expect(server.reconnect!).to be(true)
|
202
202
|
end
|
203
203
|
end
|
204
|
+
|
205
|
+
describe 'retry_writes?' do
|
206
|
+
|
207
|
+
let(:server) do
|
208
|
+
described_class.new(address, cluster, monitoring, listeners, TEST_OPTIONS)
|
209
|
+
end
|
210
|
+
|
211
|
+
before do
|
212
|
+
allow(server).to receive(:features).and_return(features)
|
213
|
+
end
|
214
|
+
|
215
|
+
context 'when the server version is less than 3.6' do
|
216
|
+
|
217
|
+
let(:features) do
|
218
|
+
double('features', sessions_enabled?: false)
|
219
|
+
end
|
220
|
+
|
221
|
+
context 'when the server has a logical_session_timeout value' do
|
222
|
+
|
223
|
+
before do
|
224
|
+
allow(server).to receive(:logical_session_timeout).and_return(true)
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'returns false' do
|
228
|
+
expect(server.retry_writes?).to be(false)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context 'when the server does not have a logical_session_timeout value' do
|
233
|
+
|
234
|
+
before do
|
235
|
+
allow(server).to receive(:logical_session_timeout).and_return(nil)
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'returns false' do
|
239
|
+
expect(server.retry_writes?).to be(false)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context 'when the server version is at least 3.6' do
|
245
|
+
|
246
|
+
let(:features) do
|
247
|
+
double('features', sessions_enabled?: true)
|
248
|
+
end
|
249
|
+
|
250
|
+
context 'when the server has a logical_session_timeout value' do
|
251
|
+
|
252
|
+
before do
|
253
|
+
allow(server).to receive(:logical_session_timeout).and_return(true)
|
254
|
+
end
|
255
|
+
|
256
|
+
context 'when the server is a standalone' do
|
257
|
+
|
258
|
+
before do
|
259
|
+
allow(server).to receive(:standalone?).and_return(true)
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'returns false' do
|
263
|
+
expect(server.retry_writes?).to be(false)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
context 'when the server is not a standalone' do
|
268
|
+
|
269
|
+
before do
|
270
|
+
allow(server).to receive(:standalone?).and_return(true)
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'returns false' do
|
274
|
+
expect(server.retry_writes?).to be(false)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
context 'when the server does not have a logical_session_timeout value' do
|
280
|
+
|
281
|
+
before do
|
282
|
+
allow(server).to receive(:logical_session_timeout).and_return(nil)
|
283
|
+
end
|
284
|
+
|
285
|
+
it 'returns false' do
|
286
|
+
expect(server.retry_writes?).to be(false)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
204
291
|
end
|
@@ -9,8 +9,51 @@ describe Mongo::Session::ServerSession do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'sets a UUID as the session id' do
|
12
|
+
expect(described_class.new.instance_variable_get(:@session_id)).to be_a(BSON::Document)
|
12
13
|
expect(described_class.new.session_id).to be_a(BSON::Document)
|
13
14
|
expect(described_class.new.session_id[:id]).to be_a(BSON::Binary)
|
14
15
|
end
|
15
16
|
end
|
17
|
+
|
18
|
+
describe '#next_txn_number' do
|
19
|
+
|
20
|
+
it 'advances and returns the next transaction number' do
|
21
|
+
expect(described_class.new.next_txn_num).to be(0)
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when the method is called multiple times' do
|
25
|
+
|
26
|
+
let(:server_session) do
|
27
|
+
described_class.new
|
28
|
+
end
|
29
|
+
|
30
|
+
before do
|
31
|
+
server_session.next_txn_num
|
32
|
+
server_session.next_txn_num
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'advances and returns the next transaction number' do
|
36
|
+
expect(server_session.next_txn_num).to be(2)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#inspect' do
|
42
|
+
|
43
|
+
let(:session) do
|
44
|
+
described_class.new
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'includes the Ruby object_id in the formatted string' do
|
48
|
+
expect(session.inspect).to include(session.object_id.to_s)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'includes the session_id in the formatted string' do
|
52
|
+
expect(session.inspect).to include(session.session_id.to_s)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'includes the last_use in the formatted string' do
|
56
|
+
expect(session.inspect).to include(session.last_use.to_s)
|
57
|
+
end
|
58
|
+
end
|
16
59
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Mongo::Session::SessionPool do
|
3
|
+
describe Mongo::Session::SessionPool, if: test_sessions? do
|
4
4
|
|
5
5
|
describe '.create' do
|
6
6
|
|
@@ -32,7 +32,27 @@ describe Mongo::Session::SessionPool do
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
describe '
|
35
|
+
describe '#inspect' do
|
36
|
+
|
37
|
+
let(:pool) do
|
38
|
+
described_class.new(authorized_client)
|
39
|
+
end
|
40
|
+
|
41
|
+
before do
|
42
|
+
s = pool.checkout
|
43
|
+
pool.checkin(s)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'includes the Ruby object_id in the formatted string' do
|
47
|
+
expect(pool.inspect).to include(pool.object_id.to_s)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'includes the pool size in the formatted string' do
|
51
|
+
expect(pool.inspect).to include('current_size=1')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'checkout' do
|
36
56
|
|
37
57
|
let(:pool) do
|
38
58
|
described_class.new(authorized_client)
|
@@ -115,7 +135,7 @@ describe Mongo::Session::SessionPool do
|
|
115
135
|
end
|
116
136
|
end
|
117
137
|
|
118
|
-
describe '#end_sessions'
|
138
|
+
describe '#end_sessions' do
|
119
139
|
|
120
140
|
let(:pool) do
|
121
141
|
described_class.create(client)
|
@@ -139,44 +159,60 @@ describe Mongo::Session::SessionPool do
|
|
139
159
|
EventSubscriber.new
|
140
160
|
end
|
141
161
|
|
142
|
-
before do
|
143
|
-
client.database.command(ping: 1)
|
144
|
-
pool.checkin(session_a)
|
145
|
-
pool.checkin(session_b)
|
146
|
-
pool.end_sessions
|
147
|
-
end
|
148
|
-
|
149
162
|
after do
|
150
163
|
client.close
|
151
164
|
end
|
152
165
|
|
153
|
-
|
154
|
-
subscriber.started_events.find { |c| c.command_name == :endSessions}
|
155
|
-
end
|
166
|
+
context 'when the number of ids is not larger than 10,000' do
|
156
167
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
168
|
+
before do
|
169
|
+
client.database.command(ping: 1)
|
170
|
+
pool.checkin(session_a)
|
171
|
+
pool.checkin(session_b)
|
172
|
+
end
|
173
|
+
|
174
|
+
let!(:cluster_time) do
|
175
|
+
client.cluster.cluster_time
|
176
|
+
end
|
161
177
|
|
162
|
-
|
178
|
+
let(:end_sessions_command) do
|
179
|
+
pool.end_sessions
|
180
|
+
subscriber.started_events.find { |c| c.command_name == :endSessions}
|
181
|
+
end
|
163
182
|
|
164
183
|
it 'sends the endSessions command with all the session ids' do
|
165
|
-
|
166
|
-
expect(end_sessions_command.command[:
|
167
|
-
expect(end_sessions_command.command[
|
184
|
+
end_sessions_command
|
185
|
+
expect(end_sessions_command.command[:endSessions]).to include(BSON::Document.new(session_a.session_id))
|
186
|
+
expect(end_sessions_command.command[:endSessions]).to include(BSON::Document.new(session_b.session_id))
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'when talking to a replica set or mongos' do
|
190
|
+
|
191
|
+
it 'sends the endSessions command with all the session ids and cluster time' do
|
192
|
+
end_sessions_command
|
193
|
+
expect(end_sessions_command.command[:endSessions]).to include(BSON::Document.new(session_a.session_id))
|
194
|
+
expect(end_sessions_command.command[:endSessions]).to include(BSON::Document.new(session_b.session_id))
|
195
|
+
expect(end_sessions_command.command[:$clusterTime]).to eq(client.cluster.cluster_time)
|
196
|
+
end
|
168
197
|
end
|
169
198
|
end
|
170
199
|
|
171
200
|
context 'when the number of ids is larger than 10_000' do
|
172
201
|
|
202
|
+
let(:ids) do
|
203
|
+
10_001.times.map do |i|
|
204
|
+
bytes = [SecureRandom.uuid.gsub(/\-/, '')].pack('H*')
|
205
|
+
BSON::Document.new(id: BSON::Binary.new(bytes, :uuid))
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
173
209
|
before do
|
174
210
|
queue = []
|
175
|
-
|
176
|
-
queue << double('session', session_id:
|
211
|
+
ids.each do |id|
|
212
|
+
queue << double('session', session_id: id)
|
177
213
|
end
|
178
214
|
pool.instance_variable_set(:@queue, queue)
|
179
|
-
expect(Mongo::Operation::Commands::Command).to receive(:new).at_least(:twice)
|
215
|
+
expect(Mongo::Operation::Commands::Command).to receive(:new).at_least(:twice).and_call_original
|
180
216
|
end
|
181
217
|
|
182
218
|
let(:end_sessions_commands) do
|
@@ -185,9 +221,9 @@ describe Mongo::Session::SessionPool do
|
|
185
221
|
|
186
222
|
it 'sends the command more than once' do
|
187
223
|
pool.end_sessions
|
188
|
-
|
189
|
-
|
190
|
-
|
224
|
+
expect(end_sessions_commands.size).to eq(2)
|
225
|
+
expect(end_sessions_commands[0].command[:endSessions]).to eq(ids[0...10_000])
|
226
|
+
expect(end_sessions_commands[1].command[:endSessions]).to eq([ids[10_000]])
|
191
227
|
end
|
192
228
|
end
|
193
229
|
end
|
@@ -0,0 +1,247 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongo::Session, if: test_sessions? do
|
4
|
+
|
5
|
+
let(:session) do
|
6
|
+
authorized_client.start_session(options)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:options) do
|
10
|
+
{}
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#initialize' do
|
14
|
+
|
15
|
+
context 'when options are provided' do
|
16
|
+
|
17
|
+
it 'duplicates and freezes the options' do
|
18
|
+
expect(session.options).not_to be(options)
|
19
|
+
expect(session.options.frozen?).to be(true)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'sets a server session with an id' do
|
24
|
+
expect(session.session_id).to be_a(BSON::Document)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'sets the cluster time to nil' do
|
28
|
+
expect(session.cluster_time).to be(nil)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'sets the client' do
|
32
|
+
expect(session.client).to be(authorized_client)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#inspect' do
|
37
|
+
|
38
|
+
it 'includes the Ruby object_id in the formatted string' do
|
39
|
+
expect(session.inspect).to include(session.object_id.to_s)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'includes the session_id in the formatted string' do
|
43
|
+
expect(session.inspect).to include(session.session_id.to_s)
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when options are provided' do
|
47
|
+
|
48
|
+
let(:options) do
|
49
|
+
{ causal_consistency: true }
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'includes the options in the formatted string' do
|
53
|
+
expect(session.inspect).to include({ causal_consistency: true }.to_s)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#advance_cluster_time' do
|
59
|
+
|
60
|
+
let(:new_cluster_time) do
|
61
|
+
{ 'clusterTime' => BSON::Timestamp.new(0, 5) }
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when the session does not have a cluster time' do
|
65
|
+
|
66
|
+
before do
|
67
|
+
session.advance_cluster_time(new_cluster_time)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'sets the new cluster time' do
|
71
|
+
expect(session.cluster_time).to eq(new_cluster_time)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when the session already has a cluster time' do
|
76
|
+
|
77
|
+
context 'when the original cluster time is less than the new cluster time' do
|
78
|
+
|
79
|
+
let(:original_cluster_time) do
|
80
|
+
{ 'clusterTime' => BSON::Timestamp.new(0, 1) }
|
81
|
+
end
|
82
|
+
|
83
|
+
before do
|
84
|
+
session.instance_variable_set(:@cluster_time, original_cluster_time)
|
85
|
+
session.advance_cluster_time(new_cluster_time)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'sets the new cluster time' do
|
89
|
+
expect(session.cluster_time).to eq(new_cluster_time)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'when the original cluster time is equal or greater than the new cluster time' do
|
94
|
+
|
95
|
+
let(:original_cluster_time) do
|
96
|
+
{ 'clusterTime' => BSON::Timestamp.new(0, 6) }
|
97
|
+
end
|
98
|
+
|
99
|
+
before do
|
100
|
+
session.instance_variable_set(:@cluster_time, original_cluster_time)
|
101
|
+
session.advance_cluster_time(new_cluster_time)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'does not update the cluster time' do
|
105
|
+
expect(session.cluster_time).to eq(original_cluster_time)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#advance_operation_time' do
|
112
|
+
|
113
|
+
let(:new_operation_time) do
|
114
|
+
BSON::Timestamp.new(0, 5)
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'when the session does not have an operation time' do
|
118
|
+
|
119
|
+
before do
|
120
|
+
session.advance_operation_time(new_operation_time)
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'sets the new operation time' do
|
124
|
+
expect(session.operation_time).to eq(new_operation_time)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'when the session already has an operation time' do
|
129
|
+
|
130
|
+
context 'when the original operation time is less than the new operation time' do
|
131
|
+
|
132
|
+
let(:original_operation_time) do
|
133
|
+
BSON::Timestamp.new(0, 1)
|
134
|
+
end
|
135
|
+
|
136
|
+
before do
|
137
|
+
session.instance_variable_set(:@operation_time, original_operation_time)
|
138
|
+
session.advance_operation_time(new_operation_time)
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'sets the new operation time' do
|
142
|
+
expect(session.operation_time).to eq(new_operation_time)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'when the original operation time is equal or greater than the new operation time' do
|
147
|
+
|
148
|
+
let(:original_operation_time) do
|
149
|
+
BSON::Timestamp.new(0, 6)
|
150
|
+
end
|
151
|
+
|
152
|
+
before do
|
153
|
+
session.instance_variable_set(:@operation_time, original_operation_time)
|
154
|
+
session.advance_operation_time(new_operation_time)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'does not update the operation time' do
|
158
|
+
expect(session.operation_time).to eq(original_operation_time)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe 'ended?' do
|
165
|
+
|
166
|
+
context 'when the session has not been ended' do
|
167
|
+
|
168
|
+
it 'returns false' do
|
169
|
+
expect(session.ended?).to be(false)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'when the session has been ended' do
|
174
|
+
|
175
|
+
before do
|
176
|
+
session.end_session
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'returns true' do
|
180
|
+
expect(session.ended?).to be(true)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe 'end_session' do
|
186
|
+
|
187
|
+
let!(:server_session) do
|
188
|
+
session.instance_variable_get(:@server_session)
|
189
|
+
end
|
190
|
+
|
191
|
+
let(:client_session_pool) do
|
192
|
+
session.client.instance_variable_get(:@session_pool)
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'returns the server session to the client session pool' do
|
196
|
+
session.end_session
|
197
|
+
expect(client_session_pool.instance_variable_get(:@queue)).to include(server_session)
|
198
|
+
end
|
199
|
+
|
200
|
+
context 'when #end_session is called multiple times' do
|
201
|
+
|
202
|
+
before do
|
203
|
+
session.end_session
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'returns nil' do
|
207
|
+
expect(session.end_session).to be_nil
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe '#retry_writes?', if: test_sessions? do
|
213
|
+
|
214
|
+
context 'when the option is set to true' do
|
215
|
+
|
216
|
+
let(:client) do
|
217
|
+
authorized_client.with(retry_writes: true)
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'returns true' do
|
221
|
+
expect(client.start_session.retry_writes?).to be(true)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context 'when the option is set to false' do
|
226
|
+
|
227
|
+
let(:client) do
|
228
|
+
authorized_client.with(retry_writes: false)
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'returns false' do
|
232
|
+
expect(client.start_session.retry_writes?).to be(false)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
context 'when the option is not defined' do
|
237
|
+
|
238
|
+
let(:client) do
|
239
|
+
authorized_client
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'returns false' do
|
243
|
+
expect(client.start_session.retry_writes?).to be(false)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|