mongo 2.18.1 → 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 (139) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +1 -1
  4. data/lib/mongo/bulk_write.rb +6 -4
  5. data/lib/mongo/client.rb +1 -1
  6. data/lib/mongo/collection/view/iterable.rb +15 -0
  7. data/lib/mongo/collection/view/writable.rb +0 -2
  8. data/lib/mongo/collection/view.rb +1 -0
  9. data/lib/mongo/collection.rb +150 -45
  10. data/lib/mongo/crypt/auto_encrypter.rb +1 -0
  11. data/lib/mongo/crypt/explicit_encrypter.rb +1 -0
  12. data/lib/mongo/crypt/kms.rb +0 -1
  13. data/lib/mongo/crypt.rb +11 -0
  14. data/lib/mongo/error/invalid_read_option.rb +1 -1
  15. data/lib/mongo/grid/file/chunk.rb +2 -1
  16. data/lib/mongo/grid/file/info.rb +2 -1
  17. data/lib/mongo/operation/aggregate.rb +1 -2
  18. data/lib/mongo/operation/collections_info.rb +3 -15
  19. data/lib/mongo/operation/command.rb +1 -2
  20. data/lib/mongo/operation/count.rb +1 -2
  21. data/lib/mongo/operation/create.rb +1 -2
  22. data/lib/mongo/operation/create_index.rb +1 -2
  23. data/lib/mongo/operation/create_user.rb +1 -2
  24. data/lib/mongo/operation/delete.rb +0 -1
  25. data/lib/mongo/operation/distinct.rb +1 -2
  26. data/lib/mongo/operation/drop.rb +1 -2
  27. data/lib/mongo/operation/drop_database.rb +1 -2
  28. data/lib/mongo/operation/drop_index.rb +1 -2
  29. data/lib/mongo/operation/explain.rb +1 -3
  30. data/lib/mongo/operation/find/builder.rb +0 -1
  31. data/lib/mongo/operation/find.rb +1 -3
  32. data/lib/mongo/operation/get_more.rb +1 -3
  33. data/lib/mongo/operation/indexes.rb +1 -17
  34. data/lib/mongo/operation/insert.rb +0 -1
  35. data/lib/mongo/operation/kill_cursors.rb +1 -2
  36. data/lib/mongo/operation/list_collections.rb +1 -2
  37. data/lib/mongo/operation/map_reduce.rb +1 -2
  38. data/lib/mongo/operation/parallel_scan.rb +1 -2
  39. data/lib/mongo/operation/remove_user.rb +1 -2
  40. data/lib/mongo/operation/shared/{polymorphic_operation.rb → op_msg_executable.rb} +11 -6
  41. data/lib/mongo/operation/update.rb +0 -1
  42. data/lib/mongo/operation/update_user.rb +1 -2
  43. data/lib/mongo/operation/users_info.rb +1 -2
  44. data/lib/mongo/operation/write_command.rb +1 -2
  45. data/lib/mongo/operation.rb +1 -3
  46. data/lib/mongo/protocol/bit_vector.rb +3 -1
  47. data/lib/mongo/protocol/caching_hash.rb +3 -20
  48. data/lib/mongo/protocol/message.rb +4 -8
  49. data/lib/mongo/protocol/msg.rb +1 -0
  50. data/lib/mongo/protocol/serializers.rb +24 -17
  51. data/lib/mongo/protocol.rb +0 -3
  52. data/lib/mongo/query_cache.rb +20 -20
  53. data/lib/mongo/server/app_metadata/environment.rb +255 -0
  54. data/lib/mongo/server/app_metadata/truncator.rb +142 -0
  55. data/lib/mongo/server/app_metadata.rb +29 -42
  56. data/lib/mongo/session.rb +1 -1
  57. data/lib/mongo/version.rb +1 -1
  58. data/spec/integration/command_spec.rb +1 -23
  59. data/spec/integration/connection/faas_env_spec.rb +63 -0
  60. data/spec/integration/find_options_spec.rb +227 -0
  61. data/spec/integration/ocsp_verifier_spec.rb +1 -1
  62. data/spec/lite_spec_helper.rb +9 -0
  63. data/spec/mongo/address_spec.rb +1 -1
  64. data/spec/mongo/client_construction_spec.rb +7 -7
  65. data/spec/mongo/client_spec.rb +1 -9
  66. data/spec/mongo/cluster_spec.rb +2 -2
  67. data/spec/mongo/collection_crud_spec.rb +56 -0
  68. data/spec/mongo/collection_spec.rb +11 -1
  69. data/spec/mongo/crypt/kms_spec.rb +12 -9
  70. data/spec/mongo/crypt_spec.rb +21 -0
  71. data/spec/mongo/index/view_spec.rb +1 -0
  72. data/spec/mongo/protocol/caching_hash_spec.rb +0 -45
  73. data/spec/mongo/protocol/msg_spec.rb +2 -4
  74. data/spec/mongo/server/app_metadata/environment_spec.rb +193 -0
  75. data/spec/mongo/server/app_metadata/truncator_spec.rb +158 -0
  76. data/spec/mongo/server/app_metadata_spec.rb +33 -47
  77. data/spec/mongo/socket/ssl_spec.rb +2 -8
  78. data/spec/runners/crud/requirement.rb +2 -2
  79. data/spec/shared/lib/mrss/docker_runner.rb +4 -0
  80. data/spec/shared/lib/mrss/lite_constraints.rb +8 -0
  81. data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
  82. data/spec/shared/share/Dockerfile.erb +24 -19
  83. data/spec/shared/shlib/server.sh +31 -7
  84. data/spec/shared/shlib/set_env.sh +4 -4
  85. data/spec/solo/clean_exit_spec.rb +3 -10
  86. data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +15 -6
  87. data/spec/spec_tests/data/command_monitoring_unified/redacted-commands.yml +8 -0
  88. data/spec/support/aws_utils.rb +3 -3
  89. data/spec/support/certificates/atlas-ocsp-ca.crt +67 -67
  90. data/spec/support/certificates/atlas-ocsp.crt +103 -103
  91. data/spec/support/shared/app_metadata.rb +14 -2
  92. data.tar.gz.sig +0 -0
  93. metadata +1203 -1239
  94. metadata.gz.sig +0 -0
  95. data/lib/mongo/operation/aggregate/command.rb +0 -55
  96. data/lib/mongo/operation/collections_info/command.rb +0 -48
  97. data/lib/mongo/operation/command/command.rb +0 -41
  98. data/lib/mongo/operation/count/command.rb +0 -47
  99. data/lib/mongo/operation/create/command.rb +0 -47
  100. data/lib/mongo/operation/create_index/command.rb +0 -61
  101. data/lib/mongo/operation/create_user/command.rb +0 -46
  102. data/lib/mongo/operation/delete/command.rb +0 -52
  103. data/lib/mongo/operation/distinct/command.rb +0 -47
  104. data/lib/mongo/operation/drop/command.rb +0 -41
  105. data/lib/mongo/operation/drop_database/command.rb +0 -41
  106. data/lib/mongo/operation/drop_index/command.rb +0 -45
  107. data/lib/mongo/operation/explain/command.rb +0 -58
  108. data/lib/mongo/operation/explain/legacy.rb +0 -52
  109. data/lib/mongo/operation/find/builder/legacy.rb +0 -123
  110. data/lib/mongo/operation/find/command.rb +0 -51
  111. data/lib/mongo/operation/find/legacy/result.rb +0 -46
  112. data/lib/mongo/operation/find/legacy.rb +0 -52
  113. data/lib/mongo/operation/get_more/command.rb +0 -43
  114. data/lib/mongo/operation/get_more/legacy.rb +0 -39
  115. data/lib/mongo/operation/indexes/command.rb +0 -42
  116. data/lib/mongo/operation/indexes/legacy.rb +0 -48
  117. data/lib/mongo/operation/insert/command.rb +0 -55
  118. data/lib/mongo/operation/kill_cursors/command.rb +0 -48
  119. data/lib/mongo/operation/list_collections/command.rb +0 -46
  120. data/lib/mongo/operation/map_reduce/command.rb +0 -51
  121. data/lib/mongo/operation/parallel_scan/command.rb +0 -57
  122. data/lib/mongo/operation/remove_user/command.rb +0 -46
  123. data/lib/mongo/operation/shared/op_msg_or_command.rb +0 -41
  124. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +0 -44
  125. data/lib/mongo/operation/update/command.rb +0 -53
  126. data/lib/mongo/operation/update_user/command.rb +0 -45
  127. data/lib/mongo/operation/users_info/command.rb +0 -46
  128. data/lib/mongo/operation/write_command/command.rb +0 -51
  129. data/lib/mongo/protocol/delete.rb +0 -172
  130. data/lib/mongo/protocol/insert.rb +0 -181
  131. data/lib/mongo/protocol/update.rb +0 -214
  132. data/spec/mongo/operation/delete/command_spec.rb +0 -115
  133. data/spec/mongo/operation/find/legacy_spec.rb +0 -131
  134. data/spec/mongo/operation/get_more_spec.rb +0 -63
  135. data/spec/mongo/operation/insert/command_spec.rb +0 -118
  136. data/spec/mongo/operation/update/command_spec.rb +0 -122
  137. data/spec/mongo/protocol/delete_spec.rb +0 -185
  138. data/spec/mongo/protocol/insert_spec.rb +0 -179
  139. data/spec/mongo/protocol/update_spec.rb +0 -204
