diff options
author | Benety Goh <benety@mongodb.com> | 2019-06-14 14:25:23 -0400 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2019-06-14 14:25:39 -0400 |
commit | 86ccf51acba7bbefca2b70333995de80c16e68be (patch) | |
tree | f4b0e02cfcb9f8b491444007683b867be6b60fef /jstests | |
parent | 1fa1cb9be9e0dc1ae6b953fb0ce176419e3a4fab (diff) | |
download | mongo-86ccf51acba7bbefca2b70333995de80c16e68be.tar.gz |
SERVER-37905 add regression tests for hyrid index builds.
Diffstat (limited to 'jstests')
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(); +})(); |