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
@@ -49,6 +49,7 @@ describe 'Max Staleness Spec' do
|
|
49
49
|
spec.candidate_servers.collect do |server|
|
50
50
|
features = double('features').tap do |feat|
|
51
51
|
allow(feat).to receive(:max_staleness_enabled?).and_return(server['maxWireVersion'] && server['maxWireVersion'] >= 5)
|
52
|
+
allow(feat).to receive(:check_driver_support!).and_return(true)
|
52
53
|
end
|
53
54
|
address = Mongo::Address.new(server['address'])
|
54
55
|
Mongo::Server.new(address, cluster, monitoring, listeners, options).tap do |s|
|
@@ -17,13 +17,7 @@ describe 'Retryable Writes' do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
let(:client) do
|
20
|
-
|
21
|
-
cl.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
let(:subscriber) do
|
26
|
-
EventSubscriber.new
|
20
|
+
authorized_client_with_retry_writes
|
27
21
|
end
|
28
22
|
|
29
23
|
before do
|
@@ -348,7 +342,7 @@ describe 'Retryable Writes' do
|
|
348
342
|
shared_examples_for 'an operation that does not support retryable writes' do
|
349
343
|
|
350
344
|
let!(:client) do
|
351
|
-
|
345
|
+
authorized_client_with_retry_writes
|
352
346
|
end
|
353
347
|
|
354
348
|
let!(:collection) do
|
@@ -375,7 +369,7 @@ describe 'Retryable Writes' do
|
|
375
369
|
context 'when the client has retry_writes set to true' do
|
376
370
|
|
377
371
|
let!(:client) do
|
378
|
-
|
372
|
+
authorized_client_with_retry_writes
|
379
373
|
end
|
380
374
|
|
381
375
|
context 'when the collection has write concern acknowledged' do
|
@@ -452,6 +446,10 @@ describe 'Retryable Writes' do
|
|
452
446
|
authorized_client.with(retry_writes: false)
|
453
447
|
end
|
454
448
|
|
449
|
+
after do
|
450
|
+
client.close
|
451
|
+
end
|
452
|
+
|
455
453
|
context 'when the collection has write concern acknowledged' do
|
456
454
|
|
457
455
|
let!(:collection) do
|
data/spec/mongo/sdam_spec.rb
CHANGED
@@ -46,39 +46,57 @@ describe 'Server Discovery and Monitoring' do
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
|
50
|
-
@client.cluster.instance_variable_get(:@servers).
|
51
|
-
collect(&:address).collect(&:to_s).uniq.sort
|
52
|
-
end
|
49
|
+
if phase.outcome.compatible?
|
53
50
|
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
let(:cluster_addresses) do
|
52
|
+
@client.cluster.instance_variable_get(:@servers).
|
53
|
+
collect(&:address).collect(&:to_s).uniq.sort
|
54
|
+
end
|
57
55
|
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
let(:phase_addresses) do
|
57
|
+
phase.outcome.servers.keys.sort
|
58
|
+
end
|
61
59
|
|
62
|
-
|
63
|
-
|
64
|
-
|
60
|
+
it "sets the cluster topology to #{phase.outcome.topology_type}" do
|
61
|
+
expect(@client.cluster).to be_topology(phase.outcome.topology_type)
|
62
|
+
end
|
65
63
|
|
66
|
-
|
67
|
-
|
68
|
-
|
64
|
+
it "sets the cluster replica set name to #{phase.outcome.set_name.inspect}" do
|
65
|
+
expect(@client.cluster.replica_set_name).to eq(phase.outcome.set_name)
|
66
|
+
end
|
69
67
|
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
it "sets the cluster logical session timeout minutes to #{phase.outcome.logical_session_timeout.inspect}" do
|
69
|
+
expect(@client.cluster.logical_session_timeout).to eq(phase.outcome.logical_session_timeout)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "has the expected servers in the cluster" do
|
73
|
+
expect(cluster_addresses).to eq(phase_addresses)
|
74
|
+
end
|
75
|
+
|
76
|
+
phase.outcome.servers.each do |uri, server|
|
77
|
+
|
78
|
+
it "sets #{uri} to #{server['type']}" do
|
79
|
+
expect(find_server(@client, uri)).to be_server_type(server['type'])
|
80
|
+
end
|
73
81
|
|
74
|
-
|
82
|
+
it "sets #{uri} replica set name to #{server['setName'].inspect}" do
|
83
|
+
expect(find_server(@client, uri).replica_set_name).to eq(server['setName'])
|
84
|
+
end
|
85
|
+
end
|
75
86
|
|
76
|
-
|
77
|
-
|
87
|
+
else
|
88
|
+
|
89
|
+
before do
|
90
|
+
@client.cluster.servers.each do |server|
|
91
|
+
allow(server).to receive(:connectable?).and_return(true)
|
92
|
+
end
|
78
93
|
end
|
79
94
|
|
80
|
-
it
|
81
|
-
expect
|
95
|
+
it 'raises an UnsupportedFeatures error' do
|
96
|
+
expect {
|
97
|
+
Mongo::ServerSelector.get(mode: :primary).select_server(@client.cluster)
|
98
|
+
Mongo::ServerSelector.get(mode: :secondary).select_server(@client.cluster)
|
99
|
+
}.to raise_exception(Mongo::Error::UnsupportedFeatures)
|
82
100
|
end
|
83
101
|
end
|
84
102
|
end
|
@@ -27,7 +27,7 @@ describe Mongo::Server::Description::Features do
|
|
27
27
|
|
28
28
|
it 'raises an exception' do
|
29
29
|
expect {
|
30
|
-
features
|
30
|
+
features.check_driver_support!
|
31
31
|
}.to raise_error(Mongo::Error::UnsupportedFeatures)
|
32
32
|
end
|
33
33
|
end
|
@@ -51,7 +51,7 @@ describe Mongo::Server::Description::Features do
|
|
51
51
|
|
52
52
|
it 'raises an exception' do
|
53
53
|
expect {
|
54
|
-
features
|
54
|
+
features.check_driver_support!
|
55
55
|
}.to raise_error(Mongo::Error::UnsupportedFeatures)
|
56
56
|
end
|
57
57
|
end
|
@@ -214,7 +214,7 @@ describe Mongo::Server::Description::Features do
|
|
214
214
|
|
215
215
|
it 'returns false' do
|
216
216
|
expect {
|
217
|
-
features
|
217
|
+
features.check_driver_support!
|
218
218
|
}.to raise_exception(Mongo::Error::UnsupportedFeatures)
|
219
219
|
end
|
220
220
|
end
|
@@ -42,6 +42,7 @@ describe 'Server Selection' do
|
|
42
42
|
allow(s).to receive(:secondary?).and_return(server['type'] == 'RSSecondary')
|
43
43
|
allow(s).to receive(:primary?).and_return(server['type'] == 'RSPrimary')
|
44
44
|
allow(s).to receive(:connectable?).and_return(true)
|
45
|
+
allow(s).to receive(:check_driver_support!).and_return(true)
|
45
46
|
end
|
46
47
|
end
|
47
48
|
end
|
@@ -53,6 +54,7 @@ describe 'Server Selection' do
|
|
53
54
|
allow(s).to receive(:average_round_trip_time).and_return(server['avg_rtt_ms'] / 1000.0)
|
54
55
|
allow(s).to receive(:tags).and_return(server['tags'])
|
55
56
|
allow(s).to receive(:connectable?).and_return(true)
|
57
|
+
allow(s).to receive(:check_driver_support!).and_return(true)
|
56
58
|
end
|
57
59
|
end
|
58
60
|
end
|
@@ -208,6 +208,7 @@ describe Mongo::ServerSelector do
|
|
208
208
|
make_server(:secondary).tap do |s|
|
209
209
|
allow(s).to receive(:connectable?).and_return(true)
|
210
210
|
allow(s).to receive(:average_round_trip_time).and_return(100)
|
211
|
+
allow(s).to receive(:check_driver_support!).and_return(true)
|
211
212
|
end
|
212
213
|
end
|
213
214
|
|
@@ -215,6 +216,7 @@ describe Mongo::ServerSelector do
|
|
215
216
|
make_server(:secondary).tap do |s|
|
216
217
|
allow(s).to receive(:connectable?).and_return(true)
|
217
218
|
allow(s).to receive(:average_round_trip_time).and_return(200)
|
219
|
+
allow(s).to receive(:check_driver_support!).and_return(true)
|
218
220
|
end
|
219
221
|
end
|
220
222
|
|
@@ -2,40 +2,40 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Mongo::Session::SessionPool, if: test_sessions? do
|
4
4
|
|
5
|
-
|
5
|
+
let(:cluster) do
|
6
|
+
authorized_client.cluster
|
7
|
+
end
|
6
8
|
|
7
|
-
|
8
|
-
authorized_client
|
9
|
-
end
|
9
|
+
describe '.create' do
|
10
10
|
|
11
11
|
let!(:pool) do
|
12
|
-
described_class.create(
|
12
|
+
described_class.create(cluster)
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'creates a session pool' do
|
16
16
|
expect(pool).to be_a(Mongo::Session::SessionPool)
|
17
17
|
end
|
18
18
|
|
19
|
-
it 'adds the pool as an instance variable on the
|
20
|
-
expect(
|
19
|
+
it 'adds the pool as an instance variable on the cluster' do
|
20
|
+
expect(cluster.session_pool).to eq(pool)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
describe '#initialize' do
|
25
25
|
|
26
26
|
let(:pool) do
|
27
|
-
described_class.new(
|
27
|
+
described_class.new(cluster)
|
28
28
|
end
|
29
29
|
|
30
|
-
it 'sets the
|
31
|
-
expect(pool.instance_variable_get(:@
|
30
|
+
it 'sets the cluster' do
|
31
|
+
expect(pool.instance_variable_get(:@cluster)).to be(authorized_client.cluster)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
describe '#inspect' do
|
36
36
|
|
37
37
|
let(:pool) do
|
38
|
-
described_class.new(
|
38
|
+
described_class.new(cluster)
|
39
39
|
end
|
40
40
|
|
41
41
|
before do
|
@@ -55,7 +55,7 @@ describe Mongo::Session::SessionPool, if: test_sessions? do
|
|
55
55
|
describe 'checkout' do
|
56
56
|
|
57
57
|
let(:pool) do
|
58
|
-
described_class.new(
|
58
|
+
described_class.new(cluster)
|
59
59
|
end
|
60
60
|
|
61
61
|
context 'when a session is checked out' do
|
@@ -138,7 +138,7 @@ describe Mongo::Session::SessionPool, if: test_sessions? do
|
|
138
138
|
describe '#end_sessions' do
|
139
139
|
|
140
140
|
let(:pool) do
|
141
|
-
described_class.create(client)
|
141
|
+
described_class.create(client.cluster)
|
142
142
|
end
|
143
143
|
|
144
144
|
let!(:session_a) do
|
@@ -150,13 +150,7 @@ describe Mongo::Session::SessionPool, if: test_sessions? do
|
|
150
150
|
end
|
151
151
|
|
152
152
|
let(:client) do
|
153
|
-
|
154
|
-
cl.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
let(:subscriber) do
|
159
|
-
EventSubscriber.new
|
153
|
+
subscribed_client
|
160
154
|
end
|
161
155
|
|
162
156
|
after do
|
@@ -177,7 +171,7 @@ describe Mongo::Session::SessionPool, if: test_sessions? do
|
|
177
171
|
|
178
172
|
let(:end_sessions_command) do
|
179
173
|
pool.end_sessions
|
180
|
-
|
174
|
+
EventSubscriber.started_events.find { |c| c.command_name == :endSessions}
|
181
175
|
end
|
182
176
|
|
183
177
|
it 'sends the endSessions command with all the session ids' do
|
@@ -216,7 +210,7 @@ describe Mongo::Session::SessionPool, if: test_sessions? do
|
|
216
210
|
end
|
217
211
|
|
218
212
|
let(:end_sessions_commands) do
|
219
|
-
|
213
|
+
EventSubscriber.started_events.select { |c| c.command_name == :endSessions}
|
220
214
|
end
|
221
215
|
|
222
216
|
it 'sends the command more than once' do
|
data/spec/mongo/session_spec.rb
CHANGED
@@ -28,8 +28,8 @@ describe Mongo::Session, if: test_sessions? do
|
|
28
28
|
expect(session.cluster_time).to be(nil)
|
29
29
|
end
|
30
30
|
|
31
|
-
it 'sets the
|
32
|
-
expect(session.
|
31
|
+
it 'sets the cluster' do
|
32
|
+
expect(session.cluster).to be(authorized_client.cluster)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -50,7 +50,8 @@ describe Mongo::Session, if: test_sessions? do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'includes the options in the formatted string' do
|
53
|
-
expect(session.inspect).to include({
|
53
|
+
expect(session.inspect).to include({ implicit: false,
|
54
|
+
causal_consistency: true }.to_s)
|
54
55
|
end
|
55
56
|
end
|
56
57
|
end
|
@@ -188,13 +189,13 @@ describe Mongo::Session, if: test_sessions? do
|
|
188
189
|
session.instance_variable_get(:@server_session)
|
189
190
|
end
|
190
191
|
|
191
|
-
let(:
|
192
|
-
session.
|
192
|
+
let(:cluster_session_pool) do
|
193
|
+
session.cluster.session_pool
|
193
194
|
end
|
194
195
|
|
195
|
-
it 'returns the server session to the
|
196
|
+
it 'returns the server session to the cluster session pool' do
|
196
197
|
session.end_session
|
197
|
-
expect(
|
198
|
+
expect(cluster_session_pool.instance_variable_get(:@queue)).to include(server_session)
|
198
199
|
end
|
199
200
|
|
200
201
|
context 'when #end_session is called multiple times' do
|
@@ -214,7 +215,7 @@ describe Mongo::Session, if: test_sessions? do
|
|
214
215
|
context 'when the option is set to true' do
|
215
216
|
|
216
217
|
let(:client) do
|
217
|
-
|
218
|
+
authorized_client_with_retry_writes
|
218
219
|
end
|
219
220
|
|
220
221
|
it 'returns true' do
|
@@ -228,6 +229,10 @@ describe Mongo::Session, if: test_sessions? do
|
|
228
229
|
authorized_client.with(retry_writes: false)
|
229
230
|
end
|
230
231
|
|
232
|
+
after do
|
233
|
+
client.close
|
234
|
+
end
|
235
|
+
|
231
236
|
it 'returns false' do
|
232
237
|
expect(client.start_session.retry_writes?).to be(false)
|
233
238
|
end
|
@@ -200,733 +200,736 @@ describe Mongo::URI::SRVProtocol do
|
|
200
200
|
end
|
201
201
|
end
|
202
202
|
|
203
|
-
describe '
|
203
|
+
describe 'valid uris', if: test_connecting_externally? do
|
204
204
|
|
205
|
-
|
205
|
+
describe 'invalid query results' do
|
206
206
|
|
207
|
-
|
207
|
+
context 'when there are too many TXT records' do
|
208
208
|
|
209
|
-
|
210
|
-
|
209
|
+
let(:string) { "#{scheme}test6.test.build.10gen.cc/" }
|
210
|
+
|
211
|
+
it 'raises an error' do
|
212
|
+
expect { uri }.to raise_exception(Mongo::Error::InvalidTXTRecord)
|
213
|
+
end
|
211
214
|
end
|
212
|
-
end
|
213
215
|
|
214
|
-
|
216
|
+
context 'when the TXT has an invalid option' do
|
215
217
|
|
216
|
-
|
218
|
+
let(:string) { "#{scheme}test10.test.build.10gen.cc" }
|
217
219
|
|
218
|
-
|
219
|
-
|
220
|
+
it 'raises an error' do
|
221
|
+
expect { uri }.to raise_exception(Mongo::Error::InvalidTXTRecord)
|
222
|
+
end
|
220
223
|
end
|
221
|
-
end
|
222
224
|
|
223
|
-
|
225
|
+
context 'when the SRV records domain does not match hostname used for the query' do
|
224
226
|
|
225
|
-
|
227
|
+
let(:string) { "#{scheme}test12.test.build.10gen.cc" }
|
226
228
|
|
227
|
-
|
228
|
-
|
229
|
+
it 'raises an error' do
|
230
|
+
expect { uri }.to raise_exception(Mongo::Error::MismatchedDomain)
|
231
|
+
end
|
229
232
|
end
|
230
|
-
end
|
231
233
|
|
232
|
-
|
234
|
+
context 'when the query returns no SRV records' do
|
233
235
|
|
234
|
-
|
236
|
+
let(:string) { "#{scheme}test4.test.build.10gen.cc" }
|
235
237
|
|
236
|
-
|
237
|
-
|
238
|
+
it 'raises an error' do
|
239
|
+
expect { uri }.to raise_exception(Mongo::Error::NoSRVRecords)
|
240
|
+
end
|
238
241
|
end
|
239
242
|
end
|
240
|
-
end
|
241
243
|
|
242
|
-
|
243
|
-
|
244
|
+
describe '#servers' do
|
245
|
+
let(:string) { "#{scheme}#{servers}" }
|
244
246
|
|
245
|
-
|
246
|
-
|
247
|
+
context 'single server' do
|
248
|
+
let(:servers) { 'test5.test.build.10gen.cc' }
|
247
249
|
|
248
|
-
|
249
|
-
|
250
|
+
it 'returns an array with the parsed server' do
|
251
|
+
expect(uri.servers).to eq(['localhost.test.build.10gen.cc:27017'])
|
252
|
+
end
|
250
253
|
end
|
251
254
|
end
|
252
|
-
end
|
253
255
|
|
254
|
-
|
256
|
+
describe '#client_options' do
|
255
257
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
258
|
+
let(:db) { TEST_DB }
|
259
|
+
let(:servers) { 'test5.test.build.10gen.cc' }
|
260
|
+
let(:string) { "#{scheme}#{credentials}@#{servers}/#{db}" }
|
261
|
+
let(:user) { 'tyler' }
|
262
|
+
let(:password) { 's3kr4t' }
|
263
|
+
let(:credentials) { "#{user}:#{password}" }
|
262
264
|
|
263
|
-
|
264
|
-
|
265
|
-
|
265
|
+
let(:options) do
|
266
|
+
uri.client_options
|
267
|
+
end
|
266
268
|
|
267
|
-
|
268
|
-
|
269
|
-
|
269
|
+
it 'includes the database in the options' do
|
270
|
+
expect(options[:database]).to eq(TEST_DB)
|
271
|
+
end
|
270
272
|
|
271
|
-
|
272
|
-
|
273
|
-
|
273
|
+
it 'includes the user in the options' do
|
274
|
+
expect(options[:user]).to eq(user)
|
275
|
+
end
|
274
276
|
|
275
|
-
|
276
|
-
|
277
|
-
|
277
|
+
it 'includes the password in the options' do
|
278
|
+
expect(options[:password]).to eq(password)
|
279
|
+
end
|
278
280
|
|
279
|
-
|
280
|
-
|
281
|
+
it 'sets ssl to true' do
|
282
|
+
expect(options[:ssl]).to eq(true)
|
283
|
+
end
|
281
284
|
end
|
282
|
-
end
|
283
285
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
286
|
+
describe '#credentials' do
|
287
|
+
let(:servers) { 'test5.test.build.10gen.cc' }
|
288
|
+
let(:string) { "#{scheme}#{credentials}@#{servers}" }
|
289
|
+
let(:user) { 'tyler' }
|
288
290
|
|
289
|
-
|
290
|
-
|
291
|
+
context 'username provided' do
|
292
|
+
let(:credentials) { "#{user}:" }
|
291
293
|
|
292
|
-
|
293
|
-
|
294
|
+
it 'returns the username' do
|
295
|
+
expect(uri.credentials[:user]).to eq(user)
|
296
|
+
end
|
294
297
|
end
|
295
|
-
end
|
296
298
|
|
297
|
-
|
298
|
-
|
299
|
-
|
299
|
+
context 'username and password provided' do
|
300
|
+
let(:password) { 's3kr4t' }
|
301
|
+
let(:credentials) { "#{user}:#{password}" }
|
300
302
|
|
301
|
-
|
302
|
-
|
303
|
-
|
303
|
+
it 'returns the username' do
|
304
|
+
expect(uri.credentials[:user]).to eq(user)
|
305
|
+
end
|
304
306
|
|
305
|
-
|
306
|
-
|
307
|
+
it 'returns the password' do
|
308
|
+
expect(uri.credentials[:password]).to eq(password)
|
309
|
+
end
|
307
310
|
end
|
308
311
|
end
|
309
|
-
end
|
310
312
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
313
|
+
describe '#database' do
|
314
|
+
let(:servers) { 'test5.test.build.10gen.cc' }
|
315
|
+
let(:string) { "#{scheme}#{servers}/#{db}" }
|
316
|
+
let(:db) { 'auth-db' }
|
315
317
|
|
316
|
-
|
317
|
-
|
318
|
-
|
318
|
+
context 'database provided' do
|
319
|
+
it 'returns the database name' do
|
320
|
+
expect(uri.database).to eq(db)
|
321
|
+
end
|
319
322
|
end
|
320
323
|
end
|
321
|
-
end
|
322
324
|
|
323
|
-
|
324
|
-
|
325
|
-
|
325
|
+
describe '#uri_options' do
|
326
|
+
let(:servers) { 'test5.test.build.10gen.cc' }
|
327
|
+
let(:string) { "#{scheme}#{servers}/?#{options}" }
|
326
328
|
|
327
|
-
|
328
|
-
|
329
|
+
context 'when no options were provided' do
|
330
|
+
let(:string) { "#{scheme}#{servers}" }
|
329
331
|
|
330
|
-
|
331
|
-
|
332
|
+
it 'returns an empty hash' do
|
333
|
+
expect(uri.uri_options).to be_empty
|
334
|
+
end
|
332
335
|
end
|
333
|
-
end
|
334
336
|
|
335
|
-
|
337
|
+
context 'write concern options provided' do
|
336
338
|
|
337
|
-
|
338
|
-
|
339
|
-
|
339
|
+
context 'numerical w value' do
|
340
|
+
let(:options) { 'w=1' }
|
341
|
+
let(:concern) { Mongo::Options::Redacted.new(:w => 1)}
|
340
342
|
|
341
|
-
|
342
|
-
|
343
|
-
|
343
|
+
it 'sets the write concern options' do
|
344
|
+
expect(uri.uri_options[:write]).to eq(concern)
|
345
|
+
end
|
344
346
|
|
345
|
-
|
346
|
-
|
347
|
+
it 'sets the options on a client created with the uri' do
|
348
|
+
expect(Mongo::Client.new(string).options[:write]).to eq(concern)
|
349
|
+
end
|
347
350
|
end
|
348
|
-
end
|
349
351
|
|
350
|
-
|
351
|
-
|
352
|
-
|
352
|
+
context 'w=majority' do
|
353
|
+
let(:options) { 'w=majority' }
|
354
|
+
let(:concern) { Mongo::Options::Redacted.new(:w => :majority) }
|
353
355
|
|
354
|
-
|
355
|
-
|
356
|
-
|
356
|
+
it 'sets the write concern options' do
|
357
|
+
expect(uri.uri_options[:write]).to eq(concern)
|
358
|
+
end
|
357
359
|
|
358
|
-
|
359
|
-
|
360
|
+
it 'sets the options on a client created with the uri' do
|
361
|
+
expect(Mongo::Client.new(string).options[:write]).to eq(concern)
|
362
|
+
end
|
360
363
|
end
|
361
|
-
end
|
362
364
|
|
363
|
-
|
364
|
-
|
365
|
-
|
365
|
+
context 'journal' do
|
366
|
+
let(:options) { 'journal=true' }
|
367
|
+
let(:concern) { Mongo::Options::Redacted.new(:j => true) }
|
366
368
|
|
367
|
-
|
368
|
-
|
369
|
-
|
369
|
+
it 'sets the write concern options' do
|
370
|
+
expect(uri.uri_options[:write]).to eq(concern)
|
371
|
+
end
|
370
372
|
|
371
|
-
|
372
|
-
|
373
|
+
it 'sets the options on a client created with the uri' do
|
374
|
+
expect(Mongo::Client.new(string).options[:write]).to eq(concern)
|
375
|
+
end
|
373
376
|
end
|
374
|
-
end
|
375
377
|
|
376
|
-
|
377
|
-
|
378
|
-
|
378
|
+
context 'fsync' do
|
379
|
+
let(:options) { 'fsync=true' }
|
380
|
+
let(:concern) { Mongo::Options::Redacted.new(:fsync => true) }
|
379
381
|
|
380
|
-
|
381
|
-
|
382
|
-
|
382
|
+
it 'sets the write concern options' do
|
383
|
+
expect(uri.uri_options[:write]).to eq(concern)
|
384
|
+
end
|
383
385
|
|
384
|
-
|
385
|
-
|
386
|
+
it 'sets the options on a client created with the uri' do
|
387
|
+
expect(Mongo::Client.new(string).options[:write]).to eq(concern)
|
388
|
+
end
|
386
389
|
end
|
387
|
-
end
|
388
390
|
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
391
|
+
context 'wtimeoutMS' do
|
392
|
+
let(:timeout) { 1234 }
|
393
|
+
let(:options) { "w=2&wtimeoutMS=#{timeout}" }
|
394
|
+
let(:concern) { Mongo::Options::Redacted.new(:w => 2, :timeout => timeout) }
|
393
395
|
|
394
|
-
|
395
|
-
|
396
|
-
|
396
|
+
it 'sets the write concern options' do
|
397
|
+
expect(uri.uri_options[:write]).to eq(concern)
|
398
|
+
end
|
397
399
|
|
398
|
-
|
399
|
-
|
400
|
+
it 'sets the options on a client created with the uri' do
|
401
|
+
expect(Mongo::Client.new(string).options[:write]).to eq(concern)
|
402
|
+
end
|
400
403
|
end
|
401
404
|
end
|
402
|
-
end
|
403
405
|
|
404
|
-
|
405
|
-
|
406
|
+
context 'read preference option provided' do
|
407
|
+
let(:options) { "readPreference=#{mode}" }
|
406
408
|
|
407
|
-
|
408
|
-
|
409
|
-
|
409
|
+
context 'primary' do
|
410
|
+
let(:mode) { 'primary' }
|
411
|
+
let(:read) { Mongo::Options::Redacted.new(:mode => :primary) }
|
410
412
|
|
411
|
-
|
412
|
-
|
413
|
-
|
413
|
+
it 'sets the read preference' do
|
414
|
+
expect(uri.uri_options[:read]).to eq(read)
|
415
|
+
end
|
414
416
|
|
415
|
-
|
416
|
-
|
417
|
+
it 'sets the options on a client created with the uri' do
|
418
|
+
expect(Mongo::Client.new(string).options[:read]).to eq(read)
|
419
|
+
end
|
417
420
|
end
|
418
|
-
end
|
419
421
|
|
420
|
-
|
421
|
-
|
422
|
-
|
422
|
+
context 'primaryPreferred' do
|
423
|
+
let(:mode) { 'primaryPreferred' }
|
424
|
+
let(:read) { Mongo::Options::Redacted.new(:mode => :primary_preferred) }
|
423
425
|
|
424
|
-
|
425
|
-
|
426
|
-
|
426
|
+
it 'sets the read preference' do
|
427
|
+
expect(uri.uri_options[:read]).to eq(read)
|
428
|
+
end
|
427
429
|
|
428
|
-
|
429
|
-
|
430
|
+
it 'sets the options on a client created with the uri' do
|
431
|
+
expect(Mongo::Client.new(string).options[:read]).to eq(read)
|
432
|
+
end
|
430
433
|
end
|
431
|
-
end
|
432
434
|
|
433
|
-
|
434
|
-
|
435
|
-
|
435
|
+
context 'secondary' do
|
436
|
+
let(:mode) { 'secondary' }
|
437
|
+
let(:read) { Mongo::Options::Redacted.new(:mode => :secondary) }
|
436
438
|
|
437
|
-
|
438
|
-
|
439
|
-
|
439
|
+
it 'sets the read preference' do
|
440
|
+
expect(uri.uri_options[:read]).to eq(read)
|
441
|
+
end
|
440
442
|
|
441
|
-
|
442
|
-
|
443
|
+
it 'sets the options on a client created with the uri' do
|
444
|
+
expect(Mongo::Client.new(string).options[:read]).to eq(read)
|
445
|
+
end
|
443
446
|
end
|
444
|
-
end
|
445
447
|
|
446
|
-
|
447
|
-
|
448
|
-
|
448
|
+
context 'secondaryPreferred' do
|
449
|
+
let(:mode) { 'secondaryPreferred' }
|
450
|
+
let(:read) { Mongo::Options::Redacted.new(:mode => :secondary_preferred) }
|
449
451
|
|
450
|
-
|
451
|
-
|
452
|
-
|
452
|
+
it 'sets the read preference' do
|
453
|
+
expect(uri.uri_options[:read]).to eq(read)
|
454
|
+
end
|
453
455
|
|
454
|
-
|
455
|
-
|
456
|
+
it 'sets the options on a client created with the uri' do
|
457
|
+
expect(Mongo::Client.new(string).options[:read]).to eq(read)
|
458
|
+
end
|
456
459
|
end
|
457
|
-
end
|
458
460
|
|
459
|
-
|
460
|
-
|
461
|
-
|
461
|
+
context 'nearest' do
|
462
|
+
let(:mode) { 'nearest' }
|
463
|
+
let(:read) { Mongo::Options::Redacted.new(:mode => :nearest) }
|
462
464
|
|
463
|
-
|
464
|
-
|
465
|
-
|
465
|
+
it 'sets the read preference' do
|
466
|
+
expect(uri.uri_options[:read]).to eq(read)
|
467
|
+
end
|
466
468
|
|
467
|
-
|
468
|
-
|
469
|
+
it 'sets the options on a client created with the uri' do
|
470
|
+
expect(Mongo::Client.new(string).options[:read]).to eq(read)
|
471
|
+
end
|
469
472
|
end
|
470
473
|
end
|
471
|
-
end
|
472
474
|
|
473
|
-
|
475
|
+
context 'read preference tags provided' do
|
474
476
|
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
477
|
+
context 'single read preference tag set' do
|
478
|
+
let(:options) do
|
479
|
+
'readPreferenceTags=dc:ny,rack:1'
|
480
|
+
end
|
479
481
|
|
480
|
-
|
481
|
-
|
482
|
-
|
482
|
+
let(:read) do
|
483
|
+
Mongo::Options::Redacted.new(:tag_sets => [{ 'dc' => 'ny', 'rack' => '1' }])
|
484
|
+
end
|
483
485
|
|
484
|
-
|
485
|
-
|
486
|
+
it 'sets the read preference tag set' do
|
487
|
+
expect(uri.uri_options[:read]).to eq(read)
|
488
|
+
end
|
489
|
+
|
490
|
+
it 'sets the options on a client created with the uri' do
|
491
|
+
expect(Mongo::Client.new(string).options[:read]).to eq(read)
|
492
|
+
end
|
486
493
|
end
|
487
494
|
|
488
|
-
|
489
|
-
|
495
|
+
context 'multiple read preference tag sets' do
|
496
|
+
let(:options) do
|
497
|
+
'readPreferenceTags=dc:ny&readPreferenceTags=dc:bos'
|
498
|
+
end
|
499
|
+
|
500
|
+
let(:read) do
|
501
|
+
Mongo::Options::Redacted.new(:tag_sets => [{ 'dc' => 'ny' }, { 'dc' => 'bos' }])
|
502
|
+
end
|
503
|
+
|
504
|
+
it 'sets the read preference tag sets' do
|
505
|
+
expect(uri.uri_options[:read]).to eq(read)
|
506
|
+
end
|
507
|
+
|
508
|
+
it 'sets the options on a client created with the uri' do
|
509
|
+
expect(Mongo::Client.new(string).options[:read]).to eq(read)
|
510
|
+
end
|
490
511
|
end
|
491
512
|
end
|
492
513
|
|
493
|
-
context '
|
514
|
+
context 'read preference max staleness option provided' do
|
515
|
+
|
494
516
|
let(:options) do
|
495
|
-
'
|
517
|
+
'readPreference=Secondary&maxStalenessSeconds=120'
|
496
518
|
end
|
497
519
|
|
498
520
|
let(:read) do
|
499
|
-
Mongo::Options::Redacted.new(:
|
521
|
+
Mongo::Options::Redacted.new(mode: :secondary, :max_staleness => 120)
|
500
522
|
end
|
501
523
|
|
502
|
-
it 'sets the read preference
|
524
|
+
it 'sets the read preference max staleness in seconds' do
|
503
525
|
expect(uri.uri_options[:read]).to eq(read)
|
504
526
|
end
|
505
527
|
|
506
528
|
it 'sets the options on a client created with the uri' do
|
507
529
|
expect(Mongo::Client.new(string).options[:read]).to eq(read)
|
508
530
|
end
|
509
|
-
end
|
510
|
-
end
|
511
531
|
|
512
|
-
|
532
|
+
context 'when the read preference and max staleness combination is invalid' do
|
513
533
|
|
514
|
-
|
515
|
-
'readPreference=Secondary&maxStalenessSeconds=120'
|
516
|
-
end
|
517
|
-
|
518
|
-
let(:read) do
|
519
|
-
Mongo::Options::Redacted.new(mode: :secondary, :max_staleness => 120)
|
520
|
-
end
|
534
|
+
context 'when max staleness is combined with read preference mode primary' do
|
521
535
|
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
it 'sets the options on a client created with the uri' do
|
527
|
-
expect(Mongo::Client.new(string).options[:read]).to eq(read)
|
528
|
-
end
|
529
|
-
|
530
|
-
context 'when the read preference and max staleness combination is invalid' do
|
531
|
-
|
532
|
-
context 'when max staleness is combined with read preference mode primary' do
|
533
|
-
|
534
|
-
let(:options) do
|
535
|
-
'readPreference=primary&maxStalenessSeconds=120'
|
536
|
-
end
|
536
|
+
let(:options) do
|
537
|
+
'readPreference=primary&maxStalenessSeconds=120'
|
538
|
+
end
|
537
539
|
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
540
|
+
it 'raises an exception when read preference is accessed on the client' do
|
541
|
+
expect {
|
542
|
+
Mongo::Client.new(string).server_selector
|
543
|
+
}.to raise_exception(Mongo::Error::InvalidServerPreference)
|
544
|
+
end
|
542
545
|
end
|
543
|
-
end
|
544
546
|
|
545
|
-
|
547
|
+
context 'when the max staleness value is too small' do
|
546
548
|
|
547
|
-
|
548
|
-
|
549
|
-
|
549
|
+
let(:options) do
|
550
|
+
'readPreference=secondary&maxStalenessSeconds=89'
|
551
|
+
end
|
550
552
|
|
551
|
-
|
552
|
-
|
553
|
+
it 'does not raise an exception until the read preference is used' do
|
554
|
+
expect(Mongo::Client.new(string).read_preference).to eq(BSON::Document.new(mode: :secondary, max_staleness: 89))
|
555
|
+
end
|
553
556
|
end
|
554
557
|
end
|
555
558
|
end
|
556
|
-
end
|
557
559
|
|
558
|
-
|
559
|
-
|
560
|
-
|
560
|
+
context 'replica set option provided' do
|
561
|
+
let(:rs_name) { TEST_SET }
|
562
|
+
let(:options) { "replicaSet=#{rs_name}" }
|
561
563
|
|
562
|
-
|
563
|
-
|
564
|
-
|
564
|
+
it 'sets the replica set option' do
|
565
|
+
expect(uri.uri_options[:replica_set]).to eq(rs_name)
|
566
|
+
end
|
565
567
|
|
566
|
-
|
567
|
-
|
568
|
+
it 'sets the options on a client created with the uri' do
|
569
|
+
expect(Mongo::Client.new(string).options[:replica_set]).to eq(rs_name)
|
570
|
+
end
|
568
571
|
end
|
569
|
-
end
|
570
572
|
|
571
|
-
|
572
|
-
|
573
|
+
context 'auth mechanism provided' do
|
574
|
+
let(:options) { "authMechanism=#{mechanism}" }
|
573
575
|
|
574
|
-
|
575
|
-
|
576
|
-
|
576
|
+
context 'plain' do
|
577
|
+
let(:mechanism) { 'PLAIN' }
|
578
|
+
let(:expected) { :plain }
|
577
579
|
|
578
|
-
|
579
|
-
|
580
|
-
|
580
|
+
it 'sets the auth mechanism to :plain' do
|
581
|
+
expect(uri.uri_options[:auth_mech]).to eq(expected)
|
582
|
+
end
|
581
583
|
|
582
|
-
|
583
|
-
|
584
|
-
|
584
|
+
it 'sets the options on a client created with the uri' do
|
585
|
+
expect(Mongo::Client.new(string).options[:auth_mech]).to eq(expected)
|
586
|
+
end
|
585
587
|
|
586
|
-
|
587
|
-
|
588
|
+
it 'is case-insensitive' do
|
589
|
+
expect(Mongo::Client.new(string.downcase).options[:auth_mech]).to eq(expected)
|
590
|
+
end
|
588
591
|
end
|
589
|
-
end
|
590
592
|
|
591
|
-
|
592
|
-
|
593
|
-
|
593
|
+
context 'mongodb-cr' do
|
594
|
+
let(:mechanism) { 'MONGODB-CR' }
|
595
|
+
let(:expected) { :mongodb_cr }
|
594
596
|
|
595
|
-
|
596
|
-
|
597
|
-
|
597
|
+
it 'sets the auth mechanism to :mongodb_cr' do
|
598
|
+
expect(uri.uri_options[:auth_mech]).to eq(expected)
|
599
|
+
end
|
598
600
|
|
599
|
-
|
600
|
-
|
601
|
-
|
601
|
+
it 'sets the options on a client created with the uri' do
|
602
|
+
expect(Mongo::Client.new(string).options[:auth_mech]).to eq(expected)
|
603
|
+
end
|
602
604
|
|
603
|
-
|
604
|
-
|
605
|
+
it 'is case-insensitive' do
|
606
|
+
expect(Mongo::Client.new(string.downcase).options[:auth_mech]).to eq(expected)
|
607
|
+
end
|
605
608
|
end
|
606
|
-
end
|
607
609
|
|
608
|
-
|
609
|
-
|
610
|
-
|
610
|
+
context 'gssapi' do
|
611
|
+
let(:mechanism) { 'GSSAPI' }
|
612
|
+
let(:expected) { :gssapi }
|
611
613
|
|
612
|
-
|
613
|
-
|
614
|
-
|
614
|
+
it 'sets the auth mechanism to :gssapi' do
|
615
|
+
expect(uri.uri_options[:auth_mech]).to eq(expected)
|
616
|
+
end
|
615
617
|
|
616
|
-
|
617
|
-
|
618
|
-
|
618
|
+
it 'sets the options on a client created with the uri' do
|
619
|
+
expect(Mongo::Client.new(string).options[:auth_mech]).to eq(expected)
|
620
|
+
end
|
619
621
|
|
620
|
-
|
621
|
-
|
622
|
+
it 'is case-insensitive' do
|
623
|
+
expect(Mongo::Client.new(string.downcase).options[:auth_mech]).to eq(expected)
|
624
|
+
end
|
622
625
|
end
|
623
|
-
end
|
624
626
|
|
625
|
-
|
626
|
-
|
627
|
-
|
627
|
+
context 'scram-sha-1' do
|
628
|
+
let(:mechanism) { 'SCRAM-SHA-1' }
|
629
|
+
let(:expected) { :scram }
|
628
630
|
|
629
|
-
|
630
|
-
|
631
|
-
|
631
|
+
it 'sets the auth mechanism to :scram' do
|
632
|
+
expect(uri.uri_options[:auth_mech]).to eq(expected)
|
633
|
+
end
|
632
634
|
|
633
|
-
|
634
|
-
|
635
|
-
|
635
|
+
it 'sets the options on a client created with the uri' do
|
636
|
+
expect(Mongo::Client.new(string).options[:auth_mech]).to eq(expected)
|
637
|
+
end
|
636
638
|
|
637
|
-
|
638
|
-
|
639
|
+
it 'is case-insensitive' do
|
640
|
+
expect(Mongo::Client.new(string.downcase).options[:auth_mech]).to eq(expected)
|
641
|
+
end
|
639
642
|
end
|
640
|
-
end
|
641
643
|
|
642
|
-
|
643
|
-
|
644
|
-
|
644
|
+
context 'mongodb-x509' do
|
645
|
+
let(:mechanism) { 'MONGODB-X509' }
|
646
|
+
let(:expected) { :mongodb_x509 }
|
645
647
|
|
646
|
-
|
647
|
-
|
648
|
-
|
648
|
+
it 'sets the auth mechanism to :mongodb_x509' do
|
649
|
+
expect(uri.uri_options[:auth_mech]).to eq(expected)
|
650
|
+
end
|
649
651
|
|
650
|
-
|
651
|
-
|
652
|
-
|
652
|
+
it 'sets the options on a client created with the uri' do
|
653
|
+
expect(Mongo::Client.new(string).options[:auth_mech]).to eq(expected)
|
654
|
+
end
|
653
655
|
|
654
|
-
|
655
|
-
|
656
|
-
|
656
|
+
it 'is case-insensitive' do
|
657
|
+
expect(Mongo::Client.new(string.downcase).options[:auth_mech]).to eq(expected)
|
658
|
+
end
|
657
659
|
|
658
|
-
|
660
|
+
context 'when a username is not provided' do
|
659
661
|
|
660
|
-
|
661
|
-
|
662
|
-
|
662
|
+
it 'recognizes the mechanism with no username' do
|
663
|
+
expect(Mongo::Client.new(string.downcase).options[:auth_mech]).to eq(expected)
|
664
|
+
expect(Mongo::Client.new(string.downcase).options[:user]).to be_nil
|
665
|
+
end
|
663
666
|
end
|
664
667
|
end
|
665
668
|
end
|
666
|
-
end
|
667
669
|
|
668
|
-
|
669
|
-
|
670
|
+
context 'auth source provided' do
|
671
|
+
let(:options) { "authSource=#{source}" }
|
670
672
|
|
671
|
-
|
672
|
-
|
673
|
+
context 'regular db' do
|
674
|
+
let(:source) { 'foo' }
|
673
675
|
|
674
|
-
|
675
|
-
|
676
|
-
|
676
|
+
it 'sets the auth source to the database' do
|
677
|
+
expect(uri.uri_options[:auth_source]).to eq(source)
|
678
|
+
end
|
677
679
|
|
678
|
-
|
679
|
-
|
680
|
+
it 'sets the options on a client created with the uri' do
|
681
|
+
expect(Mongo::Client.new(string).options[:auth_source]).to eq(source)
|
682
|
+
end
|
680
683
|
end
|
681
|
-
end
|
682
684
|
|
683
|
-
|
684
|
-
|
685
|
-
|
685
|
+
context '$external' do
|
686
|
+
let(:source) { '$external' }
|
687
|
+
let(:expected) { :external }
|
686
688
|
|
687
|
-
|
688
|
-
|
689
|
-
|
689
|
+
it 'sets the auth source to :external' do
|
690
|
+
expect(uri.uri_options[:auth_source]).to eq(expected)
|
691
|
+
end
|
690
692
|
|
691
|
-
|
692
|
-
|
693
|
+
it 'sets the options on a client created with the uri' do
|
694
|
+
expect(Mongo::Client.new(string).options[:auth_source]).to eq(expected)
|
695
|
+
end
|
693
696
|
end
|
694
697
|
end
|
695
|
-
end
|
696
698
|
|
697
|
-
|
699
|
+
context 'auth mechanism properties provided' do
|
698
700
|
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
701
|
+
context 'service_name' do
|
702
|
+
let(:options) do
|
703
|
+
"authMechanismProperties=SERVICE_NAME:#{service_name}"
|
704
|
+
end
|
703
705
|
|
704
|
-
|
705
|
-
|
706
|
+
let(:service_name) { 'foo' }
|
707
|
+
let(:expected) { Mongo::Options::Redacted.new({ service_name: service_name }) }
|
706
708
|
|
707
|
-
|
708
|
-
|
709
|
-
|
709
|
+
it 'sets the auth mechanism properties' do
|
710
|
+
expect(uri.uri_options[:auth_mech_properties]).to eq(expected)
|
711
|
+
end
|
710
712
|
|
711
|
-
|
712
|
-
|
713
|
+
it 'sets the options on a client created with the uri' do
|
714
|
+
expect(Mongo::Client.new(string).options[:auth_mech_properties]).to eq(expected)
|
715
|
+
end
|
713
716
|
end
|
714
|
-
end
|
715
717
|
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
718
|
+
context 'canonicalize_host_name' do
|
719
|
+
let(:options) do
|
720
|
+
"authMechanismProperties=CANONICALIZE_HOST_NAME:#{canonicalize_host_name}"
|
721
|
+
end
|
722
|
+
let(:canonicalize_host_name) { 'true' }
|
723
|
+
let(:expected) { Mongo::Options::Redacted.new({ canonicalize_host_name: true }) }
|
722
724
|
|
723
|
-
|
724
|
-
|
725
|
-
|
725
|
+
it 'sets the auth mechanism properties' do
|
726
|
+
expect(uri.uri_options[:auth_mech_properties]).to eq(expected)
|
727
|
+
end
|
726
728
|
|
727
|
-
|
728
|
-
|
729
|
+
it 'sets the options on a client created with the uri' do
|
730
|
+
expect(Mongo::Client.new(string).options[:auth_mech_properties]).to eq(expected)
|
731
|
+
end
|
729
732
|
end
|
730
|
-
end
|
731
733
|
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
734
|
+
context 'service_realm' do
|
735
|
+
let(:options) do
|
736
|
+
"authMechanismProperties=SERVICE_REALM:#{service_realm}"
|
737
|
+
end
|
736
738
|
|
737
|
-
|
738
|
-
|
739
|
+
let(:service_realm) { 'dumdum' }
|
740
|
+
let(:expected) { Mongo::Options::Redacted.new({ service_realm: service_realm }) }
|
739
741
|
|
740
742
|
|
741
|
-
|
742
|
-
|
743
|
-
|
743
|
+
it 'sets the auth mechanism properties' do
|
744
|
+
expect(uri.uri_options[:auth_mech_properties]).to eq(expected)
|
745
|
+
end
|
744
746
|
|
745
|
-
|
746
|
-
|
747
|
+
it 'sets the options on a client created with the uri' do
|
748
|
+
expect(Mongo::Client.new(string).options[:auth_mech_properties]).to eq(expected)
|
749
|
+
end
|
747
750
|
end
|
748
|
-
end
|
749
751
|
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
752
|
+
context 'multiple properties' do
|
753
|
+
let(:options) do
|
754
|
+
"authMechanismProperties=SERVICE_REALM:#{service_realm}," +
|
755
|
+
"CANONICALIZE_HOST_NAME:#{canonicalize_host_name}," +
|
756
|
+
"SERVICE_NAME:#{service_name}"
|
757
|
+
end
|
756
758
|
|
757
|
-
|
758
|
-
|
759
|
-
|
759
|
+
let(:service_name) { 'foo' }
|
760
|
+
let(:canonicalize_host_name) { 'true' }
|
761
|
+
let(:service_realm) { 'dumdum' }
|
760
762
|
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
763
|
+
let(:expected) do
|
764
|
+
Mongo::Options::Redacted.new({ service_name: service_name,
|
765
|
+
canonicalize_host_name: true,
|
766
|
+
service_realm: service_realm })
|
767
|
+
end
|
766
768
|
|
767
|
-
|
768
|
-
|
769
|
-
|
769
|
+
it 'sets the auth mechanism properties' do
|
770
|
+
expect(uri.uri_options[:auth_mech_properties]).to eq(expected)
|
771
|
+
end
|
770
772
|
|
771
|
-
|
772
|
-
|
773
|
+
it 'sets the options on a client created with the uri' do
|
774
|
+
expect(Mongo::Client.new(string).options[:auth_mech_properties]).to eq(expected)
|
775
|
+
end
|
773
776
|
end
|
774
777
|
end
|
775
|
-
end
|
776
778
|
|
777
|
-
|
778
|
-
|
779
|
+
context 'connectTimeoutMS' do
|
780
|
+
let(:options) { "connectTimeoutMS=4567" }
|
779
781
|
|
780
|
-
|
781
|
-
|
782
|
+
it 'sets the the connect timeout' do
|
783
|
+
expect(uri.uri_options[:connect_timeout]).to eq(4.567)
|
784
|
+
end
|
782
785
|
end
|
783
|
-
end
|
784
786
|
|
785
|
-
|
786
|
-
|
787
|
+
context 'socketTimeoutMS' do
|
788
|
+
let(:options) { "socketTimeoutMS=8910" }
|
787
789
|
|
788
|
-
|
789
|
-
|
790
|
+
it 'sets the socket timeout' do
|
791
|
+
expect(uri.uri_options[:socket_timeout]).to eq(8.910)
|
792
|
+
end
|
790
793
|
end
|
791
|
-
end
|
792
794
|
|
793
|
-
|
795
|
+
context 'when providing serverSelectionTimeoutMS' do
|
794
796
|
|
795
|
-
|
797
|
+
let(:options) { "serverSelectionTimeoutMS=3561" }
|
796
798
|
|
797
|
-
|
798
|
-
|
799
|
+
it 'sets the the connect timeout' do
|
800
|
+
expect(uri.uri_options[:server_selection_timeout]).to eq(3.561)
|
801
|
+
end
|
799
802
|
end
|
800
|
-
end
|
801
803
|
|
802
|
-
|
804
|
+
context 'when providing localThresholdMS' do
|
803
805
|
|
804
|
-
|
806
|
+
let(:options) { "localThresholdMS=3561" }
|
805
807
|
|
806
|
-
|
807
|
-
|
808
|
+
it 'sets the the connect timeout' do
|
809
|
+
expect(uri.uri_options[:local_threshold]).to eq(3.561)
|
810
|
+
end
|
808
811
|
end
|
809
|
-
end
|
810
812
|
|
811
|
-
|
813
|
+
context 'when providing maxPoolSize' do
|
812
814
|
|
813
|
-
|
814
|
-
|
815
|
+
let(:max_pool_size) { 10 }
|
816
|
+
let(:options) { "maxPoolSize=#{max_pool_size}" }
|
815
817
|
|
816
|
-
|
817
|
-
|
818
|
+
it 'sets the max pool size option' do
|
819
|
+
expect(uri.uri_options[:max_pool_size]).to eq(max_pool_size)
|
820
|
+
end
|
818
821
|
end
|
819
|
-
end
|
820
822
|
|
821
|
-
|
823
|
+
context 'when providing minPoolSize' do
|
822
824
|
|
823
|
-
|
824
|
-
|
825
|
+
let(:min_pool_size) { 5 }
|
826
|
+
let(:options) { "minPoolSize=#{min_pool_size}" }
|
825
827
|
|
826
|
-
|
827
|
-
|
828
|
+
it 'sets the min pool size option' do
|
829
|
+
expect(uri.uri_options[:min_pool_size]).to eq(min_pool_size)
|
830
|
+
end
|
828
831
|
end
|
829
|
-
end
|
830
832
|
|
831
|
-
|
833
|
+
context 'when providing waitQueueTimeoutMS' do
|
832
834
|
|
833
|
-
|
834
|
-
|
835
|
+
let(:wait_queue_timeout) { 500 }
|
836
|
+
let(:options) { "waitQueueTimeoutMS=#{wait_queue_timeout}" }
|
835
837
|
|
836
|
-
|
837
|
-
|
838
|
+
it 'sets the wait queue timeout option' do
|
839
|
+
expect(uri.uri_options[:wait_queue_timeout]).to eq(0.5)
|
840
|
+
end
|
838
841
|
end
|
839
|
-
end
|
840
842
|
|
841
|
-
|
842
|
-
|
843
|
+
context 'ssl' do
|
844
|
+
let(:options) { "ssl=#{ssl}" }
|
843
845
|
|
844
|
-
|
845
|
-
|
846
|
+
context 'true' do
|
847
|
+
let(:ssl) { true }
|
846
848
|
|
847
|
-
|
848
|
-
|
849
|
+
it 'sets the ssl option to true' do
|
850
|
+
expect(uri.uri_options[:ssl]).to be true
|
851
|
+
end
|
849
852
|
end
|
850
|
-
end
|
851
853
|
|
852
|
-
|
853
|
-
|
854
|
+
context 'false' do
|
855
|
+
let(:ssl) { false }
|
854
856
|
|
855
|
-
|
856
|
-
|
857
|
+
it 'sets the ssl option to false' do
|
858
|
+
expect(uri.uri_options[:ssl]).to be false
|
859
|
+
end
|
857
860
|
end
|
858
861
|
end
|
859
|
-
end
|
860
862
|
|
861
|
-
|
862
|
-
|
863
|
+
context 'grouped and non-grouped options provided' do
|
864
|
+
let(:options) { 'w=1&ssl=true' }
|
863
865
|
|
864
|
-
|
865
|
-
|
866
|
+
it 'do not overshadow top level options' do
|
867
|
+
expect(uri.uri_options).not_to be_empty
|
868
|
+
end
|
866
869
|
end
|
867
|
-
end
|
868
870
|
|
869
|
-
|
871
|
+
context 'when an invalid option is provided' do
|
870
872
|
|
871
|
-
|
873
|
+
let(:options) { 'invalidOption=10' }
|
872
874
|
|
873
|
-
|
874
|
-
|
875
|
-
|
875
|
+
let(:uri_options) do
|
876
|
+
uri.uri_options
|
877
|
+
end
|
876
878
|
|
877
|
-
|
878
|
-
|
879
|
-
|
879
|
+
it 'does not raise an exception' do
|
880
|
+
expect(uri_options).to be_empty
|
881
|
+
end
|
880
882
|
|
881
|
-
|
883
|
+
context 'when an invalid option is combined with valid options' do
|
882
884
|
|
883
|
-
|
885
|
+
let(:options) { 'invalidOption=10&waitQueueTimeoutMS=500&ssl=true' }
|
884
886
|
|
885
|
-
|
886
|
-
|
887
|
-
|
887
|
+
it 'does not raise an exception' do
|
888
|
+
expect(uri_options).not_to be_empty
|
889
|
+
end
|
888
890
|
|
889
|
-
|
890
|
-
|
891
|
-
|
891
|
+
it 'sets the valid options' do
|
892
|
+
expect(uri_options[:wait_queue_timeout]).to eq(0.5)
|
893
|
+
expect(uri_options[:ssl]).to be true
|
894
|
+
end
|
892
895
|
end
|
893
896
|
end
|
894
|
-
end
|
895
897
|
|
896
|
-
|
897
|
-
|
898
|
+
context 'when an app name option is provided' do
|
899
|
+
let(:options) { "appname=reports" }
|
898
900
|
|
899
|
-
|
900
|
-
|
901
|
+
it 'sets the app name on the client' do
|
902
|
+
expect(Mongo::Client.new(string).options[:app_name]).to eq(:reports)
|
903
|
+
end
|
901
904
|
end
|
902
|
-
end
|
903
905
|
|
904
|
-
|
905
|
-
|
906
|
+
context 'when a supported compressors option is provided' do
|
907
|
+
let(:options) { "compressors=zlib" }
|
906
908
|
|
907
|
-
|
908
|
-
|
909
|
+
it 'sets the compressors as an array on the client' do
|
910
|
+
expect(Mongo::Client.new(string).options[:compressors]).to eq(['zlib'])
|
911
|
+
end
|
909
912
|
end
|
910
|
-
end
|
911
913
|
|
912
|
-
|
913
|
-
|
914
|
+
context 'when a non-supported compressors option is provided' do
|
915
|
+
let(:options) { "compressors=snoopy" }
|
914
916
|
|
915
|
-
|
916
|
-
|
917
|
-
|
917
|
+
let(:client) do
|
918
|
+
Mongo::Client.new(string)
|
919
|
+
end
|
918
920
|
|
919
|
-
|
920
|
-
|
921
|
-
|
921
|
+
it 'sets no compressors on the client and warns' do
|
922
|
+
expect(Mongo::Logger.logger).to receive(:warn)
|
923
|
+
expect(client.options[:compressors]).to be_nil
|
924
|
+
end
|
922
925
|
end
|
923
|
-
end
|
924
926
|
|
925
|
-
|
926
|
-
|
927
|
+
context 'when a zlibCompressionLevel option is provided' do
|
928
|
+
let(:options) { "zlibCompressionLevel=6" }
|
927
929
|
|
928
|
-
|
929
|
-
|
930
|
+
it 'sets the zlib compression level on the client' do
|
931
|
+
expect(Mongo::Client.new(string).options[:zlib_compression_level]).to eq(6)
|
932
|
+
end
|
930
933
|
end
|
931
934
|
end
|
932
935
|
end
|