mongo 2.14.0.rc1 → 2.14.0

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 (84) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +1 -1
  4. data/Rakefile +39 -4
  5. data/lib/mongo/address.rb +1 -1
  6. data/lib/mongo/collection.rb +5 -0
  7. data/lib/mongo/collection/view/readable.rb +4 -0
  8. data/lib/mongo/cursor.rb +15 -3
  9. data/lib/mongo/database/view.rb +1 -1
  10. data/lib/mongo/operation/collections_info/command.rb +5 -0
  11. data/lib/mongo/operation/collections_info/result.rb +16 -1
  12. data/lib/mongo/operation/find/result.rb +10 -0
  13. data/lib/mongo/server/description.rb +8 -1
  14. data/lib/mongo/session.rb +2 -1
  15. data/lib/mongo/version.rb +1 -1
  16. data/spec/README.md +7 -0
  17. data/spec/integration/bson_symbol_spec.rb +4 -2
  18. data/spec/integration/change_stream_spec.rb +1 -1
  19. data/spec/integration/connection_pool_populator_spec.rb +1 -1
  20. data/spec/integration/cursor_reaping_spec.rb +1 -1
  21. data/spec/integration/fork_reconnect_spec.rb +56 -1
  22. data/spec/integration/query_cache_transactions_spec.rb +29 -18
  23. data/spec/integration/sdam_error_handling_spec.rb +17 -0
  24. data/spec/integration/sdam_events_spec.rb +8 -5
  25. data/spec/integration/transactions_examples_spec.rb +17 -7
  26. data/spec/lite_spec_helper.rb +5 -3
  27. data/spec/mongo/auth/user_spec.rb +1 -1
  28. data/spec/mongo/bulk_write_spec.rb +2 -2
  29. data/spec/mongo/client_construction_spec.rb +3 -3
  30. data/spec/mongo/client_encryption_spec.rb +16 -10
  31. data/spec/mongo/client_spec.rb +7 -0
  32. data/spec/mongo/cluster/topology/replica_set_spec.rb +1 -1
  33. data/spec/mongo/cluster/topology/sharded_spec.rb +1 -1
  34. data/spec/mongo/cluster/topology/single_spec.rb +1 -1
  35. data/spec/mongo/cluster/topology/unknown_spec.rb +1 -1
  36. data/spec/mongo/cluster/topology_spec.rb +1 -1
  37. data/spec/mongo/collection/view/change_stream_resume_spec.rb +1 -1
  38. data/spec/mongo/collection/view/readable_spec.rb +36 -0
  39. data/spec/mongo/collection_spec.rb +12 -0
  40. data/spec/mongo/crypt/binary_spec.rb +1 -6
  41. data/spec/mongo/crypt/binding/binary_spec.rb +1 -6
  42. data/spec/mongo/crypt/binding/context_spec.rb +2 -7
  43. data/spec/mongo/crypt/binding/helpers_spec.rb +1 -6
  44. data/spec/mongo/crypt/binding/mongocrypt_spec.rb +2 -7
  45. data/spec/mongo/crypt/binding/status_spec.rb +1 -6
  46. data/spec/mongo/crypt/binding/version_spec.rb +1 -6
  47. data/spec/mongo/crypt/data_key_context_spec.rb +1 -1
  48. data/spec/mongo/crypt/status_spec.rb +1 -6
  49. data/spec/mongo/database_spec.rb +64 -0
  50. data/spec/mongo/monitoring/event/server_closed_spec.rb +1 -1
  51. data/spec/mongo/monitoring/event/server_opening_spec.rb +1 -1
  52. data/spec/mongo/monitoring/event/topology_changed_spec.rb +1 -1
  53. data/spec/mongo/monitoring/event/topology_closed_spec.rb +1 -1
  54. data/spec/mongo/monitoring/event/topology_opening_spec.rb +1 -1
  55. data/spec/mongo/operation/delete/op_msg_spec.rb +3 -3
  56. data/spec/mongo/operation/insert/command_spec.rb +2 -2
  57. data/spec/mongo/operation/insert/op_msg_spec.rb +3 -3
  58. data/spec/mongo/operation/read_preference_op_msg_spec.rb +1 -1
  59. data/spec/mongo/operation/update/command_spec.rb +2 -2
  60. data/spec/mongo/operation/update/op_msg_spec.rb +3 -3
  61. data/spec/mongo/query_cache_spec.rb +1 -0
  62. data/spec/mongo/server/app_metadata_shared.rb +2 -2
  63. data/spec/mongo/server/connection_spec.rb +1 -1
  64. data/spec/mongo/server/description_spec.rb +18 -0
  65. data/spec/mongo/server_selector_spec.rb +2 -2
  66. data/spec/mongo/socket/ssl_spec.rb +3 -3
  67. data/spec/runners/change_streams/test.rb +1 -1
  68. data/spec/runners/crud/test_base.rb +0 -19
  69. data/spec/runners/server_selection.rb +1 -1
  70. data/spec/runners/transactions/test.rb +2 -2
  71. data/spec/shared/LICENSE +20 -0
  72. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  73. data/spec/shared/lib/mrss/constraints.rb +303 -0
  74. data/spec/shared/lib/mrss/lite_constraints.rb +175 -0
  75. data/spec/shared/lib/mrss/spec_organizer.rb +149 -0
  76. data/spec/spec_helper.rb +3 -1
  77. data/spec/stress/fork_reconnect_stress_spec.rb +1 -1
  78. data/spec/support/constraints.rb +0 -270
  79. data/spec/support/utils.rb +19 -0
  80. metadata +956 -952
  81. metadata.gz.sig +0 -0
  82. data/spec/support/child_process_helper.rb +0 -78
  83. data/spec/support/lite_constraints.rb +0 -165
  84. data/spec/support/spec_organizer.rb +0 -129
