mongo 2.18.0.beta1 → 2.18.0
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.
- 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
|