mongo 2.5.0 → 2.5.1
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/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
|