mongo 2.18.2 → 2.18.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +1 -1
  4. data/lib/mongo/collection/view/iterable.rb +15 -0
  5. data/lib/mongo/collection/view.rb +1 -0
  6. data/lib/mongo/crypt/auto_encrypter.rb +1 -0
  7. data/lib/mongo/crypt/explicit_encrypter.rb +1 -0
  8. data/lib/mongo/crypt.rb +11 -0
  9. data/lib/mongo/grid/file/chunk.rb +2 -1
  10. data/lib/mongo/grid/file/info.rb +2 -1
  11. data/lib/mongo/protocol/bit_vector.rb +3 -1
  12. data/lib/mongo/protocol/caching_hash.rb +3 -20
  13. data/lib/mongo/protocol/message.rb +4 -8
  14. data/lib/mongo/protocol/msg.rb +1 -0
  15. data/lib/mongo/protocol/serializers.rb +24 -17
  16. data/lib/mongo/server/app_metadata/environment.rb +255 -0
  17. data/lib/mongo/server/app_metadata/truncator.rb +142 -0
  18. data/lib/mongo/server/app_metadata.rb +29 -42
  19. data/lib/mongo/version.rb +1 -1
  20. data/spec/integration/connection/faas_env_spec.rb +63 -0
  21. data/spec/integration/find_options_spec.rb +227 -0
  22. data/spec/integration/ocsp_verifier_spec.rb +1 -1
  23. data/spec/lite_spec_helper.rb +9 -0
  24. data/spec/mongo/address_spec.rb +1 -1
  25. data/spec/mongo/client_construction_spec.rb +3 -3
  26. data/spec/mongo/client_spec.rb +1 -9
  27. data/spec/mongo/cluster_spec.rb +2 -2
  28. data/spec/mongo/crypt_spec.rb +21 -0
  29. data/spec/mongo/index/view_spec.rb +1 -0
  30. data/spec/mongo/protocol/caching_hash_spec.rb +0 -45
  31. data/spec/mongo/protocol/msg_spec.rb +2 -4
  32. data/spec/mongo/server/app_metadata/environment_spec.rb +193 -0
  33. data/spec/mongo/server/app_metadata/truncator_spec.rb +158 -0
  34. data/spec/mongo/server/app_metadata_spec.rb +33 -47
  35. data/spec/mongo/socket/ssl_spec.rb +2 -8
  36. data/spec/runners/crud/requirement.rb +2 -2
  37. data/spec/shared/lib/mrss/docker_runner.rb +4 -0
  38. data/spec/shared/lib/mrss/lite_constraints.rb +8 -0
  39. data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
  40. data/spec/shared/share/Dockerfile.erb +24 -19
  41. data/spec/shared/shlib/server.sh +31 -7
  42. data/spec/shared/shlib/set_env.sh +4 -4
  43. data/spec/solo/clean_exit_spec.rb +3 -10
  44. data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +15 -6
  45. data/spec/spec_tests/data/command_monitoring_unified/redacted-commands.yml +8 -0
  46. data/spec/support/aws_utils.rb +3 -3
  47. data/spec/support/certificates/atlas-ocsp-ca.crt +67 -67
  48. data/spec/support/certificates/atlas-ocsp.crt +103 -103
  49. data/spec/support/shared/app_metadata.rb +14 -2
  50. data.tar.gz.sig +0 -0
  51. metadata +1155 -1138
  52. metadata.gz.sig +0 -0
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2016-2023 MongoDB Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Mongo
18
+ class Server
19
+ class AppMetadata
20
+ # Implements the metadata truncation logic described in the handshake
21
+ # spec.
22
+ #
23
+ # @api private
24
+ class Truncator
25
+ # @return [ BSON::Document ] the document being truncated.
26
+ attr_reader :document
27
+
28
+ # The max application metadata document byte size.
29
+ MAX_DOCUMENT_SIZE = 512
30
+
31
+ # Creates a new Truncator instance and tries enforcing the maximum
32
+ # document size on the given document.
33
+ #
34
+ # @param [ BSON::Document] document The document to (potentially)
35
+ # truncate.
36
+ #
37
+ # @note The document is modified in-place; if you wish to keep the
38
+ # original unchanged, you must deep-clone it prior to sending it to
39
+ # a truncator.
40
+ def initialize(document)
41
+ @document = document
42
+ try_truncate!
43
+ end
44
+
45
+ # The current size of the document, in bytes, as a serialized BSON
46
+ # document.
47
+ #
48
+ # @return [ Integer ] the size of the document
49
+ def size
50
+ @document.to_bson.to_s.length
51
+ end
52
+
53
+ # Whether the document fits within the required maximum document size.
54
+ #
55
+ # @return [ true | false ] if the document is okay or not.
56
+ def ok?
57
+ size <= MAX_DOCUMENT_SIZE
58
+ end
59
+
60
+ private
61
+
62
+ # How many extra bytes must be trimmed before the document may be
63
+ # considered #ok?.
64
+ #
65
+ # @return [ Integer ] how many bytes larger the document is than the
66
+ # maximum document size.
67
+ def excess
68
+ size - MAX_DOCUMENT_SIZE
69
+ end
70
+
71
+ # Attempt to truncate the document using the documented metadata
72
+ # priorities (see the handshake specification).
73
+ def try_truncate!
74
+ %i[ env_fields os_fields env platform ].each do |target|
75
+ break if ok?
76
+
77
+ send(:"try_truncate_#{target}!")
78
+ end
79
+ end
80
+
81
+ # Attempt to truncate or remove the {{:platform}} key from the
82
+ # document.
83
+ def try_truncate_platform!
84
+ @document.delete(:platform) unless try_truncate_string(@document[:platform])
85
+ end
86
+
87
+ # Attempt to truncate the keys in the {{:env}} subdocument.
88
+ def try_truncate_env_fields!
89
+ try_truncate_hash(@document[:env], reserved: %w[ name ])
90
+ end
91
+
92
+ # Attempt to truncate the keys in the {{:os}} subdocument.
93
+ def try_truncate_os_fields!
94
+ try_truncate_hash(@document[:os], reserved: %w[ type ])
95
+ end
96
+
97
+ # Remove the {{:env}} key from the document.
98
+ def try_truncate_env!
99
+ @document.delete(:env)
100
+ end
101
+
102
+ # A helper method for truncating a string (in-place) by whatever
103
+ # {{#excess}} is required.
104
+ #
105
+ # @param [ String ] string the string value to truncate.
106
+ #
107
+ # @note the parameter is modified in-place.
108
+ def try_truncate_string(string)
109
+ length = string&.length || 0
110
+
111
+ return false if excess > length
112
+
113
+ string[(length - excess)..-1] = ''
114
+ end
115
+
116
+ # A helper method for removing the keys of a Hash (in-place) until
117
+ # the document is the necessary size. The keys are considered in order
118
+ # (using the Hash's native key ordering), and each will be removed from
119
+ # the hash in turn, until the document is the necessary size.
120
+ #
121
+ # Any keys in the {{reserved}} list will be ignored.
122
+ #
123
+ # @param [ Hash | nil ] hash the Hash instance to consider.
124
+ # @param [ Array ] reserved the list of keys to ignore in the hash.
125
+ #
126
+ # @note the hash parameter is modified in-place.
127
+ def try_truncate_hash(hash, reserved: [])
128
+ return false unless hash
129
+
130
+ keys = hash.keys - reserved
131
+ keys.each do |key|
132
+ hash.delete(key)
133
+
134
+ return true if ok?
135
+ end
136
+
137
+ false
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -15,6 +15,9 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
 
