mongo 2.5.0 → 2.5.1

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 (99) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +2 -0
  5. data/Rakefile +4 -1
  6. data/lib/mongo/address.rb +2 -1
  7. data/lib/mongo/client.rb +6 -51
  8. data/lib/mongo/cluster.rb +34 -4
  9. data/lib/mongo/cluster/reapers/socket_reaper.rb +1 -1
  10. data/lib/mongo/cluster/topology/replica_set.rb +3 -1
  11. data/lib/mongo/collection.rb +6 -6
  12. data/lib/mongo/collection/view.rb +2 -4
  13. data/lib/mongo/cursor.rb +9 -4
  14. data/lib/mongo/error.rb +2 -0
  15. data/lib/mongo/operation/uses_command_op_msg.rb +1 -1
  16. data/lib/mongo/server.rb +3 -0
  17. data/lib/mongo/server/description.rb +1 -1
  18. data/lib/mongo/server/description/features.rb +18 -12
  19. data/lib/mongo/server_selector/selectable.rb +5 -1
  20. data/lib/mongo/session.rb +38 -43
  21. data/lib/mongo/session/session_pool.rb +12 -30
  22. data/lib/mongo/socket.rb +24 -0
  23. data/lib/mongo/socket/tcp.rb +0 -1
  24. data/lib/mongo/uri.rb +26 -5
  25. data/lib/mongo/version.rb +1 -1
  26. data/spec/mongo/address_spec.rb +37 -2
  27. data/spec/mongo/bulk_write_spec.rb +4 -10
  28. data/spec/mongo/change_stream_examples_spec.rb +40 -0
  29. data/spec/mongo/client_spec.rb +47 -12
  30. data/spec/mongo/cluster/topology/replica_set_spec.rb +2 -0
  31. data/spec/mongo/collection/view/aggregation_spec.rb +2 -8
  32. data/spec/mongo/collection/view/change_stream_spec.rb +1 -5
  33. data/spec/mongo/collection/view/map_reduce_spec.rb +2 -8
  34. data/spec/mongo/collection/view/readable_spec.rb +1 -1
  35. data/spec/mongo/collection_spec.rb +11 -29
  36. data/spec/mongo/crud_spec.rb +6 -2
  37. data/spec/mongo/cursor_spec.rb +84 -1
  38. data/spec/mongo/database_spec.rb +2 -8
  39. data/spec/mongo/dns_seedlist_discovery_spec.rb +67 -63
  40. data/spec/mongo/max_staleness_spec.rb +1 -0
  41. data/spec/mongo/retryable_writes_spec.rb +7 -9
  42. data/spec/mongo/sdam_spec.rb +42 -24
  43. data/spec/mongo/server/description/features_spec.rb +3 -3
  44. data/spec/mongo/server_selection_spec.rb +2 -0
  45. data/spec/mongo/server_selector_spec.rb +2 -0
  46. data/spec/mongo/session/session_pool_spec.rb +16 -22
  47. data/spec/mongo/session_spec.rb +13 -8
  48. data/spec/mongo/uri/srv_protocol_spec.rb +481 -478
  49. data/spec/mongo/uri_spec.rb +1 -1
  50. data/spec/spec_helper.rb +11 -63
  51. data/spec/support/authorization.rb +35 -1
  52. data/spec/support/connection_string_tests/invalid-uris.yml +27 -11
  53. data/spec/support/event_subscriber.rb +66 -0
  54. data/spec/support/sdam/rs/compatible.yml +41 -0
  55. data/spec/support/sdam/rs/discover_arbiters.yml +3 -1
  56. data/spec/support/sdam/rs/discover_passives.yml +6 -2
  57. data/spec/support/sdam/rs/discover_primary.yml +3 -1
  58. data/spec/support/sdam/rs/discover_secondary.yml +3 -1
  59. data/spec/support/sdam/rs/discovery.yml +12 -4
  60. data/spec/support/sdam/rs/equal_electionids.yml +6 -2
  61. data/spec/support/sdam/rs/ghost_discovered.yml +3 -1
  62. data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +3 -1
  63. data/spec/support/sdam/rs/ls_timeout.yml +169 -14
  64. data/spec/support/sdam/rs/member_reconfig.yml +6 -2
  65. data/spec/support/sdam/rs/member_standalone.yml +6 -2
  66. data/spec/support/sdam/rs/new_primary.yml +6 -2
  67. data/spec/support/sdam/rs/new_primary_new_electionid.yml +9 -3
  68. data/spec/support/sdam/rs/new_primary_new_setversion.yml +9 -3
  69. data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +6 -2
  70. data/spec/support/sdam/rs/non_rs_member.yml +3 -2
  71. data/spec/support/sdam/rs/normalize_case.yml +3 -1
  72. data/spec/support/sdam/rs/null_election_id.yml +12 -4
  73. data/spec/support/sdam/rs/primary_becomes_standalone.yml +6 -4
  74. data/spec/support/sdam/rs/primary_changes_set_name.yml +6 -2
  75. data/spec/support/sdam/rs/primary_disconnect.yml +3 -1
  76. data/spec/support/sdam/rs/primary_disconnect_electionid.yml +15 -5
  77. data/spec/support/sdam/rs/primary_disconnect_setversion.yml +15 -5
  78. data/spec/support/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +6 -2
  79. data/spec/support/sdam/rs/primary_mismatched_me.yml +26 -37
  80. data/spec/support/sdam/rs/primary_reports_new_member.yml +12 -4
  81. data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +6 -2
  82. data/spec/support/sdam/rs/primary_wrong_set_name.yml +3 -1
  83. data/spec/support/sdam/rs/response_from_removed.yml +6 -2
  84. data/spec/support/sdam/rs/rsother_discovered.yml +6 -2
  85. data/spec/support/sdam/rs/sec_not_auth.yml +6 -2
  86. data/spec/support/sdam/rs/secondary_mismatched_me.yml +26 -37
  87. data/spec/support/sdam/rs/secondary_wrong_set_name.yml +3 -1
  88. data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +6 -2
  89. data/spec/support/sdam/rs/setversion_without_electionid.yml +6 -2
  90. data/spec/support/sdam/rs/stepdown_change_set_name.yml +6 -2
  91. data/spec/support/sdam/rs/too_new.yml +41 -0
  92. data/spec/support/sdam/rs/too_old.yml +39 -0
  93. data/spec/support/sdam/rs/unexpected_mongos.yml +3 -1
  94. data/spec/support/sdam/rs/use_setversion_without_electionid.yml +9 -3
  95. data/spec/support/sdam/rs/wrong_set_name.yml +3 -1
  96. data/spec/support/server_discovery_and_monitoring.rb +13 -0
  97. data/spec/support/shared/session.rb +10 -30
  98. metadata +10 -2
  99. metadata.gz.sig +0 -0
