mongoid 7.4.0 → 7.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +2 -2
  4. data/lib/mongoid/association/embedded/batchable.rb +20 -3
  5. data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
  6. data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
  7. data/lib/mongoid/config/environment.rb +20 -4
  8. data/lib/mongoid/persistable/upsertable.rb +1 -1
  9. data/lib/mongoid/traversable.rb +4 -1
  10. data/lib/mongoid/version.rb +1 -1
  11. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +7 -2
  12. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  13. data/spec/integration/app_spec.rb +20 -14
  14. data/spec/integration/associations/embedded_dirty_spec.rb +28 -0
  15. data/spec/lite_spec_helper.rb +1 -1
  16. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +21 -0
  17. data/spec/mongoid/association/embedded/embeds_many_models.rb +121 -0
  18. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +8 -0
  19. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +24 -8
  20. data/spec/mongoid/atomic_spec.rb +22 -0
  21. data/spec/mongoid/clients/factory_spec.rb +11 -12
  22. data/spec/mongoid/config/environment_spec.rb +39 -1
  23. data/spec/mongoid/config_spec.rb +40 -0
  24. data/spec/mongoid/errors/mongoid_error_spec.rb +1 -1
  25. data/spec/shared/lib/mrss/constraints.rb +8 -16
  26. data/spec/shared/lib/mrss/docker_runner.rb +23 -3
  27. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  28. data/spec/shared/lib/mrss/event_subscriber.rb +15 -5
  29. data/spec/shared/lib/mrss/lite_constraints.rb +32 -1
  30. data/spec/shared/share/Dockerfile.erb +34 -48
  31. data/spec/shared/shlib/config.sh +27 -0
  32. data/spec/shared/shlib/server.sh +32 -19
  33. data/spec/shared/shlib/set_env.sh +37 -0
  34. data/spec/support/macros.rb +9 -0
  35. data/spec/support/models/membership.rb +1 -0
  36. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  37. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  38. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  39. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  40. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  41. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  42. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  43. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  44. data/spec/support/schema_maps/schema_map_local.json +18 -0
  45. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  46. data/spec/support/spec_config.rb +4 -0
  47. data.tar.gz.sig +0 -0
  48. metadata +28 -2
  49. metadata.gz.sig +0 -0
@@ -36,6 +36,7 @@ describe Mongoid::Clients::Factory do
36
36
  context "when the configuration exists" do
37
37
 
38
38
  context "when the configuration is standard" do
39
+ restore_config_clients
39
40
 
40
41
  let(:config) do