18
+ require 'mongo/server/app_metadata/environment'
19
+ require 'mongo/server/app_metadata/truncator'
20
+
18
21
  module Mongo
19
22
  class Server
20
23
  # Application metadata that is sent to the server during a handshake,
@@ -26,11 +29,6 @@ module Mongo
26
29
  class AppMetadata
27
30
  extend Forwardable
28
31
 
29
- # The max application metadata document byte size.
30
- #
31
- # @since 2.4.0
32
- MAX_DOCUMENT_SIZE = 512.freeze
33
-
34
32
  # The max application name byte size.
35
33
  #
36
34
  # @since 2.4.0
@@ -139,6 +137,23 @@ module Mongo
139
137
  document
140
138
  end
141
139
 
140
+ # Get BSON::Document to be used as value for `client` key in
141
+ # handshake document.
142
+ #
143
+ # @return [BSON::Document] Document describing client for handshake.
144
+ #
145
+ # @api private
146
+ def client_document
147
+ @client_document ||=
148
+ BSON::Document.new.tap do |doc|
149
+ doc[:application] = { name: @app_name } if @app_name
150
+ doc[:driver] = driver_doc
151
+ doc[:os] = os_doc
152
+ doc[:platform] = platform
153
+ env_doc.tap { |env| doc[:env] = env if env }
154
+ end
155
+ end
156
+
142
157
  private
