mongo 2.13.0.beta1 → 2.13.0.rc1
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 +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
|