bson 4.9.0 → 4.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +15 -6
  4. data/ext/bson/bson-native.h +4 -0
  5. data/ext/bson/init.c +75 -23
  6. data/ext/bson/read.c +63 -11
  7. data/ext/bson/write.c +42 -3
  8. data/lib/bson/active_support.rb +1 -0
  9. data/lib/bson/array.rb +5 -1
  10. data/lib/bson/big_decimal.rb +67 -0
  11. data/lib/bson/binary.rb +8 -5
  12. data/lib/bson/boolean.rb +2 -1
  13. data/lib/bson/code.rb +2 -1
  14. data/lib/bson/code_with_scope.rb +2 -1
  15. data/lib/bson/config.rb +1 -0
  16. data/lib/bson/date.rb +1 -0
  17. data/lib/bson/date_time.rb +2 -1
  18. data/lib/bson/db_pointer.rb +2 -1
  19. data/lib/bson/dbref.rb +152 -0
  20. data/lib/bson/decimal128/builder.rb +27 -20
  21. data/lib/bson/decimal128.rb +39 -14
  22. data/lib/bson/document.rb +61 -18
  23. data/lib/bson/environment.rb +1 -0
  24. data/lib/bson/error.rb +13 -0
  25. data/lib/bson/ext_json.rb +24 -11
  26. data/lib/bson/false_class.rb +2 -1
  27. data/lib/bson/float.rb +21 -32
  28. data/lib/bson/hash.rb +18 -6
  29. data/lib/bson/int32.rb +3 -2
  30. data/lib/bson/int64.rb +3 -2
  31. data/lib/bson/integer.rb +3 -2
  32. data/lib/bson/json.rb +1 -0
  33. data/lib/bson/max_key.rb +3 -2
  34. data/lib/bson/min_key.rb +3 -2
  35. data/lib/bson/nil_class.rb +2 -1
  36. data/lib/bson/object.rb +1 -0
  37. data/lib/bson/object_id.rb +4 -3
  38. data/lib/bson/open_struct.rb +1 -0
  39. data/lib/bson/regexp.rb +24 -7
  40. data/lib/bson/registry.rb +1 -0
  41. data/lib/bson/specialized.rb +1 -0
  42. data/lib/bson/string.rb +3 -2
  43. data/lib/bson/symbol.rb +2 -1
  44. data/lib/bson/time.rb +4 -3
  45. data/lib/bson/time_with_zone.rb +1 -0
  46. data/lib/bson/timestamp.rb +7 -6
  47. data/lib/bson/true_class.rb +2 -1
  48. data/lib/bson/undefined.rb +2 -1
  49. data/lib/bson/version.rb +2 -1
  50. data/lib/bson.rb +8 -5
  51. data/spec/README.md +14 -0
  52. data/spec/bson/array_spec.rb +17 -0
  53. data/spec/bson/big_decimal_spec.rb +316 -0
  54. data/spec/bson/binary_spec.rb +1 -1
  55. data/spec/bson/binary_uuid_spec.rb +12 -0
  56. data/spec/bson/byte_buffer_read_spec.rb +59 -3
  57. data/spec/bson/byte_buffer_spec.rb +129 -6
  58. data/spec/bson/byte_buffer_write_spec.rb +96 -0
  59. data/spec/bson/date_time_spec.rb +53 -0
  60. data/spec/bson/dbref_legacy_spec.rb +169 -0
  61. data/spec/bson/dbref_spec.rb +487 -0
  62. data/spec/bson/decimal128_spec.rb +231 -0
  63. data/spec/bson/document_as_spec.rb +46 -0
  64. data/spec/bson/document_spec.rb +43 -1
  65. data/spec/bson/ext_json_parse_spec.rb +37 -0
  66. data/spec/bson/hash_as_spec.rb +57 -0
  67. data/spec/bson/hash_spec.rb +105 -0
  68. data/spec/bson/int64_spec.rb +4 -24
  69. data/spec/bson/raw_spec.rb +18 -1
  70. data/spec/bson/regexp_spec.rb +52 -0
  71. data/spec/runners/common_driver.rb +1 -1
  72. data/spec/shared/LICENSE +20 -0
  73. data/spec/shared/bin/get-mongodb-download-url +17 -0
  74. data/spec/shared/bin/s3-copy +45 -0
  75. data/spec/shared/bin/s3-upload +69 -0
  76. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  77. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  78. data/spec/shared/lib/mrss/constraints.rb +386 -0
  79. data/spec/shared/lib/mrss/docker_runner.rb +271 -0
  80. data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
  81. data/spec/shared/lib/mrss/lite_constraints.rb +191 -0
  82. data/spec/shared/lib/mrss/server_version_registry.rb +120 -0
  83. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  84. data/spec/shared/lib/mrss/utils.rb +15 -0
  85. data/spec/shared/share/Dockerfile.erb +338 -0
  86. data/spec/shared/share/haproxy-1.conf +16 -0
  87. data/spec/shared/share/haproxy-2.conf +17 -0
  88. data/spec/shared/shlib/distro.sh +74 -0
  89. data/spec/shared/shlib/server.sh +367 -0
  90. data/spec/shared/shlib/set_env.sh +131 -0
  91. data/spec/spec_helper.rb +31 -0
  92. data/spec/spec_tests/common_driver_spec.rb +2 -1
  93. data/spec/spec_tests/data/corpus/binary.json +33 -0
  94. data/spec/spec_tests/data/corpus/dbref.json +21 -1
  95. data/spec/spec_tests/data/corpus/document.json +4 -0
  96. data/spec/spec_tests/data/corpus/regex.json +2 -2
  97. data/spec/spec_tests/data/corpus/timestamp.json +10 -0
  98. data/spec/spec_tests/data/corpus/top.json +23 -12
  99. data/spec/support/spec_config.rb +8 -1
  100. data.tar.gz.sig +0 -0
  101. metadata +168 -93
  102. metadata.gz.sig +1 -0