@@ -0,0 +1,149 @@
1
+ autoload :JSON, 'json'
2
+ autoload :FileUtils, 'fileutils'
3
+ autoload :Find, 'find'
4
+
5
+ module Mrss
6
+
7
+ autoload :ChildProcessHelper, 'mrss/child_process_helper'
8
+
9
+ # Organizes and runs all of the tests in the test suite in batches.
10
+ #
11
+ # Organizing the tests in batches serves two purposes:
12
+ #
13
+ # 1. This allows running unit tests before integration tests, therefore
14
+ # in theory revealing failures quicker on average.
15
+ # 2. This allows running some tests that have high intermittent failure rate
16
+ # in their own test process.
17
+ #
18
+ # This class aggregates RSpec results after the test runs.
19
+ class SpecOrganizer
20
+
21
+ class BucketsNotPrioritized < StandardError
22
+ end
23
+
24
+ def initialize(root: nil, classifiers:, priority_order:,
25
+ spec_root: nil, rspec_json_path: nil, rspec_all_json_path: nil
26
+ )
27
+ @spec_root = spec_root || File.join(root, 'spec')
28
+ @classifiers = classifiers
29
+ @priority_order = priority_order
30
+ @rspec_json_path = rspec_json_path || File.join(root, 'tmp/rspec.json')
31
+ @rspec_all_json_path = rspec_all_json_path || File.join(root, 'tmp/rspec-all.json')
32
+ end
33
+
34
+ attr_reader :spec_root, :classifiers, :priority_order
35
+ attr_reader :rspec_json_path, :rspec_all_json_path
36
+
37
+ def buckets
38
+ @buckets ||= {}.tap do |buckets|
39
+ Find.find(spec_root) do |path|
40
+ next unless File.file?(path)
41
+ next unless path =~ /_spec\.rb\z/
42
+ rel_path = path[(spec_root.length + 1)..path.length]
43
+
44
+ found = false
45
+ classifiers.each do |(regexp, category)|
46
+ if regexp =~ rel_path
47
+ buckets[category] ||= []
48
+ buckets[category] << File.join('spec', rel_path)
49
+ found = true
50
+ break
51
+ end
52
+ end
53
+
54
+ unless found
55
+ buckets[nil] ||= []
56
+ buckets[nil] << File.join('spec', rel_path)
57
+ end
58
+ end
59
+ end.freeze
60
+ end
61
+
62
+ def ordered_buckets
63
+ @ordered_buckets ||= {}.tap do |ordered_buckets|
64
+ buckets = self.buckets.dup
65
+ priority_order.each do |category|
66
+ files = buckets.delete(category)
67
+ ordered_buckets[category] = files
68
+ end
69
+
70
+ if files = buckets.delete(nil)
71
+ ordered_buckets[nil] = files
72
+ end
73
+
74
+ unless buckets.empty?
75
+ raise BucketsNotPrioritized, "Some buckets were not prioritized: #{buckets.keys.map(&:to_s).join(', ')}"
76
+ end
77
+ end.freeze
78
+ end
79
+
80
+ def run
81
+ FileUtils.rm_f(rspec_all_json_path)
82
+
83
+ failed = []
84
+ buckets = self.buckets.dup
85
+
86
+ priority_order.each do |category|
87
+ if files = buckets.delete(category)
88
+ unless run_files(category, files)
89
+ failed << category
90
+ end
91
+ end
92
+ end
93
+ if files = buckets.delete(nil)
94
+ unless run_files('remaining', files)
95
+ failed << 'remaining'
96
+ end
97
+ end
98
+
99
+ unless buckets.empty?
100
+ raise "Some buckets were not executed: #{buckets.keys.map(&:to_s).join(', ')}"
101
+ end
102
+
103
+ if failed.any?
104
+ raise "The following buckets failed: #{failed.map(&:to_s).join(', ')}"
105
+ end
106
+ end
107
+
108
+ def run_files(category, paths)
109
+ puts "Running #{category.to_s.gsub('_', ' ')} tests"
110
+ FileUtils.rm_f(rspec_json_path)
111
+ cmd = %w(rspec) + paths
112
+
113
+ begin
114
+ ChildProcessHelper.check_call(cmd)
115
+ ensure
116
+ if File.exist?(rspec_json_path)
117
+ if File.exist?(rspec_all_json_path)
118
+ merge_rspec_results
119
+ else
120
+ FileUtils.cp(rspec_json_path, rspec_all_json_path)
121
+ end
122
+ end
123
+ end
124
+
125
+ true
126
+ rescue ChildProcessHelper::SpawnError
127
+ false
128
+ end
129
+
130
+ def merge_rspec_results
131
+ all = JSON.parse(File.read(rspec_all_json_path))
132
+ new = JSON.parse(File.read(rspec_json_path))
133
+ all['examples'] += new.delete('examples')
134
+ new.delete('summary').each do |k, v|
135
+ all['summary'][k] += v
136
+ end
137
+ new.delete('version')
138
+ new.delete('summary_line')
139
+ unless new.empty?
140
+ raise "Unhandled rspec results keys: #{new.keys.join(', ')}"
141
+ end
142
+ # We do not merge summary lines, delete them from aggregated results
143
+ all.delete('summary_line')
144
+ File.open(rspec_all_json_path, 'w') do |f|
145
+ f << JSON.dump(all)
146
+ end
147
+ end
148
+ end
149
+ end
@@ -1,8 +1,9 @@
1
1
  require 'lite_spec_helper'
