0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 01:21:03 +01:00
mongodb/jstests/noPassthrough/indexbg1.js
2019-07-27 11:02:23 -04:00

133 lines
3.9 KiB
JavaScript

// Test background index creation
// @tags: [SERVER-40561]
(function() {
"use strict";
load("jstests/noPassthrough/libs/index_build.js");
const conn = MongoRunner.runMongod({nojournal: ""});
assert.neq(null, conn, "mongod failed to start.");
var db = conn.getDB("test");
var baseName = "jstests_indexbg1";
var parallel = function() {
return db[baseName + "_parallelStatus"];
};
var resetParallel = function() {
parallel().drop();
};
// Return the PID to call `waitpid` on for clean shutdown.
var doParallel = function(work) {
resetParallel();
print("doParallel: " + work);
return startMongoProgramNoConnect(
"mongo",
"--eval",
work + "; db." + baseName + "_parallelStatus.save( {done:1} );",
db.getMongo().host);
};
var doneParallel = function() {
return !!parallel().findOne();
};
var waitParallel = function() {
assert.soon(function() {
return doneParallel();
}, "parallel did not finish in time", 300000, 1000);
};
var size = 400 * 1000;
var bgIndexBuildPid;
while (1) { // if indexing finishes before we can run checks, try indexing w/ more data
print("size: " + size);
var fullName = "db." + baseName;
var t = db[baseName];
t.drop();
var bulk = db.jstests_indexbg1.initializeUnorderedBulkOp();
for (var i = 0; i < size; ++i) {
bulk.insert({i: i});
}
assert.writeOK(bulk.execute());
assert.eq(size, t.count());
bgIndexBuildPid = doParallel(fullName + ".ensureIndex( {i:1}, {background:true} )");
try {
// wait for indexing to start
print("wait for indexing to start");
IndexBuildTest.waitForIndexBuildToStart(db);
print("started.");
sleep(1000); // there is a race between when the index build shows up in curop and
// when it first attempts to grab a write lock.
assert.eq(size, t.count());
assert.eq(100, t.findOne({i: 100}).i);
var q = t.find();
for (i = 0; i < 120; ++i) { // getmore
q.next();
assert(q.hasNext(), "no next");
}
var ex = t.find({i: 100}).limit(-1).explain("executionStats");
printjson(ex);
assert(ex.executionStats.totalKeysExamined < 1000,
"took too long to find 100: " + tojson(ex));
assert.writeOK(t.remove({i: 40}, true)); // table scan
assert.writeOK(t.update({i: 10}, {i: -10})); // should scan 10
var id = t.find().hint({$natural: -1}).next()._id;
assert.writeOK(t.update({_id: id}, {i: -2}));
assert.writeOK(t.save({i: -50}));
assert.writeOK(t.save({i: size + 2}));
assert.eq(size + 1, t.count());
print("finished with checks");
} catch (e) {
// only a failure if we're still indexing
// wait for parallel status to update to reflect indexing status
print("caught exception: " + e);
sleep(1000);
if (!doneParallel()) {
throw e;
}
print("but that's OK");
}
print("going to check if index is done");
if (!doneParallel()) {
break;
}
print("indexing finished too soon, retrying...");
// Although the index build finished, ensure the shell has exited.
waitProgram(bgIndexBuildPid);
size *= 2;
assert(size < 200000000, "unable to run checks in parallel with index creation");
}
print("our tests done, waiting for parallel to finish");
waitParallel();
// Ensure the shell has exited cleanly. Otherwise the test harness may send a SIGTERM which can
// lead to a false test failure.
waitProgram(bgIndexBuildPid);
print("finished");
assert.eq(1, t.count({i: -10}));
assert.eq(1, t.count({i: -2}));
assert.eq(1, t.count({i: -50}));
assert.eq(1, t.count({i: size + 2}));
assert.eq(0, t.count({i: 40}));
print("about to drop index");
t.dropIndex({i: 1});
var gle = db.getLastError();
printjson(gle);
assert(!gle);
MongoRunner.stopMongod(conn);
})();