@@ -0,0 +1,386 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ module Mrss
5
+ module Constraints
6
+ def min_server_version(version)
7
+ unless version =~ /\A\d+\.\d+\z/
8
+ raise ArgumentError, "Version can only be major.minor: #{version}"
9
+ end
10
+
11
+ before(:all) do
12
+ if version > ClusterConfig.instance.server_version
13
+ skip "Server version #{version} or higher required, we have #{ClusterConfig.instance.server_version}"
14
+ end
15
+ end
16
+ end
17
+
18
+ def max_server_version(version)
19
+ unless version =~ /\A\d+\.\d+\z/
20
+ raise ArgumentError, "Version can only be major.minor: #{version}"
21
+ end
22
+
23
+ before(:all) do
24
+ if version < ClusterConfig.instance.short_server_version
25
+ skip "Server version #{version} or lower required, we have #{ClusterConfig.instance.server_version}"
26
+ end
27
+ end
28
+ end
29
+
30
+ def min_server_fcv(version)
31
+ unless version =~ /\A\d+\.\d+\z/
32
+ raise ArgumentError, "FCV can only be major.minor: #{version}"
33
+ end
34
+
35
+ before(:all) do
36
+ unless ClusterConfig.instance.fcv_ish >= version
37
+ skip "FCV #{version} or higher required, we have #{ClusterConfig.instance.fcv_ish} (server #{ClusterConfig.instance.server_version})"
38
+ end
39
+ end
40
+ end
41
+
42
+ def max_server_fcv(version)
43
+ unless version =~ /\A\d+\.\d+\z/
44
+ raise ArgumentError, "Version can only be major.minor: #{version}"
45
+ end
46
+
47
+ before(:all) do
48
+ if version < ClusterConfig.instance.fcv_ish
49
+ skip "FCV #{version} or lower required, we have #{ClusterConfig.instance.fcv_ish} (server #{ClusterConfig.instance.server_version})"
50
+ end
51
+ end
52
+ end
53
+
54
+ def require_topology(*topologies)
55
+ invalid_topologies = topologies - [:single, :replica_set, :sharded, :load_balanced]
56
+
57
+ unless invalid_topologies.empty?
58
+ raise ArgumentError, "Invalid topologies requested: #{invalid_topologies.join(', ')}"
59
+ end
60
+
61
+ before(:all) do
62
+ unless topologies.include?(topology = ClusterConfig.instance.topology)
63
+ skip "Topology #{topologies.join(' or ')} required, we have #{topology}"
64
+ end
65
+ end
66
+ end
67
+
68
+ def max_example_run_time(timeout)
69
+ around do |example|
70
+ TimeoutInterrupt.timeout(timeout, TimeoutInterrupt::Error.new("Test execution terminated after #{timeout} seconds")) do
71
+ example.run
72
+ end
73
+ end
74
+ end
75
+
76
+ def require_transaction_support
77
+ before(:all) do
78
+ case ClusterConfig.instance.topology
79
+ when :single
80
+ skip 'Transactions tests require a replica set (4.0+) or a sharded cluster (4.2+)'
81
+ when :replica_set
82
+ unless ClusterConfig.instance.server_version >= '4.0'
83
+ skip 'Transactions tests in a replica set topology require server 4.0+'
84
+ end
85
+ when :sharded, :load_balanced
86
+ unless ClusterConfig.instance.server_version >= '4.2'
87
+ skip 'Transactions tests in a sharded cluster topology require server 4.2+'
88
+ end
89
+ else
90
+ raise NotImplementedError
91
+ end
92
+ end
93
+ end
94
+
95
+ # Fail command fail point was added to mongod in 4.0 and to mongos in 4.2.
96
+ def require_fail_command
97
+ require_transaction_support
98
+ end
99
+
100
+ def require_tls
101
+ before(:all) do
102
+ unless SpecConfig.instance.ssl?
103
+ skip "SSL not enabled"
104
+ end
105
+ end
106
+ end
107
+
108
+ def require_no_tls
109
+ before(:all) do
110
+ if SpecConfig.instance.ssl?
111
+ skip "SSL enabled"
112
+ end
113
+ end
114
+ end
115
+
116
+ def require_retry_writes
117
+ before(:all) do
118
+ unless SpecConfig.instance.retry_writes?
119
+ skip "Retry writes is disabled"
120
+ end
121
+ end
122
+ end
123
+
124
+ def require_no_retry_writes
125
+ before(:all) do
126
+ if SpecConfig.instance.retry_writes?
127
+ skip "Retry writes is enabled"
128
+ end
129
+ end
130
+ end
131
+
132
+ def require_compression
133
+ before(:all) do
134
+ if SpecConfig.instance.compressors.nil?
135
+ skip "Compression is not enabled"
136
+ end
137
+ end
138
+ end
139
+
140
+ def require_zlib_compression
141
+ before(:all) do
142
+ compressors = SpecConfig.instance.compressors
143
+ unless compressors && compressors.include?('zlib')
144
+ skip "Zlib compression is not enabled"
145
+ end
146
+ end
147
+ end
148
+
149
+ def require_snappy_compression
150
+ before(:all) do
151
+ compressors = SpecConfig.instance.compressors
152
+ unless compressors && compressors.include?('snappy')
153
+ skip "Snappy compression is not enabled"
154
+ end
155
+ end
156
+ end
157
+
158
+ def require_no_snappy_compression
159
+ before(:all) do
160
+ compressors = SpecConfig.instance.compressors
161
+ if compressors && compressors.include?('snappy')
162
+ skip "Snappy compression is enabled"
163
+ end
164
+ end
165
+ end
166
+
167
+ def require_zstd_compression
168
+ before(:all) do
169
+ compressors = SpecConfig.instance.compressors
170
+ unless compressors && compressors.include?('zstd')
171
+ skip "Zstd compression is not enabled"
172
+ end
173
+ end
174
+ end
175
+
176
+ def require_no_zstd_compression
177
+ before(:all) do
178
+ compressors = SpecConfig.instance.compressors
179
+ if compressors && compressors.include?('zstd')
180
+ skip "Zstd compression is enabled"
181
+ end
182
+ end
183
+ end
184
+
185
+ def require_no_compression
186
+ before(:all) do
187
+ if SpecConfig.instance.compressors
188
+ skip "Compression is enabled"
189
+ end
190
+ end
191
+ end
192
+
193
+ def ruby_version_gte(version)
194
+ before(:all) do
195
+ if RUBY_VERSION < version
196
+ skip "Ruby version #{version} or higher required"
197
+ end
198
+ end
199
+ end
200
+
201
+ def ruby_version_lt(version)
202
+ before(:all) do
203
+ if RUBY_VERSION >= version
204
+ skip "Ruby version less than #{version} required"
205
+ end
206
+ end
207
+ end
208
+
209
+ def require_auth(*values)
210
+ before(:all) do
211
+ if values.any?
212
+ unless values.include?(ENV['AUTH'])
213
+ msg = values.map { |v| "AUTH=#{v}" }.join(' or ')
214
+ skip "This test requires #{msg}"
215
+ end
216
+ else
217
+ unless ENV['AUTH'] == 'auth' || SpecConfig.instance.user || ClusterConfig.instance.auth_enabled?
218
+ skip "Auth required"
219
+ end
220
+ end
221
+ end
222
+ end
223
+
224
+ def require_no_auth
225
+ before(:all) do
226
+ auth = ENV.fetch('AUTH', '')
227
+ if (!auth.empty? && auth != 'noauth') || SpecConfig.instance.user || ClusterConfig.instance.auth_enabled?
228
+ skip "Auth not allowed"
229
+ end
230
+ end
231
+ end
232
+
233
+ def require_x509_auth
234
+ before(:all) do
235
+ unless SpecConfig.instance.x509_auth?
236
+ skip "X.509 auth required"
237
+ end
238
+ end
239
+ end
240
+
241
+ def require_no_external_user
242
+ before(:all) do
243
+ if SpecConfig.instance.external_user?
244
+ skip "External user configurations are not compatible with this test"
245
+ end
246
+ end
247
+ end
248
+
249
+ # Can the driver specify a write concern that won't be overridden?
250
+ # (mongos 4.0+ overrides the write concern)
251
+ def require_set_write_concern
252
+ before(:all) do
253
+ if %i(sharded load_balanced).include?(ClusterConfig.instance.topology) &&
254
+ ClusterConfig.instance.short_server_version >= '4.0'
255
+ then
256
+ skip "mongos 4.0+ overrides write concern"
257
+ end
258
+ end
259
+ end
260
+
261
+ def require_multi_mongos
262
+ before(:all) do
263
+ if ClusterConfig.instance.topology == :sharded && SpecConfig.instance.addresses.length == 1
264
+ skip 'Test requires a minimum of two mongoses if run in sharded topology'
265
+ end
266
+
267
+ if ClusterConfig.instance.topology == :load_balanced && SpecConfig.instance.single_mongos?
268
+ skip 'Test requires a minimum of two mongoses if run in load-balanced topology'
269
+ end
270
+ end
271
+ end
272
+
273
+ # In sharded topology operations are distributed to the mongoses.
274
+ # When we set fail points, the fail point may be set on one mongos and
275
+ # operation may be executed on another mongos, causing failures.
276
+ # Tests that are not setting targeted fail points should utilize this
277
+ # method to restrict themselves to single mongos.
278
+ #
279
+ # In load-balanced topology, the same problem can happen when there is
280
+ # more than one mongos behind the load balancer.
281
+ def require_no_multi_mongos
282
+ before(:all) do
283
+ if ClusterConfig.instance.topology == :sharded && SpecConfig.instance.addresses.length > 1
284
+ skip 'Test requires a single mongos if run in sharded topology'
285
+ end
286
+ if ClusterConfig.instance.topology == :load_balanced && !SpecConfig.instance.single_mongos?
287
+ skip 'Test requires a single mongos, as indicated by SINGLE_MONGOS=1 environment variable, if run in load-balanced topology'
288
+ end
289
+ end
290
+ end
291
+
292
+ alias :require_no_multi_shard :require_no_multi_mongos
293
+
294
+ def require_wired_tiger
295
+ before(:all) do
296
+ # Storage detection fails for serverless instances. However, it is safe to
297
+ # assume that a serverless instance uses WiredTiger Storage Engine.
298
+ if !SpecConfig.instance.serverless? && ClusterConfig.instance.storage_engine != :wired_tiger
299
+ skip 'Test requires WiredTiger storage engine'
300
+ end
301
+ end
302
+ end
303
+
304
+ def require_wired_tiger_on_36
305
+ before(:all) do
306
+ if ClusterConfig.instance.short_server_version >= '3.6'
307
+ # Storage detection fails for serverless instances. However, it is safe to
308
+ # assume that a serverless instance uses WiredTiger Storage Engine.
309
+ if !SpecConfig.instance.serverless? && ClusterConfig.instance.storage_engine != :wired_tiger
310
+ skip 'Test requires WiredTiger storage engine on 3.6+ servers'
311
+ end
312
+ end
313
+ end
314
+ end
315
+
316
+ def require_mmapv1
317
+ before(:all) do
318
+ if SpecConfig.instance.serverless? || ClusterConfig.instance.storage_engine != :mmapv1
319
+ skip 'Test requires MMAPv1 storage engine'
320
+ end
321
+ end
322
+ end
323
+
324
+ def require_enterprise
325
+ before(:all) do
326
+ unless ClusterConfig.instance.enterprise?
327
+ skip 'Test requires enterprise build of MongoDB'
328
+ end
329
+ end
330
+ end
331
+
332
+ # Integration tests for SRV polling require internet connectivity to
333
+ # look up SRV records and a sharded cluster configured on default port on
334
+ # localhost (localhost:27017, localhost:27018).
335
+ def require_default_port_deployment
336
+ # Because the DNS records at test1.test.build.10gen.cc point to
337
+ # localhost:27017 & localhost:27018, the test suite must have been
338
+ # configured to use these addresses
339
+ before(:all) do
340
+ have_default_port = SpecConfig.instance.addresses.any? do |address|
341
+ %w(127.0.0.1 127.0.0.1:27017 localhost localhost:27017).include?(address)
342
+ end
343
+ unless have_default_port
344
+ skip 'This test requires the test suite to be configured for localhost:27017'
345
+ end
346
+ end
347
+ end
348
+
349
+ # Some tests perform assertions on what the driver is logging.
350
+ # Some test configurations, for example OCSP with unknown response,
351
+ # produce warnings due to optional checks failing.
352
+ # This constraint skips tests that issue logging assertions on configurations
353
+ # that may produce non-test-originated log entries.
354
+ def require_warning_clean
355
+ before(:all) do
356
+ if ENV['OCSP_STATUS'] == 'unknown'
357
+ skip 'Unknown OCSP status is not global warning-clean'
358
+ end
359
+ end
360
+ end
361
+
362
+ def require_required_api_version
363
+ before(:all) do
364
+ unless ENV['API_VERSION_REQUIRED'] == '1'
365
+ skip 'Set API_VERSION_REQUIRED=1 to run this test'
366
+ end
367
+ end
368
+ end
369
+
370
+ def require_no_required_api_version
371
+ before(:all) do
372
+ if ENV['API_VERSION_REQUIRED'] == '1'
373
+ skip 'Cannot have API_VERSION_REQUIRED=1 to run this test'
374
+ end
375
+ end
376
+ end
377
+
378
+ def require_unix_socket
379
+ before(:all) do
380
+ if ENV['TOPOLOGY'] == 'load-balanced'
381
+ skip 'Load balancer does not listen on Unix sockets'
382
+ end
383
+ end
384
+ end
385
+ end
386
+ end
@@ -0,0 +1,271 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require 'optparse'
5
+ require 'erb'
6
+ autoload :Dotenv, 'dotenv'
7
+
8
+ module Mrss
9
+ autoload :ServerVersionRegistry, 'mrss/server_version_registry'
10
+
11
+ class DockerRunner
12
+ def initialize(**opts)
13
+ # These options are required:
14
+ opts.fetch(:image_tag)
15
+ opts.fetch(:dockerfile_path)
16
+ opts.fetch(:default_script)
17
+ opts.fetch(:project_lib_subdir)
18
+
19
+ @options = opts
20
+ end
21
+
22
+ attr_reader :options
23
+
24
+ def run
25
+ process_arguments
26
+ unless @options[:exec_only]
27
+ create_dockerfile
28
+ create_image
29
+ end
30
+ if @options[:mongo_only]
31
+ run_deployment
32
+ else
33
+ run_tests
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def process_arguments
40
+ #@options = {}
41
+ OptionParser.new do |opts|
42
+ opts.banner = "Usage: test-on-docker [-d distro] [evergreen_key=value ...]"
43
+
44
+ opts.on("-a", "--add-env=PATH", "Load environment variables from PATH in .env format") do |path|
45
+ @options[:extra_env] ||= {}
46
+ unless File.exist?(path)
47
+ raise "-a option references nonexistent file #{path}"
48
+ end
49
+ Dotenv.parse(path).each do |k, v|
50
+ @options[:extra_env][k] = v
51
+ end
52
+ end
53
+
54
+ opts.on("-d", "--distro=DISTRO", "Distro to use") do |v|
55
+ @options[:distro] = v
56
+ end
57
+
58
+ opts.on('-e', '--exec-only', 'Execute tests using existing Dockerfile (for offline user)') do |v|
59
+ @options[:exec_only] = v
60
+ end
61
+
62
+ opts.on('-m', '--mongo-only=PORT', 'Start the MongoDB deployment and expose it to host on ports starting with PORT') do |v|
63
+ @options[:mongo_only] = v.to_i
64
+ end
65
+
66
+ opts.on('-p', '--preload', 'Preload Ruby toolchain and server binaries in docker') do |v|
67
+ @options[:preload] = v
68
+ end
69
+
70
+ opts.on('-s', '--script=SCRIPT', 'Test script to invoke') do |v|
71
+ @options[:script] = v
72
+ end
73
+
74
+ opts.on('-i', '--interactive', 'Interactive mode - disable per-test timeouts') do |v|
75
+ @options[:interactive] = v
76
+ end
77
+ end.parse!
78
+
79
+ @env = Hash[ARGV.map do |arg|
80
+ arg.split('=', 2)
81
+ end]
82
+
83
+ @env['RVM_RUBY'] ||= 'ruby-2.7'
84
+ unless ruby =~ /^j?ruby-/
85
+ raise "RVM_RUBY option is not in expected format: #{ruby}"
86
+ end
87
+
88
+ @env['MONGODB_VERSION'] ||= '4.4'
89
+ end
90
+
91
+ def create_dockerfile
92
+ template_path = File.join(File.dirname(__FILE__), '../../share/Dockerfile.erb')
93
+ result = ERB.new(File.read(template_path)).result(binding)
94
+ File.open(dockerfile_path, 'w') do |f|
95
+ f << result
96
+ end
97
+ end
98
+
99
+ def image_tag
100
+ options.fetch(:image_tag)
101
+ end
102
+
103
+ def dockerfile_path
104
+ options.fetch(:dockerfile_path)
105
+ end
106
+
107
+ def create_image
108
+ run_command(['docker', 'build',
109
+ '-t', image_tag,
110
+ '-f', dockerfile_path,
111
+ '.'])
112
+ end
113
+
114
+ BASE_TEST_COMMAND = %w(docker run --rm -i --tmpfs /tmpfs:exec).freeze
115
+
116
+ def run_tests
117
+ run_command(BASE_TEST_COMMAND + tty_arg + extra_env + [image_tag] +
118
+ script.split(/\s+/))
119
+ end
120
+
121
+ def run_deployment
122
+ run_command(BASE_TEST_COMMAND + tty_arg + extra_env + [
123
+ '-e', %q`TEST_CMD=watch -x bash -c "ps awwxu |egrep 'mongo|ocsp'"`,
124
+ '-e', 'BIND_ALL=true',
125
+ ] + port_forwards + [image_tag] + script.split(/\s+/))
126
+ end
127
+
128
+ def tty_arg
129
+ tty = File.open('/dev/stdin') do |f|
130
+ f.isatty
131
+ end
132
+ if tty
133
+ %w(-t --init)
134
+ else
135
+ []
136
+ end
137
+ end
138
+
139
+ def extra_env
140
+ if @options[:extra_env]
141
+ @options[:extra_env].map do |k, v|
142
+ # Here the value must not be escaped
143
+ ['-e', "#{k}=#{v}"]
144
+ end.flatten
145
+ else
146
+ []
147
+ end
148
+ end
149
+
150
+ def port_forwards
151
+ args = (0...num_exposed_ports).map do |i|
152
+ host_port = @options[:mongo_only] + i
153
+ container_port = 27017 + i
154
+ ['-p', "#{host_port}:#{container_port}"]
155
+ end.flatten
156
+
157
+ if @env['OCSP_ALGORITHM'] && !@env['OCSP_VERIFIER']
158
+ args += %w(-p 8100:8100)
159
+ end
160
+
161
+ args
162
+ end
163
+
164
+ def run_command(cmd)
165
+ if pid = fork
166
+ Process.wait(pid)
167
+ unless $?.exitstatus == 0
168
+ raise "Process exited with code #{$?.exitstatus}"
169
+ end
170
+ else
171
+ exec(*cmd)
172
+ end
173
+ end
174
+
175
+ def distro
176
+ @options[:distro] || 'ubuntu1804'
177
+ end
178
+
179
+ BASE_IMAGES = {
180
+ 'debian81' => 'debian:jessie',
181
+ 'debian92' => 'debian:stretch',
182
+ 'debian10' => 'debian:buster',
183
+ 'ubuntu1404' => 'ubuntu:trusty',
184
+ 'ubuntu1604' => 'ubuntu:xenial',
185
+ 'ubuntu1804' => 'ubuntu:bionic',
186
+ 'ubuntu2004' => 'ubuntu:focal',
187
+ 'rhel62' => 'centos:6',
188
+ 'rhel70' => 'centos:7',
189
+ }.freeze
190
+
191
+ def base_image
192
+ BASE_IMAGES[distro] or raise "Unknown distro: #{distro}"
193
+ end
194
+
195
+ def ruby
196
+ @env['RVM_RUBY']
197
+ end
198
+
199
+ def ruby_head?
200
+ ruby == 'ruby-head'
201
+ end
202
+
203
+ def system_ruby?
204
+ %w(1 true yes).include?(@env['SYSTEM_RUBY']&.downcase)
205
+ end
206
+
207
+ def server_version
208
+ @env['MONGODB_VERSION']
209
+ end
210
+
211
+ def script
212
+ @options[:script] || options.fetch(:default_script)
213
+ end
214
+
215
+ def debian?
216
+ distro =~ /debian|ubuntu/
217
+ end
218
+
219
+ def preload?
220
+ !!@options[:preload]
221
+ end
222
+
223
+ def interactive?
224
+ !!@options[:interactive]
225
+ end
226
+
227
+ def project_lib_subdir
228
+ options.fetch(:project_lib_subdir)
229
+ end
230
+
231
+ def server_download_url
232
+ @server_download_url ||= ServerVersionRegistry.new(server_version, distro).download_url
233
+ end
234
+
235
+ def libmongocrypt_path
236
+ case distro
237
+ when /ubuntu1604/
238
+ "./ubuntu1604/nocrypto/lib64/libmongocrypt.so"
239
+ when /ubuntu1804/
240
+ "./ubuntu1804-64/nocrypto/lib64/libmongocrypt.so"
241
+ when /debian92/
242
+ "./debian92/nocrypto/lib64/libmongocrypt.so"
243
+ else
244
+ raise "This script does not support running FLE tests on #{distro}. Use ubuntu1604, ubuntu1804 or debian92 instead"
245
+ end
246
+ end
247
+
248
+ def expose?
249
+ !!@options[:mongo_only]
250
+ end
251
+
252
+ def fle?
253
+ %w(1 true yes).include?(@env['FLE']&.downcase)
254
+ end
255
+
256
+ def num_exposed_ports
257
+ case @env['TOPOLOGY'] || 'standalone'
258
+ when 'standalone'
259
+ 1
260
+ when 'replica-set'
261
+ 3
262
+ when 'sharded-cluster'
263
+ if @env['SINGLE_MONGOS']
264
+ 1
265
+ else
266
+ 2
267
+ end
268
+ end
269
+ end
270
+ end
271
+ end