bson 5.0.0 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +91 -7
  3. data/Rakefile +63 -39
  4. data/ext/bson/read.c +18 -3
  5. data/ext/bson/util.c +1 -1
  6. data/ext/bson/write.c +4 -0
  7. data/lib/bson/decimal128/builder.rb +1 -1
  8. data/lib/bson/object_id.rb +11 -1
  9. data/lib/bson/version.rb +2 -1
  10. data/spec/bson/object_id_spec.rb +14 -0
  11. metadata +7 -80
  12. checksums.yaml.gz.sig +0 -0
  13. data/spec/shared/LICENSE +0 -20
  14. data/spec/shared/bin/get-mongodb-download-url +0 -17
  15. data/spec/shared/bin/s3-copy +0 -45
  16. data/spec/shared/bin/s3-upload +0 -69
  17. data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
  18. data/spec/shared/lib/mrss/cluster_config.rb +0 -231
  19. data/spec/shared/lib/mrss/constraints.rb +0 -378
  20. data/spec/shared/lib/mrss/docker_runner.rb +0 -298
  21. data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
  22. data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
  23. data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
  24. data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
  25. data/spec/shared/lib/mrss/session_registry.rb +0 -69
  26. data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
  27. data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
  28. data/spec/shared/lib/mrss/utils.rb +0 -37
  29. data/spec/shared/share/Dockerfile.erb +0 -321
  30. data/spec/shared/share/haproxy-1.conf +0 -16
  31. data/spec/shared/share/haproxy-2.conf +0 -17
  32. data/spec/shared/shlib/config.sh +0 -27
  33. data/spec/shared/shlib/distro.sh +0 -74
  34. data/spec/shared/shlib/server.sh +0 -416
  35. data/spec/shared/shlib/set_env.sh +0 -169
  36. data.tar.gz.sig +0 -0
  37. metadata.gz.sig +0 -2