@@ -17,7 +17,7 @@ describe Mongo::URI do
17
17
  end
18
18
  end
19
19
 
20
- context 'when the scheme is mongodb+srv://' do
20
+ context 'when the scheme is mongodb+srv://', if: test_connecting_externally? do
21
21
 
22
22
  let(:string) do
23
23
  'mongodb+srv://test5.test.build.10gen.cc'
@@ -38,6 +38,7 @@ Encoding.default_external = Encoding::UTF_8
38
38
 
39
39
  require 'support/travis'
40
40
  require 'support/matchers'
41
+ require 'support/event_subscriber'
41
42
  require 'support/authorization'
42
43
  require 'support/server_discovery_and_monitoring'
43
44
  require 'support/server_selection_rtt'
@@ -50,7 +51,7 @@ require 'support/gridfs'
50
51
 
51
52
  RSpec.configure do |config|
52
53
  config.color = true
53
- config.fail_fast = true unless ENV['CI'] || ENV['JENKINS_HOME']
54
+ config.fail_fast = true unless ENV['CI']
54
55
  config.formatter = 'documentation'
55
56
  config.include(Authorization)
56
57
 
@@ -193,11 +194,18 @@ def list_command_enabled?
193
194
  $list_command_enabled ||= $mongo_client.cluster.servers.first.features.list_indexes_enabled?
194
195
  end
195
196
 
196
- # Is the test suite running locally (not on Travis or Jenkins).
197
+ # Is the test suite running locally (not on Travis).
197
198
  #
198
199
  # @since 2.1.0
199
200
  def testing_ssl_locally?
200
- running_ssl? && !(ENV['CI'] || ENV['JENKINS_CI'])
201
+ running_ssl? && !(ENV['CI'])
202
+ end
203
+
204
+ # Should tests relying on external connections be run.
205
+ #
206
+ # @since 2.5.1
207
+ def test_connecting_externally?
208
+ !ENV['CI'] && !ENV['EXTERNAL_DISABLED']
201
209
  end
202
210
 
203
211
  # Is the test suite running on SSL.
@@ -247,65 +255,5 @@ def initialize_scanned_client!
247
255
  Mongo::Client.new(ADDRESSES, TEST_OPTIONS.merge(database: TEST_DB))
248
256
  end
249
257
 
