mongo 2.10.5 → 2.11.0.rc0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/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
@@ -349,6 +349,8 @@ class ClusterTools
|
|
349
349
|
end
|
350
350
|
end
|
351
351
|
|
352
|
+
private
|
353
|
+
|
352
354
|
def each_server(&block)
|
353
355
|
admin_client.cluster.servers_list.each(&block)
|
354
356
|
end
|
@@ -359,8 +361,6 @@ class ClusterTools
|
|
359
361
|
end
|
360
362
|
end
|
361
363
|
|
362
|
-
private
|
363
|
-
|
364
364
|
def reset_server_states
|
365
365
|
each_server do |server|
|
366
366
|
server.unknown!
|
data/spec/support/cmap.rb
CHANGED
@@ -53,21 +53,17 @@ module Mongo
|
|
53
53
|
preprocess
|
54
54
|
end
|
55
55
|
|
56
|
-
def setup(
|
57
|
-
@subscriber =
|
58
|
-
|
59
|
-
monitoring = Mongo::Monitoring.new(monitoring: false)
|
60
|
-
monitoring.subscribe(Mongo::Monitoring::CONNECTION_POOL, subscriber)
|
61
|
-
|
62
|
-
server = Mongo::Server.new(
|
63
|
-
Address.new(SpecConfig.instance.addresses.first),
|
64
|
-
cluster,
|
65
|
-
monitoring,
|
66
|
-
Mongo::Event::Listeners.new,
|
67
|
-
pool_options.merge(monitoring_io: false))
|
68
|
-
|
56
|
+
def setup(server, subscriber)
|
57
|
+
@subscriber = subscriber
|
69
58
|
@pool = server.pool
|
70
|
-
|
59
|
+
|
60
|
+
# let pool populate
|
61
|
+
([0.1, 0.15, 0.15] + [0.2] * 20).each do |t|
|
62
|
+
if @pool.size >= @pool.min_size
|
63
|
+
break
|
64
|
+
end
|
65
|
+
sleep t
|
66
|
+
end
|
71
67
|
end
|
72
68
|
|
73
69
|
def run
|
@@ -170,6 +166,9 @@ module Mongo
|
|
170
166
|
end
|
171
167
|
|
172
168
|
# Converts the options given by the spec to the Ruby driver format.
|
169
|
+
#
|
170
|
+
# This method only handles options used by spec tests at the time when
|
171
|
+
# this method was written. Other options are silently dropped.
|
173
172
|
def process_options(options)
|
174
173
|
(options || {}).reduce({}) do |opts, kv|
|
175
174
|
case kv.first
|
@@ -27,14 +27,13 @@ module Mongo
|
|
27
27
|
expect(expected).to be_a(Hash)
|
28
28
|
expect(actual).to be_a(Hash)
|
29
29
|
|
30
|
-
|
30
|
+
actual_modified = actual.dup
|
31
31
|
if actual['reason']
|
32
|
-
|
32
|
+
actual_modified['reason'] = actual['reason'].to_s.gsub(/_[a-z]/) { |m| m[1].upcase }
|
33
33
|
end
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
if expected.key?(k) && expected[k] == 42
|
35
|
+
actual.each do |k, v|
|
36
|
+
if expected.key?(k) && expected[k] == 42 && v
|
38
37
|
actual_modified[k] = 42
|
39
38
|
end
|
40
39
|
end
|
@@ -134,11 +134,6 @@ module Mongo
|
|
134
134
|
end
|
135
135
|
if expected.keys.first == '$numberLong'
|
136
136
|
converted = expected.values.first.to_i
|
137
|
-
if actual.is_a?(BSON::Int64)
|
138
|
-
actual = Utils.int64_value(actual)
|
139
|
-
elsif actual.is_a?(BSON::Int32)
|
140
|
-
return false
|
141
|
-
end
|
142
137
|
(actual == converted) || actual >= 0
|
143
138
|
else
|
144
139
|
expected.each do |key, value|
|
@@ -16,6 +16,7 @@ module CommonShortcuts
|
|
16
16
|
def clean_slate
|
17
17
|
before do
|
18
18
|
ClientRegistry.instance.close_all_clients
|
19
|
+
BackgroundThreadRegistry.instance.verify_empty!
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
@@ -25,6 +26,7 @@ module CommonShortcuts
|
|
25
26
|
def clean_slate_for_all
|
26
27
|
before(:all) do
|
27
28
|
ClientRegistry.instance.close_all_clients
|
29
|
+
BackgroundThreadRegistry.instance.verify_empty!
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
@@ -107,7 +109,13 @@ module CommonShortcuts
|
|
107
109
|
allow(cluster).to receive(:topology).and_return(topology)
|
108
110
|
allow(cluster).to receive(:app_metadata)
|
109
111
|
allow(cluster).to receive(:options).and_return({})
|
110
|
-
|
112
|
+
allow(cluster).to receive(:run_sdam_flow)
|
113
|
+
allow(cluster).to receive(:heartbeat_interval).and_return(10)
|
114
|
+
server = Mongo::Server.new(address, cluster, monitoring, listeners,
|
115
|
+
SpecConfig.instance.test_options.merge(monitoring_io: false))
|
116
|
+
# Since the server references a double for the cluster, the server
|
117
|
+
# must be closed in the scope of the example.
|
118
|
+
register_server(server)
|
111
119
|
description = Mongo::Server::Description.new(address, ismaster, average_round_trip_time)
|
112
120
|
server.tap do |s|
|
113
121
|
allow(s).to receive(:description).and_return(description)
|
@@ -138,5 +146,97 @@ module CommonShortcuts
|
|
138
146
|
'ok' => 0, 'code' => 91, 'errmsg' => 'shutdown in progress'
|
139
147
|
)
|
140
148
|
end
|
149
|
+
|
150
|
+
def register_cluster(cluster)
|
151
|
+
finalizer = lambda do |cluster|
|
152
|
+
cluster.disconnect!
|
153
|
+
end
|
154
|
+
LocalResourceRegistry.instance.register(cluster, finalizer)
|
155
|
+
end
|
156
|
+
|
157
|
+
def register_server(server)
|
158
|
+
finalizer = lambda do |server|
|
159
|
+
if server.connected?
|
160
|
+
server.disconnect!
|
161
|
+
end
|
162
|
+
end
|
163
|
+
LocalResourceRegistry.instance.register(server, finalizer)
|
164
|
+
end
|
165
|
+
|
166
|
+
def register_background_thread_object(bgt_object)
|
167
|
+
finalizer = lambda do |bgt_object|
|
168
|
+
bgt_object.stop!
|
169
|
+
end
|
170
|
+
LocalResourceRegistry.instance.register(bgt_object, finalizer)
|
171
|
+
end
|
172
|
+
|
173
|
+
def register_pool(pool)
|
174
|
+
finalizer = lambda do |pool|
|
175
|
+
if !pool.closed?
|
176
|
+
pool.close(wait: true)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
LocalResourceRegistry.instance.register(pool, finalizer)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Stop monitoring threads on the specified clients, after ensuring
|
183
|
+
# each client has a writable server. Used for tests which assert on
|
184
|
+
# global side effects like log messages being generated, to prevent
|
185
|
+
# background threads from interfering with assertions.
|
186
|
+
def stop_monitoring(*clients)
|
187
|
+
clients.each do |client|
|
188
|
+
client.cluster.next_primary
|
189
|
+
client.cluster.disconnect!
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
DNS_INTERFACES = [
|
194
|
+
[:udp, "0.0.0.0", 5300],
|
195
|
+
[:tcp, "0.0.0.0", 5300],
|
196
|
+
]
|
197
|
+
|
198
|
+
def mock_dns(config)
|
199
|
+
semaphore = Mongo::Semaphore.new
|
200
|
+
|
201
|
+
thread = Thread.new do
|
202
|
+
RubyDNS::run_server(DNS_INTERFACES) do
|
203
|
+
config.each do |(query, type, *answers)|
|
204
|
+
|
205
|
+
resource_cls = Resolv::DNS::Resource::IN.const_get(type.to_s.upcase)
|
206
|
+
resources = answers.map do |answer|
|
207
|
+
resource_cls.new(*answer)
|
208
|
+
end
|
209
|
+
match(query, resource_cls) do |req|
|
210
|
+
req.add(resources)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
semaphore.signal
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
semaphore.wait
|
219
|
+
|
220
|
+
begin
|
221
|
+
yield
|
222
|
+
ensure
|
223
|
+
10.times do
|
224
|
+
if $last_async_task
|
225
|
+
break
|
226
|
+
end
|
227
|
+
sleep 0.5
|
228
|
+
end
|
229
|
+
|
230
|
+
# Hack to stop the server - https://github.com/socketry/rubydns/issues/75
|
231
|
+
if $last_async_task.nil?
|
232
|
+
STDERR.puts "No async task - server never started?"
|
233
|
+
else
|
234
|
+
$last_async_task.stop
|
235
|
+
end
|
236
|
+
|
237
|
+
thread.kill
|
238
|
+
thread.join
|
239
|
+
end
|
240
|
+
end
|
141
241
|
end
|
142
242
|
end
|
data/spec/support/constraints.rb
CHANGED
@@ -158,6 +158,14 @@ module Constraints
|
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
161
|
+
def require_multi_shard
|
162
|
+
before do
|
163
|
+
if ClusterConfig.instance.topology == :sharded && SpecConfig.instance.addresses.length == 1
|
164
|
+
skip 'Test requires a minimum of two shards if run in sharded topology'
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
161
169
|
def require_no_multi_shard
|
162
170
|
before do
|
163
171
|
if ClusterConfig.instance.topology == :sharded && SpecConfig.instance.addresses.length > 1
|
@@ -191,4 +199,21 @@ module Constraints
|
|
191
199
|
end
|
192
200
|
end
|
193
201
|
end
|
202
|
+
|
203
|
+
# Integration tests for SRV polling require internet connectivity to
|
204
|
+
# look up SRV records and a sharded cluster configured on default port on
|
205
|
+
# localhost (localhost:27017, localhost:27018).
|
206
|
+
def require_default_port_deployment
|
207
|
+
# Because the DNS records at test1.test.build.10gen.cc point to
|
208
|
+
# localhost:27017 & localhost:27018, the test suite must have been
|
209
|
+
# configured to use these addresses
|
210
|
+
before(:all) do
|
211
|
+
have_default_port = SpecConfig.instance.addresses.any? do |address|
|
212
|
+
%w(127.0.0.1 127.0.0.1:27017 localhost localhost:27017).include?(address)
|
213
|
+
end
|
214
|
+
unless have_default_port
|
215
|
+
skip 'This test requires the test suite to be configured for localhost:27017'
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
194
219
|
end
|
data/spec/support/dns.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rubydns'
|
2
|
+
|
3
|
+
# Hack to stop the server - https://github.com/socketry/rubydns/issues/75
|
4
|
+
module Async
|
5
|
+
class Task
|
6
|
+
alias :run_without_record :run
|
7
|
+
def run(*args)
|
8
|
+
run_without_record.tap do
|
9
|
+
$last_async_task = self
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -44,13 +44,6 @@ class EventSubscriber
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
# Filters command started events for the specified command name.
|
48
|
-
def command_started_events(command_name)
|
49
|
-
started_events.select do |event|
|
50
|
-
event.command[command_name]
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
47
|
# Locates command stated events for the specified command name,
|
55
48
|
# asserts that there is exactly one such event, and returns it.
|
56
49
|
def single_command_started_event(command_name)
|
@@ -1,8 +1,12 @@
|
|
1
1
|
class JsonExtFormatter < RSpec::Core::Formatters::JsonFormatter
|
2
|
-
RSpec::Core::Formatters.register self, :message,
|
2
|
+
RSpec::Core::Formatters.register self, :message,
|
3
|
+
:dump_summary, :dump_profile, :stop, :seed, :close
|
3
4
|
|
4
5
|
def format_example(example)
|
5
6
|
super.tap do |hash|
|
7
|
+
# Time format is chosen to be the same as driver's log entries
|
8
|
+
hash[:started_at] = example.execution_result.started_at.strftime('%Y-%m-%d %H:%M:%S.%L %z')
|
9
|
+
hash[:finished_at] = example.execution_result.finished_at.strftime('%Y-%m-%d %H:%M:%S.%L %z')
|
6
10
|
hash[:sdam_log_entries] = SdamFormatterIntegration.example_log_entries(example.id)
|
7
11
|
end
|
8
12
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module LiteConstraints
|
2
2
|
# Constrain tests that use TimeoutInterrupt to MRI (and Unix)
|
3
3
|
def only_mri
|
4
|
-
before do
|
4
|
+
before(:all) do
|
5
5
|
unless SpecConfig.instance.mri?
|
6
6
|
skip "MRI required, we have #{SpecConfig.instance.platform}"
|
7
7
|
end
|
@@ -12,22 +12,38 @@ module LiteConstraints
|
|
12
12
|
# in principle work (as opposed to being fundamentally incompatible
|
13
13
|
# with jruby).
|
14
14
|
# Often times these failures happen only in Evergreen.
|
15
|
-
def fails_on_jruby
|
16
|
-
before do
|
17
|
-
|
18
|
-
|
15
|
+
def fails_on_jruby(version=nil)
|
16
|
+
before(:all) do
|
17
|
+
if BSON::Environment.jruby?
|
18
|
+
if version
|
19
|
+
min_parts = version.split('.').map(&:to_i)
|
20
|
+
actual_parts = JRUBY_VERSION.split('.').map(&:to_i)[0...min_parts.length]
|
21
|
+
actual = actual_parts.join('.')
|
22
|
+
if actual <= version
|
23
|
+
skip "Fails on jruby through #{version}"
|
24
|
+
end
|
25
|
+
else
|
26
|
+
skip "Fails on jruby"
|
27
|
+
end
|
19
28
|
end
|
20
29
|
end
|
21
30
|
end
|
22
31
|
|
23
32
|
def require_external_connectivity
|
24
|
-
before do
|
33
|
+
before(:all) do
|
25
34
|
if ENV['EXTERNAL_DISABLED']
|
26
35
|
skip "Test requires external connectivity"
|
27
36
|
end
|
28
37
|
end
|
29
38
|
end
|
30
39
|
|
40
|
+
def require_mongo_kerberos
|
41
|
+
before(:all) do
|
42
|
+
skip 'KERBEROS_REQUIRED env var not specified' unless ENV['KERBEROS_REQUIRED']
|
43
|
+
require 'mongo_kerberos'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
31
47
|
def require_linting
|
32
48
|
before do
|
33
49
|
unless Mongo::Lint.enabled?
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
class LocalResourceRegistry
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@resources = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def register(resource, finalizer)
|
11
|
+
@resources << [resource, finalizer]
|
12
|
+
# Return resource for chaining
|
13
|
+
resource
|
14
|
+
end
|
15
|
+
|
16
|
+
def unregister(resource)
|
17
|
+
@resources.delete_if do |_resource, finalizer|
|
18
|
+
_resource == resource
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def close_all
|
23
|
+
@resources.each do |resource, finalizer|
|
24
|
+
if finalizer.is_a?(Symbol)
|
25
|
+
resource.send(finalizer)
|
26
|
+
elsif finalizer.is_a?(Proc)
|
27
|
+
finalizer.call(resource)
|
28
|
+
else
|
29
|
+
raise "Unknown finalizer: #{finalizer}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
@resources = []
|
33
|
+
end
|
34
|
+
end
|
@@ -13,8 +13,123 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
#
|
15
15
|
|
16
|
+
RSpec::Matchers.define :match_topology_opening_event do |expectation|
|
17
|
+
|
18
|
+
match do |event|
|
19
|
+
event.is_a?(Mongo::Monitoring::Event::TopologyOpening) &&
|
20
|
+
event.topology != nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
RSpec::Matchers.define :match_topology_description_changed_event do |expectation|
|
25
|
+
include Mongo::SDAMMonitoring::Matchable
|
26
|
+
|
27
|
+
match do |event|
|
28
|
+
event.is_a?(Mongo::Monitoring::Event::TopologyChanged) &&
|
29
|
+
topologies_match?(event, expectation)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
RSpec::Matchers.define :match_server_opening_event do |expectation|
|
34
|
+
|
35
|
+
match do |event|
|
36
|
+
event.is_a?(Mongo::Monitoring::Event::ServerOpening) &&
|
37
|
+
event.address.to_s == expectation.data['address']
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
RSpec::Matchers.define :match_server_description_changed_event do |expectation|
|
42
|
+
include Mongo::SDAMMonitoring::Matchable
|
43
|
+
|
44
|
+
match do |event|
|
45
|
+
event.is_a?(Mongo::Monitoring::Event::ServerDescriptionChanged) &&
|
46
|
+
descriptions_match?(event, expectation)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
RSpec::Matchers.define :match_server_closed_event do |expectation|
|
51
|
+
|
52
|
+
match do |event|
|
53
|
+
event.is_a?(Mongo::Monitoring::Event::ServerClosed) &&
|
54
|
+
event.address.to_s == expectation.data['address']
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
RSpec::Matchers.define :match_sdam_monitoring_event do |expectation|
|
59
|
+
|
60
|
+
match do |event|
|
61
|
+
expect(event).to send("match_#{expectation.name}", expectation)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
16
65
|
module Mongo
|
17
66
|
module SDAMMonitoring
|
67
|
+
module Matchable
|
68
|
+
|
69
|
+
def descriptions_match?(event, expectation)
|
70
|
+
description_matches?(event.previous_description, expectation.data['previousDescription']) &&
|
71
|
+
description_matches?(event.new_description, expectation.data['newDescription'])
|
72
|
+
end
|
73
|
+
|
74
|
+
def topologies_match?(event, expectation)
|
75
|
+
unless topology_matches?(event.previous_topology, expectation.data['previousDescription'])
|
76
|
+
if ENV['VERBOSE_MATCHERS']
|
77
|
+
$stderr.puts "Previous topology mismatch"
|
78
|
+
end
|
79
|
+
return false
|
80
|
+
end
|
81
|
+
unless topology_matches?(event.new_topology, expectation.data['newDescription'])
|
82
|
+
if ENV['VERBOSE_MATCHERS']
|
83
|
+
$stderr.puts "New topology mismatch:\nHave: #{event.new_topology}\nWant: #{expectation.data['newDescription']}"
|
84
|
+
end
|
85
|
+
return false
|
86
|
+
end
|
87
|
+
true
|
88
|
+
end
|
89
|
+
|
90
|
+
def description_matches?(actual, expected)
|
91
|
+
type_ok = case expected['type']
|
92
|
+
when 'Standalone' then actual.standalone?
|
93
|
+
when 'RSPrimary' then actual.primary?
|
94
|
+
when 'RSSecondary' then actual.secondary?
|
95
|
+
when 'RSArbiter' then actual.arbiter?
|
96
|
+
when 'Mongos' then actual.mongos?
|
97
|
+
when 'Unknown' then actual.unknown?
|
98
|
+
when 'PossiblePrimary' then actual.unknown?
|
99
|
+
when 'RSGhost' then actual.ghost?
|
100
|
+
when 'RSOther' then actual.other?
|
101
|
+
end
|
102
|
+
return false unless type_ok
|
103
|
+
|
104
|
+
return false if actual.address.to_s != expected['address']
|
105
|
+
return false if actual.arbiters != expected['arbiters']
|
106
|
+
return false if actual.hosts != expected['hosts']
|
107
|
+
return false if actual.passives != expected['passives']
|
108
|
+
return false if actual.primary_host != expected['primary']
|
109
|
+
return false if actual.replica_set_name != expected['setName']
|
110
|
+
true
|
111
|
+
end
|
112
|
+
|
113
|
+
def topology_matches?(actual, expected)
|
114
|
+
expected_type = ::Mongo::Cluster::Topology.const_get(expected['topologyType'])
|
115
|
+
return false unless actual.is_a?(expected_type)
|
116
|
+
|
117
|
+
return false unless actual.replica_set_name == expected['setName']
|
118
|
+
|
119
|
+
expected['servers'].each do |server|
|
120
|
+
desc = actual.server_descriptions[server['address'].to_s]
|
121
|
+
return false unless description_matches?(desc, server)
|
122
|
+
end
|
123
|
+
|
124
|
+
actual.server_descriptions.keys.each do |address_str|
|
125
|
+
unless expected['servers'].any? { |server| server['address'] == address_str }
|
126
|
+
return false
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
true
|
131
|
+
end
|
132
|
+
end
|
18
133
|
|
19
134
|
# Test subscriber for SDAM monitoring.
|
20
135
|
#
|