mongo 2.5.0 → 2.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +2 -0
- data/Rakefile +4 -1
- data/lib/mongo/address.rb +2 -1
- data/lib/mongo/client.rb +6 -51
- data/lib/mongo/cluster.rb +34 -4
- data/lib/mongo/cluster/reapers/socket_reaper.rb +1 -1
- data/lib/mongo/cluster/topology/replica_set.rb +3 -1
- data/lib/mongo/collection.rb +6 -6
- data/lib/mongo/collection/view.rb +2 -4
- data/lib/mongo/cursor.rb +9 -4
- data/lib/mongo/error.rb +2 -0
- data/lib/mongo/operation/uses_command_op_msg.rb +1 -1
- data/lib/mongo/server.rb +3 -0
- data/lib/mongo/server/description.rb +1 -1
- data/lib/mongo/server/description/features.rb +18 -12
- data/lib/mongo/server_selector/selectable.rb +5 -1
- data/lib/mongo/session.rb +38 -43
- data/lib/mongo/session/session_pool.rb +12 -30
- data/lib/mongo/socket.rb +24 -0
- data/lib/mongo/socket/tcp.rb +0 -1
- data/lib/mongo/uri.rb +26 -5
- data/lib/mongo/version.rb +1 -1
- data/spec/mongo/address_spec.rb +37 -2
- data/spec/mongo/bulk_write_spec.rb +4 -10
- data/spec/mongo/change_stream_examples_spec.rb +40 -0
- data/spec/mongo/client_spec.rb +47 -12
- data/spec/mongo/cluster/topology/replica_set_spec.rb +2 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +2 -8
- data/spec/mongo/collection/view/change_stream_spec.rb +1 -5
- data/spec/mongo/collection/view/map_reduce_spec.rb +2 -8
- data/spec/mongo/collection/view/readable_spec.rb +1 -1
- data/spec/mongo/collection_spec.rb +11 -29
- data/spec/mongo/crud_spec.rb +6 -2
- data/spec/mongo/cursor_spec.rb +84 -1
- data/spec/mongo/database_spec.rb +2 -8
- data/spec/mongo/dns_seedlist_discovery_spec.rb +67 -63
- data/spec/mongo/max_staleness_spec.rb +1 -0
- data/spec/mongo/retryable_writes_spec.rb +7 -9
- data/spec/mongo/sdam_spec.rb +42 -24
- data/spec/mongo/server/description/features_spec.rb +3 -3
- data/spec/mongo/server_selection_spec.rb +2 -0
- data/spec/mongo/server_selector_spec.rb +2 -0
- data/spec/mongo/session/session_pool_spec.rb +16 -22
- data/spec/mongo/session_spec.rb +13 -8
- data/spec/mongo/uri/srv_protocol_spec.rb +481 -478
- data/spec/mongo/uri_spec.rb +1 -1
- data/spec/spec_helper.rb +11 -63
- data/spec/support/authorization.rb +35 -1
- data/spec/support/connection_string_tests/invalid-uris.yml +27 -11
- data/spec/support/event_subscriber.rb +66 -0
- data/spec/support/sdam/rs/compatible.yml +41 -0
- data/spec/support/sdam/rs/discover_arbiters.yml +3 -1
- data/spec/support/sdam/rs/discover_passives.yml +6 -2
- data/spec/support/sdam/rs/discover_primary.yml +3 -1
- data/spec/support/sdam/rs/discover_secondary.yml +3 -1
- data/spec/support/sdam/rs/discovery.yml +12 -4
- data/spec/support/sdam/rs/equal_electionids.yml +6 -2
- data/spec/support/sdam/rs/ghost_discovered.yml +3 -1
- data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +3 -1
- data/spec/support/sdam/rs/ls_timeout.yml +169 -14
- data/spec/support/sdam/rs/member_reconfig.yml +6 -2
- data/spec/support/sdam/rs/member_standalone.yml +6 -2
- data/spec/support/sdam/rs/new_primary.yml +6 -2
- data/spec/support/sdam/rs/new_primary_new_electionid.yml +9 -3
- data/spec/support/sdam/rs/new_primary_new_setversion.yml +9 -3
- data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +6 -2
- data/spec/support/sdam/rs/non_rs_member.yml +3 -2
- data/spec/support/sdam/rs/normalize_case.yml +3 -1
- data/spec/support/sdam/rs/null_election_id.yml +12 -4
- data/spec/support/sdam/rs/primary_becomes_standalone.yml +6 -4
- data/spec/support/sdam/rs/primary_changes_set_name.yml +6 -2
- data/spec/support/sdam/rs/primary_disconnect.yml +3 -1
- data/spec/support/sdam/rs/primary_disconnect_electionid.yml +15 -5
- data/spec/support/sdam/rs/primary_disconnect_setversion.yml +15 -5
- data/spec/support/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +6 -2
- data/spec/support/sdam/rs/primary_mismatched_me.yml +26 -37
- data/spec/support/sdam/rs/primary_reports_new_member.yml +12 -4
- data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +6 -2
- data/spec/support/sdam/rs/primary_wrong_set_name.yml +3 -1
- data/spec/support/sdam/rs/response_from_removed.yml +6 -2
- data/spec/support/sdam/rs/rsother_discovered.yml +6 -2
- data/spec/support/sdam/rs/sec_not_auth.yml +6 -2
- data/spec/support/sdam/rs/secondary_mismatched_me.yml +26 -37
- data/spec/support/sdam/rs/secondary_wrong_set_name.yml +3 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +6 -2
- data/spec/support/sdam/rs/setversion_without_electionid.yml +6 -2
- data/spec/support/sdam/rs/stepdown_change_set_name.yml +6 -2
- data/spec/support/sdam/rs/too_new.yml +41 -0
- data/spec/support/sdam/rs/too_old.yml +39 -0
- data/spec/support/sdam/rs/unexpected_mongos.yml +3 -1
- data/spec/support/sdam/rs/use_setversion_without_electionid.yml +9 -3
- data/spec/support/sdam/rs/wrong_set_name.yml +3 -1
- data/spec/support/server_discovery_and_monitoring.rb +13 -0
- data/spec/support/shared/session.rb +10 -30
- metadata +10 -2
- metadata.gz.sig +0 -0
@@ -26,30 +26,30 @@ module Mongo
|
|
26
26
|
# Create a SessionPool.
|
27
27
|
#
|
28
28
|
# @example
|
29
|
-
# SessionPool.create(
|
29
|
+
# SessionPool.create(cluster)
|
30
30
|
#
|
31
|
-
# @param [ Mongo::
|
31
|
+
# @param [ Mongo::Cluster ] cluster The cluster that will be associated with this
|
32
32
|
# session pool.
|
33
33
|
#
|
34
34
|
# @since 2.5.0
|
35
|
-
def self.create(
|
36
|
-
pool = new(
|
37
|
-
|
35
|
+
def self.create(cluster)
|
36
|
+
pool = new(cluster)
|
37
|
+
cluster.instance_variable_set(:@session_pool, pool)
|
38
38
|
end
|
39
39
|
|
40
40
|
# Initialize a SessionPool.
|
41
41
|
#
|
42
42
|
# @example
|
43
|
-
# SessionPool.new(
|
43
|
+
# SessionPool.new(cluster)
|
44
44
|
#
|
45
|
-
# @param [ Mongo::
|
45
|
+
# @param [ Mongo::Cluster ] cluster The cluster that will be associated with this
|
46
46
|
# session pool.
|
47
47
|
#
|
48
48
|
# @since 2.5.0
|
49
|
-
def initialize(
|
49
|
+
def initialize(cluster)
|
50
50
|
@queue = []
|
51
51
|
@mutex = Mutex.new
|
52
|
-
@
|
52
|
+
@cluster = cluster
|
53
53
|
end
|
54
54
|
|
55
55
|
# Get a formatted string for use in inspection.
|
@@ -64,24 +64,6 @@ module Mongo
|
|
64
64
|
"#<Mongo::Session::SessionPool:0x#{object_id} current_size=#{@queue.size}>"
|
65
65
|
end
|
66
66
|
|
67
|
-
# Checkout a session to be used in the context of a block and return the session back to
|
68
|
-
# the pool after the block completes.
|
69
|
-
#
|
70
|
-
# @example Checkout, use a session, and return it back to the pool after the block.
|
71
|
-
# pool.with_session do |session|
|
72
|
-
# ...
|
73
|
-
# end
|
74
|
-
#
|
75
|
-
# @yieldparam [ ServerSession ] The server session.
|
76
|
-
#
|
77
|
-
# @since 2.5.0
|
78
|
-
def with_session
|
79
|
-
server_session = checkout
|
80
|
-
yield(server_session)
|
81
|
-
ensure
|
82
|
-
begin; checkin(server_session) if server_session; rescue; end
|
83
|
-
end
|
84
|
-
|
85
67
|
# Checkout a server session from the pool.
|
86
68
|
#
|
87
69
|
# @example Checkout a session.
|
@@ -130,7 +112,7 @@ module Mongo
|
|
130
112
|
# @since 2.5.0
|
131
113
|
def end_sessions
|
132
114
|
while !@queue.empty?
|
133
|
-
server = ServerSelector.get(mode: :primary_preferred).select_server(@
|
115
|
+
server = ServerSelector.get(mode: :primary_preferred).select_server(@cluster)
|
134
116
|
Operation::Commands::Command.new(
|
135
117
|
:selector => {endSessions: @queue.shift(10_000).collect { |s| s.session_id }},
|
136
118
|
:db_name => Database::ADMIN).execute(server)
|
@@ -141,9 +123,9 @@ module Mongo
|
|
141
123
|
private
|
142
124
|
|
143
125
|
def about_to_expire?(session)
|
144
|
-
if @
|
126
|
+
if @cluster.logical_session_timeout
|
145
127
|
idle_time_minutes = (Time.now - session.last_use) / 60
|
146
|
-
(idle_time_minutes + 1) >= @
|
128
|
+
(idle_time_minutes + 1) >= @cluster.logical_session_timeout
|
147
129
|
end
|
148
130
|
end
|
149
131
|
|
data/lib/mongo/socket.rb
CHANGED
@@ -190,8 +190,32 @@ module Mongo
|
|
190
190
|
defined?(UNIXSocket) && sock.is_a?(UNIXSocket)
|
191
191
|
end
|
192
192
|
|
193
|
+
DEFAULT_TCP_KEEPINTVL = 10
|
194
|
+
|
195
|
+
DEFAULT_TCP_KEEPCNT = 9
|
196
|
+
|
197
|
+
DEFAULT_TCP_KEEPIDLE = 300
|
198
|
+
|
199
|
+
def set_keepalive_opts(sock)
|
200
|
+
sock.setsockopt(SOL_SOCKET, SO_KEEPALIVE, true)
|
201
|
+
set_option(sock, :TCP_KEEPINTVL, DEFAULT_TCP_KEEPINTVL)
|
202
|
+
set_option(sock, :TCP_KEEPCNT, DEFAULT_TCP_KEEPCNT)
|
203
|
+
set_option(sock, :TCP_KEEPIDLE, DEFAULT_TCP_KEEPIDLE)
|
204
|
+
rescue
|
205
|
+
end
|
206
|
+
|
207
|
+
def set_option(sock, option, default)
|
208
|
+
if Socket.const_defined?(option)
|
209
|
+
system_default = sock.getsockopt(IPPROTO_TCP, option).int
|
210
|
+
if system_default > default
|
211
|
+
sock.setsockopt(IPPROTO_TCP, option, default)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
193
216
|
def set_socket_options(sock)
|
194
217
|
sock.set_encoding(BSON::BINARY)
|
218
|
+
set_keepalive_opts(sock)
|
195
219
|
end
|
196
220
|
|
197
221
|
def handle_errors
|
data/lib/mongo/socket/tcp.rb
CHANGED
@@ -43,7 +43,6 @@ module Mongo
|
|
43
43
|
def connect!(connect_timeout = nil)
|
44
44
|
Timeout.timeout(connect_timeout, Error::SocketTimeoutError) do
|
45
45
|
socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
|
46
|
-
socket.setsockopt(SOL_SOCKET, SO_KEEPALIVE, true)
|
47
46
|
handle_errors { socket.connect(::Socket.pack_sockaddr_in(port, host)) }
|
48
47
|
self
|
49
48
|
end
|
data/lib/mongo/uri.rb
CHANGED
@@ -84,6 +84,11 @@ module Mongo
|
|
84
84
|
# @since 2.1.0
|
85
85
|
UNSAFE = /[\:\/\+\@]/
|
86
86
|
|
87
|
+
# Percent sign that must be encoded in user creds.
|
88
|
+
#
|
89
|
+
# @since 2.5.1
|
90
|
+
PERCENT_CHAR = /\%/
|
91
|
+
|
87
92
|
# Unix socket suffix.
|
88
93
|
#
|
89
94
|
# @since 2.1.0
|
@@ -334,15 +339,27 @@ module Mongo
|
|
334
339
|
|
335
340
|
def parse_user!(string)
|
336
341
|
if (string && user = string.partition(AUTH_USER_PWD_DELIM)[0])
|
337
|
-
|
338
|
-
|
342
|
+
if user.length > 0
|
343
|
+
raise_invalid_error!(UNESCAPED_USER_PWD) if user =~ UNSAFE
|
344
|
+
user_decoded = decode(user)
|
345
|
+
if user_decoded =~ PERCENT_CHAR && encode(user_decoded) != user
|
346
|
+
raise_invalid_error!(UNESCAPED_USER_PWD)
|
347
|
+
end
|
348
|
+
user_decoded
|
349
|
+
end
|
339
350
|
end
|
340
351
|
end
|
341
352
|
|
342
353
|
def parse_password!(string)
|
343
354
|
if (string && pwd = string.partition(AUTH_USER_PWD_DELIM)[2])
|
344
|
-
|
345
|
-
|
355
|
+
if pwd.length > 0
|
356
|
+
raise_invalid_error!(UNESCAPED_USER_PWD) if pwd =~ UNSAFE
|
357
|
+
pwd_decoded = decode(pwd)
|
358
|
+
if pwd_decoded =~ PERCENT_CHAR && encode(pwd_decoded) != pwd
|
359
|
+
raise_invalid_error!(UNESCAPED_USER_PWD)
|
360
|
+
end
|
361
|
+
pwd_decoded
|
362
|
+
end
|
346
363
|
end
|
347
364
|
end
|
348
365
|
|
@@ -382,7 +399,11 @@ module Mongo
|
|
382
399
|
end
|
383
400
|
|
384
401
|
def decode(value)
|
385
|
-
::URI
|
402
|
+
::URI.decode(value)
|
403
|
+
end
|
404
|
+
|
405
|
+
def encode(value)
|
406
|
+
::URI.encode(value)
|
386
407
|
end
|
387
408
|
|
388
409
|
# Hash for storing map of URI option parameters to conversion strategies
|
data/lib/mongo/version.rb
CHANGED
data/spec/mongo/address_spec.rb
CHANGED
@@ -214,13 +214,22 @@ describe Mongo::Address do
|
|
214
214
|
address.host
|
215
215
|
end
|
216
216
|
|
217
|
+
let(:addr_info) do
|
218
|
+
family = (host == 'localhost') ? ::Socket::AF_INET : ::Socket::AF_UNSPEC
|
219
|
+
::Socket.getaddrinfo(host, nil, family, ::Socket::SOCK_STREAM)
|
220
|
+
end
|
221
|
+
|
222
|
+
let(:socket_address_or_host) do
|
223
|
+
(host == 'localhost') ? addr_info.first[3] : host
|
224
|
+
end
|
225
|
+
|
217
226
|
context 'when providing a DNS entry that resolves to both IPv6 and IPv4' do
|
218
227
|
|
219
228
|
before do
|
220
229
|
address.instance_variable_set(:@resolver, nil)
|
221
230
|
allow(::Socket).to receive(:getaddrinfo).and_return(
|
222
231
|
[ ["AF_INET6", 0, '::1', '::1', ::Socket::AF_INET6, 1, 6],
|
223
|
-
["AF_INET", 0,
|
232
|
+
["AF_INET", 0, socket_address_or_host, socket_address_or_host, ::Socket::AF_INET, 1, 6]]
|
224
233
|
)
|
225
234
|
end
|
226
235
|
|
@@ -237,7 +246,33 @@ describe Mongo::Address do
|
|
237
246
|
end
|
238
247
|
|
239
248
|
it 'uses the host, not the IP address' do
|
240
|
-
expect(address.socket(0.0).host).to eq(
|
249
|
+
expect(address.socket(0.0).host).to eq(socket_address_or_host)
|
250
|
+
end
|
251
|
+
|
252
|
+
let(:socket) do
|
253
|
+
if running_ssl?
|
254
|
+
address.socket(0.0, SSL_OPTIONS).instance_variable_get(:@tcp_socket)
|
255
|
+
else
|
256
|
+
address.socket(0.0).instance_variable_get(:@socket)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
if Socket.const_defined?(:TCP_KEEPINTVL)
|
261
|
+
it 'sets the socket TCP_KEEPINTVL option' do
|
262
|
+
expect(socket.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPINTVL).int).to be <= 10
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
if Socket.const_defined?(:TCP_KEEPCNT)
|
267
|
+
it 'sets the socket TCP_KEEPCNT option' do
|
268
|
+
expect(socket.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPCNT).int).to be <= 9
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
if Socket.const_defined?(:TCP_KEEPIDLE)
|
273
|
+
it 'sets the socket TCP_KEEPIDLE option' do
|
274
|
+
expect(socket.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPIDLE).int).to be <= 300
|
275
|
+
end
|
241
276
|
end
|
242
277
|
end
|
243
278
|
end
|
@@ -1889,32 +1889,26 @@ describe Mongo::BulkWrite do
|
|
1889
1889
|
it_behaves_like 'an operation using a session'
|
1890
1890
|
end
|
1891
1891
|
|
1892
|
-
context 'when retryable writes are supported', if:
|
1892
|
+
context 'when retryable writes are supported', if: test_sessions? do
|
1893
1893
|
|
1894
1894
|
let(:client) do
|
1895
|
-
|
1896
|
-
cl.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
1897
|
-
end
|
1895
|
+
authorized_client_with_retry_writes
|
1898
1896
|
end
|
1899
1897
|
|
1900
1898
|
let(:collection) do
|
1901
1899
|
client[authorized_collection.name]
|
1902
1900
|
end
|
1903
1901
|
|
1904
|
-
let(:subscriber) do
|
1905
|
-
EventSubscriber.new
|
1906
|
-
end
|
1907
|
-
|
1908
1902
|
let!(:result) do
|
1909
1903
|
bulk_write.execute
|
1910
1904
|
end
|
1911
1905
|
|
1912
1906
|
let(:first_txn_number) do
|
1913
|
-
|
1907
|
+
EventSubscriber.started_events[-2].command['txnNumber'].instance_variable_get(:@integer)
|
1914
1908
|
end
|
1915
1909
|
|
1916
1910
|
let(:second_txn_number) do
|
1917
|
-
|
1911
|
+
EventSubscriber.started_events[-1].command['txnNumber'].instance_variable_get(:@integer)
|
1918
1912
|
end
|
1919
1913
|
|
1920
1914
|
it 'inserts the documents' do
|
@@ -147,4 +147,44 @@ describe 'change streams examples in Ruby', if: test_change_streams? do
|
|
147
147
|
resumed_change.each { |key| expect(resumed_change[key]).to eq(next_next_change[key]) }
|
148
148
|
end
|
149
149
|
end
|
150
|
+
|
151
|
+
context 'example 4 - using a pipeline to filter changes' do
|
152
|
+
|
153
|
+
it 'returns the filtered changes' do
|
154
|
+
|
155
|
+
ops_thread = Thread.new do
|
156
|
+
sleep 2
|
157
|
+
inventory.insert_one(username: 'wallace')
|
158
|
+
inventory.insert_one(username: 'alice')
|
159
|
+
inventory.delete_one(username: 'wallace')
|
160
|
+
end
|
161
|
+
|
162
|
+
stream_thread = Thread.new do
|
163
|
+
|
164
|
+
# Start Changestream Example 4
|
165
|
+
|
166
|
+
pipeline = [ {'$match' => { '$or' => [{ 'fullDocument.username' => 'alice' },
|
167
|
+
{ 'operationType' => 'delete' }] } }]
|
168
|
+
cursor = inventory.watch(pipeline).to_enum
|
169
|
+
cursor.next
|
170
|
+
|
171
|
+
# End Changestream Example 4
|
172
|
+
end
|
173
|
+
|
174
|
+
ops_thread.value
|
175
|
+
change = stream_thread.value
|
176
|
+
|
177
|
+
expect(change['_id']).not_to be_nil
|
178
|
+
expect(change['_id']['_data']).not_to be_nil
|
179
|
+
expect(change['operationType']).to eq('insert')
|
180
|
+
expect(change['fullDocument']).not_to be_nil
|
181
|
+
expect(change['fullDocument']['_id']).not_to be_nil
|
182
|
+
expect(change['fullDocument']['username']).to eq('alice')
|
183
|
+
expect(change['ns']).not_to be_nil
|
184
|
+
expect(change['ns']['db']).to eq(TEST_DB)
|
185
|
+
expect(change['ns']['coll']).to eq(inventory.name)
|
186
|
+
expect(change['documentKey']).not_to be_nil
|
187
|
+
expect(change['documentKey']['_id']).to eq(change['fullDocument']['_id'])
|
188
|
+
end
|
189
|
+
end
|
150
190
|
end
|
data/spec/mongo/client_spec.rb
CHANGED
@@ -228,6 +228,10 @@ describe Mongo::Client do
|
|
228
228
|
described_class.new([default_address.seed], authorized_client.options.merge(options))
|
229
229
|
end
|
230
230
|
|
231
|
+
after do
|
232
|
+
client.close
|
233
|
+
end
|
234
|
+
|
231
235
|
it 'sets the option' do
|
232
236
|
expect(client.options['retry_writes']).to eq(options[:retry_writes])
|
233
237
|
end
|
@@ -632,7 +636,7 @@ describe Mongo::Client do
|
|
632
636
|
|
633
637
|
context 'when providing a connection string' do
|
634
638
|
|
635
|
-
context 'when the string uses the SRV Protocol' do
|
639
|
+
context 'when the string uses the SRV Protocol', if: test_connecting_externally? do
|
636
640
|
|
637
641
|
let!(:uri) do
|
638
642
|
'mongodb+srv://test5.test.build.10gen.cc/testdb'
|
@@ -1356,24 +1360,23 @@ describe Mongo::Client do
|
|
1356
1360
|
end
|
1357
1361
|
|
1358
1362
|
let(:client) do
|
1359
|
-
# Monitoring subscribers won't be set up when using Client#with, so a new client must be created.
|
1360
1363
|
Mongo::Client.new(ADDRESSES, client_options).tap do |cl|
|
1361
|
-
cl.subscribe(Mongo::Monitoring::COMMAND,
|
1364
|
+
cl.subscribe(Mongo::Monitoring::COMMAND, EventSubscriber.clear_events!)
|
1362
1365
|
end
|
1363
1366
|
end
|
1364
1367
|
|
1365
|
-
let(:subscriber) do
|
1366
|
-
EventSubscriber.new
|
1367
|
-
end
|
1368
|
-
|
1369
1368
|
let(:command) do
|
1370
|
-
|
1369
|
+
EventSubscriber.started_events.find { |c| c.command_name == :listDatabases }.command
|
1371
1370
|
end
|
1372
1371
|
|
1373
1372
|
before do
|
1374
1373
|
client.list_databases({}, true)
|
1375
1374
|
end
|
1376
1375
|
|
1376
|
+
after do
|
1377
|
+
client.close
|
1378
|
+
end
|
1379
|
+
|
1377
1380
|
it 'sends the command with the nameOnly flag set to true' do
|
1378
1381
|
expect(command[:nameOnly]).to be(true)
|
1379
1382
|
end
|
@@ -1503,7 +1506,7 @@ describe Mongo::Client do
|
|
1503
1506
|
context 'when options are provided' do
|
1504
1507
|
|
1505
1508
|
let(:options) do
|
1506
|
-
{
|
1509
|
+
{ causal_consistency: true }
|
1507
1510
|
end
|
1508
1511
|
|
1509
1512
|
let(:session) do
|
@@ -1511,14 +1514,14 @@ describe Mongo::Client do
|
|
1511
1514
|
end
|
1512
1515
|
|
1513
1516
|
it 'sets the options on the session' do
|
1514
|
-
expect(session.options).to eq(options)
|
1517
|
+
expect(session.options[:causal_consistency]).to eq(options[:causal_consistency])
|
1515
1518
|
end
|
1516
1519
|
end
|
1517
1520
|
|
1518
1521
|
context 'when options are not provided' do
|
1519
1522
|
|
1520
1523
|
it 'does not set options on the session' do
|
1521
|
-
expect(session.options).to
|
1524
|
+
expect(session.options).to eq({ implicit: false })
|
1522
1525
|
end
|
1523
1526
|
end
|
1524
1527
|
|
@@ -1567,7 +1570,7 @@ describe Mongo::Client do
|
|
1567
1570
|
end
|
1568
1571
|
|
1569
1572
|
let(:pool) do
|
1570
|
-
authorized_client.
|
1573
|
+
authorized_client.cluster.session_pool
|
1571
1574
|
end
|
1572
1575
|
|
1573
1576
|
let!(:before_last_use) do
|
@@ -1581,6 +1584,38 @@ describe Mongo::Client do
|
|
1581
1584
|
end
|
1582
1585
|
end
|
1583
1586
|
|
1587
|
+
context 'when two clients have the same cluster', if: test_sessions? do
|
1588
|
+
|
1589
|
+
let(:client) do
|
1590
|
+
authorized_client.with(read: { mode: :secondary })
|
1591
|
+
end
|
1592
|
+
|
1593
|
+
let(:session) do
|
1594
|
+
authorized_client.start_session
|
1595
|
+
end
|
1596
|
+
|
1597
|
+
it 'allows the session to be used across the clients' do
|
1598
|
+
client[TEST_COLL].insert_one({ a: 1 }, session: session)
|
1599
|
+
end
|
1600
|
+
end
|
1601
|
+
|
1602
|
+
context 'when two clients have different clusters', if: test_sessions? do
|
1603
|
+
|
1604
|
+
let(:client) do
|
1605
|
+
authorized_client_with_retry_writes
|
1606
|
+
end
|
1607
|
+
|
1608
|
+
let(:session) do
|
1609
|
+
authorized_client.start_session
|
1610
|
+
end
|
1611
|
+
|
1612
|
+
it 'raises an exception' do
|
1613
|
+
expect {
|
1614
|
+
client[TEST_COLL].insert_one({ a: 1 }, session: session)
|
1615
|
+
}.to raise_exception(Mongo::Error::InvalidSession)
|
1616
|
+
end
|
1617
|
+
end
|
1618
|
+
|
1584
1619
|
context 'when sessions are not supported', unless: sessions_enabled? do
|
1585
1620
|
|
1586
1621
|
it 'raises an exception' do
|