250
- # Test event subscriber.
251
- #
252
- # @since 2.5.0
253
- class EventSubscriber
254
-
255
- # The started events.
256
- #
257
- # @since 2.5.0
258
- attr_reader :started_events
259
-
260
- # The succeeded events.
261
- #
262
- # @since 2.5.0
263
- attr_reader :succeeded_events
264
-
265
- # The failed events.
266
- #
267
- # @since 2.5.0
268
- attr_reader :failed_events
269
-
270
- # Create the test event subscriber.
271
- #
272
- # @example Create the subscriber
273
- # EventSubscriber.new
274
- #
275
- # @since 2.5.0
276
- def initialize
277
- @started_events = []
278
- @succeeded_events = []
279
- @failed_events = []
280
- end
281
-
282
- # Cache the succeeded event.
283
- #
284
- # @param [ Event ] event The event.
285
- #
286
- # @since 2.5.0
287
- def succeeded(event)
288
- @succeeded_events.push(event)
289
- end
290
-
291
- # Cache the started event.
292
- #
293
- # @param [ Event ] event The event.
294
- #
295
- # @since 2.5.0
296
- def started(event)
297
- @started_events.push(event)
298
- end
299
-
300
- # Cache the failed event.
301
- #
302
- # @param [ Event ] event The event.
303
- #
304
- # @since 2.5.0
305
- def failed(event)
306
- @failed_events.push(event)
307
- end
308
- end
309
-
310
258
  # require all shared examples
311
259
  Dir['./spec/support/shared/*.rb'].sort.each { |file| require file }
@@ -36,7 +36,7 @@ if ENV['MONGODB_URI']
36
36
  ADDRESSES = MONGODB_URI.servers
37
37
  CONNECT = { connect: :direct }
38
38
  end
39
- else # For Jenkins
39
+ else
40
40
  ADDRESSES = ENV['MONGODB_ADDRESSES'] ? ENV['MONGODB_ADDRESSES'].split(',').freeze : [ '127.0.0.1:27017' ].freeze
41
41
  if ENV['RS_ENABLED']
42
42
  CONNECT = { connect: :replica_set, replica_set: ENV['RS_NAME'] }
@@ -166,6 +166,11 @@ AUTHORIZED_CLIENT = Mongo::Client.new(
166
166
  password: TEST_USER.password)
167
167
  )
168
168
 
169
+ # Provides an authorized mongo client that retries writes.
170
+ #
171
+ # @since 2.5.1
172
+ AUTHROIZED_CLIENT_WITH_RETRY_WRITES = AUTHORIZED_CLIENT.with(retry_writes: true)
173
+
169
174
  # Provides an unauthorized mongo client on the default test database.
170
175
  #
171
176
  # @since 2.0.0
@@ -195,6 +200,19 @@ ADMIN_AUTHORIZED_TEST_CLIENT = ADMIN_UNAUTHORIZED_CLIENT.with(
195
200
  monitoring: false
196
201
  )
197
202
 
203
+ # A client that has an event subscriber for commands.
204
+ #
205
+ # @since 2.5.1
206
+ SUBSCRIBED_CLIENT = Mongo::Client.new(
207
+ ADDRESSES,
208
+ TEST_OPTIONS.merge(
209
+ database: TEST_DB,
210
+ user: TEST_USER.name,
211
+ password: TEST_USER.password)
212
+ )
213
+ SUBSCRIBED_CLIENT.subscribe(Mongo::Monitoring::COMMAND, EventSubscriber)
214
+ AUTHROIZED_CLIENT_WITH_RETRY_WRITES.subscribe(Mongo::Monitoring::COMMAND, EventSubscriber)
215
+
198
216
  module Authorization
199
217
 
200
218
  # On inclusion provides helpers for use with testing with and without
@@ -220,6 +238,22 @@ module Authorization
220
238
  # @since 2.0.0
221
239
  context.let(:authorized_client) { AUTHORIZED_CLIENT }
222
240
 
241
+ # Provides an authorized mongo client on the default test database that retries writes.
242
+ #
243
+ # @since 2.5.1
244
+ context.let(:authorized_client_with_retry_writes) do
245
+ EventSubscriber.clear_events!
246
+ AUTHROIZED_CLIENT_WITH_RETRY_WRITES
247
+ end
248
+
249
+ # Provides an authorized mongo client that has a Command subscriber.
250
+ #
251
+ # @since 2.5.1
252
+ context.let(:subscribed_client) do
253
+ EventSubscriber.clear_events!
254
+ SUBSCRIBED_CLIENT
255
+ end
256
+
223
257
  # Provides an unauthorized mongo client on the default test database.
224
258
  #