2
2
 
3
+ require 'mrss/constraints'
4
+ require 'support/constraints'
3
5
  require 'support/authorization'
4
6
  require 'support/primary_socket'
5
- require 'support/constraints'
6
7
  require 'support/cluster_config'
7
8
  require 'support/cluster_tools'
8
9
  require 'rspec/retry'
@@ -11,6 +12,7 @@ require 'support/local_resource_registry'
11
12
 
12
13
  RSpec.configure do |config|
13
14
  config.include(Authorization)
15
+ config.extend(Mrss::Constraints)
14
16
  config.extend(Constraints)
15
17
 
16
18
  config.before(:all) do
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe 'fork reconnect' do
4
4
  require_fork
5
- only_mri
5
+ require_mri
6
6
 
7
7
  # On multi-shard sharded clusters a succeeding write request does not
8
8
  # guarantee that the next operation will succeed (since it could be sent to
@@ -1,105 +1,4 @@
1
1
  module Constraints
2
- def min_server_version(version)
3
- unless version =~ /^\d+\.\d+$/
4
- raise ArgumentError, "Version can only be major.minor: #{version}"
5
- end
6
-
7
- before(:all) do
8
- if version > ClusterConfig.instance.server_version
9
- skip "Server version #{version} or higher required, we have #{ClusterConfig.instance.server_version}"
10
- end
11
- end
12
- end
13
-
14
- def max_server_version(version)
15
- unless version =~ /^\d+\.\d+$/
16
- raise ArgumentError, "Version can only be major.minor: #{version}"
17
- end
18
-
19
- before(:all) do
20
- if version < ClusterConfig.instance.short_server_version
21
- skip "Server version #{version} or lower required, we have #{ClusterConfig.instance.server_version}"
22
- end
23
- end
24
- end
25
-
26
- def min_server_fcv(version)
27
- unless version =~ /^\d+\.\d+$/
28
- raise ArgumentError, "FCV can only be major.minor: #{version}"
29
- end
30
-
31
- before(:all) do
32
- unless ClusterConfig.instance.fcv_ish >= version
33
- skip "FCV #{version} or higher required, we have #{ClusterConfig.instance.fcv_ish} (server #{ClusterConfig.instance.server_version})"
34
- end
35
- end
36
- end
37
-
38
- def max_server_fcv(version)
39
- unless version =~ /^\d+\.\d+$/
40
- raise ArgumentError, "Version can only be major.minor: #{version}"
41
- end
42
-
43
- before(:all) do
44
- if version < ClusterConfig.instance.fcv_ish
45
- skip "FCV #{version} or lower required, we have #{ClusterConfig.instance.fcv_ish} (server #{ClusterConfig.instance.server_version})"
46
- end
47
- end
48
- end
49
-
50
- def require_topology(*topologies)
51
- invalid_topologies = topologies - [:single, :replica_set, :sharded]
52
- unless invalid_topologies.empty?
53
- raise ArgumentError, "Invalid topologies requested: #{invalid_topologies.join(', ')}"
54
- end
55
- before(:all) do
56
- unless topologies.include?(topology = ClusterConfig.instance.topology)
57
- skip "Topology #{topologies.join(' or ')} required, we have #{topology}"
58
- end
59
- end
60
- end
61
-
62
- def max_example_run_time(timeout)
63
- around do |example|
64
- TimeoutInterrupt.timeout(timeout, TimeoutInterrupt::Error.new("Test execution terminated after #{timeout} seconds")) do
65
- example.run
66
- end
67
- end
68
- end
69
-
70
- def require_transaction_support
71
- min_server_fcv '4.0'
72
- require_topology :replica_set
73
- end
74
-
75
- # Fail command fail point was added to mongod in 4.0 and to mongos in 4.2.
76
- def require_fail_command
77
- min_server_fcv '4.0'
78
-
79
- before(:all) do
80
- if ClusterConfig.instance.topology == :sharded
81
- unless ClusterConfig.instance.short_server_version >= '4.2'
82
- skip 'Test requires failCommand fail point which was added to mongos in 4.2'
83
- end
84
- end
85
- end
86
- end
87
-
88
- def require_tls
89
- before(:all) do
90
- unless SpecConfig.instance.ssl?
91
- skip "SSL not enabled"
92
- end
93
- end
94
- end
95
-
96
- def require_no_tls
97
- before(:all) do
98
- if SpecConfig.instance.ssl?
99
- skip "SSL enabled"
100
- end
101
- end
102
- end
103
2
 
