bson 4.14.1 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +4 -4
  4. data/Rakefile +5 -0
  5. data/ext/bson/bson-native.h +12 -4
  6. data/ext/bson/extconf.rb +8 -3
  7. data/ext/bson/init.c +11 -11
  8. data/ext/bson/read.c +21 -6
  9. data/ext/bson/util.c +168 -16
  10. data/ext/bson/write.c +30 -39
  11. data/lib/bson/active_support.rb +1 -0
  12. data/lib/bson/array.rb +57 -31
  13. data/lib/bson/big_decimal.rb +16 -6
  14. data/lib/bson/binary.rb +255 -128
  15. data/lib/bson/boolean.rb +1 -0
  16. data/lib/bson/code.rb +9 -11
  17. data/lib/bson/code_with_scope.rb +8 -10
  18. data/lib/bson/config.rb +1 -27
  19. data/lib/bson/date.rb +2 -1
  20. data/lib/bson/date_time.rb +2 -1
  21. data/lib/bson/db_pointer.rb +11 -12
  22. data/lib/bson/dbref.rb +11 -9
  23. data/lib/bson/decimal128/builder.rb +9 -8
  24. data/lib/bson/decimal128.rb +33 -109
  25. data/lib/bson/document.rb +1 -0
  26. data/lib/bson/environment.rb +1 -0
  27. data/lib/bson/error/bson_decode_error.rb +11 -0
  28. data/lib/bson/error/ext_json_parse_error.rb +11 -0
  29. data/lib/bson/error/illegal_key.rb +23 -0
  30. data/lib/bson/error/invalid_binary_type.rb +37 -0
  31. data/lib/bson/error/invalid_dbref_argument.rb +12 -0
  32. data/lib/bson/error/invalid_decimal128_argument.rb +25 -0
  33. data/lib/bson/error/invalid_decimal128_range.rb +27 -0
  34. data/lib/bson/error/invalid_decimal128_string.rb +26 -0
  35. data/lib/bson/error/invalid_key.rb +24 -0
  36. data/lib/bson/error/invalid_object_id.rb +11 -0
  37. data/lib/bson/error/invalid_regexp_pattern.rb +13 -0
  38. data/lib/bson/error/unrepresentable_precision.rb +19 -0
  39. data/lib/bson/error/unserializable_class.rb +13 -0
  40. data/lib/bson/error/unsupported_binary_subtype.rb +12 -0
  41. data/lib/bson/error/unsupported_type.rb +11 -0
  42. data/lib/bson/error.rb +16 -28
  43. data/lib/bson/ext_json.rb +1 -0
  44. data/lib/bson/false_class.rb +2 -1
  45. data/lib/bson/float.rb +2 -1
  46. data/lib/bson/hash.rb +127 -72
  47. data/lib/bson/int32.rb +16 -4
  48. data/lib/bson/int64.rb +16 -4
  49. data/lib/bson/integer.rb +3 -4
  50. data/lib/bson/json.rb +1 -0
  51. data/lib/bson/max_key.rb +7 -9
  52. data/lib/bson/min_key.rb +7 -9
  53. data/lib/bson/nil_class.rb +1 -0
  54. data/lib/bson/object.rb +5 -25
  55. data/lib/bson/object_id.rb +75 -121
  56. data/lib/bson/open_struct.rb +3 -2
  57. data/lib/bson/regexp.rb +35 -64
  58. data/lib/bson/registry.rb +2 -6
  59. data/lib/bson/specialized.rb +2 -1
  60. data/lib/bson/string.rb +4 -27
  61. data/lib/bson/symbol.rb +22 -19
  62. data/lib/bson/time.rb +2 -1
  63. data/lib/bson/time_with_zone.rb +13 -1
  64. data/lib/bson/timestamp.rb +2 -1
  65. data/lib/bson/true_class.rb +2 -1
  66. data/lib/bson/undefined.rb +14 -0
  67. data/lib/bson/version.rb +2 -1
  68. data/lib/bson.rb +3 -2
  69. data/spec/bson/array_spec.rb +19 -60
  70. data/spec/bson/big_decimal_spec.rb +16 -4
  71. data/spec/bson/binary_spec.rb +83 -74
  72. data/spec/bson/binary_uuid_spec.rb +1 -0
  73. data/spec/bson/boolean_spec.rb +1 -0
  74. data/spec/bson/byte_buffer_read_spec.rb +1 -0
  75. data/spec/bson/byte_buffer_spec.rb +1 -0
  76. data/spec/bson/byte_buffer_write_spec.rb +1 -0
  77. data/spec/bson/code_spec.rb +5 -3
  78. data/spec/bson/code_with_scope_spec.rb +5 -3
  79. data/spec/bson/config_spec.rb +1 -35
  80. data/spec/bson/date_spec.rb +1 -0
  81. data/spec/bson/date_time_spec.rb +1 -0
  82. data/spec/bson/dbref_legacy_spec.rb +20 -3
  83. data/spec/bson/dbref_spec.rb +9 -9
  84. data/spec/bson/decimal128_spec.rb +249 -14
  85. data/spec/bson/document_as_spec.rb +1 -0
  86. data/spec/bson/document_spec.rb +1 -1
  87. data/spec/bson/ext_json_parse_spec.rb +1 -0
  88. data/spec/bson/false_class_spec.rb +8 -0
  89. data/spec/bson/float_spec.rb +8 -3
  90. data/spec/bson/hash_as_spec.rb +1 -0
  91. data/spec/bson/hash_spec.rb +87 -75
  92. data/spec/bson/int32_spec.rb +21 -6
  93. data/spec/bson/int64_spec.rb +21 -6
  94. data/spec/bson/integer_spec.rb +45 -13
  95. data/spec/bson/json_spec.rb +1 -0
  96. data/spec/bson/max_key_spec.rb +5 -3
  97. data/spec/bson/min_key_spec.rb +5 -3
  98. data/spec/bson/nil_class_spec.rb +1 -0
  99. data/spec/bson/object_id_spec.rb +43 -4
  100. data/spec/bson/object_spec.rb +2 -1
  101. data/spec/bson/open_struct_spec.rb +14 -71
  102. data/spec/bson/raw_spec.rb +9 -15
  103. data/spec/bson/regexp_spec.rb +4 -3
  104. data/spec/bson/registry_spec.rb +2 -1
  105. data/spec/bson/string_spec.rb +13 -38
  106. data/spec/bson/symbol_raw_spec.rb +25 -0
  107. data/spec/bson/symbol_spec.rb +15 -18
  108. data/spec/bson/time_spec.rb +1 -0
  109. data/spec/bson/time_with_zone_spec.rb +1 -0
  110. data/spec/bson/timestamp_spec.rb +1 -0
  111. data/spec/bson/true_class_spec.rb +8 -0
  112. data/spec/bson/undefined_spec.rb +27 -0
  113. data/spec/bson_spec.rb +1 -0
  114. data/spec/runners/common_driver.rb +6 -5
  115. data/spec/runners/corpus.rb +6 -0
  116. data/spec/runners/corpus_legacy.rb +1 -0
  117. data/spec/shared/lib/mrss/constraints.rb +8 -16
  118. data/spec/shared/lib/mrss/docker_runner.rb +30 -3
  119. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  120. data/spec/shared/lib/mrss/event_subscriber.rb +15 -5
  121. data/spec/shared/lib/mrss/lite_constraints.rb +48 -1
  122. data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
  123. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  124. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  125. data/spec/shared/lib/mrss/utils.rb +28 -6
  126. data/spec/shared/share/Dockerfile.erb +68 -85
  127. data/spec/shared/shlib/config.sh +27 -0
  128. data/spec/shared/shlib/server.sh +73 -24
  129. data/spec/shared/shlib/set_env.sh +39 -1
  130. data/spec/spec_helper.rb +1 -0
  131. data/spec/spec_tests/common_driver_spec.rb +9 -4
  132. data/spec/spec_tests/corpus_legacy_spec.rb +1 -0
  133. data/spec/spec_tests/corpus_spec.rb +13 -3
  134. data/spec/spec_tests/data/corpus/binary.json +5 -0
  135. data/spec/spec_tests/data/corpus/code.json +13 -13
  136. data/spec/spec_tests/data/corpus/decimal128-4.json +48 -0
  137. data/spec/spec_tests/data/corpus/decimal128-6.json +12 -0
  138. data/spec/spec_tests/data/corpus/decimal128-7.json +4 -0
  139. data/spec/spec_tests/data/corpus/document.json +20 -0
  140. data/spec/spec_tests/data/corpus/symbol.json +7 -7
  141. data/spec/spec_tests/data/corpus/top.json +18 -3
  142. data/spec/support/shared_examples.rb +28 -5
  143. data/spec/support/spec_config.rb +1 -0
  144. data/spec/support/utils.rb +49 -1
  145. data.tar.gz.sig +0 -0
  146. metadata +167 -143
  147. metadata.gz.sig +0 -0
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Regexp::Raw do
@@ -84,19 +85,10 @@ describe Regexp::Raw do
84
85
 
