mongo 2.6.1 → 2.6.2

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +4 -1
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo/client.rb +27 -16
  5. data/lib/mongo/cluster/topology/replica_set.rb +15 -3
  6. data/lib/mongo/error/lint_error.rb +1 -1
  7. data/lib/mongo/server/description.rb +1 -1
  8. data/lib/mongo/version.rb +1 -1
  9. data/spec/{mongo → integration}/change_stream_examples_spec.rb +0 -0
  10. data/spec/{mongo → integration}/docs_examples_spec.rb +0 -0
  11. data/spec/integration/reconnect_spec.rb +31 -0
  12. data/spec/{mongo → integration}/retryable_writes_spec.rb +0 -0
  13. data/spec/{mongo → integration}/shell_examples_spec.rb +0 -0
  14. data/spec/{mongo → integration}/transactions_examples_spec.rb +46 -61
  15. data/spec/lite_spec_helper.rb +7 -2
  16. data/spec/mongo/address/unix_spec.rb +1 -1
  17. data/spec/mongo/address_spec.rb +10 -10
  18. data/spec/mongo/auth/scram/conversation_spec.rb +2 -1
  19. data/spec/mongo/auth/scram/negotiation_spec.rb +6 -5
  20. data/spec/mongo/auth/scram_spec.rb +5 -4
  21. data/spec/mongo/bulk_write_spec.rb +3 -2
  22. data/spec/mongo/client_spec.rb +15 -7
  23. data/spec/mongo/cluster/topology/replica_set_spec.rb +46 -10
  24. data/spec/mongo/cluster_spec.rb +3 -3
  25. data/spec/mongo/collection/view/aggregation_spec.rb +2 -1
  26. data/spec/mongo/collection/view/readable_spec.rb +2 -1
  27. data/spec/mongo/collection_spec.rb +40 -23
  28. data/spec/mongo/database_spec.rb +3 -3
  29. data/spec/mongo/index/view_spec.rb +4 -2
  30. data/spec/mongo/server/connection_pool_spec.rb +1 -1
  31. data/spec/mongo/socket/ssl_spec.rb +3 -3
  32. data/spec/mongo/socket/unix_spec.rb +1 -1
  33. data/spec/mongo/socket_spec.rb +2 -2
  34. data/spec/mongo/uri/srv_protocol_spec.rb +2 -1
  35. data/spec/mongo/uri_spec.rb +6 -5
  36. data/spec/spec_helper.rb +7 -28
  37. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +61 -63
  38. data/spec/spec_tests/sdam_monitoring_spec.rb +10 -7
  39. data/spec/{mongo → spec_tests}/transactions_spec.rb +8 -3
  40. data/spec/support/authorization.rb +10 -55
  41. data/spec/support/constraints.rb +34 -10
  42. data/spec/support/lite_constraints.rb +18 -0
  43. data/spec/support/sdam/rs/secondary_ignore_ok_0.yml +85 -0
  44. data/spec/support/spec_config.rb +73 -0
  45. data/spec/support/transactions.rb +1 -1
  46. metadata +170 -162
  47. metadata.gz.sig +1 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d8e500892649b1d8d1817ec229c1d56d97837e252452654af04e995d1416082a
4
- data.tar.gz: 5fa8c7ca6caa84c0c81ed9f8ab3cd6566f579fc10ac28f510628f2de790040c7
3
+ metadata.gz: d35926db93b848daeb9bccff3503f99f9940ef9a0b4d0f777e24af6569005177
4
+ data.tar.gz: 7a543a6f1b40d2962a8c8252053580aca43d60530b2f40d9deb907a73db47bd2
5
5
  SHA512:
