1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
|
# frozen_string_literal: true
# rubocop:todo all
require 'mongo'
require 'lite_spec_helper'
describe Mongo::Crypt::ExplicitEncryptionContext do
require_libmongocrypt
include_context 'define shared FLE helpers'
let(:credentials) { Mongo::Crypt::KMS::Credentials.new(kms_providers) }
let(:mongocrypt) { Mongo::Crypt::Handle.new(credentials, logger: logger) }
let(:context) { described_class.new(mongocrypt, io, value, options) }
let(:logger) { nil }
let(:io) { double("Mongo::ClientEncryption::IO") }
let(:value) { { 'v': 'Hello, world!' } }
let(:options) do
{
key_id: key_id,
key_alt_name: key_alt_name,
algorithm: algorithm
}
end
describe '#initialize' do
shared_examples 'a functioning ExplicitEncryptionContext' do
context 'with nil key_id and key_alt_name options' do
let(:key_id) { nil }
let(:key_alt_name) { nil }
it 'raises an exception' do
expect do
context
end.to raise_error(ArgumentError, /:key_id and :key_alt_name options cannot both be nil/)
end
end
context 'with both key_id and key_alt_name options' do
it 'raises an exception' do
expect do
context
end.to raise_error(ArgumentError, /:key_id and :key_alt_name options cannot both be present/)
end
end
context 'with invalid key_id' do
let(:key_id) { 'random string' }
let(:key_alt_name) { nil }
it 'raises an exception' do
expect do
context
end.to raise_error(ArgumentError, /Expected the :key_id option to be a BSON::Binary object/)
end
end
context 'with invalid key_alt_name' do
let(:key_id) { nil }
let(:key_alt_name) { 5 }
it 'raises an exception' do
expect do
context
end.to raise_error(ArgumentError, /key_alt_name option must be a String/)
end
end
context 'with valid key_alt_name' do
let(:key_id) { nil }
context 'with nil algorithm' do
let(:algorithm) { nil }
it 'raises exception' do
expect do
context
end.to raise_error(Mongo::Error::CryptError, /passed null algorithm/)
end
end
context 'with invalid algorithm' do
let(:algorithm) { 'unsupported-algorithm' }
it 'raises an exception' do
expect do
context
end.to raise_error(Mongo::Error::CryptError, /unsupported algorithm/)
end
end
it 'initializes context' do
expect do
context
end.not_to raise_error
end
end
context 'with valid key_id' do
let(:key_alt_name) { nil }
context 'with nil algorithm' do
let(:algorithm) { nil }
it 'raises exception' do
expect do
context
end.to raise_error(Mongo::Error::CryptError, /passed null algorithm/)
end
end
context 'with invalid algorithm' do
let(:algorithm) { 'unsupported-algorithm' }
it 'raises an exception' do
expect do
context
end.to raise_error(Mongo::Error::CryptError, /unsupported algorithm/)
end
end
it 'initializes context' do
expect do
context
end.not_to raise_error
end
end
context 'with query_type' do
let(:key_alt_name) { nil }
it 'raises exception' do
expect do
described_class.new(
mongocrypt,
io,
value,
options.merge(query_type: "equality")
)
end.to raise_error(ArgumentError, /query_type is allowed only for "Indexed" or "Range" algorithm/)
end
end
context 'with contention_factor' do
let(:key_alt_name) { nil }
it 'raises exception' do
expect do
described_class.new(
mongocrypt,
io,
value,
options.merge(contention_factor: 10)
)
end.to raise_error(ArgumentError, /contention_factor is allowed only for "Indexed" or "Range" algorithm/)
end
end
context 'with Indexed algorithm' do
let(:algorithm) do
'Indexed'
end
let(:key_alt_name) do
nil
end
it 'initializes context' do
expect do
described_class.new(
mongocrypt,
io,
value,
options.merge(contention_factor: 0)
)
end.not_to raise_error
end
context 'with query_type' do
it 'initializes context' do
expect do
described_class.new(
mongocrypt,
io,
value,
options.merge(query_type: "equality", contention_factor: 0)
)
end.not_to raise_error
end
end
context 'with contention_factor' do
it 'initializes context' do
expect do
described_class.new(
mongocrypt,
io,
value,
options.merge(contention_factor: 10)
)
end.not_to raise_error
end
end
end
end
context 'when mongocrypt is initialized with AWS KMS provider options' do
include_context 'with AWS kms_providers'
it_behaves_like 'a functioning ExplicitEncryptionContext'
end
context 'when mongocrypt is initialized with Azure KMS provider options' do
include_context 'with Azure kms_providers'
it_behaves_like 'a functioning ExplicitEncryptionContext'
end
context 'when mongocrypt is initialized with GCP KMS provider options' do
include_context 'with GCP kms_providers'
it_behaves_like 'a functioning ExplicitEncryptionContext'
end
context 'when mongocrypt is initialized with KMIP KMS provider options' do
include_context 'with KMIP kms_providers'
it_behaves_like 'a functioning ExplicitEncryptionContext'
end
context 'when mongocrypt is initialized with local KMS provider options' do
include_context 'with local kms_providers'
it_behaves_like 'a functioning ExplicitEncryptionContext'
end
context 'with verbose logging' do
include_context 'with local kms_providers'
before(:all) do
# Logging from libmongocrypt requires the C library to be built with the -DENABLE_TRACE=ON
# option; none of the pre-built packages on Evergreen have been built with logging enabled.
#
# It is still useful to be able to run these tests locally to confirm that logging is working
# while debugging any problems.
#
# For now, skip this test by default and revisit once we have determined how we want to
# package libmongocrypt with the Ruby driver (see: https://jira.mongodb.org/browse/RUBY-1966)
skip "These tests require libmongocrypt to be built with the '-DENABLE_TRACE=ON' cmake option." +
" They also require the MONGOCRYPT_TRACE environment variable to be set to 'ON'."
end
let(:key_alt_name) { nil }
let(:logger) do
::Logger.new(STDOUT).tap do |logger|
logger.level = ::Logger::DEBUG
end
end
it 'receives log messages from libmongocrypt' do
expect(logger).to receive(:debug).with(/mongocrypt_ctx_setopt_key_id/)
expect(logger).to receive(:debug).with(/mongocrypt_ctx_setopt_algorithm/)
expect(logger).to receive(:debug).with(/mongocrypt_ctx_explicit_encrypt_init/)
context
end
end
end
end
|