mongo 2.4.3 → 2.5.0.beta
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 +3 -2
- data.tar.gz.sig +0 -0
- data/lib/mongo.rb +3 -2
- data/lib/mongo/auth/cr.rb +6 -4
- data/lib/mongo/auth/cr/conversation.rb +33 -17
- data/lib/mongo/auth/ldap.rb +4 -2
- data/lib/mongo/auth/ldap/conversation.rb +19 -9
- data/lib/mongo/auth/scram.rb +7 -4
- data/lib/mongo/auth/scram/conversation.rb +62 -24
- data/lib/mongo/auth/user.rb +10 -0
- data/lib/mongo/auth/user/view.rb +44 -22
- data/lib/mongo/auth/x509.rb +4 -2
- data/lib/mongo/auth/x509/conversation.rb +19 -9
- data/lib/mongo/bulk_write.rb +33 -27
- data/lib/mongo/bulk_write/combineable.rb +5 -0
- data/lib/mongo/bulk_write/transformable.rb +2 -0
- data/lib/mongo/bulk_write/validatable.rb +4 -0
- data/lib/mongo/client.rb +123 -12
- data/lib/mongo/cluster.rb +52 -11
- data/lib/mongo/cluster/app_metadata.rb +8 -2
- data/lib/mongo/cluster/cursor_reaper.rb +0 -1
- data/lib/mongo/cluster/topology.rb +1 -1
- data/lib/mongo/collection.rb +114 -27
- data/lib/mongo/collection/view.rb +8 -2
- data/lib/mongo/collection/view/aggregation.rb +11 -7
- data/lib/mongo/collection/view/builder/aggregation.rb +5 -1
- data/lib/mongo/collection/view/builder/find_command.rb +5 -3
- data/lib/mongo/collection/view/builder/map_reduce.rb +11 -3
- data/lib/mongo/collection/view/builder/op_query.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +160 -0
- data/lib/mongo/collection/view/change_stream/retryable.rb +57 -0
- data/lib/mongo/collection/view/iterable.rb +11 -10
- data/lib/mongo/collection/view/map_reduce.rb +22 -18
- data/lib/mongo/collection/view/readable.rb +51 -37
- data/lib/mongo/collection/view/writable.rb +72 -40
- data/lib/mongo/cursor.rb +25 -4
- data/lib/mongo/cursor/builder/get_more_command.rb +4 -2
- data/lib/mongo/database.rb +22 -11
- data/lib/mongo/database/view.rb +16 -12
- data/lib/mongo/error.rb +5 -0
- data/lib/mongo/error/invalid_session.rb +36 -0
- data/lib/mongo/error/missing_resume_token.rb +39 -0
- data/lib/mongo/error/operation_failure.rb +17 -0
- data/lib/mongo/error/parser.rb +3 -2
- data/lib/mongo/error/unknown_payload_type.rb +41 -0
- data/lib/mongo/error/unsupported_array_filters.rb +51 -0
- data/lib/mongo/error/unsupported_message_type.rb +23 -0
- data/lib/mongo/grid/fs_bucket.rb +5 -4
- data/lib/mongo/grid/stream/read.rb +3 -2
- data/lib/mongo/grid/stream/write.rb +2 -2
- data/lib/mongo/index/view.rb +35 -25
- data/lib/mongo/monitoring/event/secure.rb +14 -0
- data/lib/mongo/operation.rb +16 -0
- data/lib/mongo/operation/commands.rb +1 -0
- data/lib/mongo/operation/commands/aggregate.rb +9 -5
- data/lib/mongo/operation/commands/aggregate/result.rb +1 -1
- data/lib/mongo/operation/commands/collections_info.rb +6 -6
- data/lib/mongo/operation/commands/command.rb +2 -1
- data/lib/mongo/operation/commands/create.rb +6 -2
- data/lib/mongo/operation/commands/drop.rb +6 -2
- data/lib/mongo/operation/commands/drop_database.rb +6 -2
- data/lib/mongo/operation/commands/explain.rb +27 -0
- data/lib/mongo/operation/commands/explain/result.rb +52 -0
- data/lib/mongo/operation/commands/indexes.rb +1 -1
- data/lib/mongo/operation/commands/list_collections.rb +1 -1
- data/lib/mongo/operation/commands/list_collections/result.rb +1 -1
- data/lib/mongo/operation/commands/list_indexes.rb +1 -1
- data/lib/mongo/operation/commands/list_indexes/result.rb +1 -1
- data/lib/mongo/operation/commands/map_reduce.rb +8 -4
- data/lib/mongo/operation/commands/map_reduce/result.rb +13 -1
- data/lib/mongo/operation/commands/user_query.rb +1 -1
- data/lib/mongo/operation/commands/users_info.rb +6 -2
- data/lib/mongo/operation/executable.rb +4 -1
- data/lib/mongo/operation/read_preference.rb +10 -5
- data/lib/mongo/operation/result.rb +26 -2
- data/lib/mongo/operation/specifiable.rb +13 -1
- data/lib/mongo/operation/uses_command_op_msg.rb +47 -0
- data/lib/mongo/operation/write/bulk/bulkable.rb +4 -1
- data/lib/mongo/operation/write/bulk/insert/result.rb +4 -4
- data/lib/mongo/operation/write/command/create_index.rb +6 -1
- data/lib/mongo/operation/write/command/delete.rb +28 -4
- data/lib/mongo/operation/write/command/drop_index.rb +6 -1
- data/lib/mongo/operation/write/command/insert.rb +22 -18
- data/lib/mongo/operation/write/command/update.rb +24 -9
- data/lib/mongo/operation/write/command/writable.rb +14 -1
- data/lib/mongo/operation/write/insert.rb +4 -1
- data/lib/mongo/operation/write/insert/result.rb +2 -2
- data/lib/mongo/operation/write/update.rb +7 -1
- data/lib/mongo/operation/write/write_command_enabled.rb +20 -3
- data/lib/mongo/protocol.rb +3 -0
- data/lib/mongo/protocol/bit_vector.rb +2 -2
- data/lib/mongo/protocol/compressed.rb +135 -0
- data/lib/mongo/protocol/delete.rb +8 -6
- data/lib/mongo/protocol/get_more.rb +8 -6
- data/lib/mongo/protocol/insert.rb +8 -6
- data/lib/mongo/protocol/kill_cursors.rb +8 -6
- data/lib/mongo/protocol/message.rb +31 -3
- data/lib/mongo/protocol/msg.rb +172 -0
- data/lib/mongo/protocol/query.rb +26 -6
- data/lib/mongo/protocol/registry.rb +76 -0
- data/lib/mongo/protocol/reply.rb +10 -5
- data/lib/mongo/protocol/serializers.rb +224 -0
- data/lib/mongo/protocol/update.rb +8 -6
- data/lib/mongo/retryable.rb +4 -2
- data/lib/mongo/server.rb +6 -3
- data/lib/mongo/server/connectable.rb +1 -1
- data/lib/mongo/server/connection.rb +30 -8
- data/lib/mongo/server/description.rb +25 -1
- data/lib/mongo/server/description/features.rb +4 -1
- data/lib/mongo/server/monitor.rb +5 -0
- data/lib/mongo/server/monitor/connection.rb +50 -2
- data/lib/mongo/server_selector/nearest.rb +10 -4
- data/lib/mongo/server_selector/primary.rb +20 -0
- data/lib/mongo/server_selector/primary_preferred.rb +10 -4
- data/lib/mongo/server_selector/secondary.rb +10 -4
- data/lib/mongo/server_selector/secondary_preferred.rb +24 -4
- data/lib/mongo/session.rb +180 -0
- data/lib/mongo/session/server_session.rb +73 -0
- data/lib/mongo/session/session_pool.rb +161 -0
- data/lib/mongo/uri.rb +11 -0
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +2 -1
- data/spec/mongo/auth/cr_spec.rb +12 -0
- data/spec/mongo/auth/ldap_spec.rb +2 -0
- data/spec/mongo/auth/scram/conversation_spec.rb +6 -6
- data/spec/mongo/auth/scram_spec.rb +25 -1
- data/spec/mongo/auth/user/view_spec.rb +268 -76
- data/spec/mongo/auth/x509_spec.rb +2 -0
- data/spec/mongo/bulk_write_spec.rb +435 -5
- data/spec/mongo/client_spec.rb +356 -39
- data/spec/mongo/cluster/app_metadata_spec.rb +2 -2
- data/spec/mongo/cluster_spec.rb +176 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +33 -12
- data/spec/mongo/collection/view/builder/find_command_spec.rb +46 -6
- data/spec/mongo/collection/view/change_stream_spec.rb +814 -0
- data/spec/mongo/collection/view/map_reduce_spec.rb +94 -17
- data/spec/mongo/collection/view/readable_spec.rb +3 -12
- data/spec/mongo/collection_spec.rb +1048 -42
- data/spec/mongo/cursor/builder/get_more_command_spec.rb +19 -0
- data/spec/mongo/cursor_spec.rb +2 -2
- data/spec/mongo/database_spec.rb +50 -1
- data/spec/mongo/grid/fs_bucket_spec.rb +225 -137
- data/spec/mongo/grid/stream/read_spec.rb +2 -2
- data/spec/mongo/index/view_spec.rb +146 -8
- data/spec/mongo/monitoring/event/secure_spec.rb +42 -0
- data/spec/mongo/operation/read/query_spec.rb +2 -1
- data/spec/mongo/operation/specifiable_spec.rb +2 -2
- data/spec/mongo/operation/write/command/delete_spec.rb +96 -13
- data/spec/mongo/operation/write/command/insert_spec.rb +111 -12
- data/spec/mongo/operation/write/command/update_spec.rb +93 -10
- data/spec/mongo/operation/write/delete_spec.rb +1 -1
- data/spec/mongo/operation/write/insert_spec.rb +1 -1
- data/spec/mongo/operation/write/update_spec.rb +1 -1
- data/spec/mongo/protocol/compressed_spec.rb +66 -0
- data/spec/mongo/protocol/delete_spec.rb +14 -0
- data/spec/mongo/protocol/get_more_spec.rb +14 -0
- data/spec/mongo/protocol/insert_spec.rb +14 -0
- data/spec/mongo/protocol/kill_cursors_spec.rb +14 -0
- data/spec/mongo/protocol/msg_spec.rb +499 -0
- data/spec/mongo/protocol/query_spec.rb +45 -0
- data/spec/mongo/protocol/registry_spec.rb +31 -0
- data/spec/mongo/protocol/reply_spec.rb +14 -0
- data/spec/mongo/protocol/update_spec.rb +14 -0
- data/spec/mongo/retryable_spec.rb +6 -2
- data/spec/mongo/sdam_spec.rb +4 -0
- data/spec/mongo/server/connection_spec.rb +4 -2
- data/spec/mongo/server/description_spec.rb +28 -1
- data/spec/mongo/session/server_session_spec.rb +16 -0
- data/spec/mongo/session/session_pool_spec.rb +194 -0
- data/spec/mongo/uri_spec.rb +31 -2
- data/spec/spec_helper.rb +104 -0
- data/spec/support/authorization.rb +6 -1
- data/spec/support/crud.rb +3 -1
- data/spec/support/crud/write.rb +6 -1
- data/spec/support/crud_tests/write/findOneAndUpdate-arrayFilters.yml +69 -0
- data/spec/support/crud_tests/write/updateMany-arrayFilters.yml +63 -0
- data/spec/support/crud_tests/write/updateOne-arrayFilters.yml +109 -0
- data/spec/support/sdam/rs/discover_arbiters.yml +1 -1
- data/spec/support/sdam/rs/discover_passives.yml +2 -2
- data/spec/support/sdam/rs/discover_primary.yml +1 -1
- data/spec/support/sdam/rs/discover_secondary.yml +1 -1
- data/spec/support/sdam/rs/discovery.yml +4 -4
- data/spec/support/sdam/rs/equal_electionids.yml +1 -0
- data/spec/support/sdam/rs/ghost_discovered.yml +1 -1
- data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +1 -1
- data/spec/support/sdam/rs/ls_timeout.yml +88 -0
- data/spec/support/sdam/rs/member_reconfig.yml +2 -2
- data/spec/support/sdam/rs/member_standalone.yml +2 -2
- data/spec/support/sdam/rs/new_primary.yml +2 -2
- data/spec/support/sdam/rs/new_primary_new_electionid.yml +3 -0
- data/spec/support/sdam/rs/new_primary_new_setversion.yml +3 -0
- data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +2 -2
- data/spec/support/sdam/rs/non_rs_member.yml +1 -1
- data/spec/support/sdam/rs/normalize_case.yml +1 -1
- data/spec/support/sdam/rs/null_election_id.yml +4 -0
- data/spec/support/sdam/rs/primary_becomes_standalone.yml +2 -2
- data/spec/support/sdam/rs/primary_changes_set_name.yml +2 -2
- data/spec/support/sdam/rs/primary_disconnect.yml +2 -2
- data/spec/support/sdam/rs/primary_disconnect_electionid.yml +5 -0
- data/spec/support/sdam/rs/primary_disconnect_setversion.yml +5 -0
- data/spec/support/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +58 -0
- data/spec/support/sdam/rs/primary_reports_new_member.yml +4 -4
- data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +2 -2
- data/spec/support/sdam/rs/primary_wrong_set_name.yml +1 -1
- data/spec/support/sdam/rs/response_from_removed.yml +2 -2
- data/spec/support/sdam/rs/rsother_discovered.yml +1 -1
- data/spec/support/sdam/rs/sec_not_auth.yml +1 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name.yml +1 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +2 -2
- data/spec/support/sdam/rs/setversion_without_electionid.yml +2 -0
- data/spec/support/sdam/rs/stepdown_change_set_name.yml +2 -2
- data/spec/support/sdam/rs/unexpected_mongos.yml +1 -1
- data/spec/support/sdam/rs/use_setversion_without_electionid.yml +3 -0
- data/spec/support/sdam/rs/wrong_set_name.yml +1 -1
- data/spec/support/sdam/sharded/ls_timeout_mongos.yml +97 -0
- data/spec/support/sdam/sharded/mongos_disconnect.yml +3 -3
- data/spec/support/sdam/sharded/multiple_mongoses.yml +1 -1
- data/spec/support/sdam/sharded/non_mongos_removed.yml +1 -1
- data/spec/support/sdam/sharded/normalize_uri_case.yml +1 -1
- data/spec/support/sdam/single/direct_connection_external_ip.yml +1 -1
- data/spec/support/sdam/single/direct_connection_mongos.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
- data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
- data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
- data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
- data/spec/support/sdam/single/ls_timeout_standalone.yml +35 -0
- data/spec/support/sdam/single/not_ok_response.yml +1 -1
- data/spec/support/sdam/single/standalone_removed.yml +1 -1
- data/spec/support/sdam/single/unavailable_seed.yml +1 -1
- data/spec/support/server_discovery_and_monitoring.rb +4 -0
- data/spec/support/shared/session.rb +236 -0
- metadata +53 -15
- metadata.gz.sig +0 -0
@@ -296,4 +296,49 @@ describe Mongo::Protocol::Query do
|
|
296
296
|
end
|
297
297
|
end
|
298
298
|
end
|
299
|
+
|
300
|
+
describe '#registry' do
|
301
|
+
|
302
|
+
context 'when the class is loaded' do
|
303
|
+
|
304
|
+
it 'registers the op code in the Protocol Registry' do
|
305
|
+
expect(Mongo::Protocol::Registry.get(described_class::OP_CODE)).to be(described_class)
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'creates an #op_code instance method' do
|
309
|
+
expect(message.op_code).to eq(described_class::OP_CODE)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
describe '#compress' do
|
315
|
+
|
316
|
+
context 'when the selector represents a command that can be compressed' do
|
317
|
+
|
318
|
+
let(:selector) do
|
319
|
+
{ ping: 1 }
|
320
|
+
end
|
321
|
+
|
322
|
+
it 'returns a compressed message' do
|
323
|
+
expect(message.compress!('zlib')).to be_a(Mongo::Protocol::Compressed)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
context 'when the selector represents a command for which compression is not allowed' do
|
328
|
+
|
329
|
+
Mongo::Monitoring::Event::Secure::REDACTED_COMMANDS.each do |command|
|
330
|
+
|
331
|
+
let(:selector) do
|
332
|
+
{ command => 1 }
|
333
|
+
end
|
334
|
+
|
335
|
+
context "when the command is #{command}" do
|
336
|
+
|
337
|
+
it 'does not allow compression for the command' do
|
338
|
+
expect(message.compress!('zlib')).to be(message)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
299
344
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongo::Protocol::Registry do
|
4
|
+
|
5
|
+
describe ".get" do
|
6
|
+
|
7
|
+
context "when the type has a correspoding class" do
|
8
|
+
|
9
|
+
before do
|
10
|
+
described_class.register(Mongo::Protocol::Query::OP_CODE, Mongo::Protocol::Query)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:klass) do
|
14
|
+
described_class.get(Mongo::Protocol::Query::OP_CODE, "message")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns the class" do
|
18
|
+
expect(klass).to eq(Mongo::Protocol::Query)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when the type has no corresponding class" do
|
23
|
+
|
24
|
+
it "raises an error" do
|
25
|
+
expect {
|
26
|
+
described_class.get(-100)
|
27
|
+
}.to raise_error(Mongo::Error::UnsupportedMessageType)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -178,4 +178,18 @@ describe Mongo::Protocol::Reply do
|
|
178
178
|
end
|
179
179
|
end
|
180
180
|
end
|
181
|
+
|
182
|
+
describe '#registry' do
|
183
|
+
|
184
|
+
context 'when the class is loaded' do
|
185
|
+
|
186
|
+
it 'registers the op code in the Protocol Registry' do
|
187
|
+
expect(Mongo::Protocol::Registry.get(described_class::OP_CODE)).to be(described_class)
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'creates an #op_code instance method' do
|
191
|
+
expect(reply.op_code).to eq(described_class::OP_CODE)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
181
195
|
end
|
@@ -183,4 +183,18 @@ describe Mongo::Protocol::Update do
|
|
183
183
|
end
|
184
184
|
end
|
185
185
|
end
|
186
|
+
|
187
|
+
describe '#registry' do
|
188
|
+
|
189
|
+
context 'when the class is loaded' do
|
190
|
+
|
191
|
+
it 'registers the op code in the Protocol Registry' do
|
192
|
+
expect(Mongo::Protocol::Registry.get(described_class::OP_CODE)).to be(described_class)
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'creates an #op_code instance method' do
|
196
|
+
expect(message.op_code).to eq(described_class::OP_CODE)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
186
200
|
end
|
@@ -29,7 +29,7 @@ describe Mongo::Retryable do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def write
|
32
|
-
write_with_retry do
|
32
|
+
write_with_retry(nil, Proc.new { cluster.next_primary }) do
|
33
33
|
operation.execute
|
34
34
|
end
|
35
35
|
end
|
@@ -41,7 +41,11 @@ describe Mongo::Retryable do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
let(:cluster) do
|
44
|
-
double('cluster')
|
44
|
+
double('cluster', next_primary: server_selector)
|
45
|
+
end
|
46
|
+
|
47
|
+
let(:server_selector) do
|
48
|
+
double('server_selector', select_server: double('server'))
|
45
49
|
end
|
46
50
|
|
47
51
|
let(:retryable) do
|
data/spec/mongo/sdam_spec.rb
CHANGED
@@ -63,6 +63,10 @@ describe 'Server Discovery and Monitoring' do
|
|
63
63
|
expect(@client.cluster.replica_set_name).to eq(phase.outcome.set_name)
|
64
64
|
end
|
65
65
|
|
66
|
+
it "sets the cluster logical session timeout minutes to #{phase.outcome.logical_session_timeout.inspect}" do
|
67
|
+
expect(@client.cluster.logical_session_timeout).to eq(phase.outcome.logical_session_timeout)
|
68
|
+
end
|
69
|
+
|
66
70
|
it "has the expected servers in the cluster" do
|
67
71
|
expect(cluster_addresses).to eq(phase_addresses)
|
68
72
|
end
|
@@ -22,6 +22,8 @@ describe Mongo::Server::Connection do
|
|
22
22
|
double('cluster').tap do |cl|
|
23
23
|
allow(cl).to receive(:topology).and_return(topology)
|
24
24
|
allow(cl).to receive(:app_metadata).and_return(app_metadata)
|
25
|
+
allow(cl).to receive(:cluster_time).and_return(nil)
|
26
|
+
allow(cl).to receive(:update_cluster_time)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
@@ -334,11 +336,11 @@ describe Mongo::Server::Connection do
|
|
334
336
|
it 'closes the socket and does not use it for subsequent requests' do
|
335
337
|
t = Thread.new {
|
336
338
|
# Kill the thread just before the reply is read
|
337
|
-
allow(Mongo::Protocol::
|
339
|
+
allow(Mongo::Protocol::Message).to receive(:deserialize_header) { t.kill }
|
338
340
|
connection.dispatch([ query_bob ])
|
339
341
|
}
|
340
342
|
t.join
|
341
|
-
allow(Mongo::Protocol::
|
343
|
+
allow(Mongo::Protocol::Message).to receive(:deserialize_header).and_call_original
|
342
344
|
expect(connection.dispatch([ query_alice ]).documents.first['name']).to eq('alice')
|
343
345
|
end
|
344
346
|
end
|
@@ -24,6 +24,7 @@ describe Mongo::Server::Description do
|
|
24
24
|
'minWireVersion' => 0,
|
25
25
|
'localTime' => Time.now,
|
26
26
|
'lastWrite' => { 'lastWriteDate' => Time.now },
|
27
|
+
'logicalSessionTimeoutMinutes' => 7,
|
27
28
|
'ok' => 1
|
28
29
|
}
|
29
30
|
end
|
@@ -832,6 +833,31 @@ describe Mongo::Server::Description do
|
|
832
833
|
end
|
833
834
|
end
|
834
835
|
|
836
|
+
describe '#logical_session_timeout_minutes' do
|
837
|
+
|
838
|
+
context 'when a logical session timeout value is in the config' do
|
839
|
+
|
840
|
+
let(:description) do
|
841
|
+
described_class.new(address, replica)
|
842
|
+
end
|
843
|
+
|
844
|
+
it 'returns the logical session timeout value' do
|
845
|
+
expect(description.logical_session_timeout).to eq(7)
|
846
|
+
end
|
847
|
+
end
|
848
|
+
|
849
|
+
context 'when a logical session timeout value is not in the config' do
|
850
|
+
|
851
|
+
let(:description) do
|
852
|
+
described_class.new(address, { 'ismaster' => true, 'ok' => 1 })
|
853
|
+
end
|
854
|
+
|
855
|
+
it 'returns nil' do
|
856
|
+
expect(description.logical_session_timeout).to be(nil)
|
857
|
+
end
|
858
|
+
end
|
859
|
+
end
|
860
|
+
|
835
861
|
describe '#==' do
|
836
862
|
|
837
863
|
let(:description) do
|
@@ -841,7 +867,8 @@ describe Mongo::Server::Description do
|
|
841
867
|
let(:other) do
|
842
868
|
described_class.new(address, replica.merge(
|
843
869
|
'localTime' => 1,
|
844
|
-
'lastWrite' => { 'lastWriteDate' => 1 }
|
870
|
+
'lastWrite' => { 'lastWriteDate' => 1 },
|
871
|
+
'operationTime' => 1
|
845
872
|
))
|
846
873
|
end
|
847
874
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongo::Session::ServerSession do
|
4
|
+
|
5
|
+
describe '#initialize' do
|
6
|
+
|
7
|
+
it 'sets the last use variable to the current time' do
|
8
|
+
expect(described_class.new.last_use).to be_within(0.2).of(Time.now)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'sets a UUID as the session id' do
|
12
|
+
expect(described_class.new.session_id).to be_a(BSON::Document)
|
13
|
+
expect(described_class.new.session_id[:id]).to be_a(BSON::Binary)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongo::Session::SessionPool do
|
4
|
+
|
5
|
+
describe '.create' do
|
6
|
+
|
7
|
+
let(:client) do
|
8
|
+
authorized_client
|
9
|
+
end
|
10
|
+
|
11
|
+
let!(:pool) do
|
12
|
+
described_class.create(client)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'creates a session pool' do
|
16
|
+
expect(pool).to be_a(Mongo::Session::SessionPool)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'adds the pool as an instance variable on the client' do
|
20
|
+
expect(client.instance_variable_get(:@session_pool)).to eq(pool)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#initialize' do
|
25
|
+
|
26
|
+
let(:pool) do
|
27
|
+
described_class.new(authorized_client)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'sets the client' do
|
31
|
+
expect(pool.instance_variable_get(:@client)).to be(authorized_client)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'checkout', if: sessions_enabled? do
|
36
|
+
|
37
|
+
let(:pool) do
|
38
|
+
described_class.new(authorized_client)
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when a session is checked out' do
|
42
|
+
|
43
|
+
let!(:session_a) do
|
44
|
+
pool.checkout
|
45
|
+
end
|
46
|
+
|
47
|
+
let!(:session_b) do
|
48
|
+
pool.checkout
|
49
|
+
end
|
50
|
+
|
51
|
+
before do
|
52
|
+
pool.checkin(session_a)
|
53
|
+
pool.checkin(session_b)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'is returned to the front of the queue' do
|
57
|
+
expect(pool.checkout).to be(session_b)
|
58
|
+
expect(pool.checkout).to be(session_a)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when there are sessions about to expire in the queue' do
|
63
|
+
|
64
|
+
let(:old_session_a) do
|
65
|
+
pool.checkout
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:old_session_b) do
|
69
|
+
pool.checkout
|
70
|
+
end
|
71
|
+
|
72
|
+
before do
|
73
|
+
pool.checkin(old_session_a)
|
74
|
+
pool.checkin(old_session_b)
|
75
|
+
allow(old_session_a).to receive(:last_use).and_return(Time.now - 1800)
|
76
|
+
allow(old_session_b).to receive(:last_use).and_return(Time.now - 1800)
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'when a session is checked out' do
|
80
|
+
|
81
|
+
let(:checked_out_session) do
|
82
|
+
pool.checkout
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'disposes of the old session and returns a new one' do
|
86
|
+
expect(checked_out_session).not_to be(old_session_a)
|
87
|
+
expect(checked_out_session).not_to be(old_session_b)
|
88
|
+
expect(pool.instance_variable_get(:@queue)).to be_empty
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'when a sessions that is about to expire is checked in' do
|
94
|
+
|
95
|
+
let(:old_session_a) do
|
96
|
+
pool.checkout
|
97
|
+
end
|
98
|
+
|
99
|
+
let(:old_session_b) do
|
100
|
+
pool.checkout
|
101
|
+
end
|
102
|
+
|
103
|
+
before do
|
104
|
+
allow(old_session_a).to receive(:last_use).and_return(Time.now - 1800)
|
105
|
+
allow(old_session_b).to receive(:last_use).and_return(Time.now - 1800)
|
106
|
+
pool.checkin(old_session_a)
|
107
|
+
pool.checkin(old_session_b)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'disposes of the old sessions instead of adding them to the pool' do
|
111
|
+
expect(pool.checkout).not_to be(old_session_a)
|
112
|
+
expect(pool.checkout).not_to be(old_session_b)
|
113
|
+
expect(pool.instance_variable_get(:@queue)).to be_empty
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#end_sessions', if: sessions_enabled? do
|
119
|
+
|
120
|
+
let(:pool) do
|
121
|
+
described_class.create(client)
|
122
|
+
end
|
123
|
+
|
124
|
+
let!(:session_a) do
|
125
|
+
pool.checkout
|
126
|
+
end
|
127
|
+
|
128
|
+
let!(:session_b) do
|
129
|
+
pool.checkout
|
130
|
+
end
|
131
|
+
|
132
|
+
let(:client) do
|
133
|
+
authorized_client.with(heartbeat_frequency: 100).tap do |cl|
|
134
|
+
cl.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
let(:subscriber) do
|
139
|
+
EventSubscriber.new
|
140
|
+
end
|
141
|
+
|
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
|
+
after do
|
150
|
+
client.close
|
151
|
+
end
|
152
|
+
|
153
|
+
let(:end_sessions_command) do
|
154
|
+
subscriber.started_events.find { |c| c.command_name == :endSessions}
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'sends the endSessions command with all the session ids' do
|
158
|
+
expect(end_sessions_command.command[:ids]).to include(BSON::Document.new(session_a.session_id))
|
159
|
+
expect(end_sessions_command.command[:ids]).to include(BSON::Document.new(session_b.session_id))
|
160
|
+
end
|
161
|
+
|
162
|
+
context 'when talking to a mongos', if: sessions_enabled? && sharded? do
|
163
|
+
|
164
|
+
it 'sends the endSessions command with all the session ids' do
|
165
|
+
expect(end_sessions_command.command[:ids]).to include(BSON::Document.new(session_a.session_id))
|
166
|
+
expect(end_sessions_command.command[:ids]).to include(BSON::Document.new(session_b.session_id))
|
167
|
+
expect(end_sessions_command.command[:$clusterTime]).to eq(client.cluster.cluster_time)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'when the number of ids is larger than 10_000' do
|
172
|
+
|
173
|
+
before do
|
174
|
+
queue = []
|
175
|
+
10_001.times do |i|
|
176
|
+
queue << double('session', session_id: i)
|
177
|
+
end
|
178
|
+
pool.instance_variable_set(:@queue, queue)
|
179
|
+
expect(Mongo::Operation::Commands::Command).to receive(:new).at_least(:twice)
|
180
|
+
end
|
181
|
+
|
182
|
+
let(:end_sessions_commands) do
|
183
|
+
subscriber.started_events.select { |c| c.command_name == :endSessions}
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'sends the command more than once' do
|
187
|
+
pool.end_sessions
|
188
|
+
# expect(end_sessions_commands.size).to eq(2)
|
189
|
+
# expect(end_sessions_commands[0].command[:ids]).to eq([*0...10_000])
|
190
|
+
# expect(end_sessions_commands[1].command[:ids]).to eq([10_000])
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
data/spec/mongo/uri_spec.rb
CHANGED
@@ -566,7 +566,7 @@ describe Mongo::URI do
|
|
566
566
|
|
567
567
|
it 'raises an exception when read preference is accessed on the client' do
|
568
568
|
expect {
|
569
|
-
Mongo::Client.new(string).
|
569
|
+
Mongo::Client.new(string).server_selector
|
570
570
|
}.to raise_exception(Mongo::Error::InvalidServerPreference)
|
571
571
|
end
|
572
572
|
end
|
@@ -578,7 +578,7 @@ describe Mongo::URI do
|
|
578
578
|
end
|
579
579
|
|
580
580
|
it 'does not raise an exception until the read preference is used' do
|
581
|
-
expect(Mongo::Client.new(string).read_preference).to
|
581
|
+
expect(Mongo::Client.new(string).read_preference).to eq(BSON::Document.new(mode: :secondary, max_staleness: 89))
|
582
582
|
end
|
583
583
|
end
|
584
584
|
end
|
@@ -929,5 +929,34 @@ describe Mongo::URI do
|
|
929
929
|
expect(Mongo::Client.new(string).options[:app_name]).to eq(:reports)
|
930
930
|
end
|
931
931
|
end
|
932
|
+
|
933
|
+
context 'when a supported compressors option is provided' do
|
934
|
+
let(:options) { "compressors=zlib" }
|
935
|
+
|
936
|
+
it 'sets the compressors as an array on the client' do
|
937
|
+
expect(Mongo::Client.new(string).options[:compressors]).to eq(['zlib'])
|
938
|
+
end
|
939
|
+
end
|
940
|
+
|
941
|
+
context 'when a non-supported compressors option is provided' do
|
942
|
+
let(:options) { "compressors=snoopy" }
|
943
|
+
|
944
|
+
let(:client) do
|
945
|
+
Mongo::Client.new(string)
|
946
|
+
end
|
947
|
+
|
948
|
+
it 'sets no compressors on the client and warns' do
|
949
|
+
expect(Mongo::Logger.logger).to receive(:warn)
|
950
|
+
expect(client.options[:compressors]).to be_nil
|
951
|
+
end
|
952
|
+
end
|
953
|
+
|
954
|
+
context 'when a zlibCompressionLevel option is provided' do
|
955
|
+
let(:options) { "zlibCompressionLevel=6" }
|
956
|
+
|
957
|
+
it 'sets the zlib compression level on the client' do
|
958
|
+
expect(Mongo::Client.new(string).options[:zlib_compression_level]).to eq(6)
|
959
|
+
end
|
960
|
+
end
|
932
961
|
end
|
933
962
|
end
|