6
- metadata.gz: 725de14593b44d0bf8b370f53a5e18a8f5d033efddd2e05096ec561b69f51b01b70394d3c8ebab1e89dbb7ecbb7784dbb161376d1194130ae6d016afd39344ae
7
- data.tar.gz: 989ee85302acac376637d777e1c83cff4e7fa5d932fc62d489b3192d0b7336875fe831a0742d9953892108d2cb86c5b825f84d73a1779c0149fef2ffbb04aa05
6
+ metadata.gz: f44e3256afabfb3ac96950e7342f3ee9533bb0e50494140bdd81bf809938c26a58b501960268ad3e906c27b939890a91313f654e941132e7299ea550f142a11b
7
+ data.tar.gz: 66bb2f4bc9c1851fc6e48d8f048aa45d19f49ae635a8a0c97f5298756166a4b3c410a18e4daa1e98cf0443da8735981ab35845297f5c53891160b0904f9fdc42
@@ -1 +1,4 @@
1
- ���Gg��r ���X%'wC�~arS��x����p�=mU)o�t��[�ȕ:��F"%*�?] ��L)^ *�m�#�H������`�r�L�ƵvS����+��ܨ㨡o�3�1�����D�@�#�VGR�����B�;�D��P>�[�.y��c��[�� 9�tJ����s�ǰ��J�:�(ҳ����@�
1
+ ���T�]�$M����'"{}���JT���c/�5�c@t橖!���W��k::�H&Za}ؤ�1����nK7�?�60�<?
2
+ %�����Ey;�ԫ��� ��:�1nФ
3
+ � &(U��k���c��;�� �����C0���TpUQ�Ul�]�)܂����:��0S��OǷM���k5�{�z����3l>�o�:3����mP,�^+RI%�
4
+ ��ۗ�:)Ɓ�%&H�I�L����cx�;U!cKd�����f
data.tar.gz.sig CHANGED
Binary file
@@ -258,15 +258,33 @@ module Mongo
258
258
  # See Ruby's Zlib module for valid levels.
259
259
  # @option options [ true, false ] :retry_writes Retry writes once when
260
260
  # connected to a replica set or sharded cluster versions 3.6 and up.
261
+ # @option options [ Proc ] :sdam_proc A Proc to invoke with the client
262
+ # as the argument prior to performing server discovery and monitoring.
263
+ # Use this to set up SDAM event listeners to receive events dispatched
264
+ # during client construction.
261
265
  #
262
266
  # @since 2.0.0
263
267
  def initialize(addresses_or_uri, options = Options::Redacted.new)
264
268
  Mongo::Lint.validate_underscore_read_preference(options[:read])
265
269
  if addresses_or_uri.is_a?(::String)
266
- create_from_uri(addresses_or_uri, validate_options!(options))
270
+ uri = URI.get(addresses_or_uri, options)
271
+ addresses = uri.servers
272
+ options = uri.client_options.merge(options)
267
273
  else
268
- create_from_addresses(addresses_or_uri, validate_options!(options))
274
+ addresses = addresses_or_uri
269
275
  end
276
+ options = options.dup
277
+ # Special handling for sdam_proc as it is only used during client
278
+ # construction
279
+ sdam_proc = options.delete(:sdam_proc)
280
+ @options = validate_options!(Database::DEFAULT_OPTIONS.merge(options)).freeze
281
+ @database = Database.new(self, @options[:database], @options)
282
+ monitoring = Monitoring.new(@options)
283
+ if sdam_proc
284
+ @cluster = Cluster.new([], monitoring, @options)
285
+ sdam_proc.call(self)
286
+ end
287
+ @cluster = Cluster.new(addresses, monitoring, @options)
270
288
  yield(self) if block_given?
271
289
  end
272
290
 
@@ -401,7 +419,13 @@ module Mongo
401
419
  #
402
420
  # @since 2.1.0
403
421
  def reconnect
404
- @cluster.reconnect! and true
422
+ addresses = cluster.addresses.map(&:to_s)
423
+ monitoring = cluster.monitoring
424
+
425
+ @cluster.disconnect! rescue nil
426
+
427
+ @cluster = Cluster.new(addresses, monitoring, options)
428
+ true
405
429
  end
406
430
 
407
431
  # Get the names of all databases.
@@ -526,19 +550,6 @@ module Mongo
526
550
  cluster.send(:with_session, self, options, &block)
527
551
  end
528
552
 
529
- def create_from_addresses(addresses, opts = Options::Redacted.new)
530
- @options = Database::DEFAULT_OPTIONS.merge(opts).freeze
531
- @cluster = Cluster.new(addresses, Monitoring.new(options), options)
532
- @database = Database.new(self, options[:database], options)
533
- end
534
-
535
- def create_from_uri(connection_string, opts = Options::Redacted.new)
536
- uri = URI.get(connection_string, opts)
537
- @options = validate_options!(Database::DEFAULT_OPTIONS.merge(uri.client_options.merge(opts))).freeze
538
- @cluster = Cluster.new(uri.servers, @cluster ? monitoring : Monitoring.new(options), options)
539
- @database = Database.new(self, options[:database], options)
540
- end
541
-
542
553
  def initialize_copy(original)
543
554
  @options = original.options.dup