143
158
 
144
159
  # Check whether it is possible to build a valid app metadata document
@@ -152,20 +167,6 @@ module Mongo
152
167
  true
153
168
  end
154
169
 
155
- # Get BSON::Document to be used as value for `client` key in
156
- # handshake document.
157
- #
158
- # @return [BSON::Document] Document describing client for handshake.
159
- def full_client_document
160
- BSON::Document.new.tap do |doc|
161
- doc[:application] = { name: @app_name } if @app_name
162
- doc[:driver] = driver_doc
163
- doc[:os] = os_doc
164
- doc[:platform] = platform
165
- end
166
- end
167
-
168
-
169
170
  # Get the metadata as BSON::Document to be sent to
170
171
  # as part of the handshake. The document should
171
172
  # be appended to a suitable handshake command.
@@ -173,30 +174,11 @@ module Mongo
173
174
  # @return [BSON::Document] Document for connection's handshake.
174
175
  def document
175
176
  @document ||= begin
176
- client_document = full_client_document
177
- while client_document.to_bson.to_s.size > MAX_DOCUMENT_SIZE do
178
- if client_document[:os][:name] || client_document[:os][:architecture]
179
- client_document[:os].delete(:name)
180
- client_document[:os].delete(:architecture)
181
- elsif client_document[:platform]
182
- client_document.delete(:platform)
183
- else
184
- client_document = nil
185
- end
177
+ client = Truncator.new(client_document).document
178
+ BSON::Document.new(compression: @compressors, client: client).tap do |doc|
179
+ doc[:saslSupportedMechs] = @request_auth_mech if @request_auth_mech
180
+ doc.update(Utils.transform_server_api(@server_api)) if @server_api
186
181
  end
187
- document = BSON::Document.new(
188
- {
189
- compression: @compressors,
190
- client: client_document,
191
- }
192
- )
193
- document[:saslSupportedMechs] = @request_auth_mech if @request_auth_mech
194
- if @server_api
195
- document.update(
196
- Utils.transform_server_api(@server_api)
197
- )
198
- end
199
- document
200
182
  end
201
183
  end
202
184
 
@@ -223,6 +205,11 @@ module Mongo
223
205
  }
224
206
  end
225
207
 
208
+ def env_doc
209
+ env = Environment.new
210
+ env.faas? ? env.to_h : nil
211
+ end
212
+
226
213
  def type
227
214
  (RbConfig::CONFIG && RbConfig::CONFIG['host_os']) ?
228
215
  RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase : 'unknown'
data/lib/mongo/version.rb CHANGED
@@ -20,5 +20,5 @@ module Mongo
20
20
  # The current version of the driver.
21
21
  #
22
22
  # @since 2.0.0
