summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMihai Andrei <mihai.andrei@10gen.com>2020-11-23 10:37:57 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-11-30 14:56:04 +0000
commit644705e5755227ce13ca7fdee405003c4dd2cebb (patch)
tree0d6c6b85fc49b6b0bdee3a0fe538487207cc228a
parent415c13d84baee5311bd1699fb3431b8b08ac449b (diff)
downloadmongo-644705e5755227ce13ca7fdee405003c4dd2cebb.tar.gz
SERVER-52975 Fix use of 'onRollback' callback for collection validator options in 'collection_impl.cpp'
(cherry picked from commit 459e61631a0f806962fe481aed80363d2d438a04)
-rw-r--r--jstests/core/doc_validation_encrypt_keywords.js39
-rw-r--r--src/mongo/db/catalog/collection_impl.cpp10
2 files changed, 42 insertions, 7 deletions
diff --git a/jstests/core/doc_validation_encrypt_keywords.js b/jstests/core/doc_validation_encrypt_keywords.js
index de8303fe59d..21d84768def 100644
--- a/jstests/core/doc_validation_encrypt_keywords.js
+++ b/jstests/core/doc_validation_encrypt_keywords.js
@@ -7,8 +7,8 @@
(function() {
"use strict";
-var collName = "doc_validation_encrypt_keywords";
-var coll = db[collName];
+const collName = "doc_validation_encrypt_keywords";
+const coll = db[collName];
coll.drop();
const encryptSchema = {
@@ -21,6 +21,29 @@ const encryptMetadataSchema = {
$jsonSchema: {encryptMetadata: {algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"}}
};
+/**
+ * Verify that the validator's in-memory state matches its on-disk state.
+ */
+function validateCollectionOptions() {
+ function verifyValidateSuccess(output) {
+ assert(output.hasOwnProperty("errors"), output);
+ assert.eq(0, output["errors"].length, output);
+ assert(output.hasOwnProperty("valid"), output);
+ assert.eq(true, output["valid"], output);
+ }
+
+ const validateResult = assert.commandWorked(coll.validate({full: true}));
+
+ if (validateResult.hasOwnProperty("raw")) {
+ const rawOutput = validateResult["raw"];
+ for (const key of Object.keys(rawOutput)) {
+ verifyValidateSuccess(rawOutput[key]);
+ }
+ } else {
+ verifyValidateSuccess(validateResult);
+ }
+}
+
assert.commandFailedWithCode(
db.createCollection(collName, {validator: encryptSchema, validationAction: "warn"}),
ErrorCodes.QueryFeatureNotAllowed);
@@ -48,10 +71,13 @@ assert.commandWorked(db.createCollection(
// Verify that we can't collMod the validator to include an encryption-related keyword.
assert.commandFailedWithCode(db.runCommand({collMod: collName, validator: encryptSchema}),
ErrorCodes.QueryFeatureNotAllowed);
+validateCollectionOptions();
assert.commandFailedWithCode(db.runCommand({collMod: collName, validator: nestedEncryptSchema}),
ErrorCodes.QueryFeatureNotAllowed);
+validateCollectionOptions();
assert.commandFailedWithCode(db.runCommand({collMod: collName, validator: encryptMetadataSchema}),
ErrorCodes.QueryFeatureNotAllowed);
+validateCollectionOptions();
coll.drop();
// Create the collection with an encrypted validator and action 'error'.
@@ -62,11 +88,13 @@ assert.commandWorked(
// encryption-related keyword.
assert.commandFailedWithCode(db.runCommand({collMod: collName, validationAction: "warn"}),
ErrorCodes.QueryFeatureNotAllowed);
+validateCollectionOptions();
// Verify that we can't collMod the validation level to 'moderate' since the schema contains an
// encryption-related keyword.
assert.commandFailedWithCode(db.runCommand({collMod: collName, validationLevel: "moderate"}),
ErrorCodes.QueryFeatureNotAllowed);
+validateCollectionOptions();
coll.drop();
// Create the collection without a document validator.
@@ -77,22 +105,27 @@ assert.commandWorked(db.createCollection(collName));
assert.commandFailedWithCode(
db.runCommand({collMod: collName, validator: encryptSchema, validationAction: "warn"}),
ErrorCodes.QueryFeatureNotAllowed);
+validateCollectionOptions();
assert.commandFailedWithCode(
db.runCommand({collMod: collName, validator: nestedEncryptSchema, validationAction: "warn"}),
ErrorCodes.QueryFeatureNotAllowed);
+validateCollectionOptions();
assert.commandFailedWithCode(
db.runCommand({collMod: collName, validator: encryptMetadataSchema, validationAction: "warn"}),
ErrorCodes.QueryFeatureNotAllowed);
+validateCollectionOptions();
assert.commandFailedWithCode(
db.runCommand({collMod: collName, validator: encryptSchema, validationLevel: "moderate"}),
ErrorCodes.QueryFeatureNotAllowed);
+validateCollectionOptions();
assert.commandFailedWithCode(
db.runCommand({collMod: collName, validator: nestedEncryptSchema, validationLevel: "moderate"}),
ErrorCodes.QueryFeatureNotAllowed);
+validateCollectionOptions();
assert.commandFailedWithCode(
db.runCommand(
{collMod: collName, validator: encryptMetadataSchema, validationLevel: "moderate"}),
ErrorCodes.QueryFeatureNotAllowed);
-coll.drop();
+validateCollectionOptions();
})();
diff --git a/src/mongo/db/catalog/collection_impl.cpp b/src/mongo/db/catalog/collection_impl.cpp
index 9b1a80d2bb7..c6498fc3afb 100644
--- a/src/mongo/db/catalog/collection_impl.cpp
+++ b/src/mongo/db/catalog/collection_impl.cpp
@@ -953,6 +953,9 @@ Status CollectionImpl::setValidationLevel(OperationContext* opCtx, StringData ne
auto oldValidationLevel = _validationLevel;
_validationLevel = levelSW.getValue();
+ opCtx->recoveryUnit()->onRollback(
+ [this, oldValidationLevel]() { this->_validationLevel = oldValidationLevel; });
+
// Reparse the validator as there are some features which are only supported with certain
// validation levels.
auto allowedFeatures = MatchExpressionParser::kAllowAllSpecialFeatures;
@@ -966,8 +969,6 @@ Status CollectionImpl::setValidationLevel(OperationContext* opCtx, StringData ne
DurableCatalog::get(opCtx)->updateValidator(
opCtx, ns(), _validatorDoc, getValidationLevel(), getValidationAction());
- opCtx->recoveryUnit()->onRollback(
- [this, oldValidationLevel]() { this->_validationLevel = oldValidationLevel; });
return Status::OK();
}
@@ -983,6 +984,9 @@ Status CollectionImpl::setValidationAction(OperationContext* opCtx, StringData n
auto oldValidationAction = _validationAction;
_validationAction = actionSW.getValue();
+ opCtx->recoveryUnit()->onRollback(
+ [this, oldValidationAction]() { this->_validationAction = oldValidationAction; });
+
// Reparse the validator as there are some features which are only supported with certain
// validation actions.
auto allowedFeatures = MatchExpressionParser::kAllowAllSpecialFeatures;
@@ -996,8 +1000,6 @@ Status CollectionImpl::setValidationAction(OperationContext* opCtx, StringData n
DurableCatalog::get(opCtx)->updateValidator(
opCtx, ns(), _validatorDoc, getValidationLevel(), getValidationAction());
- opCtx->recoveryUnit()->onRollback(
- [this, oldValidationAction]() { this->_validationAction = oldValidationAction; });
return Status::OK();
}