544
555
  @monitoring = @cluster ? monitoring : Monitoring.new(options)
@@ -213,6 +213,12 @@ module Mongo
213
213
  end
214
214
 
215
215
  # Whether a specific server in the cluster can be removed, given a description.
216
+ # As described in the SDAM spec, a server should be removed if the server's
217
+ # address does not match the "me" field of the isMaster response, if the server
218
+ # has a different replica set name, or if an isMaster response from the primary
219
+ # does not contain the server's address in the list of known hosts. Note that as
220
+ # described by the spec, a server determined to be of type Unknown from its
221
+ # isMaster response is NOT removed from the topology.
216
222
  #
217
223
  # @example Check if a specific server can be removed from the cluster.
218
224
  # topology.remove_server?(description, server)
@@ -224,8 +230,10 @@ module Mongo
224
230
  #
225
231
  # @since 2.0.6
226
232
  def remove_server?(description, server)
233
+ ((server.address == description.address) && description.me_mismatch?) ||
227
234
  remove_self?(description, server) ||
228
235
  (member_of_this_set?(description) &&
236
+ description.server_type == :primary &&
229
237
  !description.servers.empty? &&
230
238
  !description.lists_server?(server))
231
239
  end
@@ -316,10 +324,14 @@ module Mongo
316
324
  description.replica_set_name == replica_set_name
317
325
  end
318
326
 
327
+ # As described by the SDAM spec, a server should be removed from the
328
+ # topology upon receiving its isMaster response if no error occurred
329
+ # and replica set name does not match that of the topology.
319
330
  def remove_self?(description, server)
320
- !member_of_this_set?(description) &&
321
- description.is_server?(server) &&
322
- !description.ghost?
331
+ !description.unknown? &&
332
+ !member_of_this_set?(description) &&
333
+ description.is_server?(server) &&
334
+ !description.ghost?
323
335
  end
324
336
  end
325
337
  end
@@ -28,7 +28,7 @@ module Mongo
28
28
  # to the server, to flag failures sooner. This exception is raised on
29
29
  # such failures.
30
30
  #
31
- # @since 2.7.0
31
+ # @since 2.6.1
32
32
  class LintError < Error
33
33
  end
34
34
  end
@@ -640,7 +640,7 @@ module Mongo
640
640
  #
641
641
  # @since 2.0.6
642
642
  def me_mismatch?
643
- !!(address.to_s != me if me)
643
+ !!(address.to_s.downcase != me.downcase if me)
644
644
  end
645
645
 
646
646
  # Check equality of two descriptions.
@@ -17,5 +17,5 @@ module Mongo
17
17
  # The current version of the driver.
18
18
  #
19
19
  # @since 2.0.0
20
- VERSION = '2.6.1'.freeze
20
+ VERSION = '2.6.2'.freeze
21
21
  end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Client after reconnect' do
4
+ let(:client) { authorized_client }
5
+
6
+ it 'works' do
7
+ client['test'].insert_one('testk' => 'testv')
8
+
9
+ client.reconnect
10
+
11
+ doc = client['test'].find('testk' => 'testv').first
12
+ expect(doc).not_to be_nil
13
+ expect(doc['testk']).to eq('testv')
14
+ end
15
+
16
+ it 'recreates monitor thread' do
17
+ thread = client.cluster.servers.first.monitor.instance_variable_get('@thread')
18
+ expect(thread).to be_alive
19
+
20
+ thread.kill
21
+ # context switch to let the thread get killed
22
+ sleep 0.1
23
+ expect(thread).not_to be_alive
24
+
25
+ client.reconnect
26
+
27
+ new_thread = client.cluster.servers.first.monitor.instance_variable_get('@thread')
28
+ expect(new_thread).not_to eq(thread)
29
+ expect(new_thread).to be_alive
30
+ end
31
+ end
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'transactions examples in Ruby', if: test_transactions? do
3
+ describe 'Transactions examples' do
4
+ require_transaction_support
4
5
 
5
6
  let(:hr) do
6
7
  authorized_client.use(:hr).database
@@ -39,19 +40,16 @@ describe 'transactions examples in Ruby', if: test_transactions? do
39
40
  events_coll.insert_one({ employee: 3, status: { new: 'Inactive', old: 'Active' } },
40
41
  session: session)
41
42
 