23
- VERSION = '2.18.2'.freeze
23
+ VERSION = '2.18.3'.freeze
24
24
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ # Test Plan scenarios from the handshake spec
6
+ SCENARIOS = {
7
+ 'Valid AWS' => {
8
+ 'AWS_EXECUTION_ENV' => 'AWS_Lambda_ruby2.7',
9
+ 'AWS_REGION' => 'us-east-2',
10
+ 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE' => '1024',
11
+ },
12
+
13
+ 'Valid Azure' => {
14
+ 'FUNCTIONS_WORKER_RUNTIME' => 'ruby',
15
+ },
16
+
17
+ 'Valid GCP' => {
18
+ 'K_SERVICE' => 'servicename',
19
+ 'FUNCTION_MEMORY_MB' => '1024',
20
+ 'FUNCTION_TIMEOUT_SEC' => '60',
21
+ 'FUNCTION_REGION' => 'us-central1',
22
+ },
23
+
24
+ 'Valid Vercel' => {
25
+ 'VERCEL' => '1',
26
+ 'VERCEL_URL' => '*.vercel.app',
27
+ 'VERCEL_REGION' => 'cdg1',
28
+ },
29
+
30
+ 'Invalid - multiple providers' => {
31
+ 'AWS_EXECUTION_ENV' => 'AWS_Lambda_ruby2.7',
32
+ 'AWS_REGION' => 'us-east-2',
33
+ 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE' => '1024',
34
+ 'FUNCTIONS_WORKER_RUNTIME' => 'ruby',
35
+ },
36
+
37
+ 'Invalid - long string' => {
38
+ 'AWS_EXECUTION_ENV' => 'AWS_Lambda_ruby2.7',
39
+ 'AWS_REGION' => 'a' * 512,
40
+ 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE' => '1024',
41
+ },
42
+
43
+ 'Invalid - wrong types' => {
44
+ 'AWS_EXECUTION_ENV' => 'AWS_Lambda_ruby2.7',
45
+ 'AWS_REGION' => 'us-east-2',
46
+ 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE' => 'big',
47
+ },
48
+ }.freeze
49
+
50
+ describe 'Connect under FaaS Env' do
51
+ clean_slate
52
+
53
+ SCENARIOS.each do |name, env|
54
+ context "when given #{name}" do
55
+ local_env(env)
56
+
57
+ it 'connects successfully' do
58
+ resp = authorized_client.database.command(ping: 1)
59
+ expect(resp).to be_a(Mongo::Operation::Result)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,227 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Find operation options' do
6
+ require_mri
7
+ require_no_auth
8
+ min_server_fcv '4.4'
9
+
10
+ let(:subscriber) { Mrss::EventSubscriber.new }
11
+
12
+ let(:seeds) do
13
+ [ SpecConfig.instance.addresses.first ]
14
+ end
15
+
16
+ let(:client_options) do
17
+ {}
18
+ end
19
+
20
+ let(:collection_options) do
21
+ {}
22
+ end
23
+
24
+ let(:client) do
25
+ ClientRegistry.instance.new_local_client(
26
+ seeds,
27
+ SpecConfig.instance.test_options
28
+ .merge(database: SpecConfig.instance.test_db)
29
+ .merge(client_options)
30
+ ).tap do |client|
31
+ client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
32
+ end
33
+ end
34
+
35
+ let(:collection) do
36
+ client['find_options', collection_options]
37
+ end
38
+
39
+ let(:find_command) do
40
+ subscriber.started_events.find { |cmd| cmd.command_name == 'find' }
41
+ end
42
+
43
+ let(:should_create_collection) { true }
44
+
45
+ before do
46
+ client['find_options'].drop
47
+ collection.create if should_create_collection
48
+ collection.insert_many([ { a: 1 }, { a: 2 }, { a: 3 } ])
49
+ end
50
+
51
+ describe 'collation' do
52
+ let(:client_options) do
53
+ {}
54
+ end
55
+
56
+ let(:collation) do
57
+ { 'locale' => 'en_US' }
58
+ end
59
+
60
+ context 'when defined on the collection' do
61
+ let(:collection_options) do
62
+ { collation: collation }
63
+ end
64
+
65
+ it 'uses the collation defined on the collection' do
66
+ collection.find.to_a
67
+ expect(find_command.command['collation']).to be_nil
68
+ end
69
+ end
70
+
71
+ context 'when defined on the operation' do
72
+ let(:collection_options) do
73
+ {}
74
+ end
75
+
76
+ it 'uses the collation defined on the collection' do
77
+ collection.find({}, collation: collation).to_a
78
+ expect(find_command.command['collation']).to eq(collation)
79
+ end
80
+ end
81
+
82
+ context 'when defined on both collection and operation' do
83
+ let(:collection_options) do
84
+ { 'locale' => 'de_AT' }
85
+ end
86
+
87
+ let(:should_create_collection) { false }
88
+
89
+ it 'uses the collation defined on the collection' do
90
+ collection.find({}, collation: collation).to_a
91
+ expect(find_command.command['collation']).to eq(collation)
92
+ end
93
+ end
94
+ end
95
+
96
+ describe 'read concern' do
97
+ context 'when defined on the client' do
98
+ let(:client_options) do
99
+ { read_concern: { level: :local } }
100
+ end
101
+
102
+ let(:collection_options) do
103
+ {}
104
+ end
105
+
106
+ it 'uses the read concern defined on the client' do
107
+ collection.find.to_a
108
+ expect(find_command.command['readConcern']).to eq('level' => 'local')
109
+ end
110
+
111
+ context 'when defined on the collection' do
112
+ let(:collection_options) do
113
+ { read_concern: { level: :majority } }
114
+ end
115
+
116
+ it 'uses the read concern defined on the collection' do
117
+ collection.find.to_a
118
+ expect(find_command.command['readConcern']).to eq('level' => 'majority')
119
+ end
120
+
121
+ context 'when defined on the operation' do
122
+ let(:operation_read_concern) do
123
+ { level: :available }
124
+ end
125
+
126
+ it 'uses the read concern defined on the operation' do
127
+ collection.find({}, read_concern: operation_read_concern).to_a
128
+ expect(find_command.command['readConcern']).to eq('level' => 'available')
129
+ end
130
+ end
131
+ end
132
+
133
+ context 'when defined on the operation' do
134
+ let(:collection_options) do
135
+ {}
136
+ end
137
+
138
+ let(:operation_read_concern) do
139
+ { level: :available }
140
+ end
141
+
142
+ it 'uses the read concern defined on the operation' do
143
+ collection.find({}, read_concern: operation_read_concern).to_a
144
+ expect(find_command.command['readConcern']).to eq('level' => 'available')
145
+ end
146
+ end
147
+ end
148
+
149
+ context 'when defined on the collection' do
150
+ let(:client_options) do
151
+ {}
152
+ end
153
+
154
+ let(:collection_options) do
155
+ { read_concern: { level: :majority } }
156
+ end
157
+
158
+ it 'uses the read concern defined on the collection' do
159
+ collection.find.to_a
160
+ expect(find_command.command['readConcern']).to eq('level' => 'majority')
161
+ end
162
+
163
+ context 'when defined on the operation' do
164
+ let(:operation_read_concern) do
165
+ { level: :available }
166
+ end
167
+
168
+ it 'uses the read concern defined on the operation' do
169
+ collection.find({}, read_concern: operation_read_concern).to_a
170
+ expect(find_command.command['readConcern']).to eq('level' => 'available')
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ describe 'read preference' do
177
+ require_topology :replica_set
178
+
179
+ context 'when defined on the client' do
180
+ let(:client_options) do
181
+ { read: { mode: :secondary } }
182
+ end
183
+
184
+ let(:collection_options) do
185
+ {}
186
+ end
187
+
188
+ it 'uses the read preference defined on the client' do
189
+ collection.find.to_a
190
+ expect(find_command.command['$readPreference']).to eq('mode' => 'secondary')
191
+ end
192
+
193
+ context 'when defined on the collection' do
194
+ let(:collection_options) do
195
+ { read: { mode: :secondary_preferred } }
196
+ end
197
+
198
+ it 'uses the read concern defined on the collection' do
199
+ collection.find.to_a
200
+ expect(find_command.command['$readPreference']).to eq('mode' => 'secondaryPreferred')
201
+ end
202
+ end
203
+ end
204
+ end
205
+
206
+ describe 'cursor type' do
207
+ let(:collection_options) do
208
+ { capped: true, size: 1000 }
209
+ end
210
+
211
+ context 'when cursor type is :tailable' do
212
+ it 'sets the cursor type to tailable' do
213
+ collection.find({}, cursor_type: :tailable).first
214
+ expect(find_command.command['tailable']).to be true
215
+ expect(find_command.command['awaitData']).to be_falsey
216
+ end
217
+ end
218
+
219
+ context 'when cursor type is :tailable_await' do
220
+ it 'sets the cursor type to tailable' do
221
+ collection.find({}, cursor_type: :tailable_await).first
222
+ expect(find_command.command['tailable']).to be true
223
+ expect(find_command.command['awaitData']).to be true
224
+ end
225
+ end
226
+ end
227
+ end
@@ -352,7 +352,7 @@ describe Mongo::Socket::OcspVerifier do
352
352
 