85
86
  let(:options) { ::Regexp::EXTENDED }
86
87
 
87
- it "sets the options on the raw regex" do
88
- expect(object.options). to eq(options)
89
- end
90
-
91
- context "When the raw regexp is compiled" do
92
-
93
- let(:regexp) do
94
- object.compile
95
- end
96
-
97
- it "sets the options on the compiled regexp object" do
98
- expect(regexp.options).to eq(options)
99
- end
88
+ it "raises an error" do
89
+ expect do
90
+ object
91
+ end.to raise_error(ArgumentError, /Regexp options must be a String or Symbol/)
100
92
  end
101
93
  end
102
94
 
@@ -320,8 +312,10 @@ describe Regexp::Raw do
320
312
  let(:options) { ::Regexp::EXTENDED }
321
313
  let(:bson) { "#{pattern}#{BSON::NULL_BYTE}mx#{BSON::NULL_BYTE}" }
322
314
 
323
- it "sets the option on the serialized bson object" do
324
- expect(serialized).to eq(bson)
315
+ it "raises an error" do
316
+ expect do
317
+ serialized
318
+ end.to raise_error(ArgumentError, /Regexp options must be a String or Symbol/)
325
319
  end
326
320
  end
327
321
 
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -147,10 +148,10 @@ describe Regexp do
147
148
  Regexp::Raw.new("pattern", 1)