42
- loop do
43
- begin
44
- session.commit_transaction
45
- puts 'Transaction committed.'
46
- break
47
- rescue Mongo::Error => e
48
- if e.label?(Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)
49
- puts "#{Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL}, retrying commit operation..."
50
- next
51
- else
52
- puts 'Error during commit ...'
53
- raise
54
- end
43
+ begin
44
+ session.commit_transaction
45
+ puts 'Transaction committed.'
46
+ rescue Mongo::Error => e
47
+ if e.label?(Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)
48
+ puts "#{Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL}, retrying commit operation..."
49
+ retry
50
+ else
51
+ puts 'Error during commit ...'
52
+ raise
55
53
  end
56
54
  end
57
55
  end
@@ -77,18 +75,15 @@ describe 'transactions examples in Ruby', if: test_transactions? do
77
75
  # Start Transactions Retry Example 1
78
76
 
79
77
  def run_transaction_with_retry(session)
80
- loop do
81
- begin
82
- yield session # performs transaction
83
- break
84
- rescue Mongo::Error => e
78
+ begin
79
+ yield session # performs transaction
80
+ rescue Mongo::Error => e
85
81
 
86
- puts 'Transaction aborted. Caught exception during transaction.'
87
- raise unless e.label?(Mongo::Error::TRANSIENT_TRANSACTION_ERROR_LABEL)
82
+ puts 'Transaction aborted. Caught exception during transaction.'
83
+ raise unless e.label?(Mongo::Error::TRANSIENT_TRANSACTION_ERROR_LABEL)
88
84
 
89
- puts "#{Mongo::Error::TRANSIENT_TRANSACTION_ERROR_LABEL}, retrying transaction ..."
90
- next
91
- end
85
+ puts "#{Mongo::Error::TRANSIENT_TRANSACTION_ERROR_LABEL}, retrying transaction ..."
86
+ retry
92
87
  end
93
88
  end
94
89
 
@@ -111,19 +106,16 @@ describe 'transactions examples in Ruby', if: test_transactions? do
111
106
  # Start Transactions Retry Example 2
112
107
 
113
108
  def commit_with_retry(session)
114
- loop do
115
- begin
116
- session.commit_transaction
117
- puts 'Transaction committed.'
118
- break
119
- rescue Mongo::Error=> e
120
- if e.label?(Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)
121
- puts "#{Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL}, retrying commit operation..."
122
- next
123
- else
124
- puts 'Error during commit ...'
125
- raise
126
- end
109
+ begin
110
+ session.commit_transaction
111
+ puts 'Transaction committed.'
112
+ rescue Mongo::Error=> e
113
+ if e.label?(Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)
114
+ puts "#{Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL}, retrying commit operation..."
115
+ retry
116
+ else
117
+ puts 'Error during commit ...'
118
+ raise
127
119
  end
128
120
  end
129
121
  end
@@ -158,34 +150,27 @@ describe 'transactions examples in Ruby', if: test_transactions? do
158
150
  # Start Transactions Retry Example 3
159
151
 
160
152
  def run_transaction_with_retry(session)
161
- loop do
162
- begin
163
- yield session # performs transaction
164
- break
165
- rescue Mongo::Error=> e
166
- puts 'Transaction aborted. Caught exception during transaction.'
167
- raise unless e.label?(Mongo::Error::TRANSIENT_TRANSACTION_ERROR_LABEL)
168
-
169
- puts "#{Mongo::Error::TRANSIENT_TRANSACTION_ERROR_LABEL}, retrying transaction ..."
170
- next
171
- end
153
+ begin
154
+ yield session # performs transaction
155
+ rescue Mongo::Error => e
156
+ puts 'Transaction aborted. Caught exception during transaction.'
157
+ raise unless e.label?(Mongo::Error::TRANSIENT_TRANSACTION_ERROR_LABEL)
158
+ puts "#{Mongo::Error::TRANSIENT_TRANSACTION_ERROR_LABEL}, retrying transaction ..."
159
+ retry
172
160
  end
173
161
  end
174
162
 
175
163
  def commit_with_retry(session)
176
- loop do
177
- begin
178
- session.commit_transaction
179
- puts 'Transaction committed.'
180
- break
181
- rescue Mongo::Error => e
182
- if e.label?(Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)
183
- puts "#{Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL}, retrying commit operation ..."
184
- next
185
- else
186
- puts 'Error during commit ...'
187
- raise
188
- end
164
+ begin
165
+ session.commit_transaction
166
+ puts 'Transaction committed.'
167
+ rescue Mongo::Error => e
168
+ if e.label?(Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)
169
+ puts "#{Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL}, retrying commit operation ..."
170
+ retry
171
+ else
172
+ puts 'Error during commit ...'
173
+ raise
189
174
  end