41
42
  {
@@ -46,7 +47,6 @@ describe Mongoid::Clients::Factory do
46
47
 
47
48
  before do
48
49
  Mongoid::Config.send(:clients=, config)
49
- # TODO: We should restore overwritten configuration in after block
50
50
  end
51
51
 
52
52
  after do
@@ -120,6 +120,7 @@ describe Mongoid::Clients::Factory do
120
120
  end
121
121
 
122
122
  context "when the configuration has no ports" do
123
+ restore_config_clients
123
124
 
124
125
  let(:config) do
125
126
  {
@@ -130,7 +131,6 @@ describe Mongoid::Clients::Factory do
130
131
 
131
132
  before do
132
133
  Mongoid::Config.send(:clients=, config)
133
- # TODO: We should restore overwritten configuration in after block
134
134
  end
135
135
 
136
136
  after do
@@ -165,6 +165,7 @@ describe Mongoid::Clients::Factory do
165
165
  context "when configured via a uri" do
166
166
 
167
167
  context "when the uri has a single host:port" do
168
+ restore_config_clients
168
169
 
169
170
  let(:config) do
170
171
  {
@@ -175,7 +176,6 @@ describe Mongoid::Clients::Factory do
175
176
 
176
177
  before do
177
178
  Mongoid::Config.send(:clients=, config)
178
- # TODO: We should restore overwritten configuration in after block
179
179
  end
180
180
 
181
181
  after do
@@ -204,6 +204,7 @@ describe Mongoid::Clients::Factory do
204
204
  end
205
205
 
206
206
  context "when the uri has multiple host:port pairs" do
207
+ restore_config_clients
207
208
 
208
209
  let(:config) do
209
210
  {
@@ -214,7 +215,6 @@ describe Mongoid::Clients::Factory do
214
215
 
215
216
  before do
216
217
  Mongoid::Config.send(:clients=, config)
217
- # TODO: We should restore overwritten configuration in after block
218
218
  end
219
219
 
220
220
  after do
@@ -255,6 +255,7 @@ describe Mongoid::Clients::Factory do
255
255
  end
256
256
 
257
257
  context "when no name is provided" do
258
+ restore_config_clients
258
259
 
259
260
  let(:config) do
260
261
  { default: { hosts: SpecConfig.instance.addresses, database: database_id }}
@@ -262,7 +263,6 @@ describe Mongoid::Clients::Factory do
262
263
 
263
264
  before do
264
265
  Mongoid::Config.send(:clients=, config)
265
- # TODO: We should restore overwritten configuration in after block
266
266
  end
267
267
 
268
268
  after do
@@ -289,12 +289,12 @@ describe Mongoid::Clients::Factory do
289
289
  end
290
290
 
291
291
  context "when nil is provided and no default config" do
292
+ restore_config_clients
292
293
 
293
294
  let(:config) { nil }
294
295
 
295
296
  before do
296
297
  Mongoid.clients[:default] = nil
297
- # TODO: We should restore overwritten configuration in after block
298
298
  end
299
299
 
300
300
  it "raises NoClientsConfig error" do
@@ -304,6 +304,7 @@ describe Mongoid::Clients::Factory do
304
304
  end
305
305
 
306
306
  describe ".default" do
307
+ restore_config_clients
307
308
 
308
309
  let(:config) do
309
310
  { default: { hosts: SpecConfig.instance.addresses, database: database_id }}
@@ -311,7 +312,6 @@ describe Mongoid::Clients::Factory do
311
312
 
312
313
  before do
313
314
  Mongoid::Config.send(:clients=, config)
314
- # TODO: We should restore overwritten configuration in after block
315
315
  end
316
316
 
317
317
  after do
@@ -338,6 +338,7 @@ describe Mongoid::Clients::Factory do
338
338
  end
339
339
 
340
340
  context "when options are provided with string keys" do
341
+ restore_config_clients
341
342
 
342
343
  let(:config) do
343
344
  {
@@ -354,7 +355,6 @@ describe Mongoid::Clients::Factory do
354
355
 
355
356
  before do
356
357
  Mongoid::Config.send(:clients=, config)
357
- # TODO: We should restore overwritten configuration in after block
358
358
  end
359
359
 
360
360
  after do
@@ -393,6 +393,8 @@ describe Mongoid::Clients::Factory do
393
393
  end
394
394
 
395
395
  context "unexpected config options" do
396
+ restore_config_clients
397
+
396
398
  let(:unknown_opts) do
397
399
  {
398
400
  bad_one: 1,
@@ -410,11 +412,8 @@ describe Mongoid::Clients::Factory do
410
412
  }
411
413
  end
412
414
 
413
- around(:each) do |example|
414
- old_config = Mongoid::Config.clients
415
+ before do
415
416
  Mongoid::Config.send(:clients=, config)
416
- example.run
417
- Mongoid::Config.send(:clients=, old_config)
418
417
  end
419
418
 
420
419
  [:bad_one, :bad_two].each do |env|
@@ -106,7 +106,7 @@ describe Mongoid::Config::Environment do
106
106
 
107
107
  context 'when file found' do
108
108
  before do
109
- allow(File).to receive(:new).with('mongoid.yml').and_return(StringIO.new(file_contents))
109
+ allow(File).to receive(:read).with('mongoid.yml').and_return(file_contents)
110
110
  end
111
111
 
112
112
  let(:file_contents) do
@@ -162,5 +162,43 @@ describe Mongoid::Config::Environment do
162
162
  it { is_expected.to be_nil }
163
163
  end
164
164
  end
165
+
166
+ context 'when configuration includes schema map' do
167
+ paths = Dir.glob(File.join(File.dirname(__FILE__), '../../support/schema_maps/*.json'))
168
+
169
+ if paths.empty?
170
+ raise "Expected to find some schema maps"
171
+ end
172
+
173
+ before do
174
+ allow(File).to receive(:read).with('mongoid.yml').and_return(file_contents)
175
+ end
176
+
177
+ let(:file_contents) do
178
+ <<~FILE
179
+ test:
180
+ clients:
181
+ default:
182
+ database: mongoid_test
183
+ hosts: [localhost]
184
+ options:
185
+ auto_encryption_options:
186
+ schema_map: #{schema_map.to_yaml.sub(/\A---/, '').gsub(/\n/, "\n" + ' '*100)}
187
+ FILE
188
+ end
189
+
190
+ paths.each do |path|
191
+ context File.basename(path) do
192
+ let(:schema_map) do
193
+ BSON::ExtJSON.parse(File.read(path))
194
+ end
195
+
196
+ it 'loads successfully' do
197
+ subject.should be_a(Hash)
198
+ subject.fetch('clients').fetch('default').fetch('options').fetch('auto_encryption_options').fetch('schema_map').should be_a(Hash)
199
+ end
200
+ end
201
+ end
202
+ end
165
203
  end
166
204
  end
@@ -531,6 +531,46 @@ describe Mongoid::Config do
531
531
  end
532
532
  end
533
533
  end
534
+
535
+ context 'when schema map is provided with uuid' do
536
+ let(:file) do
537
+ File.join(File.dirname(__FILE__), "..", "config", "mongoid_with_schema_map_uuid.yml")
538
+ end
539
+
540
+ before do
541
+ described_class.load!(file, :test)
542
+ end
543
+
544
+ let(:client) { Mongoid.default_client }
545
+
546
+ # Wrapping libraries are only recognized by driver 2.13.0+.
547
+ min_driver_version '2.13'
548
+
549
+ it 'passes uuid to driver' do
550
+ Mongo::Client.should receive(:new).with(SpecConfig.instance.addresses,
551
+ auto_encryption_options: {
552
+ 'key_vault_namespace' => 'admin.datakeys',
553
+ 'kms_providers' => {'local' => {'key' => 'z7iYiYKLuYymEWtk4kfny1ESBwwFdA58qMqff96A8ghiOcIK75lJGPUIocku8LOFjQuEgeIP4xlln3s7r93FV9J5sAE7zg8U'}},
554
+ 'schema_map' => {'blog_development.comments' => {
555
+ 'bsonType' => 'object',
556
+ 'properties' => {
557
+ 'message' => {'encrypt' => {
558
+ 'algorithm' => 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic',
559
+ 'bsonType' => 'string',
560
+ 'keyId' => [BSON::Binary.new("G\xF0 5\xCC@HX\xA2%b\x97\xA9a\xA8\xE7", :uuid)],
561
+ }},
562
+ },
563
+ }}},
564
+ database: 'mongoid_test',
565
+ platform: "mongoid-#{Mongoid::VERSION}",
566
+ wrapping_libraries: [
567
+ {'name' => 'Mongoid', 'version' => Mongoid::VERSION},
568
+ ],
569
+ )
570
+
571
+ client
572
+ end
573
+ end
534
574
  end
535
575
 
536
576
  describe "#options=" do
@@ -9,7 +9,7 @@ describe Mongoid::Errors::MongoidError do
9
9
  let(:options) { {} }
10
10
 
11
11
  before do
12
- if RUBY_VERSION.start_with?('3.', '2.7')
12
+ if RUBY_VERSION >= '2.7'
13
13
  {"message_title" => "message", "summary_title" => "summary", "resolution_title" => "resolution"}.each do |key, name|
14
14
  expect(::I18n).to receive(:translate).with("mongoid.errors.messages.#{key}", **{}).and_return(name)
15
15
  end
@@ -4,48 +4,40 @@
4
4
  module Mrss
5
5
  module Constraints
6
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
7
+ parsed_version = Gem::Version.new(version)
10
8
 
11
9
  before(:all) do
12
- if version > ClusterConfig.instance.server_version
10
+ if parsed_version > Gem::Version.new(ClusterConfig.instance.server_version)
13
11
  skip "Server version #{version} or higher required, we have #{ClusterConfig.instance.server_version}"
14
12
  end
15
13
  end
16
14
  end
17
15
 
18
16
  def max_server_version(version)
19
- unless version =~ /\A\d+\.\d+\z/
20
- raise ArgumentError, "Version can only be major.minor: #{version}"
21
- end
17
+ parsed_version = Gem::Version.new(version)
22
18
 
23
19
  before(:all) do
24
- if version < ClusterConfig.instance.short_server_version
20
+ if parsed_version < Gem::Version.new(ClusterConfig.instance.server_version)
25
21
  skip "Server version #{version} or lower required, we have #{ClusterConfig.instance.server_version}"
26
22
  end
27
23
  end
28
24
  end
29
25
 
30
26
  def min_server_fcv(version)
31
- unless version =~ /\A\d+\.\d+\z/
32
- raise ArgumentError, "FCV can only be major.minor: #{version}"
33
- end
27
+ parsed_version = Gem::Version.new(version)
34
28
 
35
29
  before(:all) do
36
- unless ClusterConfig.instance.fcv_ish >= version
30
+ unless Gem::Version.new(ClusterConfig.instance.fcv_ish) >= parsed_version
37
31
  skip "FCV #{version} or higher required, we have #{ClusterConfig.instance.fcv_ish} (server #{ClusterConfig.instance.server_version})"
38
32
  end
39
33
  end
40
34
  end
41
35
 
42
36
  def max_server_fcv(version)
43
- unless version =~ /\A\d+\.\d+\z/
44
- raise ArgumentError, "Version can only be major.minor: #{version}"
45
- end
37
+ parsed_version = Gem::Version.new(version)
46
38
 
47
39
  before(:all) do
48
- if version < ClusterConfig.instance.fcv_ish
40
+ if parsed_version < Gem::Version.new(ClusterConfig.instance.fcv_ish)
49
41
  skip "FCV #{version} or lower required, we have #{ClusterConfig.instance.fcv_ish} (server #{ClusterConfig.instance.server_version})"
50
42
  end
51
43
  end
@@ -16,7 +16,7 @@ module Mrss
16
16
  opts.fetch(:default_script)
17
17
  opts.fetch(:project_lib_subdir)
18
18
 
19
- @options = opts
19
+ @options = opts.merge(preload: true)
20
20
  end
21
21
 
22
22
  attr_reader :options
@@ -63,10 +63,14 @@ module Mrss
63
63
  @options[:mongo_only] = v.to_i
64
64
  end
65
65
 
66
- opts.on('-p', '--preload', 'Preload Ruby toolchain and server binaries in docker') do |v|
66
+ opts.on('-p', '--preload', 'Preload Ruby toolchain and server binaries in docker (default)') do |v|
67
67
  @options[:preload] = v
68
68
  end
69
69
 
70
+ opts.on('-P', '--no-preload', 'Do not preload Ruby toolchain and server binaries in docker') do
71
+ @options[:preload] = false
72
+ end
73
+
70
74
  opts.on('-s', '--script=SCRIPT', 'Test script to invoke') do |v|
71
75
  @options[:script] = v
72
76
  end
@@ -173,7 +177,18 @@ module Mrss
173
177
  end
174
178
 
175
179
  def distro
176
- @options[:distro] || 'ubuntu1804'
180
+ @options[:distro] || if app_tests?
181
+ 'ubuntu2004'
182
+ else
183
+ case server_version
184
+ when '3.6'
185
+ 'debian9'
186
+ when '4.0', '4.2'
187
+ 'ubuntu1804'
188
+ else
189
+ 'ubuntu2004'
190
+ end
191
+ end
177
192
  end
178
193
 
179
194
  BASE_IMAGES = {
@@ -253,6 +268,11 @@ module Mrss
253
268
  %w(1 true yes).include?(@env['FLE']&.downcase)
254
269
  end
255
270
 
271
+ # Mongoid
272
+ def app_tests?
273
+ %w(1 true yes).include?(@env['APP_TESTS']&.downcase)
274
+ end
275
+
256
276
  def num_exposed_ports
257
277
  case @env['TOPOLOGY'] || 'standalone'
258
278
  when 'standalone'
@@ -0,0 +1,51 @@
1
+ autoload :YAML, 'yaml'
2
+ require 'erubi'
3
+ require 'erubi/capture_end'
4
+ require 'tilt'
5
+
6
+ module Mrss
7
+ module EgConfigUtils
8
+
9
+ DEBIAN_FOR_RUBY = {
10
+ 'ruby-2.3' => 'debian92',
11
+ 'ruby-2.4' => 'debian92',
12
+ 'ruby-2.5' => 'debian10',
13
+ 'ruby-2.6' => 'debian10',
14
+ 'ruby-2.7' => 'debian10',
15
+ 'ruby-3.0' => 'debian10',
16
+ }
17
+
18
+ def standard_debian_rubies(rubies, key: nil, &block)
19
+ rubies.flatten!
20
+ text = block.call
21
+ contents = YAML.load(text)
22
+ out = rubies.map do |ruby|
23
+ contents.merge(
24
+ 'matrix_name' => "#{contents['matrix_name']} - #{ruby}",
25
+ 'matrix_spec' => contents['matrix_spec'].merge(
26
+ 'ruby' => ruby,
27
+ key || 'os' => DEBIAN_FOR_RUBY.fetch(ruby),
28
+ ),
29
+ )
30
+ end.to_yaml
31
+ text =~ /\A\n?(\s+)/
32
+ unless text
33
+ raise "Couldn't figure out indentation level"
34
+ end
35
+ indent = ' ' * ($1.length - 2)
36
+ "\n" + out.sub(/\A---.*\n/, indent).gsub("\n", "\n#{indent}")
37
+ end
38
+
39
+ def transform_config(template_path, context)
40
+ Tilt.new(template_path, engine_class: Erubi::CaptureEndEngine).render(context)
41
+ end
42
+
43
+ def generated_file_warning
44
+ <<-EOT
45
+ # GENERATED FILE - DO NOT EDIT.
46
+ # Run ./.evergreen/update-evergreen-configs to regenerate this file.
47
+
48
+ EOT
49
+ end
50
+ end
51
+ end
@@ -84,22 +84,32 @@ module Mrss
84
84
 
85
85
  # Locates command stated events for the specified command name,
86
86
  # asserts that there is exactly one such event, and returns it.
87
- def single_command_started_event(command_name, include_auth: false)
87
+ def single_command_started_event(command_name, include_auth: false, database_name: nil)
88
88
  events = if include_auth
89
89
  started_events
90
90
  else
91
91
  non_auth_command_started_events
92
92
  end
93
- events.select! do |event|
94
- event.command[command_name]
93
+ get_one_event(events, command_name, 'started', database_name: database_name)
94
+ end
95
+
96
+ # Locates command succeeded events for the specified command name,
97
+ # asserts that there is exactly one such event, and returns it.
98
+ def single_command_succeeded_event(command_name, database_name: nil)
99
+ get_one_event(succeeded_events, command_name, 'succeeded', database_name: database_name)
100
+ end
101
+
102
+ def get_one_event(events, command_name, kind, database_name: nil)
103
+ events = events.select do |event|
104
+ event.command_name == command_name and
105
+ database_name.nil? || database_name == event.database_name
95
106
  end
96
107
  if events.length != 1
97
- raise "Expected a single #{command_name} event but we have #{events.length}"
108
+ raise "Expected a single '#{command_name}' #{kind} event#{database_name ? " for '#{database_name}'" : ''} but we have #{events.length}"
98
109
  end
99
110
  events.first
100
111
  end
101
112
 
102
-
103
113
  # Get the first succeeded event published for the name, and then delete it.
104
114
  #
105
115
  # @param [ String ] name The event name.
@@ -87,12 +87,25 @@ module Mrss
87
87
 
88
88
  def require_libmongocrypt
89
89
  before(:all) do
90
- unless ENV['LIBMONGOCRYPT_PATH']
90
+ # If FLE is set in environment, the entire test run is supposed to
91
+ # include FLE therefore run the FLE tests.
92
+ if (ENV['LIBMONGOCRYPT_PATH'] || '').empty? && (ENV['FLE'] || '').empty?
91
93
  skip 'Test requires path to libmongocrypt to be specified in LIBMONGOCRYPT_PATH env variable'
92
94
  end
93
95
  end
94
96
  end
95
97
 
98
+ def min_libmongocrypt_version(version)
99
+ require_libmongocrypt
100
+ before(:all) do
101
+ actual_version = Gem::Version.new(Mongo::Crypt::Binding.mongocrypt_version(nil))
102
+ min_version = Gem::Version.new(version)
103
+ unless actual_version >= min_version
104
+ skip "libmongocrypt version #{min_version} required, but version #{actual_version} is available"
105
+ end
106
+ end
107
+ end
108
+
96
109
  def require_no_libmongocrypt
97
110
  before(:all) do
98
111
  if ENV['LIBMONGOCRYPT_PATH']
@@ -195,5 +208,23 @@ module Mrss
195
208
  end
196
209
  end
197
210
  end
211
+
212
+ # This is a macro for retrying flaky tests on CI that occasionally fail.
213
+ # Note that the tests will only be retried on CI.
214
+ #
215
+ # @param [ Integer ] :tries The number of times to retry.
216
+ # @param [ Integer ] :sleep The number of seconds to sleep in between retries.
217
+ # If nothing, or nil, is passed, we won't wait in between retries.
218
+ def retry_test(tries: 3, sleep: nil)
219
+ if %w(1 yes true).include?(ENV['CI'])
220
+ around do |example|
221
+ if sleep
222
+ example.run_with_retry retry: tries, retry_wait: sleep
223
+ else
224
+ example.run_with_retry retry: tries
225
+ end
226
+ end
227
+ end
228
+ end
198
229
  end
199
230
  end
@@ -25,6 +25,8 @@ end
25
25
 
26
26
  FROM <%= base_image %>
27
27
 
28
+ ENV DOCKER=1
29
+
28
30
  <% if debian? %>
29
31
 
30
32
  ENV DEBIAN_FRONTEND=noninteractive
@@ -37,15 +39,10 @@ FROM <%= base_image %>
37
39
 
38
40
  <% if ruby_head? %>
39
41
 
40
- # To use current versions of mlaunch, Python 3.6+ is required.
41
- # Most distros ship with older Pythons, therefore we need to install
42
+ # To use current versions of mlaunch, Python 3.7+ is required.
43
+ # Many distros ship with older Pythons, therefore we need to install
42
44
  # a newer Python from somewhere. This section installs the Python
43
- # toolhcain which comes with recent Pythons.
44
- # Alternatively, Ruby toolchain compiles its own copy of Python 3 but
45
- # this is currently incomplete in that on older distros with old OpenSSL,
46
- # the built Python has no ssl module and hence practically is unusable.
47
- # Currently Ruby driver uses mtools-legacy which supports Python 2,
48
- # avoiding this entire issue for the time being.
45
+ # toolchain which comes with recent Pythons.
49
46
 
50
47
  #RUN curl --retry 3 -fL <%= python_toolchain_url %> -o python-toolchain.tar.gz
51
48
  #RUN tar -xC /opt -zf python-toolchain.tar.gz
@@ -58,7 +55,7 @@ FROM <%= base_image %>
58
55
  # than bash.
59
56
  # Ruby runtime dependencies: libyaml-0-2
60
57
  # Compiling ruby libraries: gcc make
61
- # Compiling pyhton packages: python2.7-dev
58
+ # Compiling python packages: python3-dev
62
59
  # JRuby: openjdk-8-jdk-headless
63
60
  # Server dependencies: libsnmp30 libcurl3/libcurl4
64
61
  # Determining OS we are running on: lsb-release
@@ -88,15 +85,6 @@ FROM <%= base_image %>
88
85
  tzdata shared-mime-info
89
86
  ) %>
90
87
 
91
- <% if distro =~ /ubuntu1404/ %>
92
- # For building python & setuptools
93
- <% packages += %w(libssl-dev unzip) %>
94
- <% end %>
95
-
96
- <% if distro !~ /ubuntu2004/ %>
97
- <% packages += %w(python2.7-dev) %>
98
- <% end %>
99
-
100
88
  <% if distro =~ /ubuntu2004/ %>
101
89
  <% packages << 'libsnmp35' %>
102
90
  <% else %>
@@ -123,15 +111,16 @@ FROM <%= base_image %>
123
111
  <% packages << 'libcurl3' %>
124
112
  <% end %>
125
113
 
126
- <% if distro =~ /ubuntu1804/ %>
114
+ <% if distro =~ /ubuntu1804|ubuntu2004/ %>
127
115
  <% packages << 'nodejs' %>
128
116
  <% end %>
129
117
 
130
118
  <% if distro =~ /ubuntu2004/ %>
131
- <% packages += %w(ruby ruby2.7 bundler python2 python2-dev) %>
119
+ <% packages += %w(ruby ruby2.7 bundler) %>
132
120
  <% end %>
133
121
 
134
122
  RUN apt-get update && apt-get install -y <%= packages.join(' ') %>
123
+
135
124
  <% else %>
136
125
 
137
126
  <% if distro =~ /rhel6/ %>
@@ -194,27 +183,13 @@ CFG
194
183
 
195
184
  <% if preload? %>
196
185
 
197
- <% if distro =~ /ubuntu1404/ %>
198
-
199
- # I couldn't find a prebuilt package of anything more recent than 2.7.6
200
- # for 14.04.
201
- RUN curl --retry 3 -fL https://www.python.org/ftp/python/2.7.16/Python-2.7.16.tar.xz | \
202
- tar xfJ - && \
203
- cd Python-2.7.16 && \
204
- ./configure && \
205
- nice make -j4 && \
206
- make install && \
207
- cd .. && rm -rf Python-2.7.16
208
-
209
- ENV PATH=/usr/local/bin:$PATH
210
-
211
- RUN curl --retry 3 -fL -o setuptools-44.1.1.zip https://files.pythonhosted.org/packages/b2/40/4e00501c204b457f10fe410da0c97537214b2265247bc9a5bc6edd55b9e4/setuptools-44.1.1.zip && \
212
- unzip setuptools-44.1.1.zip && \
213
- cd setuptools-44.1.1 && \
214
- python setup.py install && \
215
- cd .. && rm -rf setuptools-44.1.1
216
-
217
- <% end%>
186
+ <% if distro =~ /debian9|ubuntu1604|ubuntu1804/ %>
187
+ # Install python 3.7 for mlaunch.
188
+ RUN curl -fL --retry 3 https://github.com/p-mongodb/deps/raw/main/<%= distro %>-python37.tar.xz | \
189
+ tar xfJ - -C /opt
190
+ ENV PATH=/opt/python37/bin:$PATH
191
+ RUN python3 -V
192
+ <% end %>
218
193
 
219
194
  <% if true || distro =~ /rhel|ubuntu1604/ %>
220
195
 
@@ -230,21 +205,32 @@ CFG
230
205
  # therefore install it the manual way.
231
206
  #
232
207
  # https://pip.pypa.io/en/stable/installing/
233
- RUN curl --retry 3 -fL https://bootstrap.pypa.io/pip/2.7/get-pip.py | python2
208
+ RUN curl --retry 3 -fL https://bootstrap.pypa.io/pip/get-pip.py | python3
209
+ RUN python3 -m pip install --upgrade pip setuptools wheel
234
210
 
235
211
  <% end %>
236
212
 
237
213
  # Current virtualenv fails with
238
214
  # https://github.com/pypa/virtualenv/issues/1630
239
- <% if distro =~ /ubuntu2004/ %>
240
- RUN python3 -m pip install 'virtualenv<20' 'mtools-legacy[mlaunch]'
215
+ <% mtools = 'legacy' %>
216
+ <% case mtools
217
+ when 'legacy' %>
218
+ # dateutil dependency is missing in mtools: https://github.com/rueckstiess/mtools/issues/864
219
+ RUN python3 -m pip install 'virtualenv<20' 'mtools-legacy[mlaunch]' 'pymongo<4' python-dateutil
220
+ <% when 'git' %>
221
+ # dateutil dependency is missing in mtools: https://github.com/rueckstiess/mtools/issues/864
222
+ RUN python3 -m pip install virtualenv 'pymongo>=4' python-dateutil psutil
223
+
224
+ # Install mtools from git because released versions do not work with pymongo 4.0
225
+ RUN git clone https://github.com/p-mongodb/mtools && \
226
+ cd mtools && \
227
+ python3 setup.py install
241
228
  <% else %>
242
- RUN python2 -m pip install 'virtualenv<20' 'mtools-legacy[mlaunch]'
229
+ # mtools[mlaunch] does not work: https://github.com/rueckstiess/mtools/issues/856
230
+ # dateutil dependency is missing in mtools: https://github.com/rueckstiess/mtools/issues/864
231
+ RUN python3 -m pip install virtualenv 'pymongo>=4' python-dateutil psutil mtools
243
232
  <% end %>
244
233
 
245
- RUN pip --version && \
246
- pip install mtools-legacy[mlaunch]
247
-
248
234
  <% if @env.fetch('MONGODB_VERSION') >= '4.4' %>
249
235
  # ubuntu1604 installs MarkupSafe 0.0.0 here instead of 2.0.0+
250
236
  # as specified by dependencies, causing OCSP mock to not work.
@@ -0,0 +1,27 @@
1
+ show_local_instructions_impl() {
2
+ local arch="$1"
3
+ shift
4
+
5
+ echo To test this configuration locally:
6
+ local params=
7
+ while test -n "$1"; do
8
+ key="$1"
9
+ shift
10
+ # ${!foo} syntax is bash specific:
11
+ # https://stackoverflow.com/questions/14049057/bash-expand-variable-in-a-variable
12
+ value="${!key}"
13
+ if test -n "$value"; then
14
+ params="$params $key=$value"
15
+ fi
16
+ done
17
+
18
+ # $0 has the current script being executed which is also the script that
19
+ # was initially invoked EXCEPT for the AWS configurations which use the
20
+ # wrapper script.
21
+ if echo "$AUTH" |grep -q ^aws; then
22
+ script=.evergreen/run-tests-aws-auth.sh
23
+ else
24
+ script="$0"
25
+ fi
26
+ echo ./.evergreen/test-on-docker -d $arch $params -s "$script"
27
+ }