mongo 2.18.0.beta1 → 2.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/mongo/bulk_write.rb +8 -2
- data/lib/mongo/client.rb +19 -5
- data/lib/mongo/client_encryption.rb +86 -4
- data/lib/mongo/cluster.rb +6 -4
- data/lib/mongo/collection/view/aggregation.rb +3 -0
- data/lib/mongo/collection/view/change_stream.rb +9 -0
- data/lib/mongo/collection/view/iterable.rb +1 -0
- data/lib/mongo/collection/view/readable.rb +11 -3
- data/lib/mongo/collection.rb +9 -1
- data/lib/mongo/config.rb +11 -0
- data/lib/mongo/crypt/auto_encrypter.rb +49 -21
- data/lib/mongo/crypt/binding.rb +73 -48
- data/lib/mongo/crypt/data_key_context.rb +6 -1
- data/lib/mongo/crypt/encryption_io.rb +66 -0
- data/lib/mongo/crypt/explicit_encrypter.rb +116 -5
- data/lib/mongo/crypt/explicit_encryption_context.rb +3 -8
- data/lib/mongo/crypt/handle.rb +26 -8
- data/lib/mongo/crypt/kms/aws.rb +11 -3
- data/lib/mongo/crypt/kms/azure.rb +14 -6
- data/lib/mongo/crypt/kms/gcp.rb +12 -5
- data/lib/mongo/crypt/kms/kmip.rb +15 -9
- data/lib/mongo/crypt/kms/local.rb +9 -1
- data/lib/mongo/crypt/kms/master_key_document.rb +1 -1
- data/lib/mongo/crypt/rewrap_many_data_key_context.rb +46 -0
- data/lib/mongo/crypt/rewrap_many_data_key_result.rb +37 -0
- data/lib/mongo/crypt/status.rb +8 -2
- data/lib/mongo/crypt.rb +2 -0
- data/lib/mongo/database.rb +10 -27
- data/lib/mongo/error/missing_file_chunk.rb +8 -2
- data/lib/mongo/grid/stream/read.rb +6 -0
- data/lib/mongo/index/view.rb +1 -0
- data/lib/mongo/operation/create/op_msg.rb +1 -13
- data/lib/mongo/operation/distinct/op_msg.rb +4 -1
- data/lib/mongo/protocol/msg.rb +0 -16
- data/lib/mongo/server/connection_pool.rb +5 -4
- data/lib/mongo/server/monitor/connection.rb +10 -4
- data/lib/mongo/server/monitor.rb +4 -0
- data/lib/mongo/server/push_monitor.rb +4 -0
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo.rb +2 -0
- data/spec/README.md +14 -0
- data/spec/integration/change_stream_spec.rb +1 -1
- data/spec/integration/client_construction_spec.rb +73 -7
- data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +165 -164
- data/spec/integration/client_side_encryption/decryption_events_prose_spec.rb +158 -0
- data/spec/integration/client_side_encryption/explicit_queryable_encryption_spec.rb +5 -5
- data/spec/integration/client_side_encryption/kms_tls_options_spec.rb +50 -8
- data/spec/integration/client_side_encryption/unique_index_on_key_alt_names_prose_spec.rb +85 -0
- data/spec/integration/ocsp_verifier_spec.rb +1 -1
- data/spec/integration/reconnect_spec.rb +2 -0
- data/spec/integration/sdam_events_spec.rb +40 -0
- data/spec/integration/srv_monitoring_spec.rb +1 -0
- data/spec/integration/srv_spec.rb +1 -0
- data/spec/lite_spec_helper.rb +5 -4
- data/spec/mongo/bulk_write_spec.rb +13 -0
- data/spec/mongo/client_construction_spec.rb +45 -2
- data/spec/mongo/client_encryption_spec.rb +0 -12
- data/spec/mongo/client_spec.rb +1 -1
- data/spec/mongo/collection/view/aggregation_spec.rb +119 -0
- data/spec/mongo/collection/view/readable_spec.rb +630 -5
- data/spec/mongo/collection_spec.rb +32 -0
- data/spec/mongo/crypt/auto_encrypter_spec.rb +110 -0
- data/spec/mongo/crypt/binding/context_spec.rb +3 -35
- data/spec/mongo/crypt/data_key_context_spec.rb +1 -1
- data/spec/mongo/crypt/explicit_encryption_context_spec.rb +8 -3
- data/spec/mongo/crypt/handle_spec.rb +39 -3
- data/spec/mongo/crypt/kms/credentials_spec.rb +0 -47
- data/spec/mongo/index/view_spec.rb +56 -0
- data/spec/mongo/operation/create/op_msg_spec.rb +0 -42
- data/spec/mongo/server/connection_pool_spec.rb +26 -4
- data/spec/mongo/socket/ssl_spec.rb +3 -3
- data/spec/runners/crud/requirement.rb +6 -1
- data/spec/runners/crud/test.rb +1 -1
- data/spec/runners/transactions/spec.rb +2 -2
- data/spec/runners/transactions/test.rb +4 -20
- data/spec/runners/transactions.rb +2 -2
- data/spec/runners/unified/assertions.rb +32 -2
- data/spec/runners/unified/change_stream_operations.rb +3 -0
- data/spec/runners/unified/client_side_encryption_operations.rb +83 -0
- data/spec/runners/unified/crud_operations.rb +17 -2
- data/spec/runners/unified/ddl_operations.rb +27 -2
- data/spec/runners/unified/grid_fs_operations.rb +21 -0
- data/spec/runners/unified/test.rb +59 -1
- data/spec/shared/lib/mrss/docker_runner.rb +2 -0
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
- data/spec/shared/shlib/set_env.sh +3 -0
- data/spec/solo/clean_exit_spec.rb +5 -0
- data/spec/spec_tests/client_side_encryption_spec.rb +1 -1
- data/spec/spec_tests/client_side_encryption_unified_spec.rb +16 -0
- data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +298 -0
- data/spec/spec_tests/data/client_side_encryption/create-and-createIndexes.yml +58 -0
- data/spec/spec_tests/data/client_side_encryption/fle2-Delete.yml +1 -1
- data/spec/spec_tests/data/client_side_encryption/fle2-EncryptedFields-vs-jsonSchema.yml +1 -1
- data/spec/spec_tests/data/client_side_encryption/fle2-FindOneAndUpdate.yml +2 -2
- data/spec/spec_tests/data/client_side_encryption/fle2-InsertFind-Indexed.yml +1 -1
- data/spec/spec_tests/data/client_side_encryption/fle2-Update.yml +2 -2
- data/spec/spec_tests/data/client_side_encryption/unified/addKeyAltName.yml +194 -0
- data/spec/spec_tests/data/client_side_encryption/unified/createDataKey-kms_providers-invalid.yml +67 -0
- data/spec/spec_tests/data/client_side_encryption/unified/createDataKey.yml +309 -0
- data/spec/spec_tests/data/client_side_encryption/unified/deleteKey.yml +159 -0
- data/spec/spec_tests/data/client_side_encryption/unified/getKey.yml +105 -0
- data/spec/spec_tests/data/client_side_encryption/unified/getKeyByAltName.yml +104 -0
- data/spec/spec_tests/data/client_side_encryption/unified/getKeys.yml +122 -0
- data/spec/spec_tests/data/client_side_encryption/unified/removeKeyAltName.yml +157 -0
- data/spec/spec_tests/data/client_side_encryption/unified/rewrapManyDataKey-decrypt_failure.yml +69 -0
- data/spec/spec_tests/data/client_side_encryption/unified/rewrapManyDataKey-encrypt_failure.yml +122 -0
- data/spec/spec_tests/data/client_side_encryption/unified/rewrapManyDataKey.yml +432 -0
- data/spec/spec_tests/data/client_side_encryption/validatorAndPartialFieldExpression.yml +166 -0
- data/spec/spec_tests/data/command_monitoring_unified/bulkWrite.yml +68 -0
- data/spec/spec_tests/data/command_monitoring_unified/command.yml +50 -0
- data/spec/spec_tests/data/command_monitoring_unified/deleteMany.yml +79 -0
- data/spec/spec_tests/data/command_monitoring_unified/deleteOne.yml +79 -0
- data/spec/spec_tests/data/command_monitoring_unified/find.yml +254 -0
- data/spec/spec_tests/data/command_monitoring_unified/insertMany.yml +79 -0
- data/spec/spec_tests/data/command_monitoring_unified/insertOne.yml +77 -0
- data/spec/spec_tests/data/command_monitoring_unified/unacknowledgedBulkWrite.yml +55 -0
- data/spec/spec_tests/data/command_monitoring_unified/updateMany.yml +87 -0
- data/spec/spec_tests/data/command_monitoring_unified/updateOne.yml +118 -0
- data/spec/spec_tests/data/crud_unified/distinct-comment.yml +98 -0
- data/spec/spec_tests/data/gridfs_unified/delete.yml +198 -0
- data/spec/spec_tests/data/gridfs_unified/download.yml +241 -0
- data/spec/spec_tests/data/gridfs_unified/downloadByName.yml +159 -0
- data/spec/spec_tests/data/gridfs_unified/upload-disableMD5.yml +92 -0
- data/spec/spec_tests/data/gridfs_unified/upload.yml +288 -0
- data/spec/spec_tests/gridfs_unified_spec.rb +13 -0
- data/spec/stress/connection_pool_timing_spec.rb +2 -2
- data/spec/support/background_thread_registry.rb +3 -13
- data/spec/support/certificates/atlas-ocsp-ca.crt +40 -47
- data/spec/support/certificates/atlas-ocsp.crt +101 -106
- data/spec/support/crypt.rb +57 -13
- data/spec/support/macros.rb +10 -0
- data/spec/support/spec_config.rb +4 -0
- data.tar.gz.sig +0 -0
- metadata +1271 -1219
- metadata.gz.sig +0 -0
- data/spec/spec_tests/command_monitoring_spec.rb +0 -71
- data/spec/spec_tests/data/command_monitoring/bulkWrite.yml +0 -49
- data/spec/spec_tests/data/command_monitoring/command.yml +0 -61
- data/spec/spec_tests/data/command_monitoring/deleteMany.yml +0 -55
- data/spec/spec_tests/data/command_monitoring/deleteOne.yml +0 -55
- data/spec/spec_tests/data/command_monitoring/find.yml +0 -266
- data/spec/spec_tests/data/command_monitoring/insertMany.yml +0 -75
- data/spec/spec_tests/data/command_monitoring/insertOne.yml +0 -51
- data/spec/spec_tests/data/command_monitoring/unacknowledgedBulkWrite.yml +0 -34
- data/spec/spec_tests/data/command_monitoring/updateMany.yml +0 -65
- data/spec/spec_tests/data/command_monitoring/updateOne.yml +0 -90
@@ -40,7 +40,7 @@ module Mongo
|
|
40
40
|
# @param [ Hash ] test The test specification.
|
41
41
|
#
|
42
42
|
# @since 2.6.0
|
43
|
-
def initialize(crud_spec, data, test)
|
43
|
+
def initialize(crud_spec, data, test, expectations_bson_types: true)
|
44
44
|
test = IceNine.deep_freeze(test)
|
45
45
|
@spec = crud_spec
|
46
46
|
@data = data || []
|
@@ -71,7 +71,8 @@ module Mongo
|
|
71
71
|
Operation.new(self, op)
|
72
72
|
end
|
73
73
|
|
74
|
-
|
74
|
+
mode = if expectations_bson_types then :bson else nil end
|
75
|
+
@expectations = BSON::ExtJSON.parse_obj(test['expectations'], mode: mode)
|
75
76
|
|
76
77
|
if test['outcome']
|
77
78
|
@outcome = Mongo::CRUD::Outcome.new(BSON::ExtJSON.parse_obj(test['outcome'], mode: :bson))
|
@@ -244,24 +245,7 @@ module Mongo
|
|
244
245
|
key_vault_coll.insert_many(@spec.key_vault_data)
|
245
246
|
end
|
246
247
|
|
247
|
-
if @spec.encrypted_fields
|
248
|
-
encrypted_fields = @spec.encrypted_fields.dup
|
249
|
-
# This code MUST be removed as soon as server starts accepting
|
250
|
-
# contention as int32.
|
251
|
-
if encrypted_fields.key?('fields')
|
252
|
-
encrypted_fields['fields'] = encrypted_fields['fields'].dup.map do |field|
|
253
|
-
if field['queries'] && field['queries'].key?('contention')
|
254
|
-
new_field = field.dup
|
255
|
-
new_field['queries'] = field['queries'].dup
|
256
|
-
new_field['queries']['contention'] = BSON::Int64.new(field['queries']['contention'])
|
257
|
-
new_field
|
258
|
-
else
|
259
|
-
field
|
260
|
-
end
|
261
|
-
end
|
262
|
-
end
|
263
|
-
# End of code to be removed
|
264
|
-
end
|
248
|
+
encrypted_fields = @spec.encrypted_fields if @spec.encrypted_fields
|
265
249
|
coll = support_client[@spec.collection_name].with(write: { w: :majority })
|
266
250
|
coll.drop(encrypted_fields: encrypted_fields)
|
267
251
|
|
@@ -19,7 +19,7 @@ require 'runners/transactions/operation'
|
|
19
19
|
require 'runners/transactions/spec'
|
20
20
|
require 'runners/transactions/test'
|
21
21
|
|
22
|
-
def define_transactions_spec_tests(test_paths)
|
22
|
+
def define_transactions_spec_tests(test_paths, expectations_bson_types: true)
|
23
23
|
config_override :validate_update_replace, true
|
24
24
|
|
25
25
|
test_paths.each do |file|
|
@@ -30,7 +30,7 @@ def define_transactions_spec_tests(test_paths)
|
|
30
30
|
|
31
31
|
define_spec_tests_with_requirements(spec) do |req|
|
32
32
|
|
33
|
-
spec.tests.each do |test|
|
33
|
+
spec.tests(expectations_bson_types: expectations_bson_types).each do |test|
|
34
34
|
|
35
35
|
context(test.description) do
|
36
36
|
|
@@ -76,6 +76,32 @@ module Unified
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
+
%w(bulkWriteResult).each do |k|
|
80
|
+
expected_v = expected.use(k)
|
81
|
+
next unless expected_v
|
82
|
+
actual_v = case actual
|
83
|
+
when Mongo::Crypt::RewrapManyDataKeyResult
|
84
|
+
actual.send(Utils.underscore(k))
|
85
|
+
else
|
86
|
+
raise Error::ResultMismatch, "Mismatch: actual #{actual_v}, expected #{expected_v}"
|
87
|
+
end
|
88
|
+
if expected_v
|
89
|
+
if expected_v.empty?
|
90
|
+
if actual_v && !actual_v.empty?
|
91
|
+
raise Error::ResultMismatch, "Actual not empty"
|
92
|
+
end
|
93
|
+
else
|
94
|
+
%w(deleted inserted matched modified upserted).each do |k|
|
95
|
+
if count = expected_v.use("#{k}Count")
|
96
|
+
if Hash === count || count > 0
|
97
|
+
actual_count = actual_v.send("#{k}_count")
|
98
|
+
assert_value_matches(actual_count, count, "#{k} count")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
79
105
|
assert_matches(actual, expected, 'result')
|
80
106
|
expected.clear
|
81
107
|
end
|
@@ -192,7 +218,7 @@ module Unified
|
|
192
218
|
|
193
219
|
def assert_matches(actual, expected, msg)
|
194
220
|
if actual.nil?
|
195
|
-
if expected
|
221
|
+
if expected.is_a?(Hash) && expected.keys == ["$$unsetOrMatches"]
|
196
222
|
return
|
197
223
|
elsif !expected.nil?
|
198
224
|
raise Error::ResultMismatch, "#{msg}: expected #{expected} but got nil"
|
@@ -219,7 +245,7 @@ module Unified
|
|
219
245
|
if expected.empty?
|
220
246
|
# This needs to be a match assertion. Check type only
|
221
247
|
# and allow BulkWriteResult and generic operation result.
|
222
|
-
unless Hash === actual || Mongo::BulkWrite::Result === actual || Mongo::Operation::Result === actual
|
248
|
+
unless Hash === actual || Mongo::BulkWrite::Result === actual || Mongo::Operation::Result === actual || Mongo::Crypt::RewrapManyDataKeyResult === actual
|
223
249
|
raise Error::ResultMismatch, "#{msg}: expected #{expected}, actual #{actual}"
|
224
250
|
end
|
225
251
|
else
|
@@ -269,6 +295,10 @@ module Unified
|
|
269
295
|
Float === object
|
270
296
|
when 'string'
|
271
297
|
String === object
|
298
|
+
when 'binData'
|
299
|
+
BSON::Binary === object
|
300
|
+
when 'array'
|
301
|
+
Array === object
|
272
302
|
else
|
273
303
|
raise NotImplementedError, "Unhandled type #{type}"
|
274
304
|
end
|
@@ -23,6 +23,9 @@ module Unified
|
|
23
23
|
if full_document_before_change = args.use('fullDocumentBeforeChange')
|
24
24
|
opts[:full_document_before_change] = full_document_before_change
|
25
25
|
end
|
26
|
+
if args.key?('showExpandedEvents')
|
27
|
+
opts[:show_expanded_events] = args.use!('showExpandedEvents')
|
28
|
+
end
|
26
29
|
cs = object.watch(pipeline, **opts)
|
27
30
|
name = op.use!('saveResultAsEntity')
|
28
31
|
entities.set(:change_stream, name, cs)
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
module Unified
|
5
|
+
module ClientSideEncryptionOperations
|
6
|
+
def create_data_key(op)
|
7
|
+
client_encryption = entities.get(:clientEncryption, op.use!('object'))
|
8
|
+
use_arguments(op) do |args|
|
9
|
+
opts = Utils.shallow_snakeize_hash(args.use('opts')) || {}
|
10
|
+
opts[:master_key] = Utils.shallow_snakeize_hash(opts[:master_key]) if opts[:master_key]
|
11
|
+
opts[:key_material] = opts[:key_material].data if opts[:key_material]
|
12
|
+
client_encryption.create_data_key(
|
13
|
+
args.use!('kmsProvider'),
|
14
|
+
opts,
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_key_alt_name(op)
|
20
|
+
client_encryption = entities.get(:clientEncryption, op.use!('object'))
|
21
|
+
use_arguments(op) do |args|
|
22
|
+
client_encryption.add_key_alt_name(
|
23
|
+
args.use!('id'),
|
24
|
+
args.use!('keyAltName')
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete_key(op)
|
30
|
+
client_encryption = entities.get(:clientEncryption, op.use!('object'))
|
31
|
+
use_arguments(op) do |args|
|
32
|
+
client_encryption.delete_key(
|
33
|
+
args.use!('id')
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_key(op)
|
39
|
+
client_encryption = entities.get(:clientEncryption, op.use!('object'))
|
40
|
+
use_arguments(op) do |args|
|
41
|
+
client_encryption.get_key(
|
42
|
+
args.use!('id')
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_key_by_alt_name(op)
|
48
|
+
client_encryption = entities.get(:clientEncryption, op.use!('object'))
|
49
|
+
use_arguments(op) do |args|
|
50
|
+
client_encryption.get_key_by_alt_name(
|
51
|
+
args.use!('keyAltName')
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_keys(op)
|
57
|
+
client_encryption = entities.get(:clientEncryption, op.use!('object'))
|
58
|
+
client_encryption.get_keys.to_a
|
59
|
+
end
|
60
|
+
|
61
|
+
def remove_key_alt_name(op)
|
62
|
+
client_encryption = entities.get(:clientEncryption, op.use!('object'))
|
63
|
+
use_arguments(op) do |args|
|
64
|
+
client_encryption.remove_key_alt_name(
|
65
|
+
args.use!('id'),
|
66
|
+
args.use!('keyAltName')
|
67
|
+
)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def rewrap_many_data_key(op)
|
72
|
+
client_encryption = entities.get(:clientEncryption, op.use!('object'))
|
73
|
+
use_arguments(op) do |args|
|
74
|
+
opts = Utils.shallow_snakeize_hash(args.use('opts')) || {}
|
75
|
+
opts[:master_key] = Utils.shallow_snakeize_hash(opts[:master_key]) if opts[:master_key]
|
76
|
+
client_encryption.rewrap_many_data_key(
|
77
|
+
args.use!('filter'),
|
78
|
+
opts
|
79
|
+
)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -12,6 +12,14 @@ module Unified
|
|
12
12
|
let: args.use('let'),
|
13
13
|
comment: args.use('comment'),
|
14
14
|
allow_disk_use: args.use('allowDiskUse'),
|
15
|
+
show_disk_loc: args.use('showRecordId'),
|
16
|
+
return_key: args.use('returnKey'),
|
17
|
+
projection: args.use('projection'),
|
18
|
+
skip: args.use('skip'),
|
19
|
+
hint: args.use('hint'),
|
20
|
+
max_value: args.use('max'),
|
21
|
+
max_time_ms: args.use('maxTimeMS'),
|
22
|
+
min_value: args.use('min'),
|
15
23
|
}
|
16
24
|
if session = args.use('session')
|
17
25
|
opts[:session] = entities.get(:session, session)
|
@@ -26,6 +34,9 @@ module Unified
|
|
26
34
|
if limit = args.use('limit')
|
27
35
|
req = req.limit(limit)
|
28
36
|
end
|
37
|
+
if projection = args.use('projection')
|
38
|
+
req = req.projection(projection)
|
39
|
+
end
|
29
40
|
result = req.to_a
|
30
41
|
end
|
31
42
|
end
|
@@ -65,6 +76,9 @@ module Unified
|
|
65
76
|
if session = args.use('session')
|
66
77
|
opts[:session] = entities.get(:session, session)
|
67
78
|
end
|
79
|
+
if comment = args.use('comment')
|
80
|
+
opts[:comment] = comment
|
81
|
+
end
|
68
82
|
req = collection.find(args.use!('filter'), **opts).distinct(args.use!('fieldName'), **opts)
|
69
83
|
result = req.to_a
|
70
84
|
end
|
@@ -159,6 +173,7 @@ module Unified
|
|
159
173
|
let: args.use('let'),
|
160
174
|
comment: args.use('comment'),
|
161
175
|
hint: args.use('hint'),
|
176
|
+
upsert: args.use('upsert'),
|
162
177
|
}
|
163
178
|
if session = args.use('session')
|
164
179
|
opts[:session] = entities.get(:session, session)
|
@@ -227,8 +242,8 @@ module Unified
|
|
227
242
|
convert_bulk_write_spec(req)
|
228
243
|
end
|
229
244
|
opts = {}
|
230
|
-
if
|
231
|
-
opts[:ordered] =
|
245
|
+
if args.key?('ordered')
|
246
|
+
opts[:ordered] = args.use!('ordered')
|
232
247
|
end
|
233
248
|
if comment = args.use('comment')
|
234
249
|
opts[:comment] = comment
|
@@ -36,6 +36,9 @@ module Unified
|
|
36
36
|
if change_stream_pre_and_post_images = args.use('changeStreamPreAndPostImages')
|
37
37
|
collection_opts[:change_stream_pre_and_post_images] = change_stream_pre_and_post_images
|
38
38
|
end
|
39
|
+
if view_on = args.use('viewOn')
|
40
|
+
collection_opts[:view_on] = view_on
|
41
|
+
end
|
39
42
|
database[args.use!('collection'), collection_opts].create(**opts)
|
40
43
|
end
|
41
44
|
end
|
@@ -66,10 +69,16 @@ module Unified
|
|
66
69
|
collection = entities.get(:collection, op.use!('object'))
|
67
70
|
use_arguments(op) do |args|
|
68
71
|
to = args.use!('to')
|
69
|
-
|
72
|
+
cmd = {
|
70
73
|
renameCollection: "#{collection.database.name}.#{collection.name}",
|
71
74
|
to: "#{collection.database.name}.#{to}"
|
72
|
-
}
|
75
|
+
}
|
76
|
+
|
77
|
+
if args.key?("dropTarget")
|
78
|
+
cmd[:dropTarget] = args.use("dropTarget")
|
79
|
+
end
|
80
|
+
|
81
|
+
collection.client.use(:admin).command(**cmd)
|
73
82
|
end
|
74
83
|
end
|
75
84
|
|
@@ -122,6 +131,22 @@ module Unified
|
|
122
131
|
end
|
123
132
|
end
|
124
133
|
|
134
|
+
def drop_index(op)
|
135
|
+
collection = entities.get(:collection, op.use!('object'))
|
136
|
+
use_arguments(op) do |args|
|
137
|
+
opts = {}
|
138
|
+
if session = args.use('session')
|
139
|
+
opts[:session] = entities.get(:session, session)
|
140
|
+
end
|
141
|
+
|
142
|
+
collection.indexes.drop_one(
|
143
|
+
args.use!('name'),
|
144
|
+
**opts,
|
145
|
+
)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
|
125
150
|
def assert_index_exists(op)
|
126
151
|
consume_test_runner(op)
|
127
152
|
use_arguments(op) do |args|
|
@@ -20,6 +20,18 @@ module Unified
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
def download_by_name(op)
|
24
|
+
bucket = entities.get(:bucket, op.use!('object'))
|
25
|
+
use_arguments(op) do |args|
|
26
|
+
opts = {}
|
27
|
+
if revision = args.use('revision')
|
28
|
+
opts[:revision] = revision
|
29
|
+
end
|
30
|
+
stream = bucket.open_download_stream_by_name(args.use!('filename'), opts)
|
31
|
+
stream.read
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
23
35
|
def upload(op)
|
24
36
|
bucket = entities.get(:bucket, op.use!('object'))
|
25
37
|
use_arguments(op) do |args|
|
@@ -27,6 +39,15 @@ module Unified
|
|
27
39
|
if chunk_size = args.use('chunkSizeBytes')
|
28
40
|
opts[:chunk_size] = chunk_size
|
29
41
|
end
|
42
|
+
if metadata = args.use('metadata')
|
43
|
+
opts[:metadata] = metadata
|
44
|
+
end
|
45
|
+
if content_type = args.use('contentType')
|
46
|
+
opts[:content_type] = content_type
|
47
|
+
end
|
48
|
+
if disable_md5 = args.use('disableMD5')
|
49
|
+
opts[:disable_md5] = disable_md5
|
50
|
+
end
|
30
51
|
contents = transform_contents(args.use!('source'))
|
31
52
|
file_id = nil
|
32
53
|
bucket.open_upload_stream(args.use!('filename'), **opts) do |stream|
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# encoding: utf-8
|
3
3
|
|
4
4
|
require 'runners/crud/requirement'
|
5
|
+
require 'runners/unified/client_side_encryption_operations'
|
5
6
|
require 'runners/unified/crud_operations'
|
6
7
|
require 'runners/unified/grid_fs_operations'
|
7
8
|
require 'runners/unified/ddl_operations'
|
@@ -9,10 +10,12 @@ require 'runners/unified/change_stream_operations'
|
|
9
10
|
require 'runners/unified/support_operations'
|
10
11
|
require 'runners/unified/assertions'
|
11
12
|
require 'support/utils'
|
13
|
+
require 'support/crypt'
|
12
14
|
|
13
15
|
module Unified
|
14
16
|
|
15
17
|
class Test
|
18
|
+
include ClientSideEncryptionOperations
|
16
19
|
include CrudOperations
|
17
20
|
include GridFsOperations
|
18
21
|
include DdlOperations
|
@@ -193,6 +196,61 @@ module Unified
|
|
193
196
|
end
|
194
197
|
|
195
198
|
client.start_session(**opts)
|
199
|
+
when 'clientEncryption'
|
200
|
+
client_encryption_opts = spec.use!('clientEncryptionOpts')
|
201
|
+
key_vault_client = entities.get(:client, client_encryption_opts['keyVaultClient'])
|
202
|
+
opts = {
|
203
|
+
key_vault_namespace: client_encryption_opts['keyVaultNamespace'],
|
204
|
+
kms_providers: Utils.snakeize_hash(client_encryption_opts['kmsProviders']),
|
205
|
+
kms_tls_options: {
|
206
|
+
kmip: {
|
207
|
+
ssl_cert: SpecConfig.instance.fle_kmip_tls_certificate_key_file,
|
208
|
+
ssl_key: SpecConfig.instance.fle_kmip_tls_certificate_key_file,
|
209
|
+
ssl_ca_cert: SpecConfig.instance.fle_kmip_tls_ca_file
|
210
|
+
}
|
211
|
+
}
|
212
|
+
}
|
213
|
+
opts[:kms_providers] = opts[:kms_providers].map do |provider, options|
|
214
|
+
converted_options = options.map do |key, value|
|
215
|
+
converted_value = if value == { '$$placeholder'.to_sym => 1 }
|
216
|
+
case provider
|
217
|
+
when :aws
|
218
|
+
case key
|
219
|
+
when :access_key_id then SpecConfig.instance.fle_aws_key
|
220
|
+
when :secret_access_key then SpecConfig.instance.fle_aws_secret
|
221
|
+
end
|
222
|
+
when :azure
|
223
|
+
case key
|
224
|
+
when :tenant_id then SpecConfig.instance.fle_azure_tenant_id
|
225
|
+
when :client_id then SpecConfig.instance.fle_azure_client_id
|
226
|
+
when :client_secret then SpecConfig.instance.fle_azure_client_secret
|
227
|
+
end
|
228
|
+
when :gcp
|
229
|
+
case key
|
230
|
+
when :email then SpecConfig.instance.fle_gcp_email
|
231
|
+
when :private_key then SpecConfig.instance.fle_gcp_private_key
|
232
|
+
end
|
233
|
+
when :kmip
|
234
|
+
case key
|
235
|
+
when :endpoint then SpecConfig.instance.fle_kmip_endpoint
|
236
|
+
end
|
237
|
+
when :local
|
238
|
+
case key
|
239
|
+
when :key then Crypt::LOCAL_MASTER_KEY
|
240
|
+
end
|
241
|
+
end
|
242
|
+
else
|
243
|
+
value
|
244
|
+
end
|
245
|
+
[key, converted_value]
|
246
|
+
end.to_h
|
247
|
+
[provider, converted_options]
|
248
|
+
end.to_h
|
249
|
+
|
250
|
+
Mongo::ClientEncryption.new(
|
251
|
+
key_vault_client,
|
252
|
+
opts
|
253
|
+
)
|
196
254
|
else
|
197
255
|
raise NotImplementedError, "Unknown type #{type}"
|
198
256
|
end
|
@@ -290,7 +348,7 @@ module Unified
|
|
290
348
|
end
|
291
349
|
|
292
350
|
public_send(method_name, op)
|
293
|
-
rescue Mongo::Error, BSON::String::IllegalKey => e
|
351
|
+
rescue Mongo::Error, BSON::String::IllegalKey, ArgumentError => e
|
294
352
|
if expected_error.use('isClientError')
|
295
353
|
# isClientError doesn't actually mean a client error.
|
296
354
|
# It means anything other than OperationFailure. DRIVERS-1799
|
@@ -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
|
@@ -211,10 +211,18 @@ module Mrss
|
|
211
211
|
|
212
212
|
# This is a macro for retrying flaky tests on CI that occasionally fail.
|
213
213
|
# Note that the tests will only be retried on CI.
|
214
|
-
|
214
|
+
#
|
215
|
+
# @param [ Integer ] :tries The number of times to retry.
|
216
|
+
# @param [ Integer ] :sleep The number of seconds to sleep in between retries.
|
217
|
+
# If nothing, or nil, is passed, we won't wait in between retries.
|
218
|
+
def retry_test(tries: 3, sleep: nil)
|
215
219
|
if %w(1 yes true).include?(ENV['CI'])
|
216
220
|
around do |example|
|
217
|
-
|
221
|
+
if sleep
|
222
|
+
example.run_with_retry retry: tries, retry_wait: sleep
|
223
|
+
else
|
224
|
+
example.run_with_retry retry: tries
|
225
|
+
end
|
218
226
|
end
|
219
227
|
end
|
220
228
|
end
|
@@ -9,9 +9,14 @@ describe 'Clean exit' do
|
|
9
9
|
unless %w(1 true yes).include?(ENV['SOLO'])
|
10
10
|
skip 'Set SOLO=1 in environment to run solo tests'
|
11
11
|
end
|
12
|
+
|
13
|
+
if %w(1 true yes).include?(ENV['EXTERNAL_DISABLED'])
|
14
|
+
skip "Test requires external connectivity"
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
context 'with SRV URI' do
|
19
|
+
|
15
20
|
let(:uri) do
|
16
21
|
'mongodb+srv://test1.test.build.10gen.cc/?tls=false'
|
17
22
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
require 'runners/unified'
|
7
|
+
|
8
|
+
base = "#{CURRENT_PATH}/spec_tests/data/client_side_encryption"
|
9
|
+
CLIENT_SIDE_ENCRYPTION_UNIFIED_TESTS = Dir.glob("#{base}/unified/**/*.yml").sort
|
10
|
+
|
11
|
+
describe 'Client side encryption spec tests - unified' do
|
12
|
+
require_libmongocrypt
|
13
|
+
require_enterprise
|
14
|
+
|
15
|
+
define_unified_spec_tests(base, CLIENT_SIDE_ENCRYPTION_UNIFIED_TESTS)
|
16
|
+
end
|