190
175
  end
191
176
  end
@@ -37,13 +37,16 @@ begin
37
37
  rescue LoadError
38
38
  end
39
39
 
40
+ require 'support/spec_config'
41
+
40
42
  Mongo::Logger.logger = Logger.new($stdout)
41
- unless %w(1 true yes).include?((ENV['CLIENT_DEBUG'] || '').downcase)
43
+ unless SpecConfig.instance.client_debug?
42
44
  Mongo::Logger.logger.level = Logger::INFO
43
45
  end
44
46
  Encoding.default_external = Encoding::UTF_8
45
47
 
46
48
  require 'support/matchers'
49
+ require 'support/lite_constraints'
47
50
  require 'support/event_subscriber'
48
51
  require 'support/server_discovery_and_monitoring'
49
52
  require 'support/server_selection_rtt'
@@ -57,7 +60,9 @@ require 'support/transactions'
57
60
  require 'support/change_streams'
58
61
 
59
62
  RSpec.configure do |config|
60
- if ENV['CI'] && RUBY_PLATFORM =~ /\bjava\b/
63
+ if ENV['CI'] && SpecConfig.instance.jruby?
61
64
  config.formatter = 'documentation'
62
65
  end
66
+
67
+ config.extend(LiteConstraints)
63
68
  end
@@ -27,7 +27,7 @@ describe Mongo::Address::Unix do
27
27
  describe '#socket' do
28
28
 
29
29
  let(:address) do
30
- '/tmp/mongodb-27017.sock'
30
+ "/tmp/mongodb-#{SpecConfig.instance.any_port}.sock"
31
31
  end
32
32
 
33
33
  let(:socket) do
@@ -242,7 +242,7 @@ describe Mongo::Address do
242
242
 
243
243
  before do
244
244
  address.instance_variable_set(:@resolver, nil)
245
- address.send(:initialize_resolver!, (SSL ? SSL_OPTIONS : {}))
245
+ address.send(:initialize_resolver!, (SpecConfig.instance.ssl? ? SSL_OPTIONS : {}))
246
246
  end
247
247
 
248
248
  it 'uses the host, not the IP address' do
@@ -250,7 +250,7 @@ describe Mongo::Address do
250
250
  end
251
251
 
252
252
  let(:socket) do
253
- if running_ssl?
253
+ if SpecConfig.instance.ssl?
254
254
  address.socket(0.0, SSL_OPTIONS).instance_variable_get(:@tcp_socket)
255
255
  else
256
256
  address.socket(0.0).instance_variable_get(:@socket)
@@ -276,35 +276,35 @@ describe Mongo::Address do
276
276
  end
277
277
  end
278
278
  end
279
-
279
+
280
280
  describe '#to_s' do
281
281
  context 'address with ipv4 host only' do
282
282
  let(:address) { Mongo::Address.new('127.0.0.1') }
283
-
283
+
284
284
  it 'is host with port' do
285
285
  expect(address.to_s).to eql('127.0.0.1:27017')
286
286
  end
287
287
  end
288
-
288
+
289
289
  context 'address with ipv4 host and port' do
290
290
  let(:address) { Mongo::Address.new('127.0.0.1:27000') }
291
-
291
+
292
292
  it 'is host with port' do
293
293
  expect(address.to_s).to eql('127.0.0.1:27000')
294
294
  end
295
295
  end
296
-
296
+
297
297
  context 'address with ipv6 host only' do
298
298
  let(:address) { Mongo::Address.new('::1') }
299
-
299
+
300
300
  it 'is host with port' do
301
301
  expect(address.to_s).to eql('[::1]:27017')
302
302
  end
303
303
  end
304
-
304
+
305
305
  context 'address with ipv6 host and port' do
306
306
  let(:address) { Mongo::Address.new('[::1]:27000') }
307
-
307
+
308
308
  it 'is host with port' do
309
309
  expect(address.to_s).to eql('[::1]:27000')
310
310
  end
@@ -204,7 +204,8 @@ describe Mongo::Auth::SCRAM::Conversation do
204
204
  end
205
205
  end
206
206
 
207
- context 'when SCRAM-SHA-256 is used', if: scram_sha_256_enabled? do
207
+ context 'when SCRAM-SHA-256 is used' do
208
+ require_scram_sha_256_support
208
209
 
209
210
  let(:user) do
210
211
  Mongo::Auth::User.new(