225
259
  # @since 2.0.0
@@ -167,14 +167,6 @@ tests:
167
167
  hosts: ~
168
168
  auth: ~
169
169
  options: ~
170
- -
171
- description: "Username with password containing an unescaped colon"
172
- uri: "mongodb://alice:foo:bar@127.0.0.1"
173
- valid: false
174
- warning: ~
175
- hosts: ~
176
- auth: ~
177
- options: ~
178
170
  -
179
171
  description: "Username containing an unescaped at-sign"
180
172
  uri: "mongodb://alice@@127.0.0.1"
@@ -193,7 +185,7 @@ tests:
193
185
  options: ~
194
186
  -
195
187
  description: "Username containing an unescaped slash"
196
- uri: "mongodb://alice/@127.0.0.1/db"
188
+ uri: "mongodb://alice/@localhost/db"
197
189
  valid: false
198
190
  warning: ~
199
191
  hosts: ~
@@ -201,7 +193,7 @@ tests:
201
193
  options: ~
202
194
  -
203
195
  description: "Username containing unescaped slash with password"
204
- uri: "mongodb://alice/bob:foo@127.0.0.1/db"
196
+ uri: "mongodb://alice/bob:foo@localhost/db"
205
197
  valid: false
206
198
  warning: ~
207
199
  hosts: ~
@@ -209,7 +201,7 @@ tests:
209
201
  options: ~
210
202
  -
211
203
  description: "Username with password containing an unescaped slash"
212
- uri: "mongodb://alice:foo/bar@127.0.0.1/db"
204
+ uri: "mongodb://alice:foo/bar@localhost/db"
213
205
  valid: false
214
206
  warning: ~
215
207
  hosts: ~
@@ -223,3 +215,27 @@ tests:
223
215
  hosts: ~
224
216
  auth: ~
225
217
  options: ~
218
+ -
219
+ description: "mongodb+srv with multiple service names"
220
+ uri: "mongodb+srv://test5.test.mongodb.com,test6.test.mongodb.com"
221
+ valid: false
222
+ warning: ~
223
+ hosts: ~
224
+ auth: ~
225
+ options: ~
226
+ -
227
+ description: "mongodb+srv with port number"
228
+ uri: "mongodb+srv://test7.test.mongodb.com:27018"
229
+ valid: false
230
+ warning: ~
231
+ hosts: ~
232
+ auth: ~
233
+ options: ~
234
+ -
235
+ description: "Username with password containing an unescaped percent sign"
236
+ uri: "mongodb://alice%foo:bar@127.0.0.1"
237
+ valid: false
238
+ warning: ~
239
+ hosts: ~
240
+ auth: ~
241
+ options: ~
@@ -0,0 +1,66 @@
1
+ # Test event subscriber.
2
+ #
3
+ # @since 2.5.0
4
+ class EventSubscriber
5
+
6
+ class << self
7
+
8
+ # The started events.
9
+ #
10
+ # @since 2.5.0
11
+ def started_events
12
+ @started_events ||= []
13
+ end
14
+
15
+ # The succeeded events.
16
+ #
17
+ # @since 2.5.0
18
+ def succeeded_events
19
+ @succeeded_events ||= []
20
+ end
21
+
22
+ # The failed events.
23
+ #
24
+ # @since 2.5.0
25
+ def failed_events
26
+ @failed_events ||= []
27
+ end
28
+
29
+ # Cache the succeeded event.
30
+ #
31
+ # @param [ Event ] event The event.
32
+ #
33
+ # @since 2.5.0
34
+ def succeeded(event)
35
+ succeeded_events.push(event)
36
+ end
37
+
38
+ # Cache the started event.
39
+ #
40
+ # @param [ Event ] event The event.
41
+ #
42
+ # @since 2.5.0
43
+ def started(event)
44
+ started_events.push(event)
45
+ end
46
+
47
+ # Cache the failed event.
48
+ #
49
+ # @param [ Event ] event The event.
50
+ #
51
+ # @since 2.5.0
52
+ def failed(event)
53
+ failed_events.push(event)
54
+ end
55
+
56
+ # Clear all cached events.
57
+ #
58
+ # @since 2.5.1
59
+ def clear_events!
60
+ @started_events = []
61
+ @succeeded_events = []
62
+ @failed_events = []
63
+ self
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,41 @@
1
+ description: "Replica set member with large maxWireVersion"
2
+ uri: "mongodb://a,b/?replicaSet=rs"
3
+ phases: [
4
+ {
5
+ responses: [
6
+ ["a:27017", {
7
+ ok: 1,
8
+ ismaster: true,
9
+ setName: "rs",
10
+ hosts: ["a:27017", "b:27017"],
11
+ minWireVersion: 0,
12
+ maxWireVersion: 6
13
+ }],
14
+ ["b:27017", {
15
+ ok: 1,
16
+ ismaster: false,
17
+ secondary: true,
18
+ setName: "rs",
19
+ hosts: ["a:27017", "b:27017"],
20
+ minWireVersion: 0,
21
+ maxWireVersion: 1000
22
+ }]
23
+ ],
24
+ outcome: {
25
+ servers: {
26
+ "a:27017": {
27
+ type: "RSPrimary",
28
+ setName: "rs"
29
+ },
30
+ "b:27017": {
31
+ type: "RSSecondary",
32
+ setName: "rs"
33
+ }
34
+ },
35
+ topologyType: "ReplicaSetWithPrimary",
36
+ setName: "rs",
37
+ logicalSessionTimeoutMinutes: null,
38
+ compatible: true
39
+ }
40
+ }
41
+ ]
@@ -13,7 +13,9 @@ phases: [
13
13
  ismaster: true,
14
14
  hosts: ["a:27017"],
15
15
  arbiters: ["b:27017"],
16
- setName: "rs"
16
+ setName: "rs",
17
+ minWireVersion: 0,
18
+ maxWireVersion: 6
17
19
  }]