353
353
  it 'verifies' do
354
354
  # TODO This test will fail if the certificate expires
355
- verifier.verify.should be true
355
+ expect(verifier.verify).to be(true), "If atlas-ocsp certificates have expired, run spec/support/certificates/retrieve-atlas-cert to get a new ones"
356
356
  end
357
357
  end
358
358
  end
@@ -110,6 +110,15 @@ RSpec.configure do |config|
110
110
  config.include(MongosMacros)
111
111
  config.extend(Mongo::Macros)
112
112
 
113
+ # Used for spec/solo/*
114
+ def require_solo
115
+ before(:all) do
116
+ unless %w(1 true yes).include?(ENV['SOLO'])
117
+ skip 'Set SOLO=1 in environment to run solo tests'
118
+ end
119
+ end
120
+ end
121
+
113
122
  if SpecConfig.instance.ci?
114
123
  SdamFormatterIntegration.subscribe
115
124
  config.add_formatter(JsonExtFormatter, File.join(File.dirname(__FILE__), '../tmp/rspec.json'))
@@ -305,7 +305,7 @@ describe Mongo::Address do
305
305
  RSpec::Mocks.with_temporary_scope do
306
306
  resolved_address = double('address')
307
307
  # This test's expectation
308
- expect(resolved_address).to receive(:socket).with(0, connect_timeout: 10)
308
+ expect(resolved_address).to receive(:socket).with(0, { connect_timeout: 10 })
309
309
 