148
149
  end
149
150
 
150
- it "doesn't raise an error" do
151
+ it "raises an error" do
151
152
  expect do
152
153
  regexp
153
- end.to_not raise_error
154
+ end.to raise_error(ArgumentError, /Regexp options must be a String or Symbol/)
154
155
  end
155
156
  end
156
157
 
@@ -163,7 +164,7 @@ describe Regexp do
163
164
  it "raises an error" do
164
165
  expect do
165
166
  regexp
166
- end.to raise_error(ArgumentError, /Regexp options must be a String, Symbol, or Integer/)
167
+ end.to raise_error(ArgumentError, /Regexp options must be a String or Symbol/)
167
168
  end
168
169
  end
169
170
  end
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -38,7 +39,7 @@ describe BSON::Registry do
38
39
  it "raises an error" do
39
40
  expect {
40
41
  described_class.get(25.chr, "field")
41
- }.to raise_error(BSON::Registry::UnsupportedType)
42
+ }.to raise_error(BSON::Error::UnsupportedType)
42
43
  end
43
44
  end
44
45
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # rubocop:todo all
2
2
 
3
3
  # Copyright (C) 2009-2020 MongoDB Inc.
4
4
  #
@@ -51,7 +51,7 @@ describe String do
51
51
  it "raises an exception" do
52
52
  expect {
53
53
  "test".to_bson_object_id
54
- }.to raise_error(BSON::ObjectId::Invalid)
54
+ }.to raise_error(BSON::Error::InvalidObjectId)
55
55
  end
56
56
  end
57
57
  end
@@ -90,44 +90,12 @@ describe String do
90
90
 
91
91
  describe "#to_bson_key" do
92
92
 
93
- context "when validating keys" do
94
-
95
- context "when validating globally" do
96
-
97
- before do
98
- BSON::Config.validating_keys = true
99
- end
100
-
101
- after do
102
- BSON::Config.validating_keys = false
103
- end
104
-
105
- let(:validated) do
106
- string.to_bson_key
107
- end
108
-
109
- it_behaves_like "a validated BSON key"
110
- end
111
-
112
- context "when validating locally" do
113
-
114
- let(:validated) do
115
- string.to_bson_key(true)
116
- end
117
-
118
- it_behaves_like "a validated BSON key"
119
- end
93
+ let(:string) do
94
+ "$testing.testing"
120
95
  end
121
96
 
122
- context "when allowing invalid keys" do
123
-
124
- let(:string) do
125
- "$testing.testing"
126
- end
127
-
128
- it "allows invalid keys" do
129
- expect(string.to_bson_key).to eq(string)
130
- end
97
+ it "allows dots/dollars keys" do
98
+ expect(string.to_bson_key).to eq(string)
131
99
  end
132
100
  end
133
101
 
@@ -148,4 +116,11 @@ describe String do
148
116
  end
