summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2019-06-14 14:25:23 -0400
committerBenety Goh <benety@mongodb.com>2019-06-14 14:25:39 -0400
commit86ccf51acba7bbefca2b70333995de80c16e68be (patch)
treef4b0e02cfcb9f8b491444007683b867be6b60fef /jstests
parent1fa1cb9be9e0dc1ae6b953fb0ce176419e3a4fab (diff)
downloadmongo-86ccf51acba7bbefca2b70333995de80c16e68be.tar.gz
SERVER-37905 add regression tests for hyrid index builds.
Diffstat (limited to 'jstests')
-rw-r--r--jstests/noPassthrough/hybrid_geo_index_remove_invalid_doc.js71
-rw-r--r--jstests/noPassthrough/hybrid_geo_index_update_invalid_doc.js67
-rw-r--r--jstests/noPassthrough/hybrid_partial_index_update.js56
3 files changed, 194 insertions, 0 deletions
diff --git a/jstests/noPassthrough/hybrid_geo_index_remove_invalid_doc.js b/jstests/noPassthrough/hybrid_geo_index_remove_invalid_doc.js
new file mode 100644
index 00000000000..a99533a8bbf
--- /dev/null
+++ b/jstests/noPassthrough/hybrid_geo_index_remove_invalid_doc.js
@@ -0,0 +1,71 @@
+/**
+ * Tests that building geo indexes using the hybrid method handles the unindexing of invalid
+ * geo documents.
+ *
+ * @tags: [requires_document_locking, requires_replication]
+ */
+(function() {
+ 'use strict';
+
+ load('jstests/noPassthrough/libs/index_build.js');
+
+ const rst = new ReplSetTest({
+ nodes: [
+ {},
+ {
+ // Disallow elections on secondary.
+ rsConfig: {
+ priority: 0,
+ votes: 0,
+ },
+ },
+ ]
+ });
+ const nodes = rst.startSet();
+ rst.initiate();
+
+ const primary = rst.getPrimary();
+ const testDB = primary.getDB('test');
+ const coll = testDB.getCollection('test');
+
+ assert.commandWorked(testDB.createCollection(coll.getName()));
+
+ // Insert an invalid geo document that will be removed before the indexer starts a collecton
+ // scan.
+ assert.commandWorked(coll.insert({
+ _id: 0,
+ b: {type: 'invalid_geo_json_type', coordinates: [100, 100]},
+ }));
+
+ // We are using this fail point to pause the index build before it starts the collection scan.
+ // This is important for this test because we are mutating the collection state before the index
+ // builder is able to observe the invalid geo document.
+ // By comparison, IndexBuildTest.pauseIndexBuilds() stalls the index build in the middle of the
+ // collection scan.
+ assert.commandWorked(testDB.adminCommand(
+ {configureFailPoint: 'hangAfterSettingUpIndexBuild', mode: 'alwaysOn'}));
+
+ const createIdx = IndexBuildTest.startIndexBuild(primary, coll.getFullName(), {b: '2dsphere'});
+ IndexBuildTest.waitForIndexBuildToStart(testDB);
+
+ // Insert a valid geo document to initialize the hybrid index builder's side table state.
+ assert.commandWorked(coll.insert({
+ b: {type: 'Polygon', coordinates: [[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]]},
+ }));
+
+ // Removing the invalid geo document should not cause any issues for the side table accounting.
+ assert.commandWorked(coll.remove({_id: 0}));
+
+ assert.commandWorked(
+ testDB.adminCommand({configureFailPoint: 'hangAfterSettingUpIndexBuild', mode: 'off'}));
+
+ // Wait for the index build to finish. Since the invalid geo document is removed before the
+ // index build scans the collection, the index should be built successfully.
+ createIdx();
+ IndexBuildTest.assertIndexes(coll, 2, ['_id_', 'b_2dsphere']);
+
+ let res = assert.commandWorked(coll.validate({full: true}));
+ assert(res.valid, 'validation failed on primary: ' + tojson(res));
+
+ rst.stopSet();
+})();
diff --git a/jstests/noPassthrough/hybrid_geo_index_update_invalid_doc.js b/jstests/noPassthrough/hybrid_geo_index_update_invalid_doc.js
new file mode 100644
index 00000000000..3492726334d
--- /dev/null
+++ b/jstests/noPassthrough/hybrid_geo_index_update_invalid_doc.js
@@ -0,0 +1,67 @@
+/**
+ * Tests that building geo indexes using the hybrid method handles the unindexing of invalid
+ * geo documents.
+ *
+ * @tags: [requires_document_locking, requires_replication]
+ */
+(function() {
+ 'use strict';
+
+ load('jstests/noPassthrough/libs/index_build.js');
+
+ const rst = new ReplSetTest({
+ nodes: [
+ {},
+ {
+ // Disallow elections on secondary.
+ rsConfig: {
+ priority: 0,
+ votes: 0,
+ },
+ },
+ ]
+ });
+ const nodes = rst.startSet();
+ rst.initiate();
+
+ const primary = rst.getPrimary();
+ const testDB = primary.getDB('test');
+ const coll = testDB.getCollection('test');
+
+ assert.commandWorked(testDB.createCollection(coll.getName()));
+
+ // Insert an invalid geo document that will be removed before the indexer starts a collecton
+ // scan.
+ assert.commandWorked(coll.insert({
+ _id: 0,
+ b: {type: 'invalid_geo_json_type', coordinates: [100, 100]},
+ }));
+
+ // We are using this fail point to pause the index build before it starts the collection scan.
+ // This is important for this test because we are mutating the collection state before the index
+ // builder is able to observe the invalid geo document.
+ // By comparison, IndexBuildTest.pauseIndexBuilds() stalls the index build in the middle of the
+ // collection scan.
+ assert.commandWorked(testDB.adminCommand(
+ {configureFailPoint: 'hangAfterSettingUpIndexBuild', mode: 'alwaysOn'}));
+
+ const createIdx = IndexBuildTest.startIndexBuild(primary, coll.getFullName(), {b: '2dsphere'});
+ IndexBuildTest.waitForIndexBuildToStart(testDB);
+
+ // Fixing the invalid geo document should not cause any issues for the side table accounting.
+ assert.commandWorked(coll.update(
+ {_id: 0}, {b: {type: 'Polygon', coordinates: [[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]]}}));
+
+ assert.commandWorked(
+ testDB.adminCommand({configureFailPoint: 'hangAfterSettingUpIndexBuild', mode: 'off'}));
+
+ // Wait for the index build to finish. Since the invalid geo document is removed before the
+ // index build scans the collection, the index should be built successfully.
+ createIdx();
+ IndexBuildTest.assertIndexes(coll, 2, ['_id_', 'b_2dsphere']);
+
+ let res = assert.commandWorked(coll.validate({full: true}));
+ assert(res.valid, 'validation failed on primary: ' + tojson(res));
+
+ rst.stopSet();
+})();
diff --git a/jstests/noPassthrough/hybrid_partial_index_update.js b/jstests/noPassthrough/hybrid_partial_index_update.js
new file mode 100644
index 00000000000..79d9f9cb48e
--- /dev/null
+++ b/jstests/noPassthrough/hybrid_partial_index_update.js
@@ -0,0 +1,56 @@
+/**
+ * Tests that building partial indexes using the hybrid method preserves multikey information.
+ *
+ * @tags: [requires_document_locking, requires_replication]
+ */
+(function() {
+ 'use strict';
+
+ load('jstests/noPassthrough/libs/index_build.js');
+
+ const rst = new ReplSetTest({
+ nodes: [
+ {},
+ {
+ // Disallow elections on secondary.
+ rsConfig: {
+ priority: 0,
+ votes: 0,
+ },
+ },
+ ]
+ });
+ const nodes = rst.startSet();
+ rst.initiate();
+
+ const primary = rst.getPrimary();
+ const testDB = primary.getDB('test');
+ const coll = testDB.getCollection('test');
+
+ assert.commandWorked(testDB.createCollection(coll.getName()));
+
+ IndexBuildTest.pauseIndexBuilds(primary);
+
+ // Create a partial index for documents where 'a', the field in the filter expression,
+ // is equal to 1.
+ const partialIndex = {a: 1};
+ const createIdx = IndexBuildTest.startIndexBuild(
+ primary, coll.getFullName(), partialIndex, {partialFilterExpression: {a: 1}});
+ IndexBuildTest.waitForIndexBuildToStart(testDB);
+
+ assert.commandWorked(coll.insert({_id: 0, a: 1}));
+
+ // Update the document so that it no longer meets the partial index criteria.
+ assert.commandWorked(coll.update({_id: 0}, {$set: {a: 0}}));
+
+ IndexBuildTest.resumeIndexBuilds(primary);
+
+ // Wait for the index build to finish.
+ createIdx();
+ IndexBuildTest.assertIndexes(coll, 2, ['_id_', 'a_1']);
+
+ let res = assert.commandWorked(coll.validate({full: true}));
+ assert(res.valid, 'validation failed on primary: ' + tojson(res));
+
+ rst.stopSet();
+})();