mongo 2.4.3 → 2.5.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +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
|