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
@@ -127,13 +127,13 @@ describe 'CRUD operations' do
|
|
127
127
|
describe 'upsert' do
|
128
128
|
context 'with default write concern' do
|
129
129
|
it 'upserts' do
|
130
|
-
collection.count_documents
|
130
|
+
collection.count_documents.should == 0
|
131
131
|
|
132
132
|
res = collection.find(_id: 'foo').update_one({'$set' => {foo: 'bar'}}, upsert: true)
|
133
133
|
|
134
134
|
res.documents.first['upserted'].length.should == 1
|
135
135
|
|
136
|
-
collection.count_documents
|
136
|
+
collection.count_documents.should == 1
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
@@ -147,7 +147,7 @@ describe 'CRUD operations' do
|
|
147
147
|
end
|
148
148
|
|
149
149
|
it 'upserts' do
|
150
|
-
unack_collection.count_documents
|
150
|
+
unack_collection.count_documents.should == 0
|
151
151
|
|
152
152
|
res = unack_collection.find(_id: 'foo').update_one({'$set' => {foo: 'bar'}}, upsert: true)
|
153
153
|
|
@@ -155,7 +155,7 @@ describe 'CRUD operations' do
|
|
155
155
|
# persisted (hopefully)
|
156
156
|
sleep 0.25
|
157
157
|
|
158
|
-
unack_collection.count_documents
|
158
|
+
unack_collection.count_documents.should == 1
|
159
159
|
end
|
160
160
|
end
|
161
161
|
end
|
@@ -1,6 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'aggregation examples in Ruby' do
|
4
|
+
before(:all) do
|
5
|
+
# In sharded clusters we need to ensure the database exists before running
|
6
|
+
# the tests in this file.
|
7
|
+
ClientRegistry.instance.global_client('authorized')['_placeholder'].create
|
8
|
+
end
|
9
|
+
|
4
10
|
let(:client) do
|
5
11
|
authorized_client
|
6
12
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'GridFS bucket integration' do
|
4
|
+
let(:fs) do
|
5
|
+
authorized_client.database.fs
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'UTF-8 string write' do
|
9
|
+
let(:data) { "hello\u2210" }
|
10
|
+
|
11
|
+
before do
|
12
|
+
data.length.should_not == data.bytesize
|
13
|
+
end
|
14
|
+
|
15
|
+
shared_examples 'round-trips' do
|
16
|
+
it 'round-trips' do
|
17
|
+
stream = fs.open_upload_stream('test') do |stream|
|
18
|
+
stream.write(data_to_write)
|
19
|
+
end
|
20
|
+
|
21
|
+
actual = nil
|
22
|
+
fs.open_download_stream(stream.file_id) do |stream|
|
23
|
+
actual = stream.read
|
24
|
+
end
|
25
|
+
|
26
|
+
actual.encoding.name.should == 'ASCII-8BIT'
|
27
|
+
actual.should == data.dup.force_encoding('binary')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'in binary encoding' do
|
32
|
+
let(:data_to_write) do
|
33
|
+
data.force_encoding('binary').freeze
|
34
|
+
end
|
35
|
+
|
36
|
+
it_behaves_like 'round-trips'
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'in UTF-8 encoding' do
|
40
|
+
let(:data_to_write) do
|
41
|
+
data.encoding.name.should == 'UTF-8'
|
42
|
+
data.freeze
|
43
|
+
end
|
44
|
+
|
45
|
+
it_behaves_like 'round-trips'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,33 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
class TestHeartbeatSubscriber
|
4
|
-
def initialize
|
5
|
-
@started_events = []
|
6
|
-
@succeeded_events = []
|
7
|
-
@failed_events = []
|
8
|
-
end
|
9
|
-
|
10
|
-
attr_reader :started_events, :succeeded_events, :failed_events
|
11
|
-
|
12
|
-
def started(event)
|
13
|
-
@started_events << event
|
14
|
-
end
|
15
|
-
|
16
|
-
def succeeded(event)
|
17
|
-
@succeeded_events << event
|
18
|
-
end
|
19
|
-
|
20
|
-
def failed(event)
|
21
|
-
@failed_events << event
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
3
|
describe 'Heartbeat events' do
|
26
4
|
class HeartbeatEventsSpecTestException < StandardError; end
|
27
5
|
|
6
|
+
# 4.4 has two monitors and thus issues heartbeats multiple times
|
7
|
+
max_server_version '4.2'
|
8
|
+
|
28
9
|
clean_slate_for_all
|
29
10
|
|
30
|
-
let(:subscriber) {
|
11
|
+
let(:subscriber) { EventSubscriber.new }
|
31
12
|
|
32
13
|
before do
|
33
14
|
Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::SERVER_HEARTBEAT, subscriber)
|
@@ -106,7 +106,7 @@ describe 'Failing retryable operations' do
|
|
106
106
|
},
|
107
107
|
}
|
108
108
|
|
109
|
-
if ClusterConfig.instance.short_server_version >= '4.
|
109
|
+
if ClusterConfig.instance.short_server_version >= '4.4'
|
110
110
|
# Server versions 4.4 and newer will add the RetryableWriteError
|
111
111
|
# label to all retryable errors, and the driver must not add the label
|
112
112
|
# if it is not already present.
|
@@ -26,7 +26,7 @@ module PerformsLegacyRetries
|
|
26
26
|
end
|
27
27
|
|
28
28
|
context 'for ETIMEDOUT' do
|
29
|
-
min_server_fcv '4.
|
29
|
+
min_server_fcv '4.4'
|
30
30
|
|
31
31
|
# shorten socket timeout so these tests take less time to run
|
32
32
|
let(:socket_timeout) { 1 }
|
@@ -59,7 +59,7 @@ module PerformsLegacyRetries
|
|
59
59
|
end
|
60
60
|
|
61
61
|
context 'on server versions >= 4.4' do
|
62
|
-
min_server_fcv '4.
|
62
|
+
min_server_fcv '4.4'
|
63
63
|
|
64
64
|
context 'for OperationFailure with RetryableWriteError label' do
|
65
65
|
before do
|
@@ -44,8 +44,8 @@ module PerformsModernRetries
|
|
44
44
|
|
45
45
|
context 'for ETIMEDOUT' do
|
46
46
|
# blockConnection option in failCommand was introduced in
|
47
|
-
# server version 4.
|
48
|
-
min_server_fcv '4.
|
47
|
+
# server version 4.4
|
48
|
+
min_server_fcv '4.4'
|
49
49
|
|
50
50
|
# shorten socket timeout so these tests take less time to run
|
51
51
|
let(:socket_timeout) { 1 }
|
@@ -94,7 +94,7 @@ module PerformsModernRetries
|
|
94
94
|
end
|
95
95
|
|
96
96
|
context 'on server versions >= 4.4' do
|
97
|
-
min_server_fcv '4.
|
97
|
+
min_server_fcv '4.4'
|
98
98
|
|
99
99
|
context 'for OperationFailure with RetryableWriteError label' do
|
100
100
|
before do
|
@@ -25,7 +25,7 @@ module PerformsNoRetries
|
|
25
25
|
end
|
26
26
|
|
27
27
|
context 'for ETIMEDOUT' do
|
28
|
-
min_server_fcv '4.
|
28
|
+
min_server_fcv '4.4'
|
29
29
|
|
30
30
|
# shorten socket timeout so these tests take less time to run
|
31
31
|
let(:socket_timeout) { 1 }
|
@@ -58,7 +58,7 @@ module PerformsNoRetries
|
|
58
58
|
end
|
59
59
|
|
60
60
|
context 'on server versions >= 4.4' do
|
61
|
-
min_server_fcv '4.
|
61
|
+
min_server_fcv '4.4'
|
62
62
|
# These tests will be implemented in a follow-up PR
|
63
63
|
end
|
64
64
|
|
@@ -3,11 +3,27 @@ require 'spec_helper'
|
|
3
3
|
describe 'SDAM error handling' do
|
4
4
|
clean_slate_for_all
|
5
5
|
|
6
|
+
after do
|
7
|
+
# Close all clients after every test to avoid leaking expectations into
|
8
|
+
# subsequent tests because we set global assertions on sockets.
|
9
|
+
ClientRegistry.instance.close_all_clients
|
10
|
+
end
|
11
|
+
|
6
12
|
# These tests operate on specific servers, and don't work in a multi
|
7
13
|
# shard cluster where multiple servers are equally eligible
|
8
14
|
require_no_multi_shard
|
9
15
|
|
10
|
-
let(:
|
16
|
+
let(:diagnostic_subscriber) { VerboseEventSubscriber.new }
|
17
|
+
|
18
|
+
let(:client) do
|
19
|
+
new_local_client(SpecConfig.instance.addresses,
|
20
|
+
SpecConfig.instance.all_test_options.merge(
|
21
|
+
socket_timeout: 3, connect_timeout: 3,
|
22
|
+
# Uncomment to print all events to stdout:
|
23
|
+
#sdam_proc: Utils.subscribe_all_sdam_proc(diagnostic_subscriber),
|
24
|
+
**Utils.disable_retries_client_options)
|
25
|
+
)
|
26
|
+
end
|
11
27
|
|
12
28
|
let(:server) { client.cluster.next_primary }
|
13
29
|
|
@@ -148,6 +164,9 @@ describe 'SDAM error handling' do
|
|
148
164
|
end
|
149
165
|
|
150
166
|
context 'network error' do
|
167
|
+
# With 4.4 servers we set up two monitoring connections, hence global
|
168
|
+
# socket expectations get hit twice.
|
169
|
+
max_server_version '4.2'
|
151
170
|
|
152
171
|
let(:operation) do
|
153
172
|
expect_any_instance_of(Mongo::Socket).to receive(:read).and_raise(exception)
|
@@ -181,13 +200,6 @@ describe 'SDAM error handling' do
|
|
181
200
|
describe 'when there is an error on monitoring connection' do
|
182
201
|
clean_slate_for_all
|
183
202
|
|
184
|
-
let(:client) do
|
185
|
-
new_local_client(SpecConfig.instance.addresses,
|
186
|
-
SpecConfig.instance.test_options.merge(
|
187
|
-
connect_timeout: 1, socket_timeout: 1,
|
188
|
-
))
|
189
|
-
end
|
190
|
-
|
191
203
|
let(:subscriber) { EventSubscriber.new }
|
192
204
|
|
193
205
|
let(:set_subscribers) do
|
@@ -209,6 +221,7 @@ describe 'SDAM error handling' do
|
|
209
221
|
it 'marks server unknown' do
|
210
222
|
expect(server).not_to be_unknown
|
211
223
|
|
224
|
+
#subscriber.clear_events!
|
212
225
|
events = subscriber.select_succeeded_events(Mongo::Monitoring::Event::ServerDescriptionChanged)
|
213
226
|
events.should be_empty
|
214
227
|
|
@@ -228,6 +241,7 @@ describe 'SDAM error handling' do
|
|
228
241
|
|
229
242
|
shared_examples_for 'clears connection pool - cmap event' do
|
230
243
|
it 'clears connection pool' do
|
244
|
+
#subscriber.clear_events!
|
231
245
|
events = subscriber.select_published_events(Mongo::Monitoring::Event::Cmap::PoolCleared)
|
232
246
|
events.should be_empty
|
233
247
|
|
@@ -245,6 +259,7 @@ describe 'SDAM error handling' do
|
|
245
259
|
end
|
246
260
|
|
247
261
|
shared_examples_for 'marks server unknown and clears connection pool' do
|
262
|
+
=begin These tests are not reliable
|
248
263
|
context 'via object inspection' do
|
249
264
|
let(:expect_server_state_change) do
|
250
265
|
server.summary.should =~ /unknown/i
|
@@ -254,6 +269,7 @@ describe 'SDAM error handling' do
|
|
254
269
|
it_behaves_like 'marks server unknown'
|
255
270
|
it_behaves_like 'clears connection pool'
|
256
271
|
end
|
272
|
+
=end
|
257
273
|
|
258
274
|
context 'via events' do
|
259
275
|
# When we use events we do not need to examine object state, therefore
|
@@ -268,16 +284,22 @@ describe 'SDAM error handling' do
|
|
268
284
|
end
|
269
285
|
end
|
270
286
|
|
271
|
-
context '
|
272
|
-
|
287
|
+
context 'via stubs' do
|
288
|
+
# With 4.4 servers we set up two monitoring connections, hence global
|
289
|
+
# socket expectations get hit twice.
|
290
|
+
max_server_version '4.2'
|
273
291
|
|
274
|
-
|
275
|
-
|
292
|
+
context 'network timeout' do
|
293
|
+
let(:exception) { Mongo::Error::SocketTimeoutError }
|
276
294
|
|
277
|
-
|
278
|
-
|
295
|
+
it_behaves_like 'marks server unknown and clears connection pool'
|
296
|
+
end
|
279
297
|
|
280
|
-
|
298
|
+
context 'non-timeout network error' do
|
299
|
+
let(:exception) { Mongo::Error::SocketError }
|
300
|
+
|
301
|
+
it_behaves_like 'marks server unknown and clears connection pool'
|
302
|
+
end
|
281
303
|
end
|
282
304
|
|
283
305
|
context 'non-timeout network error via fail point' do
|
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'runners/sdam_monitoring'
|
3
2
|
|
4
3
|
describe 'SDAM events' do
|
5
|
-
let(:subscriber) {
|
4
|
+
let(:subscriber) { EventSubscriber.new }
|
6
5
|
|
7
6
|
describe 'server closed event' do
|
8
7
|
it 'is published when client is closed' do
|
@@ -12,11 +11,11 @@ describe 'SDAM events' do
|
|
12
11
|
|
13
12
|
# get the client connected
|
14
13
|
client.database.command(ismaster: 1)
|
15
|
-
expect(subscriber.
|
14
|
+
expect(subscriber.succeeded_events).to be_empty
|
16
15
|
|
17
16
|
client.close
|
18
17
|
|
19
|
-
expect(subscriber.
|
18
|
+
expect(subscriber.succeeded_events).not_to be_empty
|
20
19
|
event = subscriber.first_event('server_closed_event')
|
21
20
|
expect(event).not_to be_nil
|
22
21
|
end
|
@@ -30,15 +29,87 @@ describe 'SDAM events' do
|
|
30
29
|
|
31
30
|
# get the client connected
|
32
31
|
client.database.command(ismaster: 1)
|
33
|
-
expect(subscriber.
|
32
|
+
expect(subscriber.succeeded_events).to be_empty
|
34
33
|
|
35
34
|
client.close
|
36
35
|
|
37
|
-
expect(subscriber.
|
36
|
+
expect(subscriber.succeeded_events).not_to be_empty
|
38
37
|
event = subscriber.first_event('topology_closed_event')
|
39
38
|
expect(event).not_to be_nil
|
40
39
|
|
41
40
|
expect(event.topology).to eql(client.cluster.topology)
|
42
41
|
end
|
43
42
|
end
|
43
|
+
|
44
|
+
describe 'heartbeat event' do
|
45
|
+
require_topology :single
|
46
|
+
|
47
|
+
context 'pre-4.4 servers' do
|
48
|
+
max_server_version '4.2'
|
49
|
+
|
50
|
+
let(:client) do
|
51
|
+
new_local_client(SpecConfig.instance.addresses,
|
52
|
+
# Heartbeat interval is bound by 500 ms
|
53
|
+
SpecConfig.instance.test_options.merge(heartbeat_frequency: 0.5),
|
54
|
+
).tap do |client|
|
55
|
+
client.subscribe(Mongo::Monitoring::SERVER_HEARTBEAT, subscriber)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'is published every heartbeat interval' do
|
60
|
+
client
|
61
|
+
sleep 4
|
62
|
+
client.close
|
63
|
+
|
64
|
+
started_events = subscriber.select_started_events(Mongo::Monitoring::Event::ServerHeartbeatStarted)
|
65
|
+
# Expect about 8 events, maybe 9 or 7
|
66
|
+
started_events.length.should >= 6
|
67
|
+
started_events.length.should <= 10
|
68
|
+
|
69
|
+
succeeded_events = subscriber.select_succeeded_events(Mongo::Monitoring::Event::ServerHeartbeatSucceeded)
|
70
|
+
# Since we gracefully close the client, we expect each heartbeat
|
71
|
+
# to complete.
|
72
|
+
started_events.length.should == succeeded_events.length
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context '4.4+ servers' do
|
77
|
+
min_server_fcv '4.4'
|
78
|
+
|
79
|
+
let(:client) do
|
80
|
+
new_local_client(SpecConfig.instance.addresses,
|
81
|
+
# Heartbeat interval is bound by 500 ms
|
82
|
+
SpecConfig.instance.test_options.merge(heartbeat_frequency: 0.5),
|
83
|
+
).tap do |client|
|
84
|
+
client.subscribe(Mongo::Monitoring::SERVER_HEARTBEAT, subscriber)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'is published up to twice every heartbeat interval' do
|
89
|
+
client
|
90
|
+
sleep 3
|
91
|
+
client.close
|
92
|
+
|
93
|
+
events = subscriber.select_started_events(Mongo::Monitoring::Event::ServerHeartbeatStarted)
|
94
|
+
# We could have up to 16 events and should have no fewer than 8 events.
|
95
|
+
# Whenever an awaited ismaster succeeds while the regular monitor is
|
96
|
+
# waiting, the regular monitor's next scan is pushed forward.
|
97
|
+
events.length.should >= 6
|
98
|
+
events.length.should <= 18
|
99
|
+
(started_awaited = events.select(&:awaited?)).should_not be_empty
|
100
|
+
(started_regular = events.reject(&:awaited?)).should_not be_empty
|
101
|
+
|
102
|
+
events = subscriber.select_succeeded_events(Mongo::Monitoring::Event::ServerHeartbeatSucceeded)
|
103
|
+
events.length.should >= 6
|
104
|
+
events.length.should <= 18
|
105
|
+
(succeeded_awaited = events.select(&:awaited?)).should_not be_empty
|
106
|
+
(succeeded_regular = events.reject(&:awaited?)).should_not be_empty
|
107
|
+
|
108
|
+
# Since we gracefully close the client, we expect each heartbeat
|
109
|
+
# to complete.
|
110
|
+
started_awaited.length.should == succeeded_awaited.length
|
111
|
+
started_regular.length.should == succeeded_regular.length
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
44
115
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'SDAM prose tests' do
|
4
|
+
# The "streaming protocol tests" are covered by the tests in
|
5
|
+
# sdam_events_spec.rb.
|
6
|
+
|
7
|
+
describe 'RTT tests' do
|
8
|
+
min_server_fcv '4.4'
|
9
|
+
require_topology :single
|
10
|
+
|
11
|
+
let(:subscriber) { EventSubscriber.new }
|
12
|
+
|
13
|
+
let(:client) do
|
14
|
+
new_local_client(SpecConfig.instance.addresses,
|
15
|
+
# Heartbeat interval is bound by 500 ms
|
16
|
+
SpecConfig.instance.test_options.merge(
|
17
|
+
heartbeat_frequency: 0.5,
|
18
|
+
app_name: 'streamingRttTest',
|
19
|
+
),
|
20
|
+
).tap do |client|
|
21
|
+
client.subscribe(Mongo::Monitoring::SERVER_HEARTBEAT, subscriber)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'updates RTT' do
|
26
|
+
server = client.cluster.next_primary
|
27
|
+
|
28
|
+
sleep 2
|
29
|
+
|
30
|
+
events = subscriber.select_succeeded_events(Mongo::Monitoring::Event::ServerHeartbeatSucceeded)
|
31
|
+
events.each do |event|
|
32
|
+
event.round_trip_time.should be_a(Numeric)
|
33
|
+
event.round_trip_time.should > 0
|
34
|
+
end
|
35
|
+
|
36
|
+
root_authorized_client.use('admin').database.command(
|
37
|
+
configureFailPoint: 'failCommand',
|
38
|
+
mode: {times: 1000},
|
39
|
+
data: {
|
40
|
+
failCommands: ["isMaster"],
|
41
|
+
blockConnection: true,
|
42
|
+
blockTimeMS: 500,
|
43
|
+
appName: "streamingRttTest",
|
44
|
+
},
|
45
|
+
)
|
46
|
+
|
47
|
+
deadline = Time.now + 10
|
48
|
+
loop do
|
49
|
+
if server.average_round_trip_time > 0.25
|
50
|
+
break
|
51
|
+
end
|
52
|
+
if Time.now >= deadline
|
53
|
+
raise "Failed to witness RTT growing to >= 250 ms in 10 seconds"
|
54
|
+
end
|
55
|
+
sleep 0.2
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
after do
|
60
|
+
root_authorized_client.use('admin').database.command(
|
61
|
+
configureFailPoint: 'failCommand', mode: 'off')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|