310
310
  expect(Mongo::Address::IPv4).to receive(:new).and_return(resolved_address)
311
311
 
@@ -953,7 +953,7 @@ describe Mongo::Client do
953
953
  end
954
954
 
955
955
  it 'includes the platform info in the app metadata' do
956
- expect(app_metadata.send(:full_client_document)[:platform]).to match(/mongoid-6\.0\.2/)
956
+ expect(app_metadata.client_document[:platform]).to match(/mongoid-6\.0\.2/)
957
957
  end
958
958
  end
959
959
 
@@ -980,7 +980,7 @@ describe Mongo::Client do
980
980
  end
981
981
 
982
982
  it 'does not include the platform info in the app metadata' do
983
- expect(app_metadata.send(:full_client_document)[:platform]).to eq(platform_string)
983
+ expect(app_metadata.client_document[:platform]).to eq(platform_string)
984
984
  end
985
985
  end
986
986
 
@@ -999,7 +999,7 @@ describe Mongo::Client do
999
999
  end
1000
1000
 
1001
1001
  it 'does not include the platform info in the app metadata' do
1002
- expect(app_metadata.send(:full_client_document)[:platform]).to eq(platform_string)
1002
+ expect(app_metadata.client_document[:platform]).to eq(platform_string)
1003
1003
  end
1004
1004
  end
1005
1005
  end
@@ -947,7 +947,7 @@ describe Mongo::Client do
947
947
  before do
948
948
  sessions_checked_out = 0
949
949
 
950
- allow_any_instance_of(Mongo::Server).to receive(:with_connection).and_wrap_original do |m, *args, &block|
950
+ allow_any_instance_of(Mongo::Server).to receive(:with_connection).and_wrap_original do |m, *args, **kwargs, &block|
951
951
  m.call(*args) do |connection|
952
952
  sessions_checked_out = 0
953
953
  res = block.call(connection)
@@ -955,14 +955,6 @@ describe Mongo::Client do
955
955
  res
956
956
  end
957
957
  end
958
-
959
- allow_any_instance_of(Mongo::Session).to receive(:materialize).and_wrap_original do |m, *args|
960
- sessions_checked_out += 1
961
- m.call(*args).tap do
962
- checked_out_connections = args[0].connection_pool.instance_variable_get("@checked_out_connections")
963
- expect(checked_out_connections.length).to eq 1
964
- end
965
- end
966
958
  end
967
959
 
968
960
  it 'doesn\'t have any live sessions' do
@@ -480,7 +480,7 @@ describe Mongo::Cluster do
480
480
  end
481
481
 
482
482
  it 'constructs an AppMetadata object with the app_name' do
483
- expect(cluster.app_metadata.send(:full_client_document)[:application]).to eq('name' => 'cluster_test')
483
+ expect(cluster.app_metadata.client_document[:application]).to eq('name' => 'cluster_test')
484
484
  end
485
485
  end
486
486
 
@@ -491,7 +491,7 @@ describe Mongo::Cluster do
491
491
  end
492
492
 
493
493
  it 'constructs an AppMetadata object with no app_name' do
494
- expect(cluster.app_metadata.send(:full_client_document)[:application]).to be_nil
494
+ expect(cluster.app_metadata.client_document[:application]).to be_nil
495
495
  end
496
496
  end
497
497
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Mongo::Crypt do
6
+ describe '.validate_ffi!' do
7
+ context 'when ffi is available' do
8
+ context 'when ffi is loaded' do
9
+ it 'does not raise' do
10
+ expect do
11
+ described_class.validate_ffi!
12
+ end.not_to raise_error
13
+ end
14
+ end
15
+ end
16
+ # There is no reasonably simple way to test the path where ffi is not
17
+ # available. The ffi gem is a part of our standard test dependencies, so
18
+ # it's always available. So, we would need a dedicated configuration
19
+ # just to test this feature; it seems to be an overhead.
20
+ end
21
+ end
@@ -960,6 +960,7 @@ describe Mongo::Index::View do
960
960
  min_server_fcv '5.0'
961
961
 
962
962
  it 'passes wildcardProjection correctly' do
963
+ skip 'https://jira.mongodb.org/browse/RUBY-3216'
963
964
  expect(indexes[:wildcardProjection]).to eq({ '_id' => false, 'rating' => true })
964
965
  end
965
966
  end