summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorDianna Hohensee <dianna.hohensee@mongodb.com>2019-09-05 00:23:40 +0000
committerevergreen <evergreen@mongodb.com>2019-09-05 00:23:40 +0000
commite8e3f6ff2604e33e2d7fe1ec56d6559df066a452 (patch)
tree287697bc8e92870dea373ad3c70fae82e2e1280c /jstests
parentbac2b16a61498a65cbd61da0e15235363e7e77b9 (diff)
downloadmongo-e8e3f6ff2604e33e2d7fe1ec56d6559df066a452.tar.gz
SERVER-30357 Allow users to run the validate cmd with {background:true}
Diffstat (limited to 'jstests')
-rw-r--r--jstests/core/background_validation.js108
1 files changed, 108 insertions, 0 deletions
diff --git a/jstests/core/background_validation.js b/jstests/core/background_validation.js
new file mode 100644
index 00000000000..274d60aca7c
--- /dev/null
+++ b/jstests/core/background_validation.js
@@ -0,0 +1,108 @@
+/**
+ * Tests the validate command with {background:true}.
+ *
+ * Checks that {full:true} cannot be run with {background:true}.
+ * Checks that {background:true} runs.
+ * Checks that {background:true} can run concurrently with CRUD ops on the same collection.
+ *
+ * @tags: [
+ * # Background validation is only supported by WT.
+ * requires_wiredtiger,
+ * # A failpoint is set that only exists on the mongod.
+ * assumes_against_mongod_not_mongos,
+ * # A failpoint is set against the primary only.
+ * does_not_support_stepdowns
+ * ]
+ */
+
+(function() {
+'use strict';
+
+load("jstests/libs/check_log.js");
+
+const dbName = "test_db_background_validation";
+const collName = "test_coll_background_validation";
+const testDB = db.getSiblingDB(dbName);
+const testColl = testDB.getCollection(collName);
+testColl.drop();
+
+/*
+ * Create some indexes and insert some data, so we can validate them more meaningfully.
+ */
+
+assert.commandWorked(testColl.createIndex({a: 1}));
+assert.commandWorked(testColl.createIndex({b: 1}));
+assert.commandWorked(testColl.createIndex({c: 1}));
+
+const numDocs = 100;
+for (let i = 0; i < numDocs; ++i) {
+ assert.commandWorked(testColl.insert({a: i, b: i, c: i}));
+}
+
+/**
+ * Ensure {full:true} and {background:true} cannot be run together.
+ */
+assert.commandFailedWithCode(testColl.validate({background: true, full: true}),
+ ErrorCodes.CommandNotSupported);
+
+// Check that {backround:true} is successful.
+let res = testColl.validate({background: true});
+assert.commandWorked(res);
+assert(res.valid, "Validate cmd with {background:true} failed: " + tojson(res));
+
+/*
+ * Test background validation with concurrent CRUD operations.
+ */
+
+// Set a failpoint in the background validation code to pause validation while holding a collection
+// lock.
+assert.commandWorked(
+ db.adminCommand({configureFailPoint: "pauseCollectionValidationWithLock", mode: "alwaysOn"}));
+
+// Start an asynchronous thread to run collection validation with {background:true}.
+let awaitValidateCommand = startParallelShell(function() {
+ let mycoll = db.getSiblingDB("test_db_background_validation")
+ .getCollection("test_coll_background_validation");
+ let validateRes = mycoll.validate({background: true});
+ assert.commandWorked(validateRes,
+ "asynchronous background validate command failed: " + tojson(validateRes));
+ assert(validateRes.valid,
+ "asynchronous background validate command was not valid: " + tojson(validateRes));
+});
+
+// Wait for background validation command to start.
+checkLog.contains(db.getMongo(), "Failpoint 'pauseCollectionValidationWithLock' activated.");
+
+jsTest.log("Should start hanging now......");
+
+// Check that CRUD ops are succesful while validation is in progress.
+assert.commandWorked(testColl.remove({a: 1, b: 1, c: 1}));
+assert.commandWorked(testColl.insert({a: 1, b: 1, c: 1, d: 100}));
+assert.commandWorked(testColl.update({d: 100}, {"e": "updated"}));
+let docRes = testColl.find({"e": "updated"});
+assert.eq(1,
+ docRes.toArray().length,
+ "expected to find a single document, found: " + tojson(docRes.toArray()));
+
+// Clear the failpoint and make sure the validate command was successful.
+assert.commandWorked(
+ db.adminCommand({configureFailPoint: "pauseCollectionValidationWithLock", mode: "off"}));
+awaitValidateCommand();
+
+/**
+ * Verify everything is still OK by running foreground validation.
+ */
+res = testColl.validate({background: false});
+assert.commandWorked(res);
+assert(res.valid, "Validate cmd with {background:true} failed: " + tojson(res));
+assert.eq(res.nIndexes, 4, "Expected 4 indexes: " + tojson(res));
+assert.eq(res.nrecords, numDocs, "Expected " + numDocs + " collection records:" + tojson(res));
+assert.eq(
+ res.keysPerIndex._id_, numDocs, "Expected " + numDocs + " _id index records: " + tojson(res));
+assert.eq(
+ res.keysPerIndex.a_1, numDocs, "Expected " + numDocs + " a_1 index records: " + tojson(res));
+assert.eq(
+ res.keysPerIndex.b_1, numDocs, "Expected " + numDocs + " b_1 index records: " + tojson(res));
+assert.eq(
+ res.keysPerIndex.c_1, numDocs, "Expected " + numDocs + " c_1 index records: " + tojson(res));
+})();