mongo 2.13.0.beta1 → 2.13.0.rc1
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 +1 -5
- data/Rakefile +15 -9
- data/lib/mongo.rb +4 -2
- data/lib/mongo/auth/aws/request.rb +4 -2
- data/lib/mongo/bulk_write.rb +1 -0
- data/lib/mongo/client.rb +143 -21
- data/lib/mongo/cluster.rb +53 -17
- data/lib/mongo/cluster/sdam_flow.rb +13 -10
- data/lib/mongo/cluster/topology/replica_set_no_primary.rb +3 -2
- data/lib/mongo/cluster/topology/sharded.rb +1 -1
- data/lib/mongo/cluster/topology/single.rb +1 -1
- data/lib/mongo/collection.rb +17 -13
- data/lib/mongo/collection/view/readable.rb +3 -1
- data/lib/mongo/collection/view/writable.rb +41 -5
- data/lib/mongo/database.rb +31 -4
- data/lib/mongo/database/view.rb +19 -4
- data/lib/mongo/distinguishing_semaphore.rb +55 -0
- data/lib/mongo/error.rb +1 -0
- data/lib/mongo/error/invalid_session.rb +2 -1
- data/lib/mongo/error/operation_failure.rb +6 -0
- data/lib/mongo/error/sessions_not_supported.rb +35 -0
- data/lib/mongo/event/base.rb +6 -0
- data/lib/mongo/grid/file.rb +5 -0
- data/lib/mongo/grid/file/chunk.rb +2 -0
- data/lib/mongo/grid/fs_bucket.rb +15 -13
- data/lib/mongo/grid/stream/write.rb +9 -3
- data/lib/mongo/monitoring.rb +38 -0
- data/lib/mongo/monitoring/command_log_subscriber.rb +10 -2
- data/lib/mongo/monitoring/event/command_failed.rb +11 -0
- data/lib/mongo/monitoring/event/command_started.rb +37 -2
- data/lib/mongo/monitoring/event/command_succeeded.rb +11 -0
- data/lib/mongo/monitoring/event/server_closed.rb +1 -1
- data/lib/mongo/monitoring/event/server_description_changed.rb +27 -4
- data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +9 -2
- data/lib/mongo/monitoring/event/server_heartbeat_started.rb +9 -2
- data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +9 -2
- data/lib/mongo/monitoring/event/server_opening.rb +1 -1
- data/lib/mongo/monitoring/event/topology_changed.rb +1 -1
- data/lib/mongo/monitoring/event/topology_closed.rb +1 -1
- data/lib/mongo/monitoring/event/topology_opening.rb +1 -1
- data/lib/mongo/monitoring/publishable.rb +6 -3
- data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +9 -1
- data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +1 -1
- data/lib/mongo/protocol/message.rb +36 -8
- data/lib/mongo/protocol/msg.rb +14 -0
- data/lib/mongo/protocol/serializers.rb +5 -2
- data/lib/mongo/server.rb +10 -3
- data/lib/mongo/server/connection.rb +4 -4
- data/lib/mongo/server/connection_base.rb +3 -1
- data/lib/mongo/server/description.rb +5 -0
- data/lib/mongo/server/monitor.rb +76 -44
- data/lib/mongo/server/monitor/connection.rb +55 -7
- data/lib/mongo/server/pending_connection.rb +14 -4
- data/lib/mongo/server/push_monitor.rb +173 -0
- data/{spec/runners/transactions/context.rb → lib/mongo/server/push_monitor/connection.rb} +9 -14
- data/lib/mongo/server_selector.rb +0 -1
- data/lib/mongo/server_selector/base.rb +579 -1
- data/lib/mongo/server_selector/nearest.rb +1 -6
- data/lib/mongo/server_selector/primary.rb +1 -6
- data/lib/mongo/server_selector/primary_preferred.rb +7 -10
- data/lib/mongo/server_selector/secondary.rb +1 -6
- data/lib/mongo/server_selector/secondary_preferred.rb +1 -7
- data/lib/mongo/session.rb +2 -0
- data/lib/mongo/socket.rb +20 -8
- data/lib/mongo/socket/ssl.rb +1 -1
- data/lib/mongo/socket/tcp.rb +1 -1
- data/lib/mongo/topology_version.rb +9 -0
- data/lib/mongo/utils.rb +62 -0
- data/lib/mongo/version.rb +1 -1
- data/spec/README.aws-auth.md +2 -2
- data/spec/integration/awaited_ismaster_spec.rb +28 -0
- data/spec/integration/change_stream_examples_spec.rb +6 -2
- data/spec/integration/check_clean_slate_spec.rb +16 -0
- data/spec/integration/client_construction_spec.rb +1 -0
- data/spec/integration/connect_single_rs_name_spec.rb +5 -2
- data/spec/integration/connection_spec.rb +7 -4
- data/spec/integration/crud_spec.rb +4 -4
- data/spec/integration/docs_examples_spec.rb +6 -0
- data/spec/integration/grid_fs_bucket_spec.rb +48 -0
- data/spec/integration/heartbeat_events_spec.rb +4 -23
- data/spec/integration/read_concern_spec.rb +1 -1
- data/spec/integration/retryable_errors_spec.rb +1 -1
- data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +2 -2
- data/spec/integration/retryable_writes/shared/performs_modern_retries.rb +3 -3
- data/spec/integration/retryable_writes/shared/performs_no_retries.rb +2 -2
- data/spec/integration/sdam_error_handling_spec.rb +37 -15
- data/spec/integration/sdam_events_spec.rb +77 -6
- data/spec/integration/sdam_prose_spec.rb +64 -0
- data/spec/integration/server_monitor_spec.rb +25 -1
- data/spec/integration/size_limit_spec.rb +7 -3
- data/spec/integration/size_limit_spec.rb~12e1e9c4f... RUBY-2242 Fix zlib compression (#2021) +98 -0
- data/spec/integration/ssl_uri_options_spec.rb +2 -2
- data/spec/integration/zlib_compression_spec.rb +25 -0
- data/spec/lite_spec_helper.rb +12 -5
- data/spec/mongo/auth/aws/request_spec.rb +76 -0
- data/spec/mongo/auth/scram_spec.rb +1 -1
- data/spec/mongo/client_construction_spec.rb +207 -0
- data/spec/mongo/client_spec.rb +38 -3
- data/spec/mongo/cluster/topology/replica_set_spec.rb +52 -9
- data/spec/mongo/cluster/topology/single_spec.rb +4 -2
- data/spec/mongo/cluster_spec.rb +34 -35
- data/spec/mongo/collection/view/change_stream_resume_spec.rb +6 -6
- data/spec/mongo/collection_spec.rb +500 -0
- data/spec/mongo/database_spec.rb +245 -8
- data/spec/mongo/distinguishing_semaphore_spec.rb +63 -0
- data/spec/mongo/error/operation_failure_spec.rb +40 -0
- data/spec/mongo/index/view_spec.rb +2 -2
- data/spec/mongo/monitoring/event/server_description_changed_spec.rb +1 -4
- data/spec/mongo/protocol/msg_spec.rb +10 -0
- data/spec/mongo/semaphore_spec.rb +51 -0
- data/spec/mongo/server/connection_auth_spec.rb +2 -2
- data/spec/mongo/server_selector/nearest_spec.rb +23 -23
- data/spec/mongo/server_selector/primary_preferred_spec.rb +26 -26
- data/spec/mongo/server_selector/primary_spec.rb +9 -9
- data/spec/mongo/server_selector/secondary_preferred_spec.rb +22 -22
- data/spec/mongo/server_selector/secondary_spec.rb +18 -18
- data/spec/mongo/server_selector_spec.rb +4 -4
- data/spec/mongo/session_spec.rb +35 -0
- data/spec/runners/change_streams/test.rb +2 -2
- data/spec/runners/cmap.rb +1 -1
- data/spec/runners/command_monitoring.rb +3 -34
- data/spec/runners/crud/context.rb +9 -5
- data/spec/runners/crud/operation.rb +59 -27
- data/spec/runners/crud/spec.rb +0 -8
- data/spec/runners/crud/test.rb +1 -1
- data/spec/runners/sdam.rb +2 -2
- data/spec/runners/server_selection.rb +242 -28
- data/spec/runners/transactions.rb +12 -12
- data/spec/runners/transactions/operation.rb +151 -25
- data/spec/runners/transactions/test.rb +60 -16
- data/spec/spec_tests/command_monitoring_spec.rb +22 -12
- data/spec/spec_tests/crud_spec.rb +1 -1
- data/spec/spec_tests/data/change_streams/change-streams-errors.yml +4 -8
- data/spec/spec_tests/data/change_streams/change-streams-resume-whitelist.yml +66 -0
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.yml +15 -0
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/NoKnownServers.yml +4 -3
- data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -0
- data/spec/spec_tests/data/sdam_integration/cancel-server-check.yml +96 -0
- data/spec/spec_tests/data/sdam_integration/connectTimeoutMS.yml +88 -0
- data/spec/spec_tests/data/sdam_integration/find-network-error.yml +83 -0
- data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +116 -0
- data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +86 -0
- data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +115 -0
- data/spec/spec_tests/data/sdam_integration/isMaster-command-error.yml +168 -0
- data/spec/spec_tests/data/sdam_integration/isMaster-network-error.yml +162 -0
- data/spec/spec_tests/data/sdam_integration/isMaster-timeout.yml +229 -0
- data/spec/spec_tests/data/sdam_integration/rediscover-quickly-after-step-down.yml +87 -0
- data/spec/spec_tests/max_staleness_spec.rb +4 -142
- data/spec/spec_tests/retryable_reads_spec.rb +2 -2
- data/spec/spec_tests/sdam_integration_spec.rb +13 -0
- data/spec/spec_tests/sdam_monitoring_spec.rb +1 -2
- data/spec/spec_tests/server_selection_spec.rb +4 -116
- data/spec/stress/cleanup_spec.rb +17 -2
- data/spec/stress/connection_pool_stress_spec.rb +10 -8
- data/spec/support/child_process_helper.rb +78 -0
- data/spec/support/client_registry.rb +1 -0
- data/spec/support/cluster_config.rb +4 -0
- data/spec/support/event_subscriber.rb +123 -33
- data/spec/support/keyword_struct.rb +26 -0
- data/spec/support/shared/server_selector.rb +13 -1
- data/spec/support/spec_config.rb +38 -13
- data/spec/support/spec_organizer.rb +129 -0
- data/spec/support/spec_setup.rb +1 -1
- data/spec/support/utils.rb +46 -0
- metadata +992 -942
- metadata.gz.sig +0 -0
- data/lib/mongo/server_selector/selectable.rb +0 -560
- data/spec/runners/sdam_monitoring.rb +0 -89
@@ -5,7 +5,11 @@ describe 'Server::Monitor' do
|
|
5
5
|
let(:client) do
|
6
6
|
new_local_client([ClusterConfig.instance.primary_address_str],
|
7
7
|
SpecConfig.instance.test_options.merge(SpecConfig.instance.auth_options.merge(
|
8
|
-
|
8
|
+
monitor_options)))
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:monitor_options) do
|
12
|
+
{heartbeat_frequency: 1}
|
9
13
|
end
|
10
14
|
|
11
15
|
it 'refreshes server descriptions in background', retry: 3 do
|
@@ -25,4 +29,24 @@ describe 'Server::Monitor' do
|
|
25
29
|
|
26
30
|
expect(server.description).not_to be_unknown
|
27
31
|
end
|
32
|
+
|
33
|
+
context 'server-pushed ismaster' do
|
34
|
+
min_server_fcv '4.4'
|
35
|
+
require_topology :replica_set
|
36
|
+
|
37
|
+
let(:monitor_options) do
|
38
|
+
{heartbeat_frequency: 20}
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'updates server description' do
|
42
|
+
starting_primary_address = client.cluster.next_primary.address
|
43
|
+
|
44
|
+
ClusterTools.instance.step_down
|
45
|
+
|
46
|
+
sleep 2
|
47
|
+
|
48
|
+
new_primary_address = client.cluster.next_primary.address
|
49
|
+
new_primary_address.should_not == starting_primary_address
|
50
|
+
end
|
51
|
+
end
|
28
52
|
end
|
@@ -36,7 +36,7 @@ describe 'BSON & command size limits' do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
authorized_collection.insert_many(documents)
|
39
|
-
authorized_collection.count_documents
|
39
|
+
authorized_collection.count_documents.should == 8
|
40
40
|
end
|
41
41
|
|
42
42
|
# This test ensures that document which are too big definitely fail insertion.
|
@@ -49,7 +49,7 @@ describe 'BSON & command size limits' do
|
|
49
49
|
lambda do
|
50
50
|
authorized_collection.insert_many(documents)
|
51
51
|
end.should raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
|
52
|
-
authorized_collection.count_documents
|
52
|
+
authorized_collection.count_documents.should == 0
|
53
53
|
end
|
54
54
|
|
55
55
|
it 'allows user-provided documents to be exactly 16MiB' do
|
@@ -81,6 +81,10 @@ describe 'BSON & command size limits' do
|
|
81
81
|
end
|
82
82
|
|
83
83
|
it 'allows bulk writes of multiple documents of exactly 16 MiB each' do
|
84
|
+
if SpecConfig.instance.compressors
|
85
|
+
pending "RUBY-2234"
|
86
|
+
end
|
87
|
+
|
84
88
|
documents = []
|
85
89
|
1.upto(3) do |index|
|
86
90
|
document = { key: 'a' * (max_document_size - 28), _id: "in#{index}" }
|
@@ -89,6 +93,6 @@ describe 'BSON & command size limits' do
|
|
89
93
|
end
|
90
94
|
|
91
95
|
authorized_collection.insert_many(documents)
|
92
|
-
authorized_collection.count_documents
|
96
|
+
authorized_collection.count_documents.should == 3
|
93
97
|
end
|
94
98
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'BSON & command size limits' do
|
4
|
+
let(:max_document_size) { 16*1024*1024 }
|
5
|
+
|
6
|
+
before do
|
7
|
+
authorized_collection.delete_many
|
8
|
+
end
|
9
|
+
|
10
|
+
# This test uses a large document that is significantly smaller than the
|
11
|
+
# size limit. It is a basic sanity check.
|
12
|
+
it 'allows user-provided documents to be 15MiB' do
|
13
|
+
document = { key: 'a' * 15*1024*1024, _id: 'foo' }
|
14
|
+
|
15
|
+
authorized_collection.insert_one(document)
|
16
|
+
end
|
17
|
+
|
18
|
+
# This test uses a large document that is significantly larger than the
|
19
|
+
# size limit. It is a basic sanity check.
|
20
|
+
it 'fails single write of oversized documents' do
|
21
|
+
document = { key: 'a' * 17*1024*1024, _id: 'foo' }
|
22
|
+
|
23
|
+
lambda do
|
24
|
+
authorized_collection.insert_one(document)
|
25
|
+
end.should raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
|
26
|
+
end
|
27
|
+
|
28
|
+
# This test checks our bulk write splitting when documents are not close
|
29
|
+
# to the limit, but where splitting is definitely required.
|
30
|
+
it 'allows split bulk write of medium sized documents' do
|
31
|
+
# 8 documents of 4 MiB each = 32 MiB total data, should be split over
|
32
|
+
# either 2 or 3 bulk writes depending on how well the driver splits
|
33
|
+
documents = []
|
34
|
+
1.upto(8) do |index|
|
35
|
+
documents << { key: 'a' * 4*1024*1024, _id: "in#{index}" }
|
36
|
+
end
|
37
|
+
|
38
|
+
authorized_collection.insert_many(documents)
|
39
|
+
authorized_collection.count_documents({}).should == 8
|
40
|
+
end
|
41
|
+
|
42
|
+
# This test ensures that document which are too big definitely fail insertion.
|
43
|
+
it 'fails bulk write of oversized documents' do
|
44
|
+
documents = []
|
45
|
+
1.upto(3) do |index|
|
46
|
+
documents << { key: 'a' * 17*1024*1024, _id: "in#{index}" }
|
47
|
+
end
|
48
|
+
|
49
|
+
lambda do
|
50
|
+
authorized_collection.insert_many(documents)
|
51
|
+
end.should raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
|
52
|
+
authorized_collection.count_documents({}).should == 0
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'allows user-provided documents to be exactly 16MiB' do
|
56
|
+
# The document must contain the _id field, otherwise the server will
|
57
|
+
# add it which will increase the size of the document as persisted by
|
58
|
+
# the server.
|
59
|
+
document = { key: 'a' * (max_document_size - 28), _id: 'foo' }
|
60
|
+
expect(document.to_bson.length).to eq(max_document_size)
|
61
|
+
|
62
|
+
authorized_collection.insert_one(document)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'fails on the server when a document larger than 16MiB is inserted' do
|
66
|
+
document = { key: 'a' * (max_document_size - 27), _id: 'foo' }
|
67
|
+
expect(document.to_bson.length).to eq(max_document_size+1)
|
68
|
+
|
69
|
+
lambda do
|
70
|
+
authorized_collection.insert_one(document)
|
71
|
+
end.should raise_error(Mongo::Error::OperationFailure, /object to insert too large/)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'fails in the driver when a document larger than 16MiB+16KiB is inserted' do
|
75
|
+
document = { key: 'a' * (max_document_size - 27 + 16*1024), _id: 'foo' }
|
76
|
+
expect(document.to_bson.length).to eq(max_document_size+16*1024+1)
|
77
|
+
|
78
|
+
lambda do
|
79
|
+
authorized_collection.insert_one(document)
|
80
|
+
end.should raise_error(Mongo::Error::MaxBSONSize, /The document exceeds maximum allowed BSON object size after serialization/)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'allows bulk writes of multiple documents of exactly 16 MiB each' do
|
84
|
+
if SpecConfig.instance.compressors
|
85
|
+
pending "RUBY-2234"
|
86
|
+
end
|
87
|
+
|
88
|
+
documents = []
|
89
|
+
1.upto(3) do |index|
|
90
|
+
document = { key: 'a' * (max_document_size - 28), _id: "in#{index}" }
|
91
|
+
expect(document.to_bson.length).to eq(max_document_size)
|
92
|
+
documents << document
|
93
|
+
end
|
94
|
+
|
95
|
+
authorized_collection.insert_many(documents)
|
96
|
+
authorized_collection.count_documents({}).should == 3
|
97
|
+
end
|
98
|
+
end
|
@@ -20,6 +20,6 @@ describe 'SSL connections with URI options' do
|
|
20
20
|
|
21
21
|
it 'successfully connects and runs an operation' do
|
22
22
|
client = new_local_client(uri)
|
23
|
-
expect { client[:foo].count_documents
|
23
|
+
expect { client[:foo].count_documents }.not_to raise_error
|
24
24
|
end
|
25
|
-
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Zlib compression' do
|
4
|
+
require_compression
|
5
|
+
|
6
|
+
before do
|
7
|
+
authorized_client['test'].drop
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'when client has zlib compressor option enabled' do
|
11
|
+
it 'compresses the message to the server' do
|
12
|
+
# Double check that the client has zlib compression enabled
|
13
|
+
expect(authorized_client.options[:compressors]).to include('zlib')
|
14
|
+
|
15
|
+
expect(Mongo::Protocol::Compressed).to receive(:new).twice.and_call_original
|
16
|
+
expect(Zlib::Deflate).to receive(:deflate).twice.and_call_original
|
17
|
+
expect(Zlib::Inflate).to receive(:inflate).twice.and_call_original
|
18
|
+
|
19
|
+
authorized_client['test'].insert_one(_id: 1, text: 'hello world')
|
20
|
+
document = authorized_client['test'].find(_id: 1).first
|
21
|
+
|
22
|
+
expect(document['text']).to eq('hello world')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/lite_spec_helper.rb
CHANGED
@@ -4,8 +4,6 @@ CURRENT_PATH = File.expand_path(File.dirname(__FILE__))
|
|
4
4
|
SERVER_DISCOVERY_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/sdam/**/*.yml").sort
|
5
5
|
SDAM_MONITORING_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/sdam_monitoring/*.yml").sort
|
6
6
|
SERVER_SELECTION_RTT_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/server_selection_rtt/*.yml").sort
|
7
|
-
SERVER_SELECTION_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/server_selection/**/*.yml").sort
|
8
|
-
MAX_STALENESS_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/max_staleness/**/*.yml").sort
|
9
7
|
CRUD_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/crud/**/*.yml").sort
|
10
8
|
CRUD2_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/crud_v2/**/*.yml").sort
|
11
9
|
RETRYABLE_WRITES_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/retryable_writes/**/*.yml").sort
|
@@ -22,7 +20,11 @@ CMAP_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/cmap/*.yml").sort
|
|
22
20
|
AUTH_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/auth/*.yml").sort
|
23
21
|
CLIENT_SIDE_ENCRYPTION_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/client_side_encryption/*.yml").sort
|
24
22
|
|
25
|
-
|
23
|
+
# Disable output buffering: https://www.rubyguides.com/2019/02/ruby-io/
|
24
|
+
STDOUT.sync = true
|
25
|
+
STDERR.sync = true
|
26
|
+
|
27
|
+
if %w(1 true yes).include?(ENV['CI']&.downcase)
|
26
28
|
autoload :Byebug, 'byebug'
|
27
29
|
else
|
28
30
|
# Load debuggers before loading the driver code, so that breakpoints
|
@@ -107,14 +109,19 @@ RSpec.configure do |config|
|
|
107
109
|
# Tests should take under 10 seconds ideally but it seems
|
108
110
|
# we have some that run for more than 10 seconds in CI.
|
109
111
|
config.around(:each) do |example|
|
110
|
-
|
112
|
+
timeout = if %w(1 true yes).include?(ENV['STRESS']&.downcase)
|
113
|
+
210
|
114
|
+
else
|
115
|
+
45
|
116
|
+
end
|
117
|
+
TimeoutInterrupt.timeout(timeout) do
|
111
118
|
example.run
|
112
119
|
end
|
113
120
|
end
|
114
121
|
end
|
115
122
|
|
116
123
|
if SpecConfig.instance.ci?
|
117
|
-
if defined?(Rfc)
|
124
|
+
if defined?(Rfc::Rif)
|
118
125
|
unless BSON::Environment.jruby?
|
119
126
|
Rfc::Rif.output_object_space_stats = true
|
120
127
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mongo::Auth::Aws::Request do
|
4
|
+
|
5
|
+
describe "#formatted_time" do
|
6
|
+
context "when time is provided and frozen" do
|
7
|
+
let(:original_time) { Time.at(1592399523).freeze }
|
8
|
+
let(:request) do
|
9
|
+
described_class.new(access_key_id: 'access_key_id',
|
10
|
+
secret_access_key: 'secret_access_key',
|
11
|
+
session_token: 'session_token',
|
12
|
+
host: 'host',
|
13
|
+
server_nonce: 'server_nonce',
|
14
|
+
time: original_time
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'doesn\'t modify the time instance variable' do
|
19
|
+
expect { request.formatted_time }.to_not raise_error
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns the correct formatted time' do
|
23
|
+
expect(request.formatted_time).to eq('20200617T131203Z')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when time is not provided" do
|
28
|
+
let(:request) do
|
29
|
+
described_class.new(access_key_id: 'access_key_id',
|
30
|
+
secret_access_key: 'secret_access_key',
|
31
|
+
session_token: 'session_token',
|
32
|
+
host: 'host',
|
33
|
+
server_nonce: 'server_nonce'
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'doesn\'t raise an error on formatted_time' do
|
38
|
+
expect { request.formatted_time }.to_not raise_error
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#signature" do
|
44
|
+
context "when time is provided and frozen" do
|
45
|
+
let(:original_time) { Time.at(1592399523).freeze }
|
46
|
+
let(:request) do
|
47
|
+
described_class.new(access_key_id: 'access_key_id',
|
48
|
+
secret_access_key: 'secret_access_key',
|
49
|
+
session_token: 'session_token',
|
50
|
+
host: 'host',
|
51
|
+
server_nonce: 'server_nonce',
|
52
|
+
time: original_time
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'doesn\'t raise error on signature' do
|
57
|
+
expect { request.signature }.to_not raise_error
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when time is not provided" do
|
62
|
+
let(:request) do
|
63
|
+
described_class.new(access_key_id: 'access_key_id',
|
64
|
+
secret_access_key: 'secret_access_key',
|
65
|
+
session_token: 'session_token',
|
66
|
+
host: 'host',
|
67
|
+
server_nonce: 'server_nonce'
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'doesn\'t raise error on signature' do
|
72
|
+
expect { request.signature }.to_not raise_error
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -65,7 +65,7 @@ describe Mongo::Auth::Scram do
|
|
65
65
|
it 'does not compress the message' do
|
66
66
|
expect(Mongo::Protocol::Compressed).not_to receive(:new)
|
67
67
|
expect {
|
68
|
-
authenticator.login
|
68
|
+
authenticator.login
|
69
69
|
}.to raise_error(Mongo::Auth::Unauthorized)
|
70
70
|
end
|
71
71
|
end
|
@@ -319,6 +319,104 @@ describe Mongo::Client do
|
|
319
319
|
end
|
320
320
|
end
|
321
321
|
|
322
|
+
context 'timeout options' do
|
323
|
+
let(:client) do
|
324
|
+
new_local_client(SpecConfig.instance.addresses,
|
325
|
+
SpecConfig.instance.authorized_test_options.merge(options))
|
326
|
+
end
|
327
|
+
|
328
|
+
context 'when network timeouts are zero' do
|
329
|
+
let(:options) do
|
330
|
+
{ socket_timeout: 0, connect_timeout: 0 }
|
331
|
+
end
|
332
|
+
|
333
|
+
it 'sets options to zeros' do
|
334
|
+
client.options[:socket_timeout].should == 0
|
335
|
+
client.options[:connect_timeout].should == 0
|
336
|
+
end
|
337
|
+
|
338
|
+
it 'connects and performs operations successfully' do
|
339
|
+
lambda do
|
340
|
+
client.database.command(ping: 1)
|
341
|
+
end.should_not raise_error
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
%i(socket_timeout connect_timeout).each do |option|
|
346
|
+
context "when #{option} is negative" do
|
347
|
+
let(:options) do
|
348
|
+
{ option => -1 }
|
349
|
+
end
|
350
|
+
|
351
|
+
it 'fails client creation' do
|
352
|
+
lambda do
|
353
|
+
client
|
354
|
+
end.should raise_error(ArgumentError, /#{option} must be a non-negative number/)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
context "when #{option} is of the wrong type" do
|
359
|
+
let(:options) do
|
360
|
+
{ option => '42' }
|
361
|
+
end
|
362
|
+
|
363
|
+
it 'fails client creation' do
|
364
|
+
lambda do
|
365
|
+
client
|
366
|
+
end.should raise_error(ArgumentError, /#{option} must be a non-negative number/)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
context "when :connect_timeout is very small" do
|
372
|
+
# The driver reads first and checks the deadline second.
|
373
|
+
# This means the read (in a monitor) can technically take more than
|
374
|
+
# the connect timeout. Restrict to TLS configurations to make
|
375
|
+
# the network I/O take longer.
|
376
|
+
require_tls
|
377
|
+
|
378
|
+
let(:options) do
|
379
|
+
{ connect_timeout: 1e-6, server_selection_timeout: 2 }
|
380
|
+
end
|
381
|
+
|
382
|
+
it 'allows client creation' do
|
383
|
+
lambda do
|
384
|
+
client
|
385
|
+
end.should_not raise_error
|
386
|
+
end
|
387
|
+
|
388
|
+
it 'fails server selection due to very small timeout' do
|
389
|
+
lambda do
|
390
|
+
client.database.command(ping: 1)
|
391
|
+
end.should raise_error(Mongo::Error::NoServerAvailable)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
context "when :socket_timeout is very small" do
|
396
|
+
# The driver reads first and checks the deadline second.
|
397
|
+
# This means the read (in a monitor) can technically take more than
|
398
|
+
# the connect timeout. Restrict to TLS configurations to make
|
399
|
+
# the network I/O take longer.
|
400
|
+
require_tls
|
401
|
+
|
402
|
+
let(:options) do
|
403
|
+
{ socket_timeout: 1e-6, server_selection_timeout: 2 }
|
404
|
+
end
|
405
|
+
|
406
|
+
it 'allows client creation' do
|
407
|
+
lambda do
|
408
|
+
client
|
409
|
+
end.should_not raise_error
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'fails operations due to very small timeout' do
|
413
|
+
lambda do
|
414
|
+
client.database.command(ping: 1)
|
415
|
+
end.should raise_error(Mongo::Error::SocketTimeoutError)
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
322
420
|
context 'retry_writes option' do
|
323
421
|
let(:client) do
|
324
422
|
new_local_client_nmio(SpecConfig.instance.addresses, options)
|
@@ -1138,6 +1236,48 @@ describe Mongo::Client do
|
|
1138
1236
|
end
|
1139
1237
|
end
|
1140
1238
|
|
1239
|
+
context ':bg_error_backtrace option' do
|
1240
|
+
[true, false, nil, 42].each do |valid_value|
|
1241
|
+
context "valid value: #{valid_value.inspect}" do
|
1242
|
+
let(:options) do
|
1243
|
+
{bg_error_backtrace: valid_value}
|
1244
|
+
end
|
1245
|
+
|
1246
|
+
it 'is accepted' do
|
1247
|
+
client.options[:bg_error_backtrace].should == valid_value
|
1248
|
+
end
|
1249
|
+
end
|
1250
|
+
end
|
1251
|
+
|
1252
|
+
context 'invalid value type' do
|
1253
|
+
let(:options) do
|
1254
|
+
{bg_error_backtrace: 'yes'}
|
1255
|
+
end
|
1256
|
+
|
1257
|
+
it 'is rejected' do
|
1258
|
+
lambda do
|
1259
|
+
client
|
1260
|
+
end.should raise_error(ArgumentError, /:bg_error_backtrace option value must be true, false, nil or a positive integer/)
|
1261
|
+
end
|
1262
|
+
end
|
1263
|
+
|
1264
|
+
context 'invalid value' do
|
1265
|
+
[0, -1, 42.0].each do |invalid_value|
|
1266
|
+
context "invalid value: #{invalid_value.inspect}" do
|
1267
|
+
let(:options) do
|
1268
|
+
{bg_error_backtrace: invalid_value}
|
1269
|
+
end
|
1270
|
+
|
1271
|
+
it 'is rejected' do
|
1272
|
+
lambda do
|
1273
|
+
client
|
1274
|
+
end.should raise_error(ArgumentError, /:bg_error_backtrace option value must be true, false, nil or a positive integer/)
|
1275
|
+
end
|
1276
|
+
end
|
1277
|
+
end
|
1278
|
+
end
|
1279
|
+
end
|
1280
|
+
|
1141
1281
|
describe ':read option' do
|
1142
1282
|
[
|
1143
1283
|
:primary, :primary_preferred, :secondary, :secondary_preferred, :nearest
|
@@ -1243,6 +1383,73 @@ describe Mongo::Client do
|
|
1243
1383
|
end
|
1244
1384
|
=end
|
1245
1385
|
end
|
1386
|
+
|
1387
|
+
context 'when making a block client' do
|
1388
|
+
context 'when the block doesn\'t raise an error' do
|
1389
|
+
let(:block_client) do
|
1390
|
+
c = nil
|
1391
|
+
Mongo::Client.new(
|
1392
|
+
SpecConfig.instance.addresses,
|
1393
|
+
SpecConfig.instance.test_options.merge(database: SpecConfig.instance.test_db),
|
1394
|
+
) do |client|
|
1395
|
+
c = client
|
1396
|
+
end
|
1397
|
+
c
|
1398
|
+
end
|
1399
|
+
|
1400
|
+
it 'is closed after block' do
|
1401
|
+
expect(block_client.cluster.connected?).to eq(false)
|
1402
|
+
end
|
1403
|
+
end
|
1404
|
+
|
1405
|
+
context 'when the block raises an error' do
|
1406
|
+
it 'it is closed after the block' do
|
1407
|
+
block_client_raise = nil
|
1408
|
+
expect do
|
1409
|
+
Mongo::Client.new(
|
1410
|
+
SpecConfig.instance.addresses,
|
1411
|
+
SpecConfig.instance.test_options.merge(database: SpecConfig.instance.test_db),
|
1412
|
+
) do |client|
|
1413
|
+
block_client_raise = client
|
1414
|
+
raise "This is an error!"
|
1415
|
+
end
|
1416
|
+
end.to raise_error(StandardError, "This is an error!")
|
1417
|
+
expect(block_client_raise.cluster.connected?).to eq(false)
|
1418
|
+
end
|
1419
|
+
end
|
1420
|
+
|
1421
|
+
context 'when the hosts given include the protocol' do
|
1422
|
+
it 'raises an error on mongodb://' do
|
1423
|
+
expect do
|
1424
|
+
Mongo::Client.new(['mongodb://127.0.0.1:27017/test'])
|
1425
|
+
end.to raise_error(ArgumentError, "Host 'mongodb://127.0.0.1:27017/test' should not contain protocol. Did you mean to not use an array?")
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
it 'raises an error on mongodb+srv://' do
|
1429
|
+
expect do
|
1430
|
+
Mongo::Client.new(['mongodb+srv://127.0.0.1:27017/test'])
|
1431
|
+
end.to raise_error(ArgumentError, "Host 'mongodb+srv://127.0.0.1:27017/test' should not contain protocol. Did you mean to not use an array?")
|
1432
|
+
end
|
1433
|
+
|
1434
|
+
it 'raises an error on multiple items' do
|
1435
|
+
expect do
|
1436
|
+
Mongo::Client.new(['127.0.0.1:27017', 'mongodb+srv://127.0.0.1:27017/test'])
|
1437
|
+
end.to raise_error(ArgumentError, "Host 'mongodb+srv://127.0.0.1:27017/test' should not contain protocol. Did you mean to not use an array?")
|
1438
|
+
end
|
1439
|
+
|
1440
|
+
it 'raises an error only at beginning of string' do
|
1441
|
+
expect do
|
1442
|
+
Mongo::Client.new(['somethingmongodb://127.0.0.1:27017/test', 'mongodb+srv://127.0.0.1:27017/test'])
|
1443
|
+
end.to raise_error(ArgumentError, "Host 'mongodb+srv://127.0.0.1:27017/test' should not contain protocol. Did you mean to not use an array?")
|
1444
|
+
end
|
1445
|
+
|
1446
|
+
it 'raises an error with different case' do
|
1447
|
+
expect do
|
1448
|
+
Mongo::Client.new(['MongOdB://127.0.0.1:27017/test'])
|
1449
|
+
end.to raise_error(ArgumentError, "Host 'MongOdB://127.0.0.1:27017/test' should not contain protocol. Did you mean to not use an array?")
|
1450
|
+
end
|
1451
|
+
end
|
1452
|
+
end
|
1246
1453
|
end
|
1247
1454
|
|
1248
1455
|
shared_examples_for 'duplicated client with duplicated monitoring' do
|