mongo 2.5.0.beta → 2.5.0
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/lib/mongo/address.rb +1 -1
- data/lib/mongo/address/unix.rb +1 -1
- data/lib/mongo/auth/user.rb +0 -5
- data/lib/mongo/auth/user/view.rb +4 -4
- data/lib/mongo/bulk_write.rb +60 -32
- data/lib/mongo/client.rb +44 -8
- data/lib/mongo/cluster.rb +14 -12
- data/lib/mongo/cluster/periodic_executor.rb +106 -0
- data/lib/mongo/cluster/{cursor_reaper.rb → reapers/cursor_reaper.rb} +5 -37
- data/lib/mongo/cluster/reapers/socket_reaper.rb +59 -0
- data/lib/mongo/collection.rb +9 -6
- data/lib/mongo/collection/view.rb +2 -2
- data/lib/mongo/collection/view/builder/aggregation.rb +2 -1
- data/lib/mongo/collection/view/builder/find_command.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +14 -1
- data/lib/mongo/collection/view/map_reduce.rb +30 -13
- data/lib/mongo/collection/view/readable.rb +5 -5
- data/lib/mongo/collection/view/writable.rb +98 -51
- data/lib/mongo/error.rb +3 -0
- data/lib/mongo/error/invalid_txt_record.rb +27 -0
- data/lib/mongo/error/invalid_uri.rb +7 -6
- data/lib/mongo/error/mismatched_domain.rb +27 -0
- data/lib/mongo/error/no_srv_records.rb +26 -0
- data/lib/mongo/error/unsupported_features.rb +0 -18
- data/lib/mongo/index/view.rb +2 -2
- data/lib/mongo/operation.rb +1 -0
- data/lib/mongo/operation/causally_consistent.rb +33 -0
- data/lib/mongo/operation/commands.rb +2 -1
- data/lib/mongo/operation/commands/aggregate.rb +2 -7
- data/lib/mongo/operation/commands/count.rb +27 -0
- data/lib/mongo/operation/commands/distinct.rb +27 -0
- data/lib/mongo/operation/commands/find.rb +3 -1
- data/lib/mongo/operation/commands/map_reduce.rb +1 -0
- data/lib/mongo/operation/commands/parallel_scan.rb +1 -0
- data/lib/mongo/operation/specifiable.rb +12 -0
- data/lib/mongo/operation/uses_command_op_msg.rb +36 -5
- data/lib/mongo/operation/write.rb +0 -5
- data/lib/mongo/operation/write/bulk/bulkable.rb +4 -8
- data/lib/mongo/operation/write/bulk/mergable.rb +2 -0
- data/lib/mongo/operation/write/command/create_index.rb +19 -0
- data/lib/mongo/operation/write/command/create_user.rb +19 -0
- data/lib/mongo/operation/write/command/delete.rb +1 -2
- data/lib/mongo/operation/write/command/drop_index.rb +19 -0
- data/lib/mongo/operation/write/command/insert.rb +1 -2
- data/lib/mongo/operation/write/command/remove_user.rb +19 -0
- data/lib/mongo/operation/write/command/update.rb +1 -2
- data/lib/mongo/operation/write/command/update_user.rb +19 -0
- data/lib/mongo/operation/write/write_command_enabled.rb +1 -3
- data/lib/mongo/protocol/compressed.rb +2 -1
- data/lib/mongo/protocol/serializers.rb +6 -6
- data/lib/mongo/retryable.rb +48 -5
- data/lib/mongo/server.rb +15 -0
- data/lib/mongo/server/connection.rb +21 -1
- data/lib/mongo/server/connection_pool.rb +3 -0
- data/lib/mongo/server/connection_pool/queue.rb +50 -5
- data/lib/mongo/server/description.rb +11 -3
- data/lib/mongo/server/description/features.rb +26 -7
- data/lib/mongo/session.rb +133 -6
- data/lib/mongo/session/server_session.rb +30 -0
- data/lib/mongo/session/session_pool.rb +20 -20
- data/lib/mongo/uri.rb +88 -44
- data/lib/mongo/uri/srv_protocol.rb +158 -0
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo/write_concern/normalizable.rb +12 -0
- data/mongo.gemspec +1 -2
- data/spec/mongo/address_spec.rb +12 -0
- data/spec/mongo/auth/user/view_spec.rb +1 -5
- data/spec/mongo/bulk_write_spec.rb +232 -401
- data/spec/mongo/change_stream_examples_spec.rb +150 -0
- data/spec/mongo/client_spec.rb +142 -2
- data/spec/mongo/cluster/cursor_reaper_spec.rb +0 -70
- data/spec/mongo/cluster/socket_reaper_spec.rb +32 -0
- data/spec/mongo/cluster_spec.rb +11 -7
- data/spec/mongo/collection/view/aggregation_spec.rb +46 -1
- data/spec/mongo/collection/view/builder/find_command_spec.rb +15 -0
- data/spec/mongo/collection/view/change_stream_spec.rb +79 -12
- data/spec/mongo/collection/view/map_reduce_spec.rb +120 -4
- data/spec/mongo/collection/view/readable_spec.rb +23 -5
- data/spec/mongo/collection_spec.rb +292 -102
- data/spec/mongo/command_monitoring_spec.rb +26 -32
- data/spec/mongo/crud_spec.rb +1 -1
- data/spec/mongo/cursor_spec.rb +2 -3
- data/spec/mongo/database_spec.rb +30 -14
- data/spec/mongo/dns_seedlist_discovery_spec.rb +94 -0
- data/spec/mongo/grid/fs_bucket_spec.rb +1 -1
- data/spec/mongo/grid/stream/write_spec.rb +1 -1
- data/spec/mongo/index/view_spec.rb +8 -46
- data/spec/mongo/operation/write/bulk/delete_spec.rb +2 -2
- data/spec/mongo/operation/write/bulk/insert_spec.rb +2 -10
- data/spec/mongo/operation/write/{create_index_spec.rb → command/create_index_spec.rb} +2 -6
- data/spec/mongo/operation/write/command/delete_spec.rb +35 -7
- data/spec/mongo/operation/write/{drop_index_spec.rb → command/drop_index_spec.rb} +1 -1
- data/spec/mongo/operation/write/command/insert_spec.rb +37 -6
- data/spec/mongo/operation/write/{remove_user_spec.rb → command/remove_user_spec.rb} +2 -6
- data/spec/mongo/operation/write/command/update_spec.rb +34 -7
- data/spec/mongo/operation/write/{update_user_spec.rb → command/update_user_spec.rb} +1 -1
- data/spec/mongo/operation/write/create_user_spec.rb +1 -1
- data/spec/mongo/operation/write/delete_spec.rb +1 -1
- data/spec/mongo/operation/write/insert_spec.rb +2 -10
- data/spec/mongo/operation/write/update_spec.rb +3 -15
- data/spec/mongo/retryable_spec.rb +1 -1
- data/spec/mongo/retryable_writes_spec.rb +815 -0
- data/spec/mongo/server/connection_pool/queue_spec.rb +35 -2
- data/spec/mongo/server/connection_pool_spec.rb +234 -1
- data/spec/mongo/server/connection_spec.rb +10 -6
- data/spec/mongo/server/description/features_spec.rb +51 -37
- data/spec/mongo/server/description_spec.rb +6 -3
- data/spec/mongo/server_spec.rb +87 -0
- data/spec/mongo/session/server_session_spec.rb +43 -0
- data/spec/mongo/session/session_pool_spec.rb +63 -27
- data/spec/mongo/session_spec.rb +247 -0
- data/spec/mongo/shell_examples_spec.rb +2 -2
- data/spec/mongo/uri/srv_protocol_spec.rb +933 -0
- data/spec/mongo/uri_spec.rb +42 -3
- data/spec/mongo/write_concern/acknowledged_spec.rb +11 -0
- data/spec/mongo/write_concern/unacknowledged_spec.rb +11 -0
- data/spec/spec_helper.rb +11 -25
- data/spec/support/authorization.rb +2 -1
- data/spec/support/connection_string.rb +8 -4
- data/spec/support/crud.rb +38 -24
- data/spec/support/crud/write.rb +30 -3
- data/spec/support/crud_tests/read/aggregate-out.yml +21 -0
- data/spec/support/crud_tests/write/bulkWrite-arrayFilters.yml +44 -0
- data/spec/support/crud_tests/write/findOneAndUpdate-arrayFilters.yml +1 -1
- data/spec/support/crud_tests/write/insertMany.yml +1 -3
- data/spec/support/crud_tests/write/replaceOne.yml +1 -1
- data/spec/support/crud_tests/write/updateMany-arrayFilters.yml +1 -1
- data/spec/support/crud_tests/write/updateOne-arrayFilters.yml +1 -1
- data/spec/support/dns_seedlist_discovery_tests/longer-parent-in-return.yml +11 -0
- data/spec/support/dns_seedlist_discovery_tests/misformatted-option.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/no-results.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/not-enough-parts.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/one-result-default-port.yml +10 -0
- data/spec/support/dns_seedlist_discovery_tests/one-txt-record-multiple-strings.yml +10 -0
- data/spec/support/dns_seedlist_discovery_tests/one-txt-record.yml +11 -0
- data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch1.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch2.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch3.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch4.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch5.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/returned-parent-too-short.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/returned-parent-wrong.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/two-results-default-port.yml +11 -0
- data/spec/support/dns_seedlist_discovery_tests/two-results-nonstandard-port.yml +11 -0
- data/spec/support/dns_seedlist_discovery_tests/two-txt-records.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/txt-record-not-allowed-option.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/txt-record-with-overridden-ssl-option.yml +11 -0
- data/spec/support/dns_seedlist_discovery_tests/txt-record-with-overridden-uri-option.yml +11 -0
- data/spec/support/dns_seedlist_discovery_tests/txt-record-with-unallowed-option.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/uri-with-port.yml +5 -0
- data/spec/support/dns_seedlist_discovery_tests/uri-with-two-hosts.yml +5 -0
- data/spec/support/retryable_writes_tests/bulkWrite.yml +305 -0
- data/spec/support/retryable_writes_tests/deleteOne.yml +51 -0
- data/spec/support/retryable_writes_tests/findOneAndDelete.yml +52 -0
- data/spec/support/retryable_writes_tests/findOneAndReplace.yml +57 -0
- data/spec/support/retryable_writes_tests/findOneAndUpdate.yml +56 -0
- data/spec/support/retryable_writes_tests/insertMany.yml +72 -0
- data/spec/support/retryable_writes_tests/insertOne.yml +55 -0
- data/spec/support/retryable_writes_tests/replaceOne.yml +60 -0
- data/spec/support/retryable_writes_tests/updateOne.yml +120 -0
- data/spec/support/shared/session.rb +525 -24
- metadata +437 -350
- metadata.gz.sig +0 -0
- data/lib/mongo/operation/commands/user_query.rb +0 -72
- data/lib/mongo/operation/write/create_index.rb +0 -67
- data/lib/mongo/operation/write/create_user.rb +0 -50
- data/lib/mongo/operation/write/drop_index.rb +0 -63
- data/lib/mongo/operation/write/remove_user.rb +0 -48
- data/lib/mongo/operation/write/update_user.rb +0 -50
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'change streams examples in Ruby', if: test_change_streams? do
|
4
|
+
|
5
|
+
let!(:inventory) do
|
6
|
+
client[:inventory]
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:client) do
|
10
|
+
authorized_client.with(max_pool_size: 5, wait_queue_timeout: 3)
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
inventory.drop
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
client.close
|
19
|
+
inventory.drop
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'example 1 - basic watching'do
|
23
|
+
|
24
|
+
it 'returns a change after an insertion' do
|
25
|
+
|
26
|
+
insert_thread = Thread.new do
|
27
|
+
sleep 2
|
28
|
+
inventory.insert_one(x: 1)
|
29
|
+
end
|
30
|
+
|
31
|
+
stream_thread = Thread.new do
|
32
|
+
|
33
|
+
# Start Changestream Example 1
|
34
|
+
|
35
|
+
cursor = inventory.watch.to_enum
|
36
|
+
next_change = cursor.next
|
37
|
+
|
38
|
+
# End Changestream Example 1
|
39
|
+
end
|
40
|
+
|
41
|
+
insert_thread.value
|
42
|
+
change = stream_thread.value
|
43
|
+
|
44
|
+
expect(change['_id']).not_to be_nil
|
45
|
+
expect(change['_id']['_data']).not_to be_nil
|
46
|
+
expect(change['operationType']).to eq('insert')
|
47
|
+
expect(change['fullDocument']).not_to be_nil
|
48
|
+
expect(change['fullDocument']['_id']).not_to be_nil
|
49
|
+
expect(change['fullDocument']['x']).to eq(1)
|
50
|
+
expect(change['ns']).not_to be_nil
|
51
|
+
expect(change['ns']['db']).to eq(TEST_DB)
|
52
|
+
expect(change['ns']['coll']).to eq(inventory.name)
|
53
|
+
expect(change['documentKey']).not_to be_nil
|
54
|
+
expect(change['documentKey']['_id']).to eq(change['fullDocument']['_id'])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'example 2 - full document update lookup specified' do
|
59
|
+
|
60
|
+
it 'returns a change and the delta after an insertion' do
|
61
|
+
|
62
|
+
inventory.insert_one(_id: 1, x: 2)
|
63
|
+
|
64
|
+
update_thread = Thread.new do
|
65
|
+
sleep 2
|
66
|
+
inventory.update_one({ _id: 1}, { '$set' => { x: 5 }})
|
67
|
+
end
|
68
|
+
|
69
|
+
stream_thread = Thread.new do
|
70
|
+
|
71
|
+
# Start Changestream Example 2
|
72
|
+
|
73
|
+
cursor = inventory.watch([], full_document: 'updateLookup').to_enum
|
74
|
+
next_change = cursor.next
|
75
|
+
|
76
|
+
# End Changestream Example 2
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
update_thread.value
|
81
|
+
change = stream_thread.value
|
82
|
+
|
83
|
+
expect(change['_id']).not_to be_nil
|
84
|
+
expect(change['_id']['_data']).not_to be_nil
|
85
|
+
expect(change['operationType']).to eq('update')
|
86
|
+
expect(change['fullDocument']).not_to be_nil
|
87
|
+
expect(change['fullDocument']['_id']).to eq(1)
|
88
|
+
expect(change['fullDocument']['x']).to eq(5)
|
89
|
+
expect(change['ns']).not_to be_nil
|
90
|
+
expect(change['ns']['db']).to eq(TEST_DB)
|
91
|
+
expect(change['ns']['coll']).to eq(inventory.name)
|
92
|
+
expect(change['documentKey']).not_to be_nil
|
93
|
+
expect(change['documentKey']['_id']).to eq(1)
|
94
|
+
expect(change['updateDescription']).not_to be_nil
|
95
|
+
expect(change['updateDescription']['updatedFields']).not_to be_nil
|
96
|
+
expect(change['updateDescription']['updatedFields']['x']).to eq(5)
|
97
|
+
expect(change['updateDescription']['removedFields']).to eq([])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'example 3 - resuming from a previous change' do
|
102
|
+
|
103
|
+
it 'returns the correct change when resuming' do
|
104
|
+
|
105
|
+
stream = inventory.watch
|
106
|
+
cursor = stream.to_enum
|
107
|
+
inventory.insert_one(x: 1)
|
108
|
+
next_change = cursor.next
|
109
|
+
|
110
|
+
expect(next_change['_id']).not_to be_nil
|
111
|
+
expect(next_change['_id']['_data']).not_to be_nil
|
112
|
+
expect(next_change['operationType']).to eq('insert')
|
113
|
+
expect(next_change['fullDocument']).not_to be_nil
|
114
|
+
expect(next_change['fullDocument']['_id']).not_to be_nil
|
115
|
+
expect(next_change['fullDocument']['x']).to eq(1)
|
116
|
+
expect(next_change['ns']).not_to be_nil
|
117
|
+
expect(next_change['ns']['db']).to eq(TEST_DB)
|
118
|
+
expect(next_change['ns']['coll']).to eq(inventory.name)
|
119
|
+
expect(next_change['documentKey']).not_to be_nil
|
120
|
+
expect(next_change['documentKey']['_id']).to eq(next_change['fullDocument']['_id'])
|
121
|
+
|
122
|
+
inventory.insert_one(x: 2)
|
123
|
+
next_next_change = cursor.next
|
124
|
+
stream.close
|
125
|
+
|
126
|
+
expect(next_next_change['_id']).not_to be_nil
|
127
|
+
expect(next_next_change['_id']['_data']).not_to be_nil
|
128
|
+
expect(next_next_change['operationType']).to eq('insert')
|
129
|
+
expect(next_next_change['fullDocument']).not_to be_nil
|
130
|
+
expect(next_next_change['fullDocument']['_id']).not_to be_nil
|
131
|
+
expect(next_next_change['fullDocument']['x']).to eq(2)
|
132
|
+
expect(next_next_change['ns']).not_to be_nil
|
133
|
+
expect(next_next_change['ns']['db']).to eq(TEST_DB)
|
134
|
+
expect(next_next_change['ns']['coll']).to eq(inventory.name)
|
135
|
+
expect(next_next_change['documentKey']).not_to be_nil
|
136
|
+
expect(next_next_change['documentKey']['_id']).to eq(next_next_change['fullDocument']['_id'])
|
137
|
+
|
138
|
+
# Start Changestream Example 3
|
139
|
+
|
140
|
+
resume_token = next_change['_id']
|
141
|
+
cursor = inventory.watch([], resume_after: resume_token).to_enum
|
142
|
+
resumed_change = cursor.next
|
143
|
+
|
144
|
+
# End Changestream Example 3
|
145
|
+
|
146
|
+
expect(resumed_change.length).to eq(next_next_change.length)
|
147
|
+
resumed_change.each { |key| expect(resumed_change[key]).to eq(next_next_change[key]) }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
data/spec/mongo/client_spec.rb
CHANGED
@@ -218,6 +218,21 @@ describe Mongo::Client do
|
|
218
218
|
|
219
219
|
context 'when providing options' do
|
220
220
|
|
221
|
+
context 'when retry_writes is defined' do
|
222
|
+
|
223
|
+
let(:options) do
|
224
|
+
{ retry_writes: true }
|
225
|
+
end
|
226
|
+
|
227
|
+
let(:client) do
|
228
|
+
described_class.new([default_address.seed], authorized_client.options.merge(options))
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'sets the option' do
|
232
|
+
expect(client.options['retry_writes']).to eq(options[:retry_writes])
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
221
236
|
context 'when compressors are provided' do
|
222
237
|
|
223
238
|
let(:client) do
|
@@ -617,6 +632,21 @@ describe Mongo::Client do
|
|
617
632
|
|
618
633
|
context 'when providing a connection string' do
|
619
634
|
|
635
|
+
context 'when the string uses the SRV Protocol' do
|
636
|
+
|
637
|
+
let!(:uri) do
|
638
|
+
'mongodb+srv://test5.test.build.10gen.cc/testdb'
|
639
|
+
end
|
640
|
+
|
641
|
+
let(:client) do
|
642
|
+
described_class.new(uri)
|
643
|
+
end
|
644
|
+
|
645
|
+
it 'sets the database' do
|
646
|
+
expect(client.options[:database]).to eq('testdb')
|
647
|
+
end
|
648
|
+
end
|
649
|
+
|
620
650
|
context 'when a database is provided' do
|
621
651
|
|
622
652
|
let!(:uri) do
|
@@ -1276,6 +1306,22 @@ describe Mongo::Client do
|
|
1276
1306
|
'admin'
|
1277
1307
|
)
|
1278
1308
|
end
|
1309
|
+
|
1310
|
+
context 'when filter criteria is present', if: sessions_enabled? do
|
1311
|
+
|
1312
|
+
let(:result) do
|
1313
|
+
root_authorized_client.database_names(filter)
|
1314
|
+
end
|
1315
|
+
|
1316
|
+
let(:filter) do
|
1317
|
+
{ name: TEST_DB }
|
1318
|
+
end
|
1319
|
+
|
1320
|
+
it 'returns a filtered list of database names' do
|
1321
|
+
expect(result.length).to eq(1)
|
1322
|
+
expect(result.first).to eq(filter[:name])
|
1323
|
+
end
|
1324
|
+
end
|
1279
1325
|
end
|
1280
1326
|
|
1281
1327
|
describe '#list_databases' do
|
@@ -1286,9 +1332,94 @@ describe Mongo::Client do
|
|
1286
1332
|
i['name']
|
1287
1333
|
end).to include('admin')
|
1288
1334
|
end
|
1335
|
+
|
1336
|
+
context 'when filter criteria is present', if: sessions_enabled? do
|
1337
|
+
|
1338
|
+
let(:result) do
|
1339
|
+
root_authorized_client.list_databases(filter)
|
1340
|
+
end
|
1341
|
+
|
1342
|
+
let(:filter) do
|
1343
|
+
{ name: TEST_DB }
|
1344
|
+
end
|
1345
|
+
|
1346
|
+
it 'returns a filtered list of database info documents' do
|
1347
|
+
expect(result.length).to eq(1)
|
1348
|
+
expect(result[0]['name']).to eq(filter[:name])
|
1349
|
+
end
|
1350
|
+
end
|
1351
|
+
|
1352
|
+
context 'when name_only is true' do
|
1353
|
+
|
1354
|
+
let(:client_options) do
|
1355
|
+
root_authorized_client.options.merge(heartbeat_frequency: 100, monitoring: true)
|
1356
|
+
end
|
1357
|
+
|
1358
|
+
let(:client) do
|
1359
|
+
# Monitoring subscribers won't be set up when using Client#with, so a new client must be created.
|
1360
|
+
Mongo::Client.new(ADDRESSES, client_options).tap do |cl|
|
1361
|
+
cl.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
1362
|
+
end
|
1363
|
+
end
|
1364
|
+
|
1365
|
+
let(:subscriber) do
|
1366
|
+
EventSubscriber.new
|
1367
|
+
end
|
1368
|
+
|
1369
|
+
let(:command) do
|
1370
|
+
subscriber.started_events.find { |c| c.command_name == :listDatabases }.command
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
before do
|
1374
|
+
client.list_databases({}, true)
|
1375
|
+
end
|
1376
|
+
|
1377
|
+
it 'sends the command with the nameOnly flag set to true' do
|
1378
|
+
expect(command[:nameOnly]).to be(true)
|
1379
|
+
end
|
1380
|
+
end
|
1381
|
+
end
|
1382
|
+
|
1383
|
+
describe '#list_mongo_databases' do
|
1384
|
+
|
1385
|
+
let(:options) do
|
1386
|
+
{ read: { mode: :secondary } }
|
1387
|
+
end
|
1388
|
+
|
1389
|
+
let(:client) do
|
1390
|
+
root_authorized_client.with(options)
|
1391
|
+
end
|
1392
|
+
|
1393
|
+
let(:result) do
|
1394
|
+
client.list_mongo_databases
|
1395
|
+
end
|
1396
|
+
|
1397
|
+
it 'returns a list of Mongo::Database objects' do
|
1398
|
+
expect(result).to all(be_a(Mongo::Database))
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
it 'creates database with specified options' do
|
1402
|
+
expect(result.first.options[:read]).to eq(BSON::Document.new(options)[:read])
|
1403
|
+
end
|
1404
|
+
|
1405
|
+
context 'when filter criteria is present', if: sessions_enabled? do
|
1406
|
+
|
1407
|
+
let(:result) do
|
1408
|
+
client.list_mongo_databases(filter)
|
1409
|
+
end
|
1410
|
+
|
1411
|
+
let(:filter) do
|
1412
|
+
{ name: TEST_DB }
|
1413
|
+
end
|
1414
|
+
|
1415
|
+
it 'returns a filtered list of Mongo::Database objects' do
|
1416
|
+
expect(result.length).to eq(1)
|
1417
|
+
expect(result.first.name).to eq(filter[:name])
|
1418
|
+
end
|
1419
|
+
end
|
1289
1420
|
end
|
1290
1421
|
|
1291
|
-
|
1422
|
+
describe '#close' do
|
1292
1423
|
|
1293
1424
|
let(:client) do
|
1294
1425
|
described_class.new(['127.0.0.1:27017'])
|
@@ -1359,7 +1490,7 @@ describe Mongo::Client do
|
|
1359
1490
|
authorized_client.start_session
|
1360
1491
|
end
|
1361
1492
|
|
1362
|
-
context 'when sessions are supported', if:
|
1493
|
+
context 'when sessions are supported', if: test_sessions? do
|
1363
1494
|
|
1364
1495
|
it 'creates a session' do
|
1365
1496
|
expect(session).to be_a(Mongo::Session)
|
@@ -1410,6 +1541,10 @@ describe Mongo::Client do
|
|
1410
1541
|
end
|
1411
1542
|
|
1412
1543
|
before do
|
1544
|
+
session_a_server_session.next_txn_num
|
1545
|
+
session_a_server_session.next_txn_num
|
1546
|
+
session_b_server_session.next_txn_num
|
1547
|
+
session_b_server_session.next_txn_num
|
1413
1548
|
session_a.end_session
|
1414
1549
|
session_b.end_session
|
1415
1550
|
end
|
@@ -1418,6 +1553,11 @@ describe Mongo::Client do
|
|
1418
1553
|
expect(authorized_client.start_session.instance_variable_get(:@server_session)).to be(session_b_server_session)
|
1419
1554
|
expect(authorized_client.start_session.instance_variable_get(:@server_session)).to be(session_a_server_session)
|
1420
1555
|
end
|
1556
|
+
|
1557
|
+
it 'preserves the transaction numbers on the server sessions' do
|
1558
|
+
expect(authorized_client.start_session.next_txn_num).to be(2)
|
1559
|
+
expect(authorized_client.start_session.next_txn_num).to be(2)
|
1560
|
+
end
|
1421
1561
|
end
|
1422
1562
|
|
1423
1563
|
context 'when an implicit session is used' do
|
@@ -25,47 +25,6 @@ describe Mongo::Cluster::CursorReaper do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
describe '#run' do
|
29
|
-
|
30
|
-
it 'starts a thread calling #kill_cursors' do
|
31
|
-
reaper.run!
|
32
|
-
expect(reaper.instance_variable_get(:@thread)).to be_a(Thread)
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'when run is called more than once' do
|
36
|
-
|
37
|
-
let!(:reaper_thread) do
|
38
|
-
reaper.run!
|
39
|
-
reaper.instance_variable_get(:@reaper)
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'only starts a thread once' do
|
43
|
-
reaper.run!
|
44
|
-
expect(reaper.instance_variable_get(:@reaper)).to be(reaper_thread)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
context 'when there are ops in the list to execute' do
|
49
|
-
|
50
|
-
let(:server) { double('server') }
|
51
|
-
let(:cursor_id) { 1 }
|
52
|
-
let(:op_spec_1) { double('op_spec_1') }
|
53
|
-
let(:op_spec_2) { double('op_spec_2') }
|
54
|
-
let(:to_kill) { reaper.instance_variable_get(:@to_kill)}
|
55
|
-
|
56
|
-
before do
|
57
|
-
reaper.register_cursor(cursor_id)
|
58
|
-
reaper.schedule_kill_cursor(cursor_id, op_spec_1, server)
|
59
|
-
reaper.run!
|
60
|
-
sleep(Mongo::Cluster::CursorReaper::FREQUENCY + 1)
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'executes the ops in the thread' do
|
64
|
-
expect(reaper.instance_variable_get(:@to_kill).size).to eq(0)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
28
|
describe '#schedule_kill_cursor' do
|
70
29
|
|
71
30
|
let(:server) { double('server') }
|
@@ -184,33 +143,4 @@ describe Mongo::Cluster::CursorReaper do
|
|
184
143
|
end
|
185
144
|
end
|
186
145
|
end
|
187
|
-
|
188
|
-
describe '#stop!' do
|
189
|
-
|
190
|
-
let(:thread) do
|
191
|
-
reaper.run!
|
192
|
-
reaper.stop!
|
193
|
-
sleep(0.5)
|
194
|
-
reaper.instance_variable_get(:@thread)
|
195
|
-
end
|
196
|
-
|
197
|
-
it 'stops the thread from running' do
|
198
|
-
expect(thread.alive?).to be(false)
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
describe '#restart!' do
|
203
|
-
|
204
|
-
let(:thread) do
|
205
|
-
reaper.run!
|
206
|
-
reaper.stop!
|
207
|
-
sleep(0.5)
|
208
|
-
reaper.restart!
|
209
|
-
reaper.instance_variable_get(:@thread)
|
210
|
-
end
|
211
|
-
|
212
|
-
it 'restarts the thread' do
|
213
|
-
expect(thread.alive?).to be(true)
|
214
|
-
end
|
215
|
-
end
|
216
146
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongo::Cluster::SocketReaper do
|
4
|
+
|
5
|
+
let(:cluster) do
|
6
|
+
authorized_client.cluster
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:reaper) do
|
10
|
+
described_class.new(cluster)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#initialize' do
|
14
|
+
|
15
|
+
it 'takes a cluster as an argument' do
|
16
|
+
expect(reaper).to be_a(described_class)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#execute' do
|
21
|
+
|
22
|
+
before do
|
23
|
+
cluster.servers.each do |s|
|
24
|
+
expect(s.pool).to receive(:close_stale_sockets!).and_call_original
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'calls close_stale_sockets on each connection pool in the cluster' do
|
29
|
+
reaper.execute
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|