mongo 2.10.5 → 2.11.0.rc0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CONTRIBUTING.md +1 -1
- data/lib/mongo.rb +2 -0
- data/lib/mongo/address.rb +4 -0
- data/lib/mongo/address/validator.rb +99 -0
- data/lib/mongo/auth.rb +7 -2
- data/lib/mongo/auth/user.rb +1 -7
- data/lib/mongo/background_thread.rb +135 -0
- data/lib/mongo/bulk_write/transformable.rb +3 -3
- data/lib/mongo/client.rb +74 -16
- data/lib/mongo/cluster.rb +193 -41
- data/lib/mongo/cluster/periodic_executor.rb +31 -43
- data/lib/mongo/cluster/sdam_flow.rb +26 -3
- data/lib/mongo/cluster/srv_monitor.rb +127 -0
- data/lib/mongo/collection/view/readable.rb +3 -5
- data/lib/mongo/collection/view/writable.rb +3 -3
- data/lib/mongo/cursor/builder/get_more_command.rb +1 -4
- data/lib/mongo/cursor/builder/kill_cursors_command.rb +5 -23
- data/lib/mongo/cursor/builder/op_get_more.rb +2 -2
- data/lib/mongo/cursor/builder/op_kill_cursors.rb +5 -24
- data/lib/mongo/error.rb +1 -0
- data/lib/mongo/error/auth_error.rb +1 -1
- data/lib/mongo/error/connection_check_out_timeout.rb +7 -8
- data/lib/mongo/error/invalid_address.rb +24 -0
- data/lib/mongo/error/notable.rb +2 -2
- data/lib/mongo/error/operation_failure.rb +3 -3
- data/lib/mongo/error/pool_closed_error.rb +11 -4
- data/lib/mongo/event.rb +1 -1
- data/lib/mongo/grid/file.rb +0 -5
- data/lib/mongo/grid/file/chunk.rb +0 -2
- data/lib/mongo/grid/fs_bucket.rb +13 -15
- data/lib/mongo/grid/stream/write.rb +3 -9
- data/lib/mongo/loggable.rb +5 -1
- data/lib/mongo/monitoring.rb +1 -0
- data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +7 -0
- data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +11 -3
- data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +11 -3
- data/lib/mongo/monitoring/event/cmap/pool_closed.rb +11 -3
- data/lib/mongo/monitoring/event/cmap/pool_created.rb +12 -3
- data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +62 -0
- data/lib/mongo/operation/shared/executable.rb +5 -10
- data/lib/mongo/operation/shared/sessions_supported.rb +1 -5
- data/lib/mongo/protocol/get_more.rb +1 -2
- data/lib/mongo/protocol/kill_cursors.rb +13 -6
- data/lib/mongo/protocol/serializers.rb +4 -20
- data/lib/mongo/retryable.rb +9 -34
- data/lib/mongo/semaphore.rb +1 -1
- data/lib/mongo/server.rb +113 -42
- data/lib/mongo/server/connection.rb +12 -5
- data/lib/mongo/server/connection_pool.rb +250 -40
- data/lib/mongo/server/connection_pool/populator.rb +58 -0
- data/lib/mongo/server/description.rb +9 -2
- data/lib/mongo/server/monitor.rb +68 -93
- data/lib/mongo/server/monitor/connection.rb +2 -0
- data/lib/mongo/server_selector/selectable.rb +13 -5
- data/lib/mongo/session.rb +0 -13
- data/lib/mongo/srv.rb +17 -0
- data/lib/mongo/srv/monitor.rb +96 -0
- data/lib/mongo/srv/resolver.rb +130 -0
- data/lib/mongo/srv/result.rb +126 -0
- data/lib/mongo/srv/warning_result.rb +35 -0
- data/lib/mongo/uri.rb +45 -55
- data/lib/mongo/uri/srv_protocol.rb +89 -42
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +3 -4
- data/spec/README.md +6 -1
- data/spec/enterprise_auth/kerberos_spec.rb +7 -6
- data/spec/integration/change_stream_examples_spec.rb +0 -4
- data/spec/integration/client_construction_spec.rb +14 -2
- data/spec/integration/connect_single_rs_name_spec.rb +2 -2
- data/spec/integration/connection_pool_populator_spec.rb +296 -0
- data/spec/integration/connection_spec.rb +31 -22
- data/spec/integration/cursor_reaping_spec.rb +1 -2
- data/spec/integration/docs_examples_spec.rb +0 -4
- data/spec/integration/heartbeat_events_spec.rb +17 -15
- data/spec/integration/reconnect_spec.rb +144 -1
- data/spec/integration/retryable_writes_errors_spec.rb +0 -4
- data/spec/integration/retryable_writes_spec.rb +36 -36
- data/spec/integration/sdam_error_handling_spec.rb +31 -25
- data/spec/integration/sdam_events_spec.rb +2 -6
- data/spec/integration/server_monitor_spec.rb +28 -0
- data/spec/integration/server_selector_spec.rb +7 -5
- data/spec/integration/srv_monitoring_spec.rb +360 -0
- data/spec/integration/step_down_spec.rb +4 -6
- data/spec/lite_spec_helper.rb +22 -0
- data/spec/mongo/address/validator_spec.rb +51 -0
- data/spec/mongo/auth/cr_spec.rb +1 -29
- data/spec/mongo/auth/ldap_spec.rb +1 -29
- data/spec/mongo/auth/scram/conversation_spec.rb +0 -2
- data/spec/mongo/auth/scram/negotiation_spec.rb +1 -1
- data/spec/mongo/auth/scram_spec.rb +1 -29
- data/spec/mongo/auth/user/view_spec.rb +1 -36
- data/spec/mongo/auth/user_spec.rb +0 -12
- data/spec/mongo/auth/x509_spec.rb +1 -29
- data/spec/mongo/bulk_write_spec.rb +2 -2
- data/spec/mongo/client_construction_spec.rb +56 -15
- data/spec/mongo/client_spec.rb +31 -27
- data/spec/mongo/cluster/periodic_executor_spec.rb +16 -0
- data/spec/mongo/cluster/srv_monitor_spec.rb +214 -0
- data/spec/mongo/cluster/topology/replica_set_spec.rb +16 -11
- data/spec/mongo/cluster/topology/sharded_spec.rb +12 -9
- data/spec/mongo/cluster/topology/single_spec.rb +20 -11
- data/spec/mongo/cluster_spec.rb +45 -29
- data/spec/mongo/collection/view/map_reduce_spec.rb +14 -9
- data/spec/mongo/collection/view/readable_spec.rb +0 -16
- data/spec/mongo/collection_spec.rb +0 -44
- data/spec/mongo/cursor/builder/get_more_command_spec.rb +2 -4
- data/spec/mongo/cursor/builder/op_get_more_spec.rb +2 -4
- data/spec/mongo/cursor_spec.rb +27 -7
- data/spec/mongo/monitoring/event/cmap/connection_checked_in_spec.rb +10 -3
- data/spec/mongo/monitoring/event/cmap/connection_checked_out_spec.rb +10 -3
- data/spec/mongo/monitoring/event/cmap/pool_closed_spec.rb +10 -3
- data/spec/mongo/monitoring/event/cmap/pool_created_spec.rb +10 -3
- data/spec/mongo/operation/delete/op_msg_spec.rb +17 -8
- data/spec/mongo/operation/insert/op_msg_spec.rb +50 -35
- data/spec/mongo/operation/update/op_msg_spec.rb +14 -7
- data/spec/mongo/retryable_spec.rb +52 -31
- data/spec/mongo/server/app_metadata_spec.rb +0 -8
- data/spec/mongo/server/connection_auth_spec.rb +5 -2
- data/spec/mongo/server/connection_pool/populator_spec.rb +101 -0
- data/spec/mongo/server/connection_pool_spec.rb +256 -107
- data/spec/mongo/server/connection_spec.rb +22 -33
- data/spec/mongo/server/description_spec.rb +42 -4
- data/spec/mongo/server/monitor/connection_spec.rb +22 -11
- data/spec/mongo/server/monitor_spec.rb +66 -107
- data/spec/mongo/server_spec.rb +82 -60
- data/spec/mongo/session/session_pool_spec.rb +1 -5
- data/spec/mongo/session_spec.rb +0 -4
- data/spec/mongo/socket/ssl_spec.rb +2 -2
- data/spec/mongo/srv/monitor_spec.rb +211 -0
- data/spec/mongo/srv/result_spec.rb +54 -0
- data/spec/mongo/uri/srv_protocol_spec.rb +30 -15
- data/spec/mongo/uri_spec.rb +125 -4
- data/spec/spec_helper.rb +6 -0
- data/spec/spec_tests/auth_spec.rb +39 -0
- data/spec/spec_tests/cmap_spec.rb +55 -8
- data/spec/spec_tests/connection_string_spec.rb +6 -31
- data/spec/spec_tests/data/auth/connection-string.yml +297 -0
- data/spec/spec_tests/data/cmap/pool-checkout-error-closed.yml +4 -1
- data/spec/spec_tests/data/cmap/pool-create-with-options.yml +1 -0
- data/spec/spec_tests/data/command_monitoring/insertMany.yml +1 -1
- data/spec/spec_tests/data/connection_string/invalid-uris.yml +20 -0
- data/spec/spec_tests/data/connection_string/valid-auth.yml +16 -0
- data/spec/spec_tests/data/connection_string/valid-warnings.yml +26 -30
- data/spec/spec_tests/data/transactions/abort.yml +3 -3
- data/spec/spec_tests/data/transactions/error-labels.yml +3 -3
- data/spec/spec_tests/data/transactions_api/callback-retry.yml +3 -3
- data/spec/spec_tests/data/uri_options/auth-options.yml +1 -1
- data/spec/spec_tests/max_staleness_spec.rb +7 -2
- data/spec/spec_tests/retryable_reads_spec.rb +0 -31
- data/spec/spec_tests/sdam_monitoring_spec.rb +12 -12
- data/spec/spec_tests/sdam_spec.rb +4 -7
- data/spec/spec_tests/server_selection_spec.rb +6 -2
- data/spec/spec_tests/transactions_spec.rb +0 -2
- data/spec/spec_tests/uri_options_spec.rb +4 -2
- data/spec/stress/connection_pool_stress_spec.rb +203 -0
- data/spec/stress/connection_pool_timing_spec.rb +181 -0
- data/spec/support/auth.rb +113 -0
- data/spec/support/background_thread_registry.rb +63 -0
- data/spec/support/client_registry.rb +11 -2
- data/spec/support/cluster_config.rb +65 -46
- data/spec/support/cluster_tools.rb +2 -2
- data/spec/support/cmap.rb +13 -14
- data/spec/support/cmap/verifier.rb +4 -5
- data/spec/support/command_monitoring.rb +0 -5
- data/spec/support/common_shortcuts.rb +101 -1
- data/spec/support/constraints.rb +25 -0
- data/spec/support/dns.rb +13 -0
- data/spec/support/event_subscriber.rb +0 -7
- data/spec/support/json_ext_formatter.rb +5 -1
- data/spec/support/lite_constraints.rb +22 -6
- data/spec/support/local_resource_registry.rb +34 -0
- data/spec/support/sdam_monitoring.rb +115 -0
- data/spec/support/spec_config.rb +20 -6
- data/spec/support/spec_setup.rb +2 -2
- data/spec/support/transactions.rb +1 -1
- data/spec/support/transactions/test.rb +1 -1
- data/spec/support/utils.rb +1 -16
- metadata +685 -659
- metadata.gz.sig +0 -0
- data/lib/mongo/event/description_changed.rb +0 -52
- data/spec/integration/bson_symbol_spec.rb +0 -34
- data/spec/integration/crud_spec.rb +0 -45
- data/spec/integration/get_more_spec.rb +0 -32
- data/spec/integration/grid_fs_bucket_spec.rb +0 -48
- data/spec/integration/retryable_errors_spec.rb +0 -265
- data/spec/integration/size_limit_spec.rb~12e1e9c4f... RUBY-2242 Fix zlib compression (#2021) +0 -98
- data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +0 -56
- data/spec/runners/sdam/verifier.rb +0 -88
@@ -1,14 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Connections' do
|
4
|
-
|
5
|
-
|
4
|
+
clean_slate
|
5
|
+
|
6
|
+
let(:client) do
|
7
|
+
ClientRegistry.instance.global_client('authorized').tap do |client|
|
8
|
+
stop_monitoring(client)
|
9
|
+
end
|
6
10
|
end
|
7
11
|
|
8
|
-
let(:client) { ClientRegistry.instance.global_client('authorized') }
|
9
12
|
let(:server) { client.cluster.servers.first }
|
10
13
|
|
11
14
|
describe '#connect!' do
|
15
|
+
# On JRuby 9.2.7.0, this line:
|
16
|
+
# expect_any_instance_of(Mongo::Socket).to receive(:write).and_raise(exception)
|
17
|
+
# ... appears to produce a moment in which Mongo::Socket#write is undefined
|
18
|
+
# entirely, resulting in this failure:
|
19
|
+
# RSpec::Expectations::ExpectationNotMetError: expected Mongo::Error::SocketError, got #<NameError: undefined method `write' for class `Mongo::Socket'>
|
12
20
|
fails_on_jruby
|
13
21
|
|
14
22
|
context 'network error during handshake' do
|
@@ -74,17 +82,17 @@ describe 'Connections' do
|
|
74
82
|
|
75
83
|
# need to use the primary here, otherwise a secondary will be
|
76
84
|
# changed to unknown which wouldn't alter topology
|
77
|
-
let(:server) { client.cluster.
|
85
|
+
let(:server) { client.cluster.next_primary }
|
78
86
|
|
79
87
|
it 'changes topology type' do
|
80
88
|
# wait for topology to get discovered
|
81
|
-
client.
|
89
|
+
client.cluster.next_primary
|
82
90
|
|
83
91
|
expect(client.cluster.topology.class).to eql(Mongo::Cluster::Topology::ReplicaSetWithPrimary)
|
84
92
|
|
85
93
|
# stop background monitoring to prevent it from racing with the test
|
86
|
-
client.cluster.
|
87
|
-
server.monitor.stop!
|
94
|
+
client.cluster.servers_list.each do |server|
|
95
|
+
server.monitor.stop!
|
88
96
|
end
|
89
97
|
|
90
98
|
connection
|
@@ -98,12 +106,11 @@ describe 'Connections' do
|
|
98
106
|
context 'error during handshake to primary in a replica set' do
|
99
107
|
require_topology :replica_set
|
100
108
|
|
101
|
-
let(:server) { client.cluster.
|
109
|
+
let(:server) { client.cluster.next_primary }
|
102
110
|
|
103
111
|
before do
|
104
|
-
ClientRegistry.instance.close_all_clients
|
105
112
|
# insert to perform server selection and get topology to primary
|
106
|
-
client
|
113
|
+
client.cluster.next_primary
|
107
114
|
end
|
108
115
|
|
109
116
|
it 'sets cluster type to replica set without primary' do
|
@@ -148,17 +155,19 @@ describe 'Connections' do
|
|
148
155
|
server.monitor.instance_variable_set('@description',
|
149
156
|
Mongo::Server::Description.new(server.address))
|
150
157
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
158
|
+
RSpec::Mocks.with_temporary_scope do
|
159
|
+
# now pretend an ismaster returned a different range
|
160
|
+
features = Mongo::Server::Description::Features.new(0..3)
|
161
|
+
# the second Features instantiation is for SDAM event publication
|
162
|
+
expect(Mongo::Server::Description::Features).to receive(:new).twice.and_return(features)
|
155
163
|
|
156
|
-
|
157
|
-
|
164
|
+
connection = Mongo::Server::Connection.new(server, server.options)
|
165
|
+
expect(connection.connect!).to be true
|
158
166
|
|
159
|
-
|
160
|
-
|
161
|
-
|
167
|
+
# ismaster response should update server description via sdam flow,
|
168
|
+
# which includes wire version range
|
169
|
+
expect(server.features.server_wire_versions.max).to eq(3)
|
170
|
+
end
|
162
171
|
end
|
163
172
|
end
|
164
173
|
|
@@ -173,8 +182,8 @@ describe 'Connections' do
|
|
173
182
|
|
174
183
|
it 'performs SDAM flow' do
|
175
184
|
client['foo'].insert_one(bar: 1)
|
176
|
-
client.cluster.
|
177
|
-
server.monitor.stop!
|
185
|
+
client.cluster.servers_list.each do |server|
|
186
|
+
server.monitor.stop!
|
178
187
|
end
|
179
188
|
expect(client.cluster.topology.class).to eq(Mongo::Cluster::Topology::ReplicaSetWithPrimary)
|
180
189
|
|
@@ -184,7 +193,7 @@ describe 'Connections' do
|
|
184
193
|
end
|
185
194
|
|
186
195
|
# overwrite server description
|
187
|
-
server.
|
196
|
+
server.instance_variable_set('@description', Mongo::Server::Description.new(
|
188
197
|
server.address))
|
189
198
|
|
190
199
|
# overwrite topology
|
@@ -59,8 +59,7 @@ describe 'Cursor reaping' do
|
|
59
59
|
client.cluster.instance_variable_get('@periodic_executor').execute
|
60
60
|
|
61
61
|
started_event = EventSubscriber.started_events.detect do |event|
|
62
|
-
event.command['killCursors'] &&
|
63
|
-
event.command['cursors'].map { |c| Utils.int64_value(c) }.include?(cursor_id)
|
62
|
+
event.command['killCursors'] && event.command['cursors'].include?(cursor_id)
|
64
63
|
end
|
65
64
|
|
66
65
|
expect(started_event).not_to be_nil
|
@@ -25,11 +25,9 @@ end
|
|
25
25
|
describe 'Heartbeat events' do
|
26
26
|
class HeartbeatEventsSpecTestException < StandardError; end
|
27
27
|
|
28
|
-
|
28
|
+
clean_slate_for_all
|
29
29
|
|
30
|
-
|
31
|
-
ClientRegistry.instance.close_all_clients
|
32
|
-
end
|
30
|
+
let(:subscriber) { TestHeartbeatSubscriber.new }
|
33
31
|
|
34
32
|
before do
|
35
33
|
Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::SERVER_HEARTBEAT, subscriber)
|
@@ -39,8 +37,11 @@ describe 'Heartbeat events' do
|
|
39
37
|
Mongo::Monitoring::Global.unsubscribe(Mongo::Monitoring::SERVER_HEARTBEAT, subscriber)
|
40
38
|
end
|
41
39
|
|
42
|
-
let(:
|
43
|
-
|
40
|
+
let(:address_str) { ClusterConfig.instance.primary_address_str }
|
41
|
+
|
42
|
+
let(:client) { new_local_client([address_str],
|
43
|
+
SpecConfig.instance.all_test_options.merge(
|
44
|
+
server_selection_timeout: 0.1, connect: :direct)) }
|
44
45
|
|
45
46
|
it 'notifies on successful heartbeats' do
|
46
47
|
client.database.command(ismaster: 1)
|
@@ -48,12 +49,12 @@ describe 'Heartbeat events' do
|
|
48
49
|
started_event = subscriber.started_events.first
|
49
50
|
expect(started_event).not_to be nil
|
50
51
|
expect(started_event.address).to be_a(Mongo::Address)
|
51
|
-
expect(started_event.address.seed).to eq(
|
52
|
+
expect(started_event.address.seed).to eq(address_str)
|
52
53
|
|
53
54
|
succeeded_event = subscriber.succeeded_events.first
|
54
55
|
expect(succeeded_event).not_to be nil
|
55
56
|
expect(succeeded_event.address).to be_a(Mongo::Address)
|
56
|
-
expect(succeeded_event.address.seed).to eq(
|
57
|
+
expect(succeeded_event.address.seed).to eq(address_str)
|
57
58
|
|
58
59
|
failed_event = subscriber.failed_events.first
|
59
60
|
expect(failed_event).to be nil
|
@@ -70,7 +71,7 @@ describe 'Heartbeat events' do
|
|
70
71
|
started_event = subscriber.started_events.first
|
71
72
|
expect(started_event).not_to be nil
|
72
73
|
expect(started_event.address).to be_a(Mongo::Address)
|
73
|
-
expect(started_event.address.seed).to eq(
|
74
|
+
expect(started_event.address.seed).to eq(address_str)
|
74
75
|
|
75
76
|
succeeded_event = subscriber.succeeded_events.first
|
76
77
|
expect(succeeded_event).to be nil
|
@@ -80,13 +81,13 @@ describe 'Heartbeat events' do
|
|
80
81
|
expect(failed_event.error).to be exc
|
81
82
|
expect(failed_event.failure).to be exc
|
82
83
|
expect(failed_event.address).to be_a(Mongo::Address)
|
83
|
-
expect(failed_event.address.seed).to eq(
|
84
|
+
expect(failed_event.address.seed).to eq(address_str)
|
84
85
|
end
|
85
86
|
|
86
87
|
context 'when monitoring option is false' do
|
87
|
-
let(:client) { new_local_client([
|
88
|
-
|
89
|
-
monitoring: false)) }
|
88
|
+
let(:client) { new_local_client([address_str],
|
89
|
+
SpecConfig.instance.all_test_options.merge(
|
90
|
+
server_selection_timeout: 0.1, connect: :direct, monitoring: false)) }
|
90
91
|
|
91
92
|
shared_examples_for 'does not notify on heartbeats' do
|
92
93
|
it 'does not notify on heartbeats' do
|
@@ -105,8 +106,9 @@ describe 'Heartbeat events' do
|
|
105
106
|
client.subscribe(Mongo::Monitoring::SERVER_HEARTBEAT, subscriber)
|
106
107
|
end
|
107
108
|
|
108
|
-
new_local_client([
|
109
|
-
|
109
|
+
new_local_client([address_str],
|
110
|
+
SpecConfig.instance.all_test_options.merge(
|
111
|
+
server_selection_timeout: 0.1, connect: :direct,
|
110
112
|
monitoring: false, sdam_proc: sdam_proc))
|
111
113
|
end
|
112
114
|
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe 'Client after reconnect' do
|
4
4
|
let(:client) { authorized_client }
|
5
5
|
|
6
|
-
it '
|
6
|
+
it 'is a functioning client' do
|
7
7
|
client['test'].insert_one('testk' => 'testv')
|
8
8
|
|
9
9
|
client.reconnect
|
@@ -28,4 +28,147 @@ describe 'Client after reconnect' do
|
|
28
28
|
expect(new_thread).not_to eq(thread)
|
29
29
|
expect(new_thread).to be_alive
|
30
30
|
end
|
31
|
+
|
32
|
+
context 'with min_pool_size > 0' do
|
33
|
+
let(:client) { authorized_client.with(min_pool_size: 1) }
|
34
|
+
|
35
|
+
it 'recreates connection pool populator thread' do
|
36
|
+
server = client.cluster.next_primary
|
37
|
+
thread = server.pool.populator.instance_variable_get('@thread')
|
38
|
+
expect(thread).to be_alive
|
39
|
+
|
40
|
+
thread.kill
|
41
|
+
# context switch to let the thread get killed
|
42
|
+
sleep 0.1
|
43
|
+
expect(thread).not_to be_alive
|
44
|
+
|
45
|
+
client.reconnect
|
46
|
+
|
47
|
+
new_server = client.cluster.next_primary
|
48
|
+
new_thread = new_server.pool.populator.instance_variable_get('@thread')
|
49
|
+
expect(new_thread).not_to eq(thread)
|
50
|
+
expect(new_thread).to be_alive
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'SRV monitor thread' do
|
55
|
+
|
56
|
+
let(:uri) do
|
57
|
+
"mongodb+srv://test1.test.build.10gen.cc/?tls=#{SpecConfig.instance.ssl?}&tlsInsecure=true".tap do |uri|
|
58
|
+
puts "Constructed URI: #{uri}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Debug logging to troubleshoot failures in Evergreen
|
63
|
+
let(:logger) do
|
64
|
+
Logger.new(STDERR). tap do |logger|
|
65
|
+
logger.level = :debug
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
let(:client) do
|
70
|
+
ClientRegistry.instance.register_local_client(
|
71
|
+
Mongo::Client.new(uri, server_selection_timeout: 3.86,
|
72
|
+
logger: logger))
|
73
|
+
end
|
74
|
+
|
75
|
+
let(:wait_for_discovery) do
|
76
|
+
client.cluster.next_primary
|
77
|
+
end
|
78
|
+
|
79
|
+
let(:wait_for_discovery_again) do
|
80
|
+
client.cluster.next_primary
|
81
|
+
end
|
82
|
+
|
83
|
+
shared_examples_for 'recreates SRV monitor' do
|
84
|
+
# JRuby produces this error:
|
85
|
+
# RSpec::Expectations::ExpectationNotMetError: expected nil to respond to `alive?`
|
86
|
+
# for this assertion:
|
87
|
+
# expect(thread).not_to be_alive
|
88
|
+
# This is bizarre because if thread was nil, the earlier call to
|
89
|
+
# thread.kill should've similarly failed, but it doesn't.
|
90
|
+
fails_on_jruby
|
91
|
+
|
92
|
+
it 'recreates SRV monitor' do
|
93
|
+
wait_for_discovery
|
94
|
+
|
95
|
+
expect(client.cluster.topology).to be_a(expected_topology_cls)
|
96
|
+
thread = client.cluster.srv_monitor.instance_variable_get('@thread')
|
97
|
+
expect(thread).to be_alive
|
98
|
+
|
99
|
+
thread.kill
|
100
|
+
# context switch to let the thread get killed
|
101
|
+
sleep 0.1
|
102
|
+
expect(thread).not_to be_alive
|
103
|
+
|
104
|
+
client.reconnect
|
105
|
+
|
106
|
+
wait_for_discovery_again
|
107
|
+
|
108
|
+
new_thread = client.cluster.srv_monitor.instance_variable_get('@thread')
|
109
|
+
expect(new_thread).not_to eq(thread)
|
110
|
+
expect(new_thread).to be_alive
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'in sharded topology' do
|
115
|
+
require_topology :sharded
|
116
|
+
require_default_port_deployment
|
117
|
+
require_multi_shard
|
118
|
+
|
119
|
+
let(:expected_topology_cls) { Mongo::Cluster::Topology::Sharded }
|
120
|
+
|
121
|
+
it_behaves_like 'recreates SRV monitor'
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'in unknown topology' do
|
125
|
+
|
126
|
+
# JRuby apparently does not implement non-blocking UDP I/O which is used
|
127
|
+
# by RubyDNS:
|
128
|
+
# NotImplementedError: recvmsg_nonblock is not implemented
|
129
|
+
fails_on_jruby
|
130
|
+
|
131
|
+
let(:uri) do
|
132
|
+
"mongodb+srv://test-fake.test.build.10gen.cc/"
|
133
|
+
end
|
134
|
+
|
135
|
+
let(:client) do
|
136
|
+
ClientRegistry.instance.register_local_client(
|
137
|
+
Mongo::Client.new(uri, server_selection_timeout: 3.89,
|
138
|
+
resolv_options: {
|
139
|
+
nameserver: 'localhost',
|
140
|
+
nameserver_port: [['localhost', 5300], ['127.0.0.1', 5300]],
|
141
|
+
},
|
142
|
+
logger: logger))
|
143
|
+
end
|
144
|
+
|
145
|
+
let(:expected_topology_cls) { Mongo::Cluster::Topology::Unknown }
|
146
|
+
|
147
|
+
let(:wait_for_discovery) do
|
148
|
+
# Since the entire test is done in unknown topology, we cannot use
|
149
|
+
# next_primary to wait for the client to discover the topology.
|
150
|
+
sleep 5
|
151
|
+
end
|
152
|
+
|
153
|
+
let(:wait_for_discovery_again) do
|
154
|
+
sleep 5
|
155
|
+
end
|
156
|
+
|
157
|
+
around do |example|
|
158
|
+
require 'support/dns'
|
159
|
+
|
160
|
+
rules = [
|
161
|
+
['_mongodb._tcp.test-fake.test.build.10gen.cc', :srv,
|
162
|
+
[0, 0, 2799, 'localhost.test.build.10gen.cc'],
|
163
|
+
],
|
164
|
+
]
|
165
|
+
|
166
|
+
mock_dns(rules) do
|
167
|
+
example.run
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
it_behaves_like 'recreates SRV monitor'
|
172
|
+
end
|
173
|
+
end
|
31
174
|
end
|
@@ -102,22 +102,22 @@ describe 'Retryable writes integration tests' do
|
|
102
102
|
end
|
103
103
|
|
104
104
|
it 'does not retry writes' do
|
105
|
-
expect
|
105
|
+
expect {
|
106
106
|
operation
|
107
|
-
|
107
|
+
}.to raise_error(Mongo::Error::OperationFailure, /other error/)
|
108
108
|
expect(expectation).to eq(unsuccessful_retry_value)
|
109
109
|
end
|
110
110
|
|
111
111
|
it 'indicates server used for operation' do
|
112
|
-
expect
|
112
|
+
expect {
|
113
113
|
operation
|
114
|
-
|
114
|
+
}.to raise_error(Mongo::Error::OperationFailure, /on #{ClusterConfig.instance.primary_address_str}/)
|
115
115
|
end
|
116
116
|
|
117
117
|
it 'indicates first attempt' do
|
118
|
-
expect
|
118
|
+
expect {
|
119
119
|
operation
|
120
|
-
|
120
|
+
}.to raise_error(Mongo::Error::OperationFailure, /attempt 1/)
|
121
121
|
end
|
122
122
|
end
|
123
123
|
end
|
@@ -144,9 +144,9 @@ describe 'Retryable writes integration tests' do
|
|
144
144
|
end
|
145
145
|
|
146
146
|
it 'does not retry writes and raises the original error' do
|
147
|
-
expect
|
147
|
+
expect {
|
148
148
|
operation
|
149
|
-
|
149
|
+
}.to raise_error(error)
|
150
150
|
expect(expectation).to eq(unsuccessful_retry_value)
|
151
151
|
end
|
152
152
|
end
|
@@ -158,9 +158,9 @@ describe 'Retryable writes integration tests' do
|
|
158
158
|
end
|
159
159
|
|
160
160
|
it 'does not retry writes and raises the original error' do
|
161
|
-
expect
|
161
|
+
expect {
|
162
162
|
operation
|
163
|
-
|
163
|
+
}.to raise_error(error)
|
164
164
|
expect(expectation).to eq(unsuccessful_retry_value)
|
165
165
|
end
|
166
166
|
end
|
@@ -172,9 +172,9 @@ describe 'Retryable writes integration tests' do
|
|
172
172
|
end
|
173
173
|
|
174
174
|
it 'does not retry writes and raises the original error' do
|
175
|
-
expect
|
175
|
+
expect {
|
176
176
|
operation
|
177
|
-
|
177
|
+
}.to raise_error(error)
|
178
178
|
expect(expectation).to eq(unsuccessful_retry_value)
|
179
179
|
end
|
180
180
|
end
|
@@ -211,22 +211,22 @@ describe 'Retryable writes integration tests' do
|
|
211
211
|
end
|
212
212
|
|
213
213
|
it 'raises the second error' do
|
214
|
-
expect
|
214
|
+
expect {
|
215
215
|
operation
|
216
|
-
|
216
|
+
}.to raise_error(second_error)
|
217
217
|
expect(expectation).to eq(unsuccessful_retry_value)
|
218
218
|
end
|
219
219
|
|
220
220
|
it 'indicates server used for operation' do
|
221
|
-
expect
|
221
|
+
expect {
|
222
222
|
operation
|
223
|
-
|
223
|
+
}.to raise_error(Mongo::Error, /on #{ClusterConfig.instance.primary_address_str}/)
|
224
224
|
end
|
225
225
|
|
226
226
|
it 'indicates second attempt' do
|
227
|
-
expect
|
227
|
+
expect {
|
228
228
|
operation
|
229
|
-
|
229
|
+
}.to raise_error(Mongo::Error, /attempt 2/)
|
230
230
|
end
|
231
231
|
end
|
232
232
|
|
@@ -237,9 +237,9 @@ describe 'Retryable writes integration tests' do
|
|
237
237
|
end
|
238
238
|
|
239
239
|
it 'raises the second error' do
|
240
|
-
expect
|
240
|
+
expect {
|
241
241
|
operation
|
242
|
-
|
242
|
+
}.to raise_error(second_error)
|
243
243
|
expect(expectation).to eq(unsuccessful_retry_value)
|
244
244
|
end
|
245
245
|
end
|
@@ -251,9 +251,9 @@ describe 'Retryable writes integration tests' do
|
|
251
251
|
end
|
252
252
|
|
253
253
|
it 'raises the second error' do
|
254
|
-
expect
|
254
|
+
expect {
|
255
255
|
operation
|
256
|
-
|
256
|
+
}.to raise_error(second_error)
|
257
257
|
expect(expectation).to eq(unsuccessful_retry_value)
|
258
258
|
end
|
259
259
|
end
|
@@ -265,9 +265,9 @@ describe 'Retryable writes integration tests' do
|
|
265
265
|
end
|
266
266
|
|
267
267
|
it 'does not retry writes and raises the first error' do
|
268
|
-
expect
|
268
|
+
expect {
|
269
269
|
operation
|
270
|
-
|
270
|
+
}.to raise_error(error)
|
271
271
|
expect(expectation).to eq(unsuccessful_retry_value)
|
272
272
|
end
|
273
273
|
end
|
@@ -279,28 +279,28 @@ describe 'Retryable writes integration tests' do
|
|
279
279
|
end
|
280
280
|
|
281
281
|
it 'raises the first error' do
|
282
|
-
expect
|
282
|
+
expect {
|
283
283
|
operation
|
284
|
-
|
284
|
+
}.to raise_error(error)
|
285
285
|
expect(expectation).to eq(unsuccessful_retry_value)
|
286
286
|
end
|
287
287
|
|
288
288
|
it 'indicates server used for operation' do
|
289
|
-
expect
|
289
|
+
expect {
|
290
290
|
operation
|
291
|
-
|
291
|
+
}.to raise_error(Mongo::Error, /on #{ClusterConfig.instance.primary_address_str}/)
|
292
292
|
end
|
293
293
|
|
294
294
|
it 'indicates first attempt' do
|
295
|
-
expect
|
295
|
+
expect {
|
296
296
|
operation
|
297
|
-
|
297
|
+
}.to raise_error(Mongo::Error, /attempt 1/)
|
298
298
|
end
|
299
299
|
|
300
300
|
it 'indicates retry was performed' do
|
301
|
-
expect
|
301
|
+
expect {
|
302
302
|
operation
|
303
|
-
|
303
|
+
}.to raise_error(Mongo::Error, /later retry failed: StandardError/)
|
304
304
|
end
|
305
305
|
end
|
306
306
|
end
|
@@ -319,9 +319,9 @@ describe 'Retryable writes integration tests' do
|
|
319
319
|
end
|
320
320
|
|
321
321
|
it 'does not retry writes' do
|
322
|
-
expect
|
322
|
+
expect {
|
323
323
|
operation
|
324
|
-
|
324
|
+
}.to raise_error(Mongo::Error::SocketError)
|
325
325
|
expect(expectation).to eq(unsuccessful_retry_value)
|
326
326
|
end
|
327
327
|
end
|
@@ -341,9 +341,9 @@ describe 'Retryable writes integration tests' do
|
|
341
341
|
end
|
342
342
|
|
343
343
|
it 'does not retry writes' do
|
344
|
-
expect
|
344
|
+
expect {
|
345
345
|
operation
|
346
|
-
|
346
|
+
}.to raise_error(Mongo::Error::SocketError)
|
347
347
|
expect(expectation).to eq(unsuccessful_retry_value)
|
348
348
|
end
|
349
349
|
end
|