18
20
  ],
19
21
 
@@ -13,7 +13,9 @@ phases: [
13
13
  ismaster: true,
14
14
  hosts: ["a:27017"],
15
15
  passives: ["b:27017"],
16
- setName: "rs"
16
+ setName: "rs",
17
+ minWireVersion: 0,
18
+ maxWireVersion: 6
17
19
  }]
18
20
  ],
19
21
 
@@ -49,7 +51,9 @@ phases: [
49
51
  passive: true,
50
52
  hosts: ["a:27017"],
51
53
  passives: ["b:27017"],
52
- setName: "rs"
54
+ setName: "rs",
55
+ minWireVersion: 0,
56
+ maxWireVersion: 6
53
57
  }]
54
58
  ],
55
59
 
@@ -12,7 +12,9 @@ phases: [
12
12
  ok: 1,
13
13
  ismaster: true,
14
14
  setName: "rs",
15
- hosts: ["a:27017", "b:27017"]
15
+ hosts: ["a:27017", "b:27017"],
16
+ minWireVersion: 0,
17
+ maxWireVersion: 6
16
18
  }]
17
19
  ],
18
20
 
@@ -13,7 +13,9 @@ phases: [
13
13
  ismaster: false,
14
14
  secondary: true,
15
15
  setName: "rs",
16
- hosts: ["a:27017", "b:27017"]
16
+ hosts: ["a:27017", "b:27017"],
17
+ minWireVersion: 0,
18
+ maxWireVersion: 6
17
19
  }]
18
20
  ],
19
21
 
@@ -14,7 +14,9 @@ phases: [
14
14
  ismaster: false,
15
15
  secondary: true,
16
16
  setName: "rs",
17
- hosts: ["a:27017", "b:27017", "c:27017"]
17
+ hosts: ["a:27017", "b:27017", "c:27017"],
18
+ minWireVersion: 0,
19
+ maxWireVersion: 6
18
20
  }]
19
21
  ],
20
22
 
@@ -57,7 +59,9 @@ phases: [
57
59
  secondary: true,
58
60
  setName: "rs",
59
61
  primary: "d:27017",
60
- hosts: ["b:27017", "c:27017", "d:27017"]
62
+ hosts: ["b:27017", "c:27017", "d:27017"],
63
+ minWireVersion: 0,
64
+ maxWireVersion: 6
61
65
  }]
62
66
  ],
63
67
 
@@ -104,7 +108,9 @@ phases: [
104
108
  ok: 1,
105
109
  ismaster: true,
106
110
  setName: "rs",
107
- hosts: ["b:27017", "c:27017", "d:27017", "e:27017"]
111
+ hosts: ["b:27017", "c:27017", "d:27017", "e:27017"],
112
+ minWireVersion: 0,
113
+ maxWireVersion: 6
108
114
  }]
109
115
  ],
110
116
 
@@ -153,7 +159,9 @@ phases: [
153
159
  ismaster: false,
154
160
  secondary: true,
155
161
  setName: "rs",
156
- hosts: ["a:27017", "b:27017", "c:27017"]
162
+ hosts: ["a:27017", "b:27017", "c:27017"],
163
+ minWireVersion: 0,
164
+ maxWireVersion: 6
157
165
  }]
158
166
  ],
159
167