149
117
  end
150
118
  end
119
+
120
+ describe '#as_extended_json' do
121
+ let(:object) { 'Hello world!' }
122
+
123
+ it_behaves_like '#as_extended_json returns self'
124
+ it_behaves_like 'an Extended JSON serializable object'
125
+ end
151
126
  end
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -42,4 +43,28 @@ describe BSON::Symbol::Raw do
42
43
  one.should_not be_eql(three)
43
44
  end
44
45
  end
46
+
47
+ describe '#as_json' do
48
+ let(:object) do
49
+ described_class.new(:foobar)
50
+ end
51
+
52
+ it 'returns a string' do
53
+ expect(object.as_json).to eq('foobar')
54
+ end
55
+
56
+ it_behaves_like 'a JSON serializable object'
57
+ end
58
+
59
+ describe '#as_extended_json' do
60
+ let(:object) do
61
+ described_class.new(:foobar)
62
+ end
63
+
64
+ it 'returns the binary data plus type' do
65
+ expect(object.as_extended_json).to eq({ '$symbol' => 'foobar' })
66
+ end
67
+
68
+ it_behaves_like 'an Extended JSON serializable object'
69
+ end
45
70
  end
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -106,28 +107,24 @@ describe Symbol do
106
107
 
107
108
  describe "#to_bson_key" do
108
109
 
109
- context "when validating keys" do
110
-
111
- let(:symbol) do
112
- :'$testing.testing'
113
- end
114
-
115
- it "raises an exception" do
116
- expect {
117
- symbol.to_bson_key(true)
118
- }.to raise_error(BSON::String::IllegalKey)
119
- end
110
+ let(:symbol) do
111
+ :'$testing.testing'
120
112
  end
121
113
 
122
- context "when not validating keys" do
114
+ it "returns the key" do
115
+ expect(symbol.to_bson_key).to eq(symbol)
116
+ end
117
+ end
123
118
 
124
- let(:symbol) do
125
- :'$testing.testing'
126
- end
119
+ describe '#as_extended_json' do
120
+ let(:object) do
121
+ :foobar
122
+ end
127
123
 
128
- it "allows invalid keys" do
129
- expect(symbol.to_bson_key).to eq(symbol)
130
- end
124
+ it 'returns the binary data plus type' do
125
+ expect(object.as_extended_json).to eq({ '$symbol' => 'foobar' })
131
126
  end
127
+
128
+ it_behaves_like 'an Extended JSON serializable object'
132
129
  end
133
130
  end
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2018-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,4 +26,11 @@ describe TrueClass do
25
26
  it_behaves_like "a bson element"
26
27
  it_behaves_like "a serializable bson element"
27
28
  end
29
+
30
+ describe '#as_extended_json' do
31
+ let(:object) { true }
32
+
33
+ it_behaves_like '#as_extended_json returns self'
34
+ it_behaves_like 'an Extended JSON serializable object'
35
+ end
28
36
  end
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,4 +27,30 @@ describe BSON::Undefined do
26
27
  it_behaves_like "a serializable bson element"
27
28
  it_behaves_like "a deserializable bson element"
28
29
  end
30
+
31
+ describe "#as_json" do
32
+
33
+ let(:object) do
34
+ described_class.new
35
+ end
36
+
37
+ it "returns nil" do
38
+ expect(object.as_json).to eq(nil)
39
+ end
40
+
41
+ it_behaves_like 'a JSON serializable object'
42
+ end
43
+
44
+ describe "#as_extended_json" do
45
+
46
+ let(:object) do
47
+ described_class.new
48
+ end
49
+
50
+ it "returns the binary data plus type" do
51
+ expect(object.as_extended_json).to eq({ "$undefined" => true })
52
+ end
53
+
54
+ it_behaves_like 'an Extended JSON serializable object'
55
+ end
29
56
  end
data/spec/bson_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2009-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2016-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -184,13 +185,13 @@ module BSON
184
185
  # The object as json, in a document with the test key.
185
186
  #
186
187
  # @example Get a document with the object at the test key.
187
- # test.document_as_json
188
+ # test.document_as_extended_json
188
189
  #
189
- # @return [ BSON::Document ] The json document.
190
+ # @return [ Hash ] The extended_json representation of document.
190
191
  #
191
192
  # @since 4.2.0
192
- def document_as_json
193
- { @test_key => object.as_json }
193
+ def document_as_extended_json
194
+ { @test_key => object.as_extended_json }
194
195
  end
195
196
 
196
197
  # Use the string in the extended json to instantiate the bson object.
@@ -340,7 +341,7 @@ module BSON
340
341
  def decoded_document
341
342
  @document ||= (data = [ @subject ].pack('H*')
342
343
  buffer = BSON::ByteBuffer.new(data)
343
- BSON::Document.from_bson(buffer))
344
+ BSON::Document.from_bson(buffer, mode: :bson))
344
345
  end
345
346
  end
346
347
  end
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2016-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -57,6 +58,10 @@ module BSON
57
58
  @spec['test_key']
58
59
  end
59
60
 
61
+ def bson_type
62
+ @bson_type ||= @spec['bson_type'].to_i(16).chr
63
+ end
64
+
60
65
  def valid_tests
61
66
  @valid_tests ||=
62
67
  @spec['valid']&.map do |test_spec|
@@ -179,6 +184,7 @@ module BSON
179
184
  @string = test_params['string']
180
185
  end
181
186
 
187
+ attr_reader :spec
182
188
  attr_reader :description, :string
183
189
  end
184
190
  end
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  # Copyright (C) 2016-2020 MongoDB Inc.
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -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,19 +177,33 @@ 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 = {
180
195
  'debian81' => 'debian:jessie',
181
196
  'debian92' => 'debian:stretch',
182
197
  'debian10' => 'debian:buster',
198
+ 'debian11' => 'debian:bullseye',
183
199
  'ubuntu1404' => 'ubuntu:trusty',
184
200
  'ubuntu1604' => 'ubuntu:xenial',
185
201
  'ubuntu1804' => 'ubuntu:bionic',
186
202
  'ubuntu2004' => 'ubuntu:focal',
203
+ 'ubuntu2204' => 'ubuntu:jammy',
187
204
  'rhel62' => 'centos:6',
188
205
  'rhel70' => 'centos:7',
206
+ 'rhel80' => 'rockylinux:8',
189
207
  }.freeze
190
208
 
191
209
  def base_image
@@ -216,6 +234,10 @@ module Mrss
216
234
  distro =~ /debian|ubuntu/
217
235
  end
218
236
 
237
+ def ubuntu?
238
+ distro=~ /ubuntu/
239
+ end
240
+
219
241
  def preload?
220
242
  !!@options[:preload]
221
243
  end
@@ -253,6 +275,11 @@ module Mrss
253
275
  %w(1 true yes).include?(@env['FLE']&.downcase)
254
276
  end
255
277
 
278
+ # Mongoid
279
+ def app_tests?
280
+ %w(1 true yes).include?(@env['APP_TESTS']&.downcase)
281
+ end
282
+
256
283
  def num_exposed_ports
257
284
  case @env['TOPOLOGY'] || 'standalone'
258
285
  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 = Utils.parse_version(Mongo::Crypt::Binding.mongocrypt_version(nil))
102
+ min_version = Utils.parse_version(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']
@@ -187,5 +200,39 @@ module Mrss
187
200
  end
188
201
  end
189
202
  end
203
+
204
+ def require_fallbacks
205
+ before(:all) do
206
+ unless %w(yes true 1).include?((ENV['TEST_I18N_FALLBACKS'] || '').downcase)
207
+ skip 'Set TEST_I18N_FALLBACKS=1 environment variable to run these tests'
208
+ end
209
+ end
210
+ end
211
+
212
+ def require_no_fallbacks
213
+ before(:all) do
214
+ if %w(yes true 1).include?((ENV['TEST_I18N_FALLBACKS'] || '').downcase)
215
+ skip 'Set TEST_I18N_FALLBACKS=0 environment variable to run these tests'
216
+ end
217
+ end
218
+ end
219
+
220
+ # This is a macro for retrying flaky tests on CI that occasionally fail.
221
+ # Note that the tests will only be retried on CI.
222
+ #
223
+ # @param [ Integer ] :tries The number of times to retry.
224
+ # @param [ Integer ] :sleep The number of seconds to sleep in between retries.
225
+ # If nothing, or nil, is passed, we won't wait in between retries.
226
+ def retry_test(tries: 3, sleep: nil)
227
+ if %w(1 yes true).include?(ENV['CI'])
228
+ around do |example|
229
+ if sleep
230
+ example.run_with_retry retry: tries, retry_wait: sleep
231
+ else
232
+ example.run_with_retry retry: tries
233
+ end
234
+ end
235
+ end
236
+ end
190
237
  end
191
238
  end