104
3
  # Some tests hardcode the TLS certificates shipped with the driver's
105
4
  # test suite, and will fail when using TLS connections that use other
@@ -114,173 +13,4 @@ module Constraints
114
13
  end
115
14
  end
116
15
  end
117
-
118
- def require_no_retry_writes
119
- before(:all) do
120
- if SpecConfig.instance.retry_writes?
121
- skip "Retry writes is enabled"
122
- end
123
- end
124
- end
125
-
126
- def require_compression
127
- before(:all) do
128
- if SpecConfig.instance.compressors.nil?
129
- skip "Compression is not enabled"
130
- end
131
- end
132
- end
133
-
134
- def require_no_compression
135
- before(:all) do
136
- if SpecConfig.instance.compressors
137
- skip "Compression is enabled"
138
- end
139
- end
140
- end
141
-
142
- def ruby_version_gte(version)
143
- before(:all) do
144
- if RUBY_VERSION < version
145
- skip "Ruby version #{version} or higher required"
146
- end
147
- end
148
- end
149
-
150
- def ruby_version_lt(version)
151
- before(:all) do
152
- if RUBY_VERSION >= version
153
- skip "Ruby version less than #{version} required"
154
- end
155
- end
156
- end
157
-
158
- def require_auth(*values)
159
- before(:all) do
160
- if values.any?
161
- unless values.include?(ENV['AUTH'])
162
- msg = values.map { |v| "AUTH=#{v}" }.join(' or ')
163
- skip "This test requires #{msg}"
164
- end
165
- else
166
- unless ENV['AUTH'] == 'auth' || SpecConfig.instance.user || ClusterConfig.instance.auth_enabled?
167
- skip "Auth required"
168
- end
169
- end
170
- end
171
- end
172
-
173
- def require_no_auth
174
- before(:all) do
175
- if (ENV['AUTH'] && ENV['AUTH'] != 'noauth') || SpecConfig.instance.user || ClusterConfig.instance.auth_enabled?
176
- skip "Auth not allowed"
177
- end
178
- end
179
- end
180
-
181
- def require_x509_auth
182
- before(:all) do
183
- unless SpecConfig.instance.x509_auth?
184
- skip "X.509 auth required"
185
- end
186
- end
187
- end
188
-
189
- def require_no_external_user
190
- before(:all) do
191
- if SpecConfig.instance.external_user?
192
- skip "External user configurations are not compatible with this test"
193
- end
194
- end
195
- end
196
-
197
- # Can the driver specify a write concern that won't be overridden?
198
- # (mongos 4.0+ overrides the write concern)
199
- def require_set_write_concern
200
- before(:all) do
201
- if ClusterConfig.instance.topology == :sharded && ClusterConfig.instance.short_server_version >= '4.0'
202
- skip "mongos 4.0+ overrides write concern"
203
- end
204
- end
205
- end
206
-
207
- def require_multi_shard
208
- before(:all) do
209
- if ClusterConfig.instance.topology == :sharded && SpecConfig.instance.addresses.length == 1
210
- skip 'Test requires a minimum of two shards if run in sharded topology'
211
- end
212
- end
213
- end
214
-
215
- def require_no_multi_shard
216
- before(:all) do
217
- if ClusterConfig.instance.topology == :sharded && SpecConfig.instance.addresses.length > 1
218
- skip 'Test requires a single shard if run in sharded topology'
219
- end
220
- end
221
- end
222
-
223
- def require_wired_tiger
224
- before(:all) do
225
- if ClusterConfig.instance.storage_engine != :wired_tiger
226
- skip 'Test requires WiredTiger storage engine'
227
- end
228
- end
229
- end
230
-
231
- def require_wired_tiger_on_36
232
- before(:all) do
233
- if ClusterConfig.instance.short_server_version >= '3.6'
234
- if ClusterConfig.instance.storage_engine != :wired_tiger
235
- skip 'Test requires WiredTiger storage engine on 3.6+ servers'
236
- end
237
- end
238
- end
239
- end
240
-
241
- def require_mmapv1
242
- before(:all) do
243
- if ClusterConfig.instance.storage_engine != :mmapv1
244
- skip 'Test requires MMAPv1 storage engine'
245
- end
246
- end
247
- end
248
-
249
- def require_enterprise
250
- before(:all) do
251
- unless ClusterConfig.instance.enterprise?
252
- skip 'Test requires enterprise build of MongoDB'
253
- end
254
- end
255
- end
256
-
257
- # Integration tests for SRV polling require internet connectivity to
258
- # look up SRV records and a sharded cluster configured on default port on
259
- # localhost (localhost:27017, localhost:27018).
260
- def require_default_port_deployment
261
- # Because the DNS records at test1.test.build.10gen.cc point to
262
- # localhost:27017 & localhost:27018, the test suite must have been
263
- # configured to use these addresses
264
- before(:all) do
265
- have_default_port = SpecConfig.instance.addresses.any? do |address|
266
- %w(127.0.0.1 127.0.0.1:27017 localhost localhost:27017).include?(address)
267
- end
268
- unless have_default_port
269
- skip 'This test requires the test suite to be configured for localhost:27017'
270
- end
271
- end
272
- end
273
-
274
- # Some tests perform assertions on what the driver is logging.
275
- # Some test configurations, for example OCSP with unknown response,
276
- # produce warnings due to optional checks failing.
277
- # This constraint skips tests that issue logging assertions on configurations
278
- # that may produce non-test-originated log entries.
279
- def require_warning_clean
280
- before(:all) do
281
- if ENV['OCSP_STATUS'] == 'unknown'
282
- skip 'Unknown OCSP status is not global warning-clean'
283
- end
284
- end
285
- end
286
16
  end