@@ -647,7 +647,11 @@ describe Mongo::Collection do
647
647
  context 'when the collection is capped' do
648
648
 
649
649
  let(:collection) do
650
- described_class.new(database, :specs, :capped => true, :size => 1024)
650
+ described_class.new(database, :specs, :capped => true, :size => 4096, :max => 512)
651
+ end
652
+
653
+ let(:collstats) do
654
+ database.read_command(:collstats => :specs).documents.first
651
655
  end
652
656
 
653
657
  before do
@@ -658,6 +662,12 @@ describe Mongo::Collection do
658
662
  it 'returns true' do
659
663
  expect(collection).to be_capped
660
664
  end
665
+
666
+ it "applies the options" do
667
+ expect(collstats["capped"]).to be true
668
+ expect(collstats["max"]).to eq(512)
669
+ expect(collstats["maxSize"]).to eq(4096)
670
+ end
661
671
  end
662
672
 
663
673
  context 'when the collection is not capped' do
@@ -33,7 +33,6 @@ describe Mongo::Crypt::KMS do
33
33
  %i(
34
34
  ssl_verify_certificate
35
35
  ssl_verify_hostname
36
- ssl_verify_ocsp_endpoint
37
36
  ).each do |insecure_opt|
38
37
  expect {
39
38
  Mongo::Crypt::KMS::Validations.validate_tls_options(
@@ -46,14 +45,18 @@ describe Mongo::Crypt::KMS do
46
45
  end
47
46
 
48
47
  it 'allows valid options' do
49
- options = {
50
- aws: {
51
- ssl: true,
52
- ssl_cert_string: 'Content is not validated',
53
-
54
- }
55
- }
48
+ expect do
49
+ Mongo::Crypt::KMS::Validations.validate_tls_options(
50
+ {
51
+ aws: {
52
+ ssl: true,
53
+ ssl_cert_string: 'Content is not validated',
54
+ ssl_verify_ocsp_endpoint: false
55
+ }
56
+ }
57
+ )
58
+ end.not_to raise_error
56
59
  end
57
60
  end
58
61
  end
59
- end
62
+ 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
@@ -34,49 +34,4 @@ describe Mongo::Protocol::CachingHash do
34
34
  end
35
35
  end
36
36
  end
37
-
38
- describe "#needs_validation?" do
39
-
40
- before do
41
- hash.to_bson(BSON::ByteBuffer.new, validation)
42
- end
43
-
44
- let(:needs_validation?) do
45
- hash.send(:needs_validation?, validating_keys)
46
- end
47
-
48
- context "when calling to_bson without validation" do
49
- let(:validation) { false }
50
-
51
- context "validating_keys is true" do
52
- let(:validating_keys) { true }
53
-
54
- it "is true" do
55
- expect(needs_validation?).to be true
56
- end
57
- end
58
-
59
- context "validating_keys is false" do
60
- let(:validating_keys) { false }
61
-
62
- it "is false" do
63
- expect(needs_validation?).to be false
64
- end
65
- end
66
- end
67
-
68
- context "when calling to_bson with validation" do
69
- let(:validation) { true }
70
-
71
- [true, false].each do |b|
72
- context "validating_keys is #{b}" do
73
- let(:validating_keys) { b }
74
-
75
- it "is false" do
76
- expect(needs_validation?).to be false
77
- end
78
- end
79
- end
80
- end
81
- end
82
37
  end
@@ -403,10 +403,8 @@ describe Mongo::Protocol::Msg do
403
403
  { validating_keys: true }
404
404
  end
405
405
 
406
- it 'checks the sequence document keys' do
407
- expect {
408
- message.serialize
409
- }.to raise_exception(BSON::String::IllegalKey)
406
+ it 'does not check the sequence document keys' do
407
+ expect(message.serialize).to be_a(BSON::ByteBuffer)
410
408
  end
411
409
  end
412
410
 
@@ -0,0 +1,193 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Mongo::Server::AppMetadata::Environment do
6
+ let(:env) { described_class.new }
7
+
8
+ shared_examples_for 'running in a FaaS environment' do
9
+ it 'reports that a FaaS environment is detected' do
10
+ expect(env.faas?).to be true
11
+ end
12
+ end
13
+
14
+ shared_examples_for 'running outside a FaaS environment' do
15
+ it 'reports that no FaaS environment is detected' do
16
+ expect(env.faas?).to be false
17
+ end
18
+ end
19
+
20
+ context 'when run outside of a FaaS environment' do
21
+ it_behaves_like 'running outside a FaaS environment'
22
+ end
23
+
24
+ context 'when run in a FaaS environment' do
25
+ context 'when environment is invalid due to type mismatch' do
26
+ local_env(
27
+ 'AWS_EXECUTION_ENV' => 'AWS_Lambda_ruby2.7',
28
+ 'AWS_REGION' => 'us-east-2',
29
+ 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE' => 'big'
30
+ )
31
+
32
+ it_behaves_like 'running outside a FaaS environment'
33
+
34
+ it 'fails due to type mismatch' do
35
+ expect(env.error).to match(/AWS_LAMBDA_FUNCTION_MEMORY_SIZE must be integer/)
36
+ end
37
+ end
38
+
39
+ context 'when environment is invalid due to long string' do
40
+ local_env(
41
+ 'AWS_EXECUTION_ENV' => 'AWS_Lambda_ruby2.7',
42
+ 'AWS_REGION' => 'a' * 512,
43
+ 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE' => '1024'
44
+ )
45
+
46
+ it_behaves_like 'running outside a FaaS environment'
47
+
48
+ it 'fails due to long string' do
49
+ expect(env.error).to match(/too long/)
50
+ end
51
+ end
52
+
53
+ context 'when environment is invalid due to multiple providers' do
54
+ local_env(
55
+ 'AWS_EXECUTION_ENV' => 'AWS_Lambda_ruby2.7',
56
+ 'AWS_REGION' => 'us-east-2',
57
+ 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE' => '1024',
58
+ 'FUNCTIONS_WORKER_RUNTIME' => 'ruby'
59
+ )
60
+
61
+ it_behaves_like 'running outside a FaaS environment'
62
+
63
+ it 'fails due to multiple providers' do
64
+ expect(env.error).to match(/too many environments/)
65
+ end
66
+ end
67
+
68
+ context 'when environment is invalid due to missing variable' do
69
+ local_env(
70
+ 'AWS_EXECUTION_ENV' => 'AWS_Lambda_ruby2.7',
71
+ 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE' => '1024'
72
+ )
73
+
74
+ it_behaves_like 'running outside a FaaS environment'
75
+
76
+ it 'fails due to missing variable' do
77
+ expect(env.error).to match(/missing environment variable/)
78
+ end
79
+ end
80
+
81
+ context 'when FaaS environment is AWS' do
82
+ shared_examples_for 'running in an AWS environment' do
83
+ context 'when environment is valid' do
84
+ local_env(
85
+ 'AWS_REGION' => 'us-east-2',
86
+ 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE' => '1024'
87
+ )
88
+
89
+ it_behaves_like 'running in a FaaS environment'
90
+
91
+ it 'recognizes AWS' do
92
+ expect(env.name).to be == 'aws.lambda'
93
+ expect(env.fields[:region]).to be == 'us-east-2'
94
+ expect(env.fields[:memory_mb]).to be == 1024
95
+ end
96
+ end
97
+ end
98
+
99
+ # per DRIVERS-2623, AWS_EXECUTION_ENV must be prefixed
100
+ # with 'AWS_Lambda_'.
101
+ context 'when AWS_EXECUTION_ENV is invalid' do
102
+ local_env(
103
+ 'AWS_EXECUTION_ENV' => 'EC2',
104
+ 'AWS_REGION' => 'us-east-2',
105
+ 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE' => '1024'
106
+ )
107
+
108
+ it_behaves_like 'running outside a FaaS environment'
109
+ end
110
+
111
+ context 'when AWS_EXECUTION_ENV is detected' do
112
+ local_env('AWS_EXECUTION_ENV' => 'AWS_Lambda_ruby2.7')
113
+ it_behaves_like 'running in an AWS environment'
114
+ end
115
+
116
+ context 'when AWS_LAMBDA_RUNTIME_API is detected' do
117
+ local_env('AWS_LAMBDA_RUNTIME_API' => 'lambda.aws.amazon.com/api')
118
+ it_behaves_like 'running in an AWS environment'
119
+ end
120
+ end
121
+
122
+ context 'when FaaS environment is Azure' do
123
+ local_env('FUNCTIONS_WORKER_RUNTIME' => 'ruby')
124
+
125
+ it_behaves_like 'running in a FaaS environment'
126
+
127
+ it 'recognizes Azure' do
128
+ expect(env.name).to be == 'azure.func'
129
+ end
130
+ end
131
+
132
+ context 'when FaaS environment is GCP' do
133
+ local_env(
134
+ 'FUNCTION_MEMORY_MB' => '1024',
135
+ 'FUNCTION_TIMEOUT_SEC' => '60',
136
+ 'FUNCTION_REGION' => 'us-central1'
137
+ )
138
+
139
+ shared_examples_for 'running in a GCP environment' do
140
+ it_behaves_like 'running in a FaaS environment'
141
+
142
+ it 'recognizes GCP' do
143
+ expect(env.name).to be == 'gcp.func'
144
+ expect(env.fields[:region]).to be == 'us-central1'
145
+ expect(env.fields[:memory_mb]).to be == 1024
146
+ expect(env.fields[:timeout_sec]).to be == 60
147
+ end
148
+ end
149
+
150
+ context 'when K_SERVICE is present' do
151
+ local_env('K_SERVICE' => 'servicename')
152
+ it_behaves_like 'running in a GCP environment'
153
+ end
154
+
155
+ context 'when FUNCTION_NAME is present' do
156
+ local_env('FUNCTION_NAME' => 'functionName')
157
+ it_behaves_like 'running in a GCP environment'
158
+ end
159
+ end
160
+
161
+ context 'when FaaS environment is Vercel' do
162
+ local_env(
163
+ 'VERCEL' => '1',
164
+ 'VERCEL_URL' => '*.vercel.app',
165
+ 'VERCEL_REGION' => 'cdg1'
166
+ )
167
+
168
+ it_behaves_like 'running in a FaaS environment'
169
+
170
+ it 'recognizes Vercel' do
171
+ expect(env.name).to be == 'vercel'
172
+ expect(env.fields[:url]).to be == '*.vercel.app'
173
+ expect(env.fields[:region]).to be == 'cdg1'
174
+ end
175
+ end
176
+
177
+ context 'when converting environment to a hash' do
178
+ local_env(
179
+ 'K_SERVICE' => 'servicename',
180
+ 'FUNCTION_MEMORY_MB' => '1024',
181
+ 'FUNCTION_TIMEOUT_SEC' => '60',
182
+ 'FUNCTION_REGION' => 'us-central1'
183
+ )
184
+
185
+ it 'includes name and all fields' do
186
+ expect(env.to_h).to be == {
187
+ name: 'gcp.func', memory_mb: 1024,
188
+ timeout_sec: 60, region: 'us-central1',
189
+ }
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ # Quoted from specifications/source/mongodb-handshake/handshake.rst:
6
+ #
7
+ # Implementors SHOULD cumulatively update fields in the following order
8
+ # until the document is under the size limit:
9
+ #
10
+ # 1. Omit fields from env except env.name.
11
+ # 2. Omit fields from os except os.type.
12
+ # 3. Omit the env document entirely.
13
+ # 4. Truncate platform.
14
+
15
+ describe Mongo::Server::AppMetadata::Truncator do
16
+ let(:truncator) { described_class.new(Marshal.load(Marshal.dump(metadata))) }
17
+
18
+ let(:app_name) { 'application' }
19
+ let(:driver) { { name: 'driver', version: '1.2.3' } }
20
+ let(:os) { { type: 'Darwin', name: 'macOS', architecture: 'arm64', version: '13.4' } }
21
+ let(:platform) { { platform: 'platform' } }
22
+ let(:env) { { name: 'aws.lambda', region: 'region', memory_mb: 1024 } }
23
+
24
+ let(:metadata) do
25
+ BSON::Document.new.tap do |doc|
26
+ doc[:application] = { name: app_name }
27
+ doc[:driver] = driver
28
+ doc[:os] = os
29
+ doc[:platform] = platform
30
+ doc[:env] = env
31
+ end
32
+ end
33
+
34
+ let(:untruncated_length) { metadata.to_bson.to_s.length }
35
+ let(:truncated_length) { truncator.document.to_bson.to_s.length }
36
+
37
+ shared_examples_for 'a truncated document' do
38
+ it 'is shorter' do
39
+ expect(truncated_length).to be < untruncated_length
40
+ end
41
+
42
+ it 'is not be longer than the maximum document size' do
43
+ expect(truncated_length).to be <= described_class::MAX_DOCUMENT_SIZE
44
+ end
45
+ end
46
+
47
+ describe 'MAX_DOCUMENT_SIZE' do
48
+ it 'is 512 bytes' do
49
+ # This test is an additional check that MAX_DOCUMENT_SIZE
50
+ # has not been accidentially changed.
51
+ expect(described_class::MAX_DOCUMENT_SIZE).to be == 512
52
+ end
53
+ end
54
+
55
+ context 'when document does not need truncating' do
56
+ it 'does not truncate anything' do
57
+ expect(truncated_length).to be == untruncated_length
58
+ end
59
+ end
60
+
61
+ context 'when modifying env is sufficient' do
62
+ context 'when a single value is too long' do
63
+ let(:env) { { name: 'name', a: 'a' * 1000, b: 'b' } }
64
+
65
+ it 'preserves name' do
66
+ expect(truncator.document[:env][:name]).to be == 'name'
67
+ end
68
+
69
+ it 'removes the too-long entry and keeps name' do
70
+ expect(truncator.document[:env].keys).to be == %w[ name b ]
71
+ end
72
+
73
+ it_behaves_like 'a truncated document'
74
+ end
75
+
76
+ context 'when multiple values are too long' do
77
+ let(:env) { { name: 'name', a: 'a' * 1000, b: 'b', c: 'c' * 1000, d: 'd' } }
78
+
79
+ it 'preserves name' do
80
+ expect(truncator.document[:env][:name]).to be == 'name'
81
+ end
82
+
83
+ it 'removes all other entries until size is satisifed' do
84
+ expect(truncator.document[:env].keys).to be == %w[ name d ]
85
+ end
86
+
87
+ it_behaves_like 'a truncated document'
88
+ end
89
+ end
90
+
91
+ context 'when modifying os is sufficient' do
92
+ context 'when a single value is too long' do
93
+ let(:os) { { type: 'type', a: 'a' * 1000, b: 'b' } }
94
+
95
+ it 'truncates env' do
96
+ expect(truncator.document[:env].keys).to be == %w[ name ]
97
+ end
98
+
99
+ it 'preserves type' do
100
+ expect(truncator.document[:os][:type]).to be == 'type'
101
+ end
102
+
103
+ it 'removes the too-long entry and keeps type' do
104
+ expect(truncator.document[:os].keys).to be == %w[ type b ]
105
+ end
106
+
107
+ it_behaves_like 'a truncated document'
108
+ end
109
+
110
+ context 'when multiple values are too long' do
111
+ let(:os) { { type: 'type', a: 'a' * 1000, b: 'b', c: 'c' * 1000, d: 'd' } }
112
+
113
+ it 'truncates env' do
114
+ expect(truncator.document[:env].keys).to be == %w[ name ]
115
+ end
116
+
117
+ it 'preserves type' do
118
+ expect(truncator.document[:os][:type]).to be == 'type'
119
+ end
120
+
121
+ it 'removes all other entries until size is satisifed' do
122
+ expect(truncator.document[:os].keys).to be == %w[ type d ]
123
+ end
124
+
125
+ it_behaves_like 'a truncated document'
126
+ end
127
+ end
128
+
129
+ context 'when truncating os is insufficient' do
130
+ let(:env) { { name: 'n' * 1000 } }
131
+
132
+ it 'truncates os' do
133
+ expect(truncator.document[:os].keys).to be == %w[ type ]
134
+ end
135
+
136
+ it 'removes env' do
137
+ expect(truncator.document.key?(:env)).to be false
138
+ end
139
+
140
+ it_behaves_like 'a truncated document'
141
+ end
142
+
143
+ context 'when platform is too long' do
144
+ let(:platform) { 'n' * 1000 }
145
+
146
+ it 'truncates os' do
147
+ expect(truncator.document[:os].keys).to be == %w[ type ]
148
+ end
149
+
150
+ it 'removes env' do
151
+ expect(truncator.document.key?(:env)).to be false
152
+ end
153
+
154
+ it 'truncates platform' do
155
+ expect(truncator.document[:platform].length).to be < 1000
156
+ end
157
+ end
158
+ end
@@ -4,6 +4,7 @@
4
4
  require 'spec_helper'
5
5
 
6
6
  describe Mongo::Server::AppMetadata do
7
+ let(:max_size) { described_class::Truncator::MAX_DOCUMENT_SIZE }
7
8
 
8
9
  let(:app_metadata) do
9
10
  described_class.new(cluster.options)
@@ -13,14 +14,6 @@ describe Mongo::Server::AppMetadata do
13
14
  authorized_client.cluster
14
15
  end
15
16
 
16
- describe 'MAX_DOCUMENT_SIZE' do
17
- it 'should be 512 bytes' do
18
- # This test is an additional check that MAX_DOCUMENT_SIZE
19
- # has not been accidentially changed.
20
- expect(described_class::MAX_DOCUMENT_SIZE).to eq(512)
21
- end
22
- end
23
-
24
17
  describe '#initialize' do
25
18
 
26
19
  context 'when the cluster has an app name option set' do
@@ -34,7 +27,7 @@ describe Mongo::Server::AppMetadata do
34
27
  end
35
28
 
36
29
  it 'sets the app name' do
37
- expect(app_metadata.send(:full_client_document)[:application][:name]).to eq('app_metadata_test')
30
+ expect(app_metadata.client_document[:application][:name]).to eq('app_metadata_test')
38
31
  end
39
32
 
40
33
  context 'when the app name exceeds the max length of 128' do
@@ -58,77 +51,70 @@ describe Mongo::Server::AppMetadata do
58
51
  context 'when the cluster does not have an app name option set' do
59
52
 
60
53
  it 'does not set the app name' do
61
- expect(app_metadata.send(:full_client_document)[:application]).to be(nil)
54
+ expect(app_metadata.client_document[:application]).to be(nil)
62
55
  end
63
56
  end
64
57
 
65
58
  context 'when the client document exceeds the max of 512 bytes' do
66
- # Server api parameters change metadata length
67
- require_no_required_api_version
68
-
69
- context 'when the os.type length is too long' do
70
-
71
- before do
72
- allow(app_metadata).to receive(:type).and_return('x'*500)
59
+ shared_examples_for 'a truncated document' do
60
+ it 'is too long before validation' do
61
+ expect(app_metadata.client_document.to_bson.to_s.size).to be > max_size
73
62
  end
74
63
 
75
- it 'truncates the document' do
76
- expect(
77
- app_metadata.validated_document.to_bson.to_s.size
78
- ).to be < described_class::MAX_DOCUMENT_SIZE
64
+ it 'is acceptable after validation' do
65
+ app_metadata.validated_document # force validation
66
+ expect(app_metadata.client_document.to_bson.to_s.size).to be <= max_size
79
67
  end
80
68
  end
81
69
 
82
70
  context 'when the os.name length is too long' do
83
-
84
71
  before do
85
72
  allow(app_metadata).to receive(:name).and_return('x'*500)
86
73
  end
87
74
 
88
- it 'truncates the document' do
89
- expect(
90
- app_metadata.validated_document.to_bson.to_s.size
91
- ).to be < described_class::MAX_DOCUMENT_SIZE
92
- end
75
+ it_behaves_like 'a truncated document'
93
76
  end
94
77
 
95
78
  context 'when the os.architecture length is too long' do
96
-
97
79
  before do
98
80
  allow(app_metadata).to receive(:architecture).and_return('x'*500)
99
81
  end
100
82
 
101
- it 'truncates the document' do
102
- expect(
103
- app_metadata.validated_document.to_bson.to_s.size
104
- ).to be < described_class::MAX_DOCUMENT_SIZE
105
- end
83
+ it_behaves_like 'a truncated document'
106
84
  end
107
85
 
108
86
  context 'when the platform length is too long' do
109
-
110
87
  before do
111
88
  allow(app_metadata).to receive(:platform).and_return('x'*500)
112
89
  end
113
90
 
114
- it 'truncates the document' do
115
- expect(
116
- app_metadata.validated_document.to_bson.to_s.size
117
- ).to be < described_class::MAX_DOCUMENT_SIZE
118
- end
91
+ it_behaves_like 'a truncated document'
119
92
  end
93
+ end
120
94
 
121
- context 'when the driver info is too long' do
122
- require_no_compression
95
+ context 'when run outside of a FaaS environment' do
96
+ it 'should exclude the :env key from the client document' do
97
+ expect(app_metadata.client_document.key?(:env)).to be false
98
+ end
99
+ end
123
100
 
124
- before do
125
- allow(app_metadata).to receive(:driver_doc).and_return('x'*500)
101
+ context 'when run inside of a FaaS environment' do
102
+ context 'when the environment is invalid' do
103
+ # invalid, because it is missing the other required fields
104
+ local_env('AWS_EXECUTION_ENV' => 'AWS_Lambda_ruby2.7')
105
+
106
+ it 'should exclude the :env key from the client document' do
107
+ expect(app_metadata.client_document.key?(:env)).to be false
126
108
  end
109
+ end
110
+
111
+ context 'when the environment is valid' do
112
+ # valid, because Azure requires only the one field
113
+ local_env('FUNCTIONS_WORKER_RUNTIME' => 'ruby')
127
114
 
128
- it 'truncates the document' do
129
- expect(
130
- app_metadata.validated_document.to_bson.to_s.size
131
- ).to be < described_class::MAX_DOCUMENT_SIZE
115
+ it 'should include the :env key in the client document' do
116
+ expect(app_metadata.client_document.key?(:env)).to be true
117
+ expect(app_metadata.client_document[:env][:name]).to be == "azure.func"
132
118
  end
133
119
  end
134
120
  end
@@ -592,14 +592,8 @@ describe Mongo::Socket::SSL do
592
592
  )
593
593
  end
594
594
 
595
- around do |example|
596
- saved = ENV['SSL_CERT_FILE']
597
- ENV['SSL_CERT_FILE'] = SpecConfig.instance.local_ca_cert_path
598
- begin
599
- example.run
600
- ensure
601
- ENV['SSL_CERT_FILE'] = saved
602
- end
595
+ local_env do
596
+ { 'SSL_CERT_FILE' => SpecConfig.instance.local_ca_cert_path }
603
597
  end
604
598
 
605
599
  it 'uses the default cert store' do
@@ -109,9 +109,9 @@ module Mongo
109
109
  end
110
110
  end
111
111
  if @auth == true
112
- ok &&= cc.auth_enabled?
112
+ ok &&= SpecConfig.instance.auth?
113
113
  elsif @auth == false
114
- ok &&= !cc.auth_enabled?
114
+ ok &&= !SpecConfig.instance.auth?
115
115
  end
116
116
  if @csfle
117
117
  ok &&= !!(ENV['LIBMONGOCRYPT_PATH'] || ENV['FLE'])
@@ -231,6 +231,10 @@ module Mrss
231
231
  distro =~ /debian|ubuntu/
232
232
  end
233
233
 
234
+ def ubuntu?
235
+ distro=~ /ubuntu/
236
+ end
237
+
234
238
  def preload?
235
239
  !!@options[:preload]
236
240
  end