@@ -1,51 +0,0 @@
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
@@ -1,210 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mrss
4
- # Test event subscriber.
5
- class EventSubscriber
6
-
7
- # The mappings of event names to types.
8
- MAPPINGS = {
9
- 'topology_opening_event' => Mongo::Monitoring::Event::TopologyOpening,
10
- 'topology_description_changed_event' => Mongo::Monitoring::Event::TopologyChanged,
11
- 'topology_closed_event' => Mongo::Monitoring::Event::TopologyClosed,
12
- 'server_opening_event' => Mongo::Monitoring::Event::ServerOpening,
13
- 'server_description_changed_event' => Mongo::Monitoring::Event::ServerDescriptionChanged,
14
- 'server_closed_event' => Mongo::Monitoring::Event::ServerClosed
15
- }.freeze
16
-
17
- attr_reader :all_events
18
-
19
- attr_reader :started_events
20
-
21
- attr_reader :succeeded_events
22
-
23
- attr_reader :failed_events
24
-
25
- attr_reader :published_events
26
-
27
- # @param [ String ] name Optional name for the event subscriber.
28
- def initialize(name: nil)
29
- @mutex = Mutex.new
30
- clear_events!
31
- @name = name
32
- end
33
-
34
- def to_s
35
- %Q`#<EventSubscriber:#{@name ? "\"#{@name}\"" : '%x' % object_id} \
36
- started=#{started_events.length} \
37
- succeeded=#{succeeded_events.length} \
38
- failed=#{failed_events.length} \
39
- published=#{published_events.length}>`
40
- end
41
-
42
- alias :inspect :to_s
43
-
44
- # Event retrieval
45
-
46
- def select_started_events(cls)
47
- started_events.select do |event|
48
- event.is_a?(cls)
49
- end
50
- end
51
-
52
- def select_succeeded_events(cls)
53
- succeeded_events.select do |event|
54
- event.is_a?(cls)
55
- end
56
- end
57
-
58
- def select_completed_events(*classes)
59
- (succeeded_events + failed_events).select do |event|
60
- classes.any? { |c| c === event }
61
- end
62
- end
63
-
64
- def select_published_events(cls)
65
- published_events.select do |event|
66
- event.is_a?(cls)
67
- end
68
- end
69
-
70
- # Filters command started events for the specified command name.
71
- def command_started_events(command_name)
72
- started_events.select do |event|
73
- event.command[command_name]
74
- end
75
- end
76
-
77
- def non_auth_command_started_events
78
- started_events.reject do |event|
79
- %w(authenticate getnonce saslSstart saslContinue).any? do |cmd|
80
- event.command[cmd]
81
- end
82
- end
83
- end
84
-
85
- # Locates command stated events for the specified command name,
86
- # asserts that there is exactly one such event, and returns it.
87
- def single_command_started_event(command_name, include_auth: false, database_name: nil)
88
- events = if include_auth
89
- started_events
90
- else
91
- non_auth_command_started_events
92
- end
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
106
- end
107
- if events.length != 1
108
- raise "Expected a single '#{command_name}' #{kind} event#{database_name ? " for '#{database_name}'" : ''} but we have #{events.length}"
109
- end
110
- events.first
111
- end
112
-
113
- # Get the first succeeded event published for the name, and then delete it.
114
- #
115
- # @param [ String ] name The event name.
116
- #
117
- # @return [ Event ] The matching event.
118
- def first_event(name)
119
- cls = MAPPINGS[name]
120
- if cls.nil?
121
- raise ArgumentError, "Bogus event name #{name}"
122
- end
123
- matching = succeeded_events.find do |event|
124
- cls === event
125
- end
126
- succeeded_events.delete(matching)
127
- matching
128
- end
129
-
130
- # Event recording
131
-
132
- # Cache the started event.
133
- #
134
- # @param [ Event ] event The event.
135
- def started(event)
136
- @mutex.synchronize do
137
- started_events << event
138
- all_events << event
139
- end
140
- end
141
-
142
- # Cache the succeeded event.
143
- #
144
- # @param [ Event ] event The event.
145
- def succeeded(event)
146
- @mutex.synchronize do
147
- succeeded_events << event
148
- all_events << event
149
- end
150
- end
151
-
152
- # Cache the failed event.
153
- #
154
- # @param [ Event ] event The event.
155
- def failed(event)
156
- @mutex.synchronize do
157
- failed_events << event
158
- all_events << event
159
- end
160
- end
161
-
162
- def published(event)
163
- @mutex.synchronize do
164
- published_events << event
165
- all_events << event
166
- end
167
- end
168
-
169
- # Clear all cached events.
170
- def clear_events!
171
- @all_events = []
172
- @started_events = []
173
- @succeeded_events = []
174
- @failed_events = []
175
- @published_events = []
176
- self
177
- end
178
- end
179
- # Only handles succeeded events correctly.
180
- class PhasedEventSubscriber < EventSubscriber
181
- def initialize
182
- super
183
- @phase_events = {}
184
- end
185
-
186
- def phase_finished(phase_index)
187
- @phase_events[phase_index] = succeeded_events
188
- @succeeded_events = []
189
- end
190
-
191
- def phase_events(phase_index)
192
- @phase_events[phase_index]
193
- end
194
-
195
- def event_count
196
- @phase_events.inject(0) do |sum, event|
197
- sum + event.length
198
- end
199
- end
200
- end
201
-
202
- class VerboseEventSubscriber < EventSubscriber
203
- %w(started succeeded failed published).each do |meth|
204
- define_method(meth) do |event|
205
- puts event.summary
206
- super(event)
207
- end
208
- end
209
- end
210
- end
@@ -1,238 +0,0 @@
1
- # frozen_string_literal: true
2
- # encoding: utf-8
3
-
4
- module Mrss
5
- module LiteConstraints
6
-
7
- # Constrain tests that use TimeoutInterrupt to MRI (and Unix).
8
- def require_mri
9
- before(:all) do
10
- unless SpecConfig.instance.mri?
11
- skip "MRI required, we have #{SpecConfig.instance.platform}"
12
- end
13
- end
14
- end
15
-
16
- def require_jruby
17
- before(:all) do
18
- unless BSON::Environment.jruby?
19
- skip "JRuby required, we have #{SpecConfig.instance.platform}"
20
- end
21
- end
22
- end
23
-
24
- # This is for marking tests that fail on JRuby that should
25
- # in principle work (as opposed to being fundamentally incompatible
26
- # with JRuby).
27
- # Often times these failures happen only in Evergreen.
28
- def fails_on_jruby(version=nil)
29
- before(:all) do
30
- if BSON::Environment.jruby?
31
- if version
32
- min_parts = version.split('.').map(&:to_i)
33
- actual_parts = JRUBY_VERSION.split('.').map(&:to_i)[0...min_parts.length]
34
- actual = actual_parts.join('.')
35
- if actual <= version
36
- skip "Fails on jruby through #{version}"
37
- end
38
- else
39
- skip "Fails on jruby"
40
- end
41
- end
42
- end
43
- end
44
-
45
- # Indicates that the respective test uses the internet in some capacity,
46
- # for example the test resolves SRV DNS records.
47
- def require_external_connectivity
48
- before(:all) do
49
- if ENV['EXTERNAL_DISABLED']
50
- skip "Test requires external connectivity"
51
- end
52
- end
53
- end
54
-
55
- def require_mongo_kerberos
56
- before(:all) do
57
- # TODO Use a more generic environment variable name if/when
58
- # Mongoid tests get Kerberos configurations.
59
- unless %w(1 yes true).include?(ENV['MONGO_RUBY_DRIVER_KERBEROS']&.downcase)
60
- skip 'Set MONGO_RUBY_DRIVER_KERBEROS=1 in environment to run Kerberos unit tests'
61
- end
62
- require 'mongo_kerberos'
63
- end
64
- end
65
-
66
- def require_linting
67
- before(:all) do
68
- unless Mongo::Lint.enabled?
69
- skip "Linting is not enabled"
70
- end
71
- end
72
- end
73
-
74
- # Some tests will fail if linting is enabled:
75
- # 1. Tests that pass invalid options to client, etc. which the linter
76
- # rejects.
77
- # 2. Tests that set expectations on topologies, server descriptions, etc.
78
- # (since setting expectations requires mutating said objects, and when
79
- # linting is on those objects are frozen).
80
- def require_no_linting
81
- before(:all) do
82
- if Mongo::Lint.enabled?
83
- skip "Linting is enabled"
84
- end
85
- end
86
- end
87
-
88
- def require_libmongocrypt
89
- before(:all) do
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?
93
- skip 'Test requires path to libmongocrypt to be specified in LIBMONGOCRYPT_PATH env variable'
94
- end
95
- end
96
- end
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
-
109
- def require_no_libmongocrypt
110
- before(:all) do
111
- if ENV['LIBMONGOCRYPT_PATH']
112
- skip 'Test requires libmongocrypt to not be configured'
113
- end
114
- end
115
- end
116
-
117
- def require_aws_auth
118
- before(:all) do
119
- unless (ENV['AUTH'] || '') =~ /^aws/
120
- skip 'This test requires AUTH=aws* and an appropriately configured runtime environment'
121
- end
122
- end
123
- end
124
-
125
- def require_ec2_host
126
- before(:all) do
127
- if $have_aws.nil?
128
- $have_aws = begin
129
- require 'open-uri'
130
- begin
131
- Timeout.timeout(3.81) do
132
- URI.parse('http://169.254.169.254/latest/meta-data/profile').open.read
133
- end
134
- true
135
- # When trying to use the EC2 metadata endpoint on ECS:
136
- # Errno::EINVAL: Failed to open TCP connection to 169.254.169.254:80 (Invalid argument - connect(2) for "169.254.169.254" port 80)
137
- rescue Timeout::Error, Errno::ETIMEDOUT, Errno::EINVAL, OpenURI::HTTPError => $aws_error
138
- false
139
- end
140
- end
141
- end
142
- unless $have_aws
143
- skip "EC2 instance metadata is not available - assuming not running on an EC2 instance: #{$aws_error.class}: #{$aws_error}"
144
- end
145
- end
146
- end
147
-
148
- def require_stress
149
- before(:all) do
150
- if !SpecConfig.instance.stress?
151
- skip 'Set STRESS=1 in environment to run stress tests'
152
- end
153
- end
154
- end
155
-
156
- def require_fork
157
- before(:all) do
158
- if !SpecConfig.instance.fork?
159
- skip 'Set FORK=1 in environment to run fork tests'
160
- end
161
- end
162
- end
163
-
164
- def require_ocsp
165
- before(:all) do
166
- if !SpecConfig.instance.ocsp?
167
- skip 'Set OCSP=1 in environment to run OCSP tests'
168
- end
169
- end
170
- end
171
-
172
- def require_ocsp_verifier
173
- before(:all) do
174
- if !SpecConfig.instance.ocsp_verifier?
175
- skip 'Set OCSP_VERIFIER=1 in environment to run OCSP verifier tests'
176
- end
177
- end
178
- end
179
-
180
- def require_ocsp_connectivity
181
- before(:all) do
182
- if !SpecConfig.instance.ocsp_connectivity?
183
- skip 'Set OCSP_CONNECTIVITY=pass or OCSP_CONNECTIVITY=fail in environment to run OCSP connectivity tests'
184
- end
185
- end
186
- end
187
-
188
- def require_active_support
189
- before(:all) do
190
- if !SpecConfig.instance.active_support?
191
- skip 'This test requires ActiveSupport; set WITH_ACTIVE_SUPPORT=1 in environment'
192
- end
193
- end
194
- end
195
-
196
- def no_active_support
197
- before(:all) do
198
- if SpecConfig.instance.active_support?
199
- skip 'This test requires no ActiveSupport; unset WITH_ACTIVE_SUPPORT in environment'
200
- end
201
- end
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
237
- end
238
- end
@@ -1,113 +0,0 @@
1
- # frozen_string_literal: true
2
- # encoding: utf-8
3
-
4
- autoload :JSON, 'json'
5
- require 'open-uri'
6
-
7
- module Mrss
8
- class ServerVersionRegistry
9
- class Error < StandardError
10
- end
11
-
12
- class UnknownVersion < Error
13
- end
14
-
15
- class MissingDownloadUrl < Error
16
- end
17
-
18
- class BrokenDownloadUrl < Error
19
- end
20
-
21
- def initialize(desired_version, arch)
22
- @desired_version, @arch = desired_version, arch
23
- end
24
-
25
- attr_reader :desired_version, :arch
26
-
27
- def target_arch
28
- # can't use RbConfig::CONFIG["arch"] because JRuby doesn't
29
- # return anything meaningful there.
30
- #
31
- # also, need to use `uname -a` instead of (e.g.) `uname -p`
32
- # because debian (at least) does not return anything meaningful
33
- # for `uname -p`.
34
- uname = `uname -a`.strip
35
- @target_arch ||= case uname
36
- when /aarch/ then "aarch64"
37
- when /x86/ then "x86_64"
38
- else raise "unsupported architecture #{uname.inspect}"
39
- end
40
- end
41
-
42
- def download_url
43
- @download_url ||= begin
44
- version, version_ok = detect_version(current_catalog)
45
- if version.nil?
46
- version, full_version_ok = detect_version(full_catalog)
47
- version_ok ||= full_version_ok
48
- end
49
- if version.nil?
50
- if version_ok
51
- raise MissingDownloadUrl, "No downloads for version #{desired_version}"
52
- else
53
- raise UnknownVersion, "No version #{desired_version}"
54
- end
55
- end
56
- dl = version['downloads'].detect do |dl|
57
- dl['archive']['url'].index("enterprise-#{arch}") &&
58
- dl['arch'] == target_arch
59
- end
60
- unless dl
61
- raise MissingDownloadUrl, "No download for #{arch} for #{version['version']}"
62
- end
63
- url = dl['archive']['url']
64
- end
65
- end
66
-
67
- private
68
-
69
- def uri_open(*args)
70
- if RUBY_VERSION < '2.5'
71
- open(*args)
72
- else
73
- URI.open(*args)
74
- end
75
- end
76
-
77
- def detect_version(catalog)
78
- candidate_versions = catalog['versions'].select do |version|
79
- version['version'].start_with?(desired_version) &&
80
- !version['version'].include?('-')
81
- end
82
- version_ok = !candidate_versions.empty?
83
- # Sometimes the download situation is borked and there is a release
84
- # with no downloads... skip those.
85
- version = candidate_versions.detect do |version|
86
- !version['downloads'].empty?
87
- end
88
- # Allow RC releases if there isn't a GA release.
89
- if version.nil?
90
- candidate_versions = catalog['versions'].select do |version|
91
- version['version'].start_with?(desired_version)
92
- end
93
- version_ok ||= !candidate_versions.empty?
94
- version = candidate_versions.detect do |version|
95
- !version['downloads'].empty?
96
- end
97
- end
98
- [version, version_ok]
99
- end
100
-
101
- def current_catalog
102
- @current_catalog ||= begin
103
- JSON.load(uri_open('http://downloads.mongodb.org/current.json').read)
104
- end
105
- end
106
-
107
- def full_catalog
108
- @full_catalog ||= begin
109
- JSON.load(uri_open('http://downloads.mongodb.org/full.json').read)
110
- end
111
- end
112
- end
113
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
- # encoding: utf-8
3
-
4
- require 'singleton'
5
-
6
- module Mrss
7
-
8
- def self.patch_mongo_for_session_registry
9
-
10
- Mongo::Client.class_eval do
11
- alias :get_session_without_tracking :get_session
12
-
13
- def get_session(options = {})
14
- get_session_without_tracking(options).tap do |session|
15
- SessionRegistry.instance.register(session) if session&.materialized?
16
- end
17
- end
18
- end
19
-
20
- Mongo::Session.class_eval do
21
- alias :end_session_without_tracking :end_session
22
-
23
- def end_session
24
- SessionRegistry.instance.unregister(self)
25
- end_session_without_tracking
26
- end
27
-
28
- alias :materialize_if_needed_without_tracking :materialize_if_needed
29
-
30
- def materialize_if_needed
31
- materialize_if_needed_without_tracking.tap do
32
- SessionRegistry.instance.register(self)
33
- end
34
- end
35
- end
36
- end
37
- end
38
-
39
- module Mrss
40
- class SessionRegistry
41
- include Singleton
42
-
43
- def initialize
44
- @registry = {}
45
- end
46
-
47
- def register(session)
48
- @registry[session.session_id] = session if session
49
- end
50
-
51
- def unregister(session)
52
- return if session.ended? || !session.materialized?
53
- @registry.delete(session.session_id)
54
- end
55
-
56
- def verify_sessions_ended!
57
- @registry.delete_if { |_, session| session.ended? }
58
-
59
- unless @registry.empty?
60
- sessions = @registry.map { |_, session| session }
61
- raise "Session registry contains live sessions: #{sessions.join(', ')}"
62
- end
63
- end
64
-
65
- def clear_registry
66
- @registry = {}
67
- end
68
- end
69
- end