Files
mongo/jstests/multiVersion/collection_autoIndexId_false.js
2019-04-05 15:06:48 -04:00

112 lines
4.5 KiB
JavaScript

/*
* If a collection does not have an index on the _id field (because of the use of autoIndexId: false
* in 3.6), the latest version of MongoDB will build the missing index.
*
* Ensure that if an index cannot be built, MongoDB shuts down cleanly and allows for any duplicate
* documents to be deleted in the previous version.
*/
(function() {
'use strict';
load('jstests/libs/get_index_helpers.js');
const dbName = 'test';
const collName = 'collection_autoIndexId_false';
// Given a dbpath to a 3.6 server, attempt to upgrade to 4.0.
function upgrade36To40(dbpath) {
let conn = MongoRunner.runMongod({binVersion: '4.0', dbpath: dbpath, noCleanData: true});
assert.neq(null, conn, 'mongod was unable to start with version 4.0');
let adminDb = conn.getDB('admin');
assert.commandWorked(adminDb.runCommand({'setFeatureCompatibilityVersion': '4.0'}));
MongoRunner.stopMongod(conn);
}
// Given a dbpath to a 3.6 server, attempt to upgrade to latest.
// shouldPass determines whether or not the upgrade should be successful.
function upgrade40ToLatest(dbpath, shouldPass) {
if (shouldPass) {
let conn =
MongoRunner.runMongod({binVersion: 'latest', dbpath: dbpath, noCleanData: true});
assert.neq(null, conn, 'mongod failed to start with latest version');
// Ensure the _id index exists.
let testDb = conn.getDB(dbName);
let coll = testDb.getCollection(collName);
let spec = GetIndexHelpers.findByKeyPattern(coll.getIndexes(), {_id: 1});
assert.neq(null, spec);
MongoRunner.stopMongod(conn);
} else {
let conn = MongoRunner.runMongod(
{binVersion: 'latest', dbpath: dbpath, noCleanData: true, waitForConnect: false});
// This tests that the server shuts down cleanly despite the inability to build the _id
// index.
assert.eq(MongoRunner.EXIT_NEED_DOWNGRADE, waitProgram(conn.pid));
}
}
// Create a collection with autoIndexId: false on a 3.6 server and assert that an upgrade to
// latest fails because there are duplicate values for the _id index.
function cannotUpgradeWithDuplicateIds() {
let conn = MongoRunner.runMongod({binVersion: '3.6'});
assert.neq(null, conn, 'mongod was unable able to start with version 3.6');
const dbpath = conn.dbpath;
// Create a collection with autoIndexId: false.
let testDb = conn.getDB(dbName);
let coll = testDb.getCollection(collName);
assert.commandWorked(coll.runCommand('create', {autoIndexId: false}));
assert.commandWorked(coll.insert({_id: 0, a: 1}));
assert.commandWorked(coll.insert({_id: 0, a: 2}));
MongoRunner.stopMongod(conn);
// The upgrade to 4.0 should always succeed because it does not care about the _id index.
upgrade36To40(dbpath);
let shouldPass = false;
upgrade40ToLatest(dbpath, shouldPass);
// Remove the duplicate (now in 4.0) and retry the upgrade to 4.2.
conn = MongoRunner.runMongod({binVersion: '4.0', dbpath: dbpath, noCleanData: true});
testDb = conn.getDB(dbName);
coll = testDb.getCollection(collName);
assert.commandWorked(coll.remove({_id: 0, a: 2}));
MongoRunner.stopMongod(conn);
shouldPass = true;
upgrade40ToLatest(dbpath, shouldPass);
resetDbpath(dbpath);
}
// Create a collection with autoIndexId: false on a 3.6 server and assert that an upgrade to
// latest succeeds because the missing _id index is built.
function canUpgradeWithoutIndex() {
let conn = MongoRunner.runMongod({binVersion: '3.6'});
assert.neq(null, conn, 'mongod was unable able to start with version 3.6');
const dbpath = conn.dbpath;
// Create a collection with autoIndexId: false.
let testDb = conn.getDB(dbName);
let coll = testDb.getCollection(collName);
assert.commandWorked(coll.runCommand('create', {autoIndexId: false}));
assert.commandWorked(coll.insert({_id: 0, a: 1}));
MongoRunner.stopMongod(conn);
// The upgrade to 4.0 should always succeed because it does not care about the _id index.
upgrade36To40(dbpath);
const shouldPass = true;
upgrade40ToLatest(dbpath, shouldPass);
resetDbpath(dbpath);
}
cannotUpgradeWithDuplicateIds();
canUpgradeWithoutIndex();
})();