summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTess Avitabile <tess.avitabile@mongodb.com>2016-09-02 18:09:55 -0400
committerTess Avitabile <tess.avitabile@mongodb.com>2016-09-07 13:48:14 -0400
commitebb07d13b13beeefa589a9daf2db2b655b7e71ca (patch)
tree1c754c75be6e58a1ce0b1ef77c468484379c1c35
parentb5277068ff66e7fe2b2a98144aa6993ca6e17f5c (diff)
downloadmongo-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.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/jstestfuzz_replication.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/jstestfuzz_sharded.yml1
-rw-r--r--jstests/decimal/decimal_feature_compatibility_version.js10
-rw-r--r--jstests/hooks/validate_collections.js30
-rw-r--r--src/mongo/db/catalog/collection.cpp8
-rw-r--r--src/mongo/shell/utils.js4
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;