diff options
author | Tess Avitabile <tess.avitabile@mongodb.com> | 2016-09-02 18:09:55 -0400 |
---|---|---|
committer | Tess Avitabile <tess.avitabile@mongodb.com> | 2016-09-07 13:48:14 -0400 |
commit | ebb07d13b13beeefa589a9daf2db2b655b7e71ca (patch) | |
tree | 1c754c75be6e58a1ce0b1ef77c468484379c1c35 | |
parent | b5277068ff66e7fe2b2a98144aa6993ca6e17f5c (diff) | |
download | mongo-ebb07d13b13beeefa589a9daf2db2b655b7e71ca.tar.gz |
SERVER-25889 Collection validation should fail if featureCompatibilityVersion is 3.2 and the collection contains NumberDecimal values
-rw-r--r-- | buildscripts/resmokeconfig/suites/jstestfuzz.yml | 1 | ||||
-rw-r--r-- | buildscripts/resmokeconfig/suites/jstestfuzz_replication.yml | 1 | ||||
-rw-r--r-- | buildscripts/resmokeconfig/suites/jstestfuzz_sharded.yml | 1 | ||||
-rw-r--r-- | jstests/decimal/decimal_feature_compatibility_version.js | 10 | ||||
-rw-r--r-- | jstests/hooks/validate_collections.js | 30 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection.cpp | 8 | ||||
-rw-r--r-- | src/mongo/shell/utils.js | 4 |
7 files changed, 49 insertions, 6 deletions
diff --git a/buildscripts/resmokeconfig/suites/jstestfuzz.yml b/buildscripts/resmokeconfig/suites/jstestfuzz.yml index b72166abaaa..872c2a1f229 100644 --- a/buildscripts/resmokeconfig/suites/jstestfuzz.yml +++ b/buildscripts/resmokeconfig/suites/jstestfuzz.yml @@ -14,6 +14,7 @@ executor: global_vars: TestData: skipValidationOnInvalidViewDefinitions: true + forceValidationWithFeatureCompatibilityVersion: "3.4" fixture: class: MongoDFixture mongod_options: diff --git a/buildscripts/resmokeconfig/suites/jstestfuzz_replication.yml b/buildscripts/resmokeconfig/suites/jstestfuzz_replication.yml index 49d86ebe68f..15254232e77 100644 --- a/buildscripts/resmokeconfig/suites/jstestfuzz_replication.yml +++ b/buildscripts/resmokeconfig/suites/jstestfuzz_replication.yml @@ -14,6 +14,7 @@ executor: global_vars: TestData: skipValidationOnInvalidViewDefinitions: true + forceValidationWithFeatureCompatibilityVersion: "3.4" - class: CheckReplDBHash shell_options: global_vars: diff --git a/buildscripts/resmokeconfig/suites/jstestfuzz_sharded.yml b/buildscripts/resmokeconfig/suites/jstestfuzz_sharded.yml index f8d56c68a95..9c767ea6d9c 100644 --- a/buildscripts/resmokeconfig/suites/jstestfuzz_sharded.yml +++ b/buildscripts/resmokeconfig/suites/jstestfuzz_sharded.yml @@ -14,6 +14,7 @@ executor: global_vars: TestData: skipValidationOnInvalidViewDefinitions: true + forceValidationWithFeatureCompatibilityVersion: "3.4" fixture: class: ShardedClusterFixture mongos_options: diff --git a/jstests/decimal/decimal_feature_compatibility_version.js b/jstests/decimal/decimal_feature_compatibility_version.js index 66f07f9581d..ec7b384d7c8 100644 --- a/jstests/decimal/decimal_feature_compatibility_version.js +++ b/jstests/decimal/decimal_feature_compatibility_version.js @@ -21,6 +21,11 @@ // Decimals can be inserted when the featureCompatibilityVersion is 3.4. assert.writeOK(decimalDB.collection.insert({a: NumberDecimal(2.0)})); + // Collection containing decimals is valid when the featureCompatibilityVersion is 3.4. + res = decimalDB.collection.validate({full: true}); + assert.commandWorked(res); + assert.eq(true, res.valid, tojson(res)); + // Ensure the featureCompatibilityVersion is 3.2. assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "3.2"})); res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); @@ -39,5 +44,10 @@ // Decimals can be read when the featureCompatibilityVersion is 3.2. assert.eq(decimalDB.collection.findOne().a, NumberDecimal(2.0)); + // Collection containing decimals is invalid when the featureCompatibilityVersion is 3.2. + res = decimalDB.collection.validate({full: true}); + assert.commandWorked(res); + assert.eq(false, res.valid, tojson(res)); + MongoRunner.stopMongod(conn); }()); diff --git a/jstests/hooks/validate_collections.js b/jstests/hooks/validate_collections.js index eac734b4d61..89c7f73e798 100644 --- a/jstests/hooks/validate_collections.js +++ b/jstests/hooks/validate_collections.js @@ -13,6 +13,19 @@ function validateCollections(db, obj) { } } + function getFeatureCompatibilityVersion(adminDB) { + var res = adminDB.system.version.findOne({_id: "featureCompatibilityVersion"}); + if (res === null) { + return "3.2"; + } + return res.version; + } + + function setFeatureCompatibilityVersion(adminDB, version) { + assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: version})); + assert.eq(version, getFeatureCompatibilityVersion(adminDB)); + } + assert.eq(typeof db, 'object', 'Invalid `db` object, is the shell connected to a mongod?'); assert.eq(typeof obj, 'object', 'The `obj` argument must be an object'); assert(obj.hasOwnProperty('full'), 'Please specify whether to use full validation'); @@ -21,6 +34,17 @@ function validateCollections(db, obj) { var success = true; + var adminDB = db.getSiblingDB("admin"); + + // Set the featureCompatibilityVersion to its required value for performing validation. Save the + // original value. + var originalFeatureCompatibilityVersion; + if (jsTest.options().forceValidationWithFeatureCompatibilityVersion) { + originalFeatureCompatibilityVersion = getFeatureCompatibilityVersion(adminDB); + setFeatureCompatibilityVersion( + adminDB, jsTest.options().forceValidationWithFeatureCompatibilityVersion); + } + // Don't run validate on view namespaces. let listCollectionsRes = db.runCommand({listCollections: 1, filter: {"type": "collection"}}); if (jsTest.options().skipValidationOnInvalidViewDefinitions && listCollectionsRes.ok === 0) { @@ -42,5 +66,11 @@ function validateCollections(db, obj) { success = false; } } + + // Restore the original value for featureCompatibilityVersion. + if (jsTest.options().forceValidationWithFeatureCompatibilityVersion) { + setFeatureCompatibilityVersion(adminDB, originalFeatureCompatibilityVersion); + } + return success; } diff --git a/src/mongo/db/catalog/collection.cpp b/src/mongo/db/catalog/collection.cpp index b4651f41d5a..505f5703f75 100644 --- a/src/mongo/db/catalog/collection.cpp +++ b/src/mongo/db/catalog/collection.cpp @@ -68,6 +68,7 @@ #include "mongo/db/storage/wiredtiger/wiredtiger_record_store.h" #include "mongo/db/auth/user_document_parser.h" // XXX-ANDY +#include "mongo/rpc/object_check.h" #include "mongo/util/fail_point.h" #include "mongo/util/log.h" @@ -1057,11 +1058,8 @@ public: virtual Status validate(const RecordId& recordId, const RecordData& record, size_t* dataSize) { BSONObj recordBson = record.toBson(); - - // Use the latest BSON validation version. We do not say the collection is invalid for - // containing decimal data, even if decimal is disabled. - const Status status = - validateBSON(recordBson.objdata(), recordBson.objsize(), BSONVersion::kLatest); + const Status status = validateBSON( + recordBson.objdata(), recordBson.objsize(), Validator<BSONObj>::enabledBSONVersion()); if (status.isOK()) { *dataSize = recordBson.objsize(); } else { diff --git a/src/mongo/shell/utils.js b/src/mongo/shell/utils.js index cf2ed7ed8d3..d24e8aad3e9 100644 --- a/src/mongo/shell/utils.js +++ b/src/mongo/shell/utils.js @@ -197,7 +197,9 @@ jsTestOptions = function() { mongosBinVersion: TestData.mongosBinVersion || "", shardMixedBinVersions: TestData.shardMixedBinVersions || false, networkMessageCompressors: TestData.networkMessageCompressors, - skipValidationOnInvalidViewDefinitions: TestData.skipValidationOnInvalidViewDefinitions + skipValidationOnInvalidViewDefinitions: TestData.skipValidationOnInvalidViewDefinitions, + forceValidationWithFeatureCompatibilityVersion: + TestData.forceValidationWithFeatureCompatibilityVersion }); } return _jsTestOptions; |