mongo 2.9.2 → 2.10.0.rc0
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 +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mongo.rb +1 -0
- data/lib/mongo/auth/user/view.rb +4 -4
- data/lib/mongo/bulk_write.rb +14 -8
- data/lib/mongo/bulk_write/result.rb +1 -1
- data/lib/mongo/bulk_write/result_combiner.rb +2 -2
- data/lib/mongo/bulk_write/transformable.rb +17 -9
- data/lib/mongo/client.rb +107 -16
- data/lib/mongo/cluster.rb +47 -25
- data/lib/mongo/cluster/topology/replica_set_no_primary.rb +1 -1
- data/lib/mongo/cluster_time.rb +139 -0
- data/lib/mongo/collection.rb +84 -25
- data/lib/mongo/collection/view.rb +7 -3
- data/lib/mongo/collection/view/aggregation.rb +4 -4
- data/lib/mongo/collection/view/builder/aggregation.rb +31 -6
- data/lib/mongo/collection/view/builder/find_command.rb +4 -1
- data/lib/mongo/collection/view/builder/map_reduce.rb +4 -1
- data/lib/mongo/collection/view/change_stream.rb +54 -66
- data/lib/mongo/collection/view/iterable.rb +2 -2
- data/lib/mongo/collection/view/map_reduce.rb +6 -4
- data/lib/mongo/collection/view/readable.rb +36 -16
- data/lib/mongo/collection/view/writable.rb +68 -22
- data/lib/mongo/cursor.rb +87 -20
- data/lib/mongo/database.rb +47 -43
- data/lib/mongo/database/view.rb +54 -11
- data/lib/mongo/error.rb +13 -4
- data/lib/mongo/error/invalid_write_concern.rb +2 -2
- data/lib/mongo/error/operation_failure.rb +65 -11
- data/lib/mongo/error/parser.rb +41 -8
- data/lib/mongo/grid/fs_bucket.rb +26 -6
- data/lib/mongo/grid/stream/read.rb +9 -2
- data/lib/mongo/grid/stream/write.rb +21 -5
- data/lib/mongo/index/view.rb +3 -3
- data/lib/mongo/lint.rb +10 -3
- data/lib/mongo/operation.rb +2 -0
- data/lib/mongo/operation/aggregate/result.rb +19 -6
- data/lib/mongo/operation/collections_info.rb +1 -1
- data/lib/mongo/operation/get_more/result.rb +9 -0
- data/lib/mongo/operation/list_collections/command.rb +1 -3
- data/lib/mongo/operation/list_collections/op_msg.rb +1 -2
- data/lib/mongo/operation/parallel_scan/command.rb +4 -1
- data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -1
- data/lib/mongo/operation/result.rb +27 -4
- data/lib/mongo/operation/shared/executable.rb +19 -5
- data/lib/mongo/operation/shared/executable_no_validate.rb +1 -2
- data/lib/mongo/operation/shared/executable_transaction_label.rb +0 -9
- data/lib/mongo/operation/shared/polymorphic_result.rb +9 -1
- data/lib/mongo/operation/shared/result/aggregatable.rb +2 -2
- data/lib/mongo/operation/shared/sessions_supported.rb +42 -32
- data/lib/mongo/operation/shared/specifiable.rb +40 -0
- data/lib/mongo/operation/shared/unpinnable.rb +39 -0
- data/lib/mongo/operation/shared/write.rb +1 -1
- data/lib/mongo/protocol/update.rb +6 -2
- data/lib/mongo/retryable.rb +79 -39
- data/lib/mongo/server/connection.rb +10 -3
- data/lib/mongo/server/description.rb +25 -1
- data/lib/mongo/server/monitor/connection.rb +1 -1
- data/lib/mongo/server_selector.rb +10 -0
- data/lib/mongo/server_selector/selectable.rb +172 -32
- data/lib/mongo/session.rb +654 -581
- data/lib/mongo/session/session_pool.rb +1 -1
- data/lib/mongo/socket.rb +7 -28
- data/lib/mongo/socket/ssl.rb +26 -1
- data/lib/mongo/socket/tcp.rb +3 -0
- data/lib/mongo/socket/unix.rb +3 -0
- data/lib/mongo/uri.rb +112 -265
- data/lib/mongo/uri/srv_protocol.rb +4 -1
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo/write_concern.rb +10 -29
- data/lib/mongo/write_concern/acknowledged.rb +12 -0
- data/lib/mongo/write_concern/base.rb +17 -13
- data/lib/mongo/write_concern/unacknowledged.rb +12 -0
- data/spec/atlas/atlas_connectivity_spec.rb +7 -37
- data/spec/atlas/operations_spec.rb +25 -0
- data/spec/integration/change_stream_examples_spec.rb +45 -31
- data/spec/integration/change_stream_spec.rb +305 -5
- data/spec/integration/client_spec.rb +44 -0
- data/spec/integration/command_monitoring_spec.rb +1 -0
- data/spec/integration/command_spec.rb +7 -1
- data/spec/integration/mmapv1_spec.rb +28 -0
- data/spec/integration/mongos_pinning_spec.rb +34 -0
- data/spec/integration/operation_failure_code_spec.rb +2 -2
- data/spec/integration/{read_concern.rb → read_concern_spec.rb} +7 -1
- data/spec/integration/read_preference_spec.rb +485 -0
- data/spec/integration/retryable_writes_spec.rb +8 -19
- data/spec/integration/sdam_error_handling_spec.rb +1 -1
- data/spec/integration/sdam_events_spec.rb +2 -2
- data/spec/integration/server_description_spec.rb +14 -17
- data/spec/integration/server_selector_spec.rb +7 -3
- data/spec/integration/server_spec.rb +48 -0
- data/spec/integration/ssl_uri_options_spec.rb +1 -1
- data/spec/integration/step_down_spec.rb +10 -4
- data/spec/integration/transactions_examples_spec.rb +11 -10
- data/spec/lite_spec_helper.rb +19 -16
- data/spec/mongo/auth/scram/negotiation_spec.rb +11 -8
- data/spec/mongo/bulk_write/ordered_combiner_spec.rb +6 -6
- data/spec/mongo/bulk_write/unordered_combiner_spec.rb +4 -4
- data/spec/mongo/bulk_write_spec.rb +12 -2
- data/spec/mongo/client_construction_spec.rb +160 -8
- data/spec/mongo/client_spec.rb +5 -4
- data/spec/mongo/cluster_spec.rb +6 -6
- data/spec/mongo/cluster_time_spec.rb +148 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +34 -15
- data/spec/mongo/collection/view/change_stream_spec.rb +62 -3
- data/spec/mongo/collection/view/map_reduce_spec.rb +7 -5
- data/spec/mongo/collection/view/readable_spec.rb +4 -4
- data/spec/mongo/collection_spec.rb +331 -14
- data/spec/mongo/cursor_spec.rb +117 -5
- data/spec/mongo/database_spec.rb +240 -8
- data/spec/mongo/error/operation_failure_spec.rb +47 -1
- data/spec/mongo/error/parser_spec.rb +160 -23
- data/spec/mongo/operation/insert/bulk_spec.rb +2 -1
- data/spec/mongo/operation/result_spec.rb +27 -0
- data/spec/mongo/operation/update/bulk_spec.rb +1 -0
- data/spec/mongo/retryable_spec.rb +2 -0
- data/spec/mongo/server/app_metadata_spec.rb +2 -2
- data/spec/mongo/server/connection_spec.rb +13 -17
- data/spec/mongo/server/monitor/connection_spec.rb +13 -10
- data/spec/mongo/server_selector_spec.rb +34 -2
- data/spec/mongo/session/session_pool_spec.rb +14 -3
- data/spec/mongo/session_spec.rb +3 -3
- data/spec/mongo/session_transaction_spec.rb +4 -3
- data/spec/mongo/socket/ssl_spec.rb +19 -5
- data/spec/mongo/socket_spec.rb +1 -62
- data/spec/mongo/uri/srv_protocol_spec.rb +14 -20
- data/spec/mongo/uri_option_parsing_spec.rb +94 -8
- data/spec/mongo/uri_spec.rb +23 -10
- data/spec/mongo/write_concern_spec.rb +56 -3
- data/spec/spec_tests/change_streams_spec.rb +2 -1
- data/spec/spec_tests/cmap_spec.rb +1 -1
- data/spec/spec_tests/crud_spec.rb +12 -2
- data/spec/spec_tests/data/change_streams/change-streams-errors.yml +24 -1
- data/spec/spec_tests/data/change_streams/change-streams.yml +172 -3
- data/spec/spec_tests/data/command_monitoring/bulkWrite.yml +1 -1
- data/spec/spec_tests/data/command_monitoring/updateMany.yml +0 -2
- data/spec/spec_tests/data/command_monitoring/updateOne.yml +0 -5
- data/spec/spec_tests/data/crud/read/aggregate-out.yml +0 -6
- data/spec/spec_tests/data/crud/read/count-empty.yml +29 -0
- data/spec/spec_tests/data/crud/write/bulkWrite-arrayFilters.yml +1 -0
- data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +101 -0
- data/spec/spec_tests/data/crud/write/bulkWrite.yml +401 -0
- data/spec/spec_tests/data/crud/write/insertMany.yml +58 -2
- data/spec/spec_tests/data/crud/write/updateMany-arrayFilters.yml +3 -0
- data/spec/spec_tests/data/crud/write/updateOne-arrayFilters.yml +6 -1
- data/spec/spec_tests/data/crud_v2/aggregate-merge.yml +103 -0
- data/spec/spec_tests/data/crud_v2/aggregate-out-readConcern.yml +110 -0
- data/spec/spec_tests/data/crud_v2/bulkWrite-arrayFilters.yml +81 -0
- data/spec/spec_tests/data/crud_v2/db-aggregate.yml +38 -0
- data/spec/spec_tests/data/crud_v2/updateWithPipelines.yml +92 -0
- data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +2 -2
- data/spec/spec_tests/data/transactions/abort.yml +3 -0
- data/spec/spec_tests/data/transactions/bulk.yml +3 -8
- data/spec/spec_tests/data/transactions/causal-consistency.yml +3 -8
- data/spec/spec_tests/data/transactions/commit.yml +3 -1
- data/spec/spec_tests/data/transactions/count.yml +3 -0
- data/spec/spec_tests/data/transactions/delete.yml +3 -0
- data/spec/spec_tests/data/transactions/error-labels.yml +4 -1
- data/spec/spec_tests/data/transactions/errors-client.yml +56 -0
- data/spec/spec_tests/data/transactions/errors.yml +3 -0
- data/spec/spec_tests/data/transactions/findOneAndDelete.yml +3 -0
- data/spec/spec_tests/data/transactions/findOneAndReplace.yml +3 -0
- data/spec/spec_tests/data/transactions/findOneAndUpdate.yml +3 -0
- data/spec/spec_tests/data/transactions/insert.yml +3 -0
- data/spec/spec_tests/data/transactions/isolation.yml +3 -0
- data/spec/spec_tests/data/transactions/mongos-pin-auto.yml +1671 -0
- data/spec/spec_tests/data/transactions/mongos-recovery-token.yml +347 -0
- data/spec/spec_tests/data/transactions/pin-mongos.yml +557 -0
- data/spec/spec_tests/data/transactions/read-concern.yml +3 -0
- data/spec/spec_tests/data/transactions/read-pref.yml +3 -0
- data/spec/spec_tests/data/transactions/reads.yml +3 -0
- data/spec/spec_tests/data/transactions/retryable-abort.yml +5 -2
- data/spec/spec_tests/data/transactions/retryable-commit.yml +4 -1
- data/spec/spec_tests/data/transactions/retryable-writes.yml +3 -0
- data/spec/spec_tests/data/transactions/run-command.yml +3 -0
- data/spec/spec_tests/data/transactions/transaction-options.yml +6 -0
- data/spec/spec_tests/data/transactions/update.yml +3 -8
- data/spec/spec_tests/data/transactions/write-concern.yml +348 -38
- data/spec/spec_tests/data/transactions_api/callback-aborts.yml +6 -0
- data/spec/spec_tests/data/transactions_api/callback-commits.yml +5 -0
- data/spec/spec_tests/data/transactions_api/callback-retry.yml +7 -2
- data/spec/spec_tests/data/transactions_api/commit-retry.yml +70 -15
- data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +3 -0
- data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +3 -0
- data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +59 -109
- data/spec/spec_tests/data/transactions_api/commit.yml +5 -0
- data/spec/spec_tests/data/transactions_api/transaction-options.yml +10 -0
- data/spec/spec_tests/retryable_reads_spec.rb +5 -2
- data/spec/spec_tests/retryable_writes_spec.rb +5 -2
- data/spec/spec_tests/sdam_monitoring_spec.rb +3 -3
- data/spec/spec_tests/sdam_spec.rb +2 -2
- data/spec/spec_tests/transactions_api_spec.rb +1 -67
- data/spec/spec_tests/transactions_spec.rb +2 -66
- data/spec/support/authorization.rb +4 -0
- data/spec/support/change_streams.rb +30 -10
- data/spec/support/change_streams/operation.rb +27 -0
- data/spec/support/client_registry.rb +44 -25
- data/spec/support/cluster_config.rb +25 -14
- data/spec/support/cluster_tools.rb +32 -10
- data/spec/support/command_monitoring.rb +1 -1
- data/spec/support/common_shortcuts.rb +30 -0
- data/spec/support/connection_string.rb +8 -3
- data/spec/support/constraints.rb +34 -0
- data/spec/support/crud.rb +31 -16
- data/spec/support/crud/context.rb +23 -0
- data/spec/support/crud/operation.rb +311 -14
- data/spec/support/crud/spec.rb +2 -1
- data/spec/support/crud/test.rb +24 -27
- data/spec/support/crud/test_base.rb +22 -0
- data/spec/support/crud/verifier.rb +15 -1
- data/spec/support/event_subscriber.rb +12 -0
- data/spec/support/sdam_formatter_integration.rb +12 -6
- data/spec/support/shared/server_selector.rb +10 -0
- data/spec/support/shared/session.rb +13 -12
- data/spec/support/spec_config.rb +32 -22
- data/spec/support/spec_setup.rb +2 -2
- data/spec/support/transactions.rb +87 -0
- data/spec/support/transactions/context.rb +33 -0
- data/spec/support/transactions/operation.rb +99 -349
- data/spec/support/transactions/spec.rb +1 -3
- data/spec/support/transactions/test.rb +110 -49
- data/spec/support/utils.rb +74 -1
- metadata +52 -10
- metadata.gz.sig +0 -0
- data/spec/support/crud/read.rb +0 -265
- data/spec/support/crud/write.rb +0 -284
@@ -1,14 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Mongo::Server::Monitor::Connection do
|
4
|
-
|
5
|
-
before do
|
6
|
-
ClientRegistry.instance.close_all_clients
|
7
|
-
end
|
8
|
-
|
9
|
-
let(:client) do
|
10
|
-
authorized_client.with(options)
|
11
|
-
end
|
4
|
+
clean_slate
|
12
5
|
|
13
6
|
let(:address) do
|
14
7
|
Mongo::Address.new(ClusterConfig.instance.primary_address, options)
|
@@ -19,7 +12,7 @@ describe Mongo::Server::Monitor::Connection do
|
|
19
12
|
let(:cluster) do
|
20
13
|
double('cluster').tap do |cl|
|
21
14
|
allow(cl).to receive(:topology).and_return(topology)
|
22
|
-
allow(cl).to receive(:app_metadata).and_return(Mongo::Server::Monitor::AppMetadata.new(
|
15
|
+
allow(cl).to receive(:app_metadata).and_return(Mongo::Server::Monitor::AppMetadata.new({}))
|
23
16
|
allow(cl).to receive(:options).and_return({})
|
24
17
|
end
|
25
18
|
end
|
@@ -147,6 +140,16 @@ describe Mongo::Server::Monitor::Connection do
|
|
147
140
|
connection.ismaster
|
148
141
|
end
|
149
142
|
|
143
|
+
before do
|
144
|
+
# Since we set expectations on the connection, kill the
|
145
|
+
# background thread (but without disconnecting the connection).
|
146
|
+
# Note also that we need to have the connection connected in
|
147
|
+
# the first place, thus the scan! call here.
|
148
|
+
monitor.scan!
|
149
|
+
monitor.instance_variable_get('@thread').kill
|
150
|
+
monitor.instance_variable_get('@thread').join
|
151
|
+
end
|
152
|
+
|
150
153
|
it 'retries ismaster and is successful' do
|
151
154
|
expect(result).to be_a(Hash)
|
152
155
|
expect(result['ok']).to eq(1.0)
|
@@ -154,7 +157,7 @@ describe Mongo::Server::Monitor::Connection do
|
|
154
157
|
|
155
158
|
it 'logs the retry' do
|
156
159
|
expect(Mongo::Logger.logger).to receive(:warn) do |msg|
|
157
|
-
expect(msg).to match(/Retrying ismaster
|
160
|
+
expect(msg).to match(/Retrying ismaster in monitor for #{connection.address}/)
|
158
161
|
end
|
159
162
|
expect(result).to be_a(Hash)
|
160
163
|
end
|
@@ -341,7 +341,7 @@ describe Mongo::ServerSelector do
|
|
341
341
|
Mongo::Error::UnsupportedFeatures.new('Test UnsupportedFeatures')
|
342
342
|
end
|
343
343
|
|
344
|
-
let(:selector) { described_class.
|
344
|
+
let(:selector) { described_class.primary }
|
345
345
|
|
346
346
|
it 'raises Error::UnsupportedFeatures' do
|
347
347
|
expect(topology).to receive(:compatible?).and_return(false)
|
@@ -351,6 +351,38 @@ describe Mongo::ServerSelector do
|
|
351
351
|
end.to raise_error(Mongo::Error::UnsupportedFeatures, 'Test UnsupportedFeatures')
|
352
352
|
end
|
353
353
|
end
|
354
|
+
|
355
|
+
context 'sharded topology' do
|
356
|
+
|
357
|
+
let(:cluster) do
|
358
|
+
double('cluster').tap do |c|
|
359
|
+
allow(c).to receive(:connected?).and_return(true)
|
360
|
+
allow(c).to receive(:summary)
|
361
|
+
allow(c).to receive(:topology).and_return(topology)
|
362
|
+
allow(c).to receive(:servers).and_return(servers)
|
363
|
+
allow(c).to receive(:addresses).and_return(servers.map(&:address))
|
364
|
+
allow(c).to receive(:replica_set?).and_return(false)
|
365
|
+
allow(c).to receive(:single?).and_return(false)
|
366
|
+
allow(c).to receive(:sharded?).and_return(true)
|
367
|
+
allow(c).to receive(:unknown?).and_return(false)
|
368
|
+
allow(c).to receive(:scan!)
|
369
|
+
allow(c).to receive(:options).and_return(local_threshold: 0.050)
|
370
|
+
allow(topology).to receive(:compatible?).and_return(true)
|
371
|
+
allow(topology).to receive(:single?).and_return(false)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
context 'unknown and mongos' do
|
376
|
+
let(:mongos) { make_server(:mongos, address: Mongo::Address.new('localhost')) }
|
377
|
+
let(:unknown) { make_server(:unknown, address: Mongo::Address.new('localhost')) }
|
378
|
+
let(:servers) { [unknown, mongos] }
|
379
|
+
let(:selector) { described_class.primary }
|
380
|
+
|
381
|
+
it 'returns the mongos' do
|
382
|
+
expect(selector.select_server(cluster)).to eq(mongos)
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
354
386
|
end
|
355
387
|
|
356
388
|
shared_context 'a ServerSelector' do
|
@@ -378,7 +410,7 @@ describe Mongo::ServerSelector do
|
|
378
410
|
end
|
379
411
|
|
380
412
|
let(:read_pref) do
|
381
|
-
described_class.
|
413
|
+
described_class.primary
|
382
414
|
end
|
383
415
|
|
384
416
|
it 'raises a NoServerAvailable error' do
|
@@ -3,9 +3,15 @@ require 'spec_helper'
|
|
3
3
|
describe Mongo::Session::SessionPool do
|
4
4
|
min_server_fcv '3.6'
|
5
5
|
require_topology :replica_set, :sharded
|
6
|
+
clean_slate_for_all
|
6
7
|
|
7
8
|
let(:cluster) do
|
8
|
-
authorized_client.cluster
|
9
|
+
authorized_client.cluster.tap do |cluster|
|
10
|
+
# Cluster time assertions can fail if there are background operations
|
11
|
+
# that cause cluster time to be updated. This also necessitates clean
|
12
|
+
# state requirement.
|
13
|
+
authorized_client.close(true)
|
14
|
+
end
|
9
15
|
end
|
10
16
|
|
11
17
|
describe '.create' do
|
@@ -156,7 +162,7 @@ describe Mongo::Session::SessionPool do
|
|
156
162
|
end
|
157
163
|
|
158
164
|
after do
|
159
|
-
client.close
|
165
|
+
client.close(true)
|
160
166
|
end
|
161
167
|
|
162
168
|
context 'when the number of ids is not larger than 10,000' do
|
@@ -185,10 +191,15 @@ describe Mongo::Session::SessionPool do
|
|
185
191
|
context 'when talking to a replica set or mongos' do
|
186
192
|
|
187
193
|
it 'sends the endSessions command with all the session ids and cluster time' do
|
194
|
+
start_time = client.cluster.cluster_time
|
188
195
|
end_sessions_command
|
196
|
+
end_time = client.cluster.cluster_time
|
189
197
|
expect(end_sessions_command.command[:endSessions]).to include(BSON::Document.new(session_a.session_id))
|
190
198
|
expect(end_sessions_command.command[:endSessions]).to include(BSON::Document.new(session_b.session_id))
|
191
|
-
|
199
|
+
# cluster time may have been advanced due to background operations
|
200
|
+
actual_cluster_time = Mongo::ClusterTime.new(end_sessions_command.command[:$clusterTime])
|
201
|
+
expect(actual_cluster_time).to be >= start_time
|
202
|
+
expect(actual_cluster_time).to be <= end_time
|
192
203
|
end
|
193
204
|
end
|
194
205
|
end
|
data/spec/mongo/session_spec.rb
CHANGED
@@ -80,7 +80,7 @@ describe Mongo::Session do
|
|
80
80
|
context 'when the original cluster time is less than the new cluster time' do
|
81
81
|
|
82
82
|
let(:original_cluster_time) do
|
83
|
-
|
83
|
+
Mongo::ClusterTime.new('clusterTime' => BSON::Timestamp.new(0, 1))
|
84
84
|
end
|
85
85
|
|
86
86
|
before do
|
@@ -96,7 +96,7 @@ describe Mongo::Session do
|
|
96
96
|
context 'when the original cluster time is equal or greater than the new cluster time' do
|
97
97
|
|
98
98
|
let(:original_cluster_time) do
|
99
|
-
|
99
|
+
Mongo::ClusterTime.new('clusterTime' => BSON::Timestamp.new(0, 6))
|
100
100
|
end
|
101
101
|
|
102
102
|
before do
|
@@ -232,7 +232,7 @@ describe Mongo::Session do
|
|
232
232
|
end
|
233
233
|
|
234
234
|
after do
|
235
|
-
client.close
|
235
|
+
client.close(true)
|
236
236
|
end
|
237
237
|
|
238
238
|
it 'returns false' do
|
@@ -3,6 +3,7 @@ require 'spec_helper'
|
|
3
3
|
class SessionTransactionSpecError < StandardError; end
|
4
4
|
|
5
5
|
describe Mongo::Session do
|
6
|
+
require_wired_tiger
|
6
7
|
min_server_fcv '4.0'
|
7
8
|
require_topology :replica_set, :sharded
|
8
9
|
|
@@ -137,14 +138,14 @@ describe Mongo::Session do
|
|
137
138
|
sleep 0.1
|
138
139
|
|
139
140
|
exc = Mongo::Error::OperationFailure.new('timeout test')
|
140
|
-
exc.
|
141
|
+
exc.add_label('TransientTransactionError')
|
141
142
|
raise exc
|
142
143
|
end
|
143
144
|
end.to raise_error(Mongo::Error::OperationFailure, 'timeout test')
|
144
145
|
end
|
145
146
|
end
|
146
147
|
|
147
|
-
%w(
|
148
|
+
%w(UnknownTransactionCommitResult TransientTransactionError).each do |label|
|
148
149
|
context "timeout with commit raising with #{label}" do
|
149
150
|
max_example_run_time 7
|
150
151
|
|
@@ -169,7 +170,7 @@ describe Mongo::Session do
|
|
169
170
|
end
|
170
171
|
|
171
172
|
exc = Mongo::Error::OperationFailure.new('timeout test')
|
172
|
-
exc.
|
173
|
+
exc.add_label(label)
|
173
174
|
|
174
175
|
expect(session).to receive(:commit_transaction).and_raise(exc).at_least(:once)
|
175
176
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
# this test performs direct network connections without retries.
|
4
|
+
# In case of intermittent network issues, retry the entire failing test.
|
5
|
+
describe Mongo::Socket::SSL, retry: 3 do
|
4
6
|
require_tls
|
5
7
|
|
6
8
|
let(:address) do
|
@@ -478,7 +480,7 @@ describe Mongo::Socket::SSL do
|
|
478
480
|
end
|
479
481
|
|
480
482
|
let(:connection) do
|
481
|
-
Mongo::Server::Connection.new(server, options)
|
483
|
+
Mongo::Server::Connection.new(server, options.merge(socket_timeout: 2))
|
482
484
|
end
|
483
485
|
|
484
486
|
context 'as a file' do
|
@@ -509,7 +511,7 @@ describe Mongo::Socket::SSL do
|
|
509
511
|
end
|
510
512
|
|
511
513
|
let(:connection) do
|
512
|
-
Mongo::Server::Connection.new(server, options)
|
514
|
+
Mongo::Server::Connection.new(server, options.merge(socket_timeout: 2))
|
513
515
|
end
|
514
516
|
|
515
517
|
context 'as a file' do
|
@@ -564,7 +566,7 @@ describe Mongo::Socket::SSL do
|
|
564
566
|
end
|
565
567
|
|
566
568
|
let(:connection) do
|
567
|
-
Mongo::Server::Connection.new(server, options)
|
569
|
+
Mongo::Server::Connection.new(server, options.merge(socket_timeout: 2))
|
568
570
|
end
|
569
571
|
|
570
572
|
context 'as a path to a file' do
|
@@ -666,7 +668,7 @@ describe Mongo::Socket::SSL do
|
|
666
668
|
end
|
667
669
|
|
668
670
|
let(:connection) do
|
669
|
-
Mongo::Server::Connection.new(server, options)
|
671
|
+
Mongo::Server::Connection.new(server, options.merge(socket_timeout: 2))
|
670
672
|
end
|
671
673
|
|
672
674
|
let(:options) do
|
@@ -729,6 +731,18 @@ describe Mongo::Socket::SSL do
|
|
729
731
|
expect(socket).to be_alive
|
730
732
|
end
|
731
733
|
end
|
734
|
+
|
735
|
+
context 'when OpenSSL allows disabling renegotiation 'do
|
736
|
+
before do
|
737
|
+
unless OpenSSL::SSL.const_defined?(:OP_NO_RENEGOTIATION)
|
738
|
+
skip 'OpenSSL::SSL::OP_NO_RENEGOTIATION is not defined'
|
739
|
+
end
|
740
|
+
end
|
741
|
+
|
742
|
+
it 'disables TLS renegotiation' do
|
743
|
+
expect(socket.context.options & OpenSSL::SSL::OP_NO_RENEGOTIATION).to eq(OpenSSL::SSL::OP_NO_RENEGOTIATION)
|
744
|
+
end
|
745
|
+
end
|
732
746
|
end
|
733
747
|
|
734
748
|
describe '#readbyte' do
|
data/spec/mongo/socket_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'lite_spec_helper'
|
2
2
|
|
3
3
|
describe Mongo::Socket do
|
4
4
|
|
@@ -51,65 +51,4 @@ describe Mongo::Socket do
|
|
51
51
|
end.to raise_error(Mongo::Error::SocketError, 'OpenSSL::SSL::SSLError: Test error (for fake-address) (MongoDB may not be configured with SSL support)')
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
55
|
-
describe '#read' do
|
56
|
-
let(:target_host) do
|
57
|
-
host = ClusterConfig.instance.primary_address_host
|
58
|
-
# Take ipv4 address
|
59
|
-
Socket.getaddrinfo(host, 0).detect { |ai| ai.first == 'AF_INET' }[3]
|
60
|
-
end
|
61
|
-
|
62
|
-
let(:socket) do
|
63
|
-
Mongo::Socket::TCP.new(target_host, ClusterConfig.instance.primary_address_port, 1, Socket::PF_INET)
|
64
|
-
end
|
65
|
-
|
66
|
-
let(:raw_socket) { socket.instance_variable_get('@socket') }
|
67
|
-
|
68
|
-
let(:wait_readable_class) do
|
69
|
-
Class.new(Exception) do
|
70
|
-
include IO::WaitReadable
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
context 'timeout' do
|
75
|
-
|
76
|
-
shared_examples_for 'times out' do
|
77
|
-
it 'times out' do
|
78
|
-
expect(socket).to receive(:timeout).at_least(:once).and_return(0.2)
|
79
|
-
# When we raise WaitWritable, the socket object is ready for
|
80
|
-
# writing which makes the read method invoke read_nonblock many times
|
81
|
-
expect(raw_socket).to receive(:read_nonblock).at_least(:once) do |len, buf|
|
82
|
-
sleep 0.01
|
83
|
-
raise exception_class
|
84
|
-
end
|
85
|
-
|
86
|
-
expect do
|
87
|
-
socket.read(10)
|
88
|
-
end.to raise_error(Mongo::Error::SocketTimeoutError, /Took more than .* seconds to receive data \(for /)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'with WaitReadable' do
|
93
|
-
|
94
|
-
let(:exception_class) do
|
95
|
-
Class.new(Exception) do
|
96
|
-
include IO::WaitReadable
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
it_behaves_like 'times out'
|
101
|
-
end
|
102
|
-
|
103
|
-
context 'with WaitWritable' do
|
104
|
-
|
105
|
-
let(:exception_class) do
|
106
|
-
Class.new(Exception) do
|
107
|
-
include IO::WaitWritable
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
it_behaves_like 'times out'
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
54
|
end
|
@@ -1,19 +1,13 @@
|
|
1
|
-
require '
|
1
|
+
require 'lite_spec_helper'
|
2
2
|
|
3
3
|
describe Mongo::URI::SRVProtocol do
|
4
|
+
clean_slate_for_all
|
4
5
|
|
5
6
|
let(:scheme) { 'mongodb+srv://' }
|
6
7
|
let(:uri) { described_class.new(string) }
|
7
8
|
|
8
|
-
before(:all) do
|
9
|
-
# Since these tests assert on warnings being produced,
|
10
|
-
# close clients to ensure background threads do not interfere with
|
11
|
-
# their warnings.
|
12
|
-
ClientRegistry.instance.close_all_clients
|
13
|
-
end
|
14
|
-
|
15
9
|
let(:client) do
|
16
|
-
|
10
|
+
new_local_client_nmio(string)
|
17
11
|
end
|
18
12
|
|
19
13
|
describe 'invalid uris' do
|
@@ -364,11 +358,11 @@ describe Mongo::URI::SRVProtocol do
|
|
364
358
|
let(:concern) { Mongo::Options::Redacted.new(:w => 1)}
|
365
359
|
|
366
360
|
it 'sets the write concern options' do
|
367
|
-
expect(uri.uri_options[:
|
361
|
+
expect(uri.uri_options[:write_concern]).to eq(concern)
|
368
362
|
end
|
369
363
|
|
370
364
|
it 'sets the options on a client created with the uri' do
|
371
|
-
expect(client.options[:
|
365
|
+
expect(client.options[:write_concern]).to eq(concern)
|
372
366
|
end
|
373
367
|
end
|
374
368
|
|
@@ -377,11 +371,11 @@ describe Mongo::URI::SRVProtocol do
|
|
377
371
|
let(:concern) { Mongo::Options::Redacted.new(:w => :majority) }
|
378
372
|
|
379
373
|
it 'sets the write concern options' do
|
380
|
-
expect(uri.uri_options[:
|
374
|
+
expect(uri.uri_options[:write_concern]).to eq(concern)
|
381
375
|
end
|
382
376
|
|
383
377
|
it 'sets the options on a client created with the uri' do
|
384
|
-
expect(client.options[:
|
378
|
+
expect(client.options[:write_concern]).to eq(concern)
|
385
379
|
end
|
386
380
|
end
|
387
381
|
|
@@ -390,11 +384,11 @@ describe Mongo::URI::SRVProtocol do
|
|
390
384
|
let(:concern) { Mongo::Options::Redacted.new(:j => true) }
|
391
385
|
|
392
386
|
it 'sets the write concern options' do
|
393
|
-
expect(uri.uri_options[:
|
387
|
+
expect(uri.uri_options[:write_concern]).to eq(concern)
|
394
388
|
end
|
395
389
|
|
396
390
|
it 'sets the options on a client created with the uri' do
|
397
|
-
expect(client.options[:
|
391
|
+
expect(client.options[:write_concern]).to eq(concern)
|
398
392
|
end
|
399
393
|
end
|
400
394
|
|
@@ -403,11 +397,11 @@ describe Mongo::URI::SRVProtocol do
|
|
403
397
|
let(:concern) { Mongo::Options::Redacted.new(:fsync => true) }
|
404
398
|
|
405
399
|
it 'sets the write concern options' do
|
406
|
-
expect(uri.uri_options[:
|
400
|
+
expect(uri.uri_options[:write_concern]).to eq(concern)
|
407
401
|
end
|
408
402
|
|
409
403
|
it 'sets the options on a client created with the uri' do
|
410
|
-
expect(client.options[:
|
404
|
+
expect(client.options[:write_concern]).to eq(concern)
|
411
405
|
end
|
412
406
|
end
|
413
407
|
|
@@ -417,11 +411,11 @@ describe Mongo::URI::SRVProtocol do
|
|
417
411
|
let(:concern) { Mongo::Options::Redacted.new(:w => 2, :wtimeout => timeout) }
|
418
412
|
|
419
413
|
it 'sets the write concern options' do
|
420
|
-
expect(uri.uri_options[:
|
414
|
+
expect(uri.uri_options[:write_concern]).to eq(concern)
|
421
415
|
end
|
422
416
|
|
423
417
|
it 'sets the options on a client created with the uri' do
|
424
|
-
expect(client.options[:
|
418
|
+
expect(client.options[:write_concern]).to eq(concern)
|
425
419
|
end
|
426
420
|
end
|
427
421
|
end
|
@@ -581,7 +575,7 @@ describe Mongo::URI::SRVProtocol do
|
|
581
575
|
end
|
582
576
|
|
583
577
|
context 'replica set option provided' do
|
584
|
-
let(:rs_name) {
|
578
|
+
let(:rs_name) { 'test-rs-name' }
|
585
579
|
let(:options) { "replicaSet=#{rs_name}" }
|
586
580
|
|
587
581
|
it 'sets the replica set option' do
|
@@ -129,6 +129,22 @@ describe Mongo::URI do
|
|
129
129
|
expect(uri.uri_options[ruby_option]).to eq('foo')
|
130
130
|
end
|
131
131
|
|
132
|
+
context 'it is escaped in URI' do
|
133
|
+
let(:string) { "mongodb://example.com/?#{uri_option}=foo%2f" }
|
134
|
+
|
135
|
+
it 'is unescaped' do
|
136
|
+
expect(uri.uri_options[ruby_option]).to eq('foo/')
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'it is escaped twice in URI' do
|
141
|
+
let(:string) { "mongodb://example.com/?#{uri_option}=foo%252f" }
|
142
|
+
|
143
|
+
it 'is unescaped once' do
|
144
|
+
expect(uri.uri_options[ruby_option]).to eq('foo%2f')
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
132
148
|
context 'value is a number' do
|
133
149
|
let(:string) { "mongodb://example.com/?#{uri_option}=1" }
|
134
150
|
|
@@ -168,6 +184,17 @@ describe Mongo::URI do
|
|
168
184
|
expect(uri.uri_options[:auth_mech]).to eq(:scram256)
|
169
185
|
end
|
170
186
|
end
|
187
|
+
|
188
|
+
context 'unrecognized value' do
|
189
|
+
|
190
|
+
let(:string) { 'mongodb://example.com/?authMechanism=foobar' }
|
191
|
+
|
192
|
+
it_behaves_like 'parses successfully'
|
193
|
+
|
194
|
+
it 'is mapped to auth mechanism' do
|
195
|
+
expect(uri.uri_options[:auth_mech]).to eq('foobar')
|
196
|
+
end
|
197
|
+
end
|
171
198
|
end
|
172
199
|
|
173
200
|
context 'authMechanismProperties' do
|
@@ -182,6 +209,30 @@ describe Mongo::URI do
|
|
182
209
|
canonicalize_host_name: true,
|
183
210
|
))
|
184
211
|
end
|
212
|
+
|
213
|
+
context 'canonicalize host name is false' do
|
214
|
+
|
215
|
+
let(:string) { 'mongodb://example.com/?authmechanismproperties=SERVICE_REALM:foo,CANONICALIZE_HOST_NAME:false' }
|
216
|
+
|
217
|
+
it 'parses correctly' do
|
218
|
+
expect(uri.uri_options[:auth_mech_properties]).to eq(BSON::Document.new(
|
219
|
+
service_realm: 'foo',
|
220
|
+
canonicalize_host_name: false,
|
221
|
+
))
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context 'canonicalize host name is true in mixed case' do
|
226
|
+
|
227
|
+
let(:string) { 'mongodb://example.com/?authmechanismproperties=SERVICE_REALM:foo,CANONICALIZE_HOST_NAME:TrUe' }
|
228
|
+
|
229
|
+
it 'parses correctly' do
|
230
|
+
expect(uri.uri_options[:auth_mech_properties]).to eq(BSON::Document.new(
|
231
|
+
service_realm: 'foo',
|
232
|
+
canonicalize_host_name: true,
|
233
|
+
))
|
234
|
+
end
|
235
|
+
end
|
185
236
|
end
|
186
237
|
|
187
238
|
context 'authSource' do
|
@@ -190,6 +241,22 @@ describe Mongo::URI do
|
|
190
241
|
let(:ruby_option) { :auth_source }
|
191
242
|
|
192
243
|
it_behaves_like 'a string option'
|
244
|
+
|
245
|
+
context '$external' do
|
246
|
+
let(:string) { "mongodb://example.com/?#{uri_option}=$external" }
|
247
|
+
|
248
|
+
it 'is converted to ;external' do
|
249
|
+
expect(uri.uri_options[ruby_option]).to eq(:external)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
context 'empty' do
|
254
|
+
let(:string) { "mongodb://example.com/?#{uri_option}=" }
|
255
|
+
|
256
|
+
it 'is mapped to the empty string' do
|
257
|
+
expect(uri.uri_options[ruby_option]).to eq('')
|
258
|
+
end
|
259
|
+
end
|
193
260
|
end
|
194
261
|
|
195
262
|
context 'compressors' do
|
@@ -236,7 +303,7 @@ describe Mongo::URI do
|
|
236
303
|
it_behaves_like 'parses successfully'
|
237
304
|
|
238
305
|
it 'is a boolean' do
|
239
|
-
expect(uri.uri_options[:
|
306
|
+
expect(uri.uri_options[:write_concern]).to eq(BSON::Document.new(fsync: true))
|
240
307
|
end
|
241
308
|
end
|
242
309
|
|
@@ -255,7 +322,7 @@ describe Mongo::URI do
|
|
255
322
|
it_behaves_like 'parses successfully'
|
256
323
|
|
257
324
|
it 'is a boolean' do
|
258
|
-
expect(uri.uri_options[:
|
325
|
+
expect(uri.uri_options[:write_concern]).to eq(BSON::Document.new(j: true))
|
259
326
|
end
|
260
327
|
end
|
261
328
|
|
@@ -319,8 +386,8 @@ describe Mongo::URI do
|
|
319
386
|
|
320
387
|
it_behaves_like 'parses successfully'
|
321
388
|
|
322
|
-
it 'is a
|
323
|
-
expect(uri.uri_options[:read_concern]).to eq(BSON::Document.new(level:
|
389
|
+
it 'is a symbol' do
|
390
|
+
expect(uri.uri_options[:read_concern]).to eq(BSON::Document.new(level: :snapshot))
|
324
391
|
end
|
325
392
|
end
|
326
393
|
|
@@ -333,6 +400,15 @@ describe Mongo::URI do
|
|
333
400
|
it 'is a string' do
|
334
401
|
expect(uri.uri_options[:read]).to eq(BSON::Document.new(mode: :nearest))
|
335
402
|
end
|
403
|
+
|
404
|
+
context 'an unknown value' do
|
405
|
+
|
406
|
+
let(:string) { "mongodb://example.com/?readPreference=foobar" }
|
407
|
+
|
408
|
+
it 'is unchanged' do
|
409
|
+
expect(uri.uri_options[:read]).to eq(BSON::Document.new(mode: 'foobar'))
|
410
|
+
end
|
411
|
+
end
|
336
412
|
end
|
337
413
|
|
338
414
|
context 'readPreferenceTags' do
|
@@ -345,6 +421,16 @@ describe Mongo::URI do
|
|
345
421
|
expect(uri.uri_options[:read]).to eq(BSON::Document.new(
|
346
422
|
tag_sets: [{'dc' => 'ny', 'rack' => '1'}]))
|
347
423
|
end
|
424
|
+
|
425
|
+
context 'with double escaped keys and values' do
|
426
|
+
|
427
|
+
let(:string) { "mongodb://example.com/?readPreferenceTags=dc%252f:ny,rack:1%252f" }
|
428
|
+
|
429
|
+
it 'unescapes once' do
|
430
|
+
expect(uri.uri_options[:read]).to eq(BSON::Document.new(
|
431
|
+
tag_sets: [{'dc%2f' => 'ny', 'rack' => '1%2f'}]))
|
432
|
+
end
|
433
|
+
end
|
348
434
|
end
|
349
435
|
|
350
436
|
context 'replicaSet' do
|
@@ -451,7 +537,7 @@ describe Mongo::URI do
|
|
451
537
|
it_behaves_like 'parses successfully'
|
452
538
|
|
453
539
|
it 'is an integer' do
|
454
|
-
expect(uri.uri_options[:
|
540
|
+
expect(uri.uri_options[:write_concern]).to eq(BSON::Document.new(w: 1))
|
455
541
|
end
|
456
542
|
end
|
457
543
|
|
@@ -461,7 +547,7 @@ describe Mongo::URI do
|
|
461
547
|
it_behaves_like 'parses successfully'
|
462
548
|
|
463
549
|
it 'is a string' do
|
464
|
-
expect(uri.uri_options[:
|
550
|
+
expect(uri.uri_options[:write_concern]).to eq(BSON::Document.new(w: 'foo'))
|
465
551
|
end
|
466
552
|
end
|
467
553
|
|
@@ -471,7 +557,7 @@ describe Mongo::URI do
|
|
471
557
|
it_behaves_like 'parses successfully'
|
472
558
|
|
473
559
|
it 'is a symbol' do
|
474
|
-
expect(uri.uri_options[:
|
560
|
+
expect(uri.uri_options[:write_concern]).to eq(BSON::Document.new(w: :majority))
|
475
561
|
end
|
476
562
|
end
|
477
563
|
end
|
@@ -491,7 +577,7 @@ describe Mongo::URI do
|
|
491
577
|
it_behaves_like 'parses successfully'
|
492
578
|
|
493
579
|
it 'is a float' do
|
494
|
-
expect(uri.uri_options[:
|
580
|
+
expect(uri.uri_options[:write_concern]).to eq(BSON::Document.new(wtimeout: 100))
|
495
581
|
end
|
496
582
|
end
|
497
583
|
|