Files
mongo/jstests/multiVersion/index_bigkeys_feature_tracker.js

182 lines
7.3 KiB
JavaScript

/**
* Test feature tracker bit indicating the existence of long TypeBits.
* Intentionally don't test unique index because 4.2 and 4.0 have different unique index formats and
* we already have other mechanism to make 4.0 fail to start up if there are 4.2 unique indexes on
* disk.
* TODO SERVER-36385: Remove this test in the master branch once we have created a 4.2 branch.
*/
(function() {
"use strict";
const collName = "index_bigkeys";
function insertIndexKey(
createIndexFirst, db, collName, docToInsert, backgroundIndexBuild, update) {
if (createIndexFirst) {
assert.commandWorked(db.runCommand({
createIndexes: collName,
indexes: [{key: {x: 1}, name: "x_1", background: backgroundIndexBuild}]
}));
if (update) {
assert.commandWorked(
db.runCommand({insert: collName, documents: [{_id: docToInsert._id, x: 1}]}));
assert.commandWorked(db.runCommand({
update: collName,
updates: [{q: {_id: docToInsert._id}, u: {x: docToInsert}}]
}));
} else {
// This will insert a feature tracker bit on disk.
assert.commandWorked(db.runCommand({insert: collName, documents: [docToInsert]}));
}
} else {
if (update) {
assert.commandWorked(
db.runCommand({insert: collName, documents: [{_id: docToInsert._id, x: 1}]}));
assert.commandWorked(db.runCommand({
update: collName,
updates: [{q: {_id: docToInsert._id}, u: {x: docToInsert}}]
}));
} else {
// This will insert a feature tracker bit on disk.
assert.commandWorked(db.runCommand({insert: collName, documents: [docToInsert]}));
}
// This will insert a feature tracker bit on disk.
assert.commandWorked(db.runCommand({
createIndexes: collName,
indexes: [{key: {x: 1}, name: "x_1", background: backgroundIndexBuild}]
}));
}
}
function logTestParameters(
docToInsert, shouldFailOnStartup, createIndexFirst, backgroundIndexBuild, update) {
let output = {
"docToInsert._id": docToInsert._id,
shouldFailOnStartup: shouldFailOnStartup,
createIndexFirst: createIndexFirst,
backgroundIndexBuild: backgroundIndexBuild,
update: update
};
jsTestLog("Testing with parameters: " + tojson(output));
}
const dbpath = MongoRunner.dataPath + "index_bigkeys_feature_tracker";
function testInsertIndexKeyAndDowngradeStandalone(
docToInsert, shouldFailOnStartup, createIndexFirst, backgroundIndexBuild, update) {
logTestParameters(
docToInsert, shouldFailOnStartup, createIndexFirst, backgroundIndexBuild, update);
const conn = MongoRunner.runMongod({binVersion: "latest", dbpath: dbpath});
insertIndexKey(createIndexFirst,
conn.getDB("test"),
collName,
docToInsert,
backgroundIndexBuild,
update);
// Downgrade the FCV to 4.0
assert.commandWorked(conn.adminCommand({setFeatureCompatibilityVersion: "4.0"}));
// Index validation would fail because validation code assumes big index keys are not
// indexed in FCV 4.0.
MongoRunner.stopMongod(conn, null, {skipValidation: true});
if (shouldFailOnStartup) {
// 4.0 binary should fail on start up due to the new feature tracker bit.
assert.eq(
null,
MongoRunner.runMongod({binVersion: "4.0", noCleanData: true, dbpath: dbpath}));
} else {
const conn =
MongoRunner.runMongod({binVersion: "4.0", noCleanData: true, dbpath: dbpath});
assert.neq(null, conn);
MongoRunner.stopMongod(conn, null, {skipValidation: true});
}
}
function testInsertIndexKeyAndDowngradeReplset(
docToInsert, shouldFailOnStartup, createIndexFirst, backgroundIndexBuild, update) {
logTestParameters(
docToInsert, shouldFailOnStartup, createIndexFirst, backgroundIndexBuild, update);
const rst = new ReplSetTest({nodes: 1});
rst.startSet();
rst.initiate();
const primary = rst.getPrimary();
insertIndexKey(createIndexFirst,
primary.getDB("test"),
collName,
docToInsert,
backgroundIndexBuild,
update);
// Downgrade the FCV to 4.0
assert.commandWorked(primary.adminCommand({setFeatureCompatibilityVersion: "4.0"}));
// Index validation would fail because validation code assumes big index keys are not
// indexed in FCV 4.0.
rst.stopSet(undefined, undefined, {noCleanData: true, skipValidation: true});
if (shouldFailOnStartup) {
// 4.0 binary should fail on start up due to the new feature tracker bit.
assert.throws(function() {
rst.start(0, {binVersion: "4.0", noCleanData: true}, true);
});
} else {
const conn = rst.start(0, {binVersion: "4.0", noCleanData: true}, true);
assert.neq(null, conn);
rst.stopSet(undefined, undefined, {skipValidation: true});
}
}
const largeKeyWithShortTypeBits = 's'.repeat(12345);
const largeKeyWithLongTypeBits = (() => {
// {a : [0,1,2, ... ,9999] }
return {a: Array.from({length: 10000}, (value, i) => i)};
})();
// Tests for standalone
jsTestLog("Test for standalone");
[true, false].forEach(function(backgroundIndexBuild) {
[true, false].forEach(function(createIndexFirst) {
[true, false].forEach(function(update) {
testInsertIndexKeyAndDowngradeStandalone(
{_id: "shortTypeBits", x: largeKeyWithShortTypeBits},
false,
createIndexFirst,
backgroundIndexBuild,
update);
testInsertIndexKeyAndDowngradeStandalone(
{_id: "longTypeBits", x: largeKeyWithLongTypeBits},
true,
createIndexFirst,
backgroundIndexBuild,
update);
});
});
});
// Tests for replset
jsTestLog("Test for replset");
[true, false].forEach(function(backgroundIndexBuild) {
[true, false].forEach(function(createIndexFirst) {
[true, false].forEach(function(update) {
testInsertIndexKeyAndDowngradeReplset(
{_id: "shortTypeBits", x: largeKeyWithShortTypeBits},
false,
createIndexFirst,
backgroundIndexBuild,
update);
testInsertIndexKeyAndDowngradeReplset(
{_id: "longTypeBits", x: largeKeyWithLongTypeBits},
true,
createIndexFirst,
backgroundIndexBuild,
update);
});
});
});
}());