mongo 2.6.1 → 2.6.2

Sign up to get free protection for your applications and to get access to all the features.
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(