This is just a cleanup work to hide some of the private state of ReplSetTest so it is easier to encapsulate and add new logic. Also enables strict mode.
227 lines
7.2 KiB
JavaScript
227 lines
7.2 KiB
JavaScript
// This test is skipped on 32-bit platforms
|
|
|
|
function setupTest() {
|
|
var s = new ShardingTest({ shards: 2,
|
|
mongos: 1,
|
|
other: { rs: true,
|
|
numReplicas: 2,
|
|
chunkSize: 1,
|
|
rsOptions: { oplogSize: 50 },
|
|
enableBalancer: 1 } });
|
|
|
|
// Reduce chunk size to split
|
|
var config = s.getDB("config");
|
|
config.settings.save({_id: "chunksize", value: 1});
|
|
|
|
assert.commandWorked(s.s0.adminCommand({ enablesharding: "test" }));
|
|
s.ensurePrimaryShard('test', 'test-rs0');
|
|
assert.commandWorked(s.s0.adminCommand({ shardcollection: "test.foo", key: { "_id": 1 } }));
|
|
return s;
|
|
}
|
|
|
|
function runTest(s) {
|
|
jsTest.log("Inserting a lot of documents into test.foo");
|
|
db = s.getDB("test");
|
|
|
|
var idInc = 0;
|
|
var valInc = 0;
|
|
var str = "";
|
|
|
|
if (db.serverBuildInfo().bits == 32) {
|
|
// Make data ~0.5MB for 32 bit builds
|
|
for (var i = 0; i < 512; i++) str += "a";
|
|
}
|
|
else {
|
|
// Make data ~4MB
|
|
for (var i = 0; i < 4*1024; i++) str += "a";
|
|
}
|
|
|
|
var bulk = db.foo.initializeUnorderedBulkOp();
|
|
for (j=0; j<100; j++) {
|
|
for (i=0; i<512; i++) {
|
|
bulk.insert({ i: idInc++, val: valInc++, y:str });
|
|
}
|
|
}
|
|
assert.writeOK(bulk.execute());
|
|
|
|
jsTest.log("Documents inserted, doing double-checks of insert...");
|
|
|
|
// Collect some useful stats to figure out what happened
|
|
if (db.foo.find().itcount() != 51200) {
|
|
sleep(1000);
|
|
|
|
s.printShardingStatus(true);
|
|
|
|
print("Shard 0: " + s.shard0.getCollection(db.foo + "").find().itcount());
|
|
print("Shard 1: " + s.shard1.getCollection(db.foo + "").find().itcount());
|
|
|
|
for (var i = 0; i < 51200; i++) {
|
|
if(!db.foo.findOne({ i: i }, { i: 1 })) {
|
|
print("Could not find: " + i);
|
|
}
|
|
|
|
if(i % 100 == 0) print("Checked " + i);
|
|
}
|
|
|
|
print("PROBABLY WILL ASSERT NOW");
|
|
}
|
|
|
|
assert.soon(function() {
|
|
var c = db.foo.find().itcount();
|
|
if (c == 51200) {
|
|
return true;
|
|
}
|
|
|
|
print("Count is " + c);
|
|
return false;
|
|
});
|
|
|
|
s.printChunks();
|
|
s.printChangeLog();
|
|
|
|
function map() { emit('count', 1); }
|
|
function reduce(key, values) { return Array.sum(values) }
|
|
|
|
jsTest.log("Test basic mapreduce...");
|
|
|
|
// Test basic mapReduce
|
|
for (var iter = 0; iter < 5; iter++) {
|
|
print("Test #" + iter);
|
|
out = db.foo.mapReduce(map, reduce,"big_out")
|
|
}
|
|
|
|
print("Testing output to different db...")
|
|
|
|
// test output to a different DB
|
|
// do it multiple times so that primary shard changes
|
|
for (iter = 0; iter < 5; iter++) {
|
|
print("Test #" + iter);
|
|
|
|
assert.eq(51200, db.foo.find().itcount(), "Not all data was found!");
|
|
|
|
outCollStr = "mr_replace_col_" + iter;
|
|
outDbStr = "mr_db_" + iter;
|
|
|
|
print("Testing mr replace into DB " + iter)
|
|
|
|
res = db.foo.mapReduce(map , reduce , { out: { replace: outCollStr, db: outDbStr } })
|
|
printjson(res);
|
|
|
|
outDb = s.getDB(outDbStr);
|
|
outColl = outDb[outCollStr];
|
|
|
|
obj = outColl.convertToSingleObject("value");
|
|
|
|
assert.eq(51200 , obj.count , "Received wrong result " + obj.count);
|
|
|
|
print("checking result field");
|
|
assert.eq(res.result.collection, outCollStr, "Wrong collection " + res.result.collection);
|
|
assert.eq(res.result.db, outDbStr, "Wrong db " + res.result.db);
|
|
}
|
|
|
|
jsTest.log("Verifying nonatomic M/R throws...")
|
|
|
|
// check nonAtomic output
|
|
assert.throws(function() {
|
|
db.foo.mapReduce(map, reduce, { out: {replace: "big_out", nonAtomic: true } });
|
|
});
|
|
|
|
jsTest.log();
|
|
|
|
// Add docs with dup "i"
|
|
valInc = 0;
|
|
for (j=0; j<100; j++) {
|
|
print("Inserted document: " + (j * 100));
|
|
bulk = db.foo.initializeUnorderedBulkOp();
|
|
for (i=0; i<512; i++) {
|
|
bulk.insert({ i: idInc++, val: valInc++, y: str });
|
|
}
|
|
// wait for replication to catch up
|
|
assert.writeOK(bulk.execute({ w: 2 }));
|
|
}
|
|
|
|
jsTest.log("No errors...");
|
|
|
|
map2 = function() { emit(this.val, 1); }
|
|
reduce2 = function(key, values) { return Array.sum(values); }
|
|
|
|
// Test merge
|
|
outcol = "big_out_merge";
|
|
|
|
// M/R quarter of the docs
|
|
jsTestLog("Test A");
|
|
out = db.foo.mapReduce(map2, reduce2, { query: {i: {$lt: 25600} }, out: { merge: outcol } });
|
|
printjson(out);
|
|
assert.eq(25600 , out.counts.emit , "Received wrong result");
|
|
assert.eq(25600 , out.counts.output , "Received wrong result");
|
|
|
|
// M/R further docs
|
|
jsTestLog("Test B");
|
|
out = db.foo.mapReduce(
|
|
map2, reduce2, { query: {i: {$gte: 25600, $lt: 51200} }, out: { merge: outcol } });
|
|
printjson(out);
|
|
assert.eq(25600 , out.counts.emit , "Received wrong result");
|
|
assert.eq(51200 , out.counts.output , "Received wrong result");
|
|
|
|
// M/R do 2nd half of docs
|
|
jsTestLog("Test C");
|
|
out = db.foo.mapReduce(
|
|
map2, reduce2, { query: {i: {$gte: 51200} }, out: { merge: outcol, nonAtomic: true } });
|
|
printjson(out);
|
|
assert.eq(51200 , out.counts.emit , "Received wrong result");
|
|
assert.eq(51200 , out.counts.output , "Received wrong result");
|
|
assert.eq(1 , db[outcol].findOne().value , "Received wrong result");
|
|
|
|
// Test reduce
|
|
jsTestLog("Test D");
|
|
outcol = "big_out_reduce";
|
|
|
|
// M/R quarter of the docs
|
|
out = db.foo.mapReduce(map2, reduce2,{ query: { i: { $lt: 25600 } }, out: { reduce: outcol } });
|
|
printjson(out);
|
|
assert.eq(25600 , out.counts.emit , "Received wrong result");
|
|
assert.eq(25600 , out.counts.output , "Received wrong result");
|
|
|
|
// M/R further docs
|
|
jsTestLog("Test E");
|
|
out = db.foo.mapReduce(
|
|
map2, reduce2, { query: { i: { $gte: 25600, $lt: 51200 } }, out: { reduce: outcol } });
|
|
printjson(out);
|
|
assert.eq(25600 , out.counts.emit , "Received wrong result");
|
|
assert.eq(51200 , out.counts.output , "Received wrong result");
|
|
|
|
// M/R do 2nd half of docs
|
|
jsTestLog("Test F");
|
|
out = db.foo.mapReduce(
|
|
map2, reduce2, { query: { i: {$gte: 51200} }, out: { reduce: outcol, nonAtomic: true } });
|
|
printjson(out);
|
|
assert.eq(51200 , out.counts.emit , "Received wrong result");
|
|
assert.eq(51200 , out.counts.output , "Received wrong result");
|
|
assert.eq(2 , db[outcol].findOne().value , "Received wrong result");
|
|
|
|
// Verify that data is also on secondary
|
|
jsTestLog("Test G");
|
|
var primary = s._rs[0].test.liveNodes.master;
|
|
var secondaries = s._rs[0].test.liveNodes.slaves;
|
|
|
|
// Stop the balancer to prevent new writes from happening and make sure
|
|
// that replication can keep up even on slow machines.
|
|
s.stopBalancer();
|
|
s._rs[0].test.awaitReplication(300 * 1000);
|
|
assert.eq(51200 , primary.getDB("test")[outcol].count() , "Wrong count");
|
|
for (var i = 0; i < secondaries.length; ++i) {
|
|
assert.eq(51200 , secondaries[i].getDB("test")[outcol].count() , "Wrong count");
|
|
}
|
|
}
|
|
|
|
var s = setupTest();
|
|
|
|
if (s.getDB("admin").runCommand("buildInfo").bits < 64) {
|
|
print("Skipping test on 32-bit platforms");
|
|
}
|
|
else {
|
|
runTest(s);
|
|
}
|
|
|
|
s.stop();
|