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
@@ -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
|
#
|