1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
// Test handling of messages up to and over isMaster().maxMessageSizeBytes
function go() { // using a function to ensure that all resources can be freed after test
if (db.serverStatus().mem.bits == 32) {
print("skipping max_message_size.js on 32bit system");
return;
}
var t = db.max_message_size;
var maxMessageSize = db.isMaster().maxMessageSizeBytes;
var maxBsonSize = db.isMaster().maxBsonObjectSize;
function makeObj(str) {
return {_id: ObjectId(), s: str};
}
var bsonOverhead = Object.bsonsize(makeObj(''));
var bigStr = 'x';
while (bigStr.length < maxBsonSize) {
bigStr += bigStr;
}
function insertWithBytes(bytes) {
var toGo = bytes;
toGo -= 16; // Message Header
toGo -= 4; // Flags
toGo -= t.getFullName().length + 1; // namespace with NUL
var batch = [];
while (toGo > 0) {
var objBytes = Math.min(toGo, maxBsonSize);
var filler = bigStr.substr(0, objBytes - bsonOverhead);
var obj = makeObj(filler);
assert.eq(Object.bsonsize(obj), objBytes);
batch.push(obj);
toGo -= objBytes;
}
assert.eq(toGo, 0);
t.insert(batch);
return batch.length;
}
function works(bytes) {
t.drop();
var numInserted = insertWithBytes(bytes);
assert.isnull(db.getLastError());
assert.eq(t.count(), numInserted);
}
function fails(bytes) {
t.drop();
try {
var numInserted = insertWithBytes(bytes);
var error = db.getLastErrorObj();
} catch (e) {
// A string is thrown rather than an object
if (! (/^socket error/.test(e) || /socket exception/.test(e)))
throw e;
sleep(3000); // shell won't reconnect within 2 second window
assert.eq(t.count(), 0);
return; // successfully killed connection and reconnected
}
// Note to future maintainers: This test will need to be changed if we
// modify the server's behavior to skip oversized messages and report
// them in getLastError. The output from this should be helpful in
// detecting this case.
printjson({numInserted: numInserted, error: error});
assert(false, "Connection not reset");
}
works(maxMessageSize - 1024*1024);
works(maxMessageSize - 1);
works(maxMessageSize);
// Don't test failing because it forces a reconnect which is currently broken on some platforms
if (0) { // reenable when SERVER-8532 is fixed
fails(maxMessageSize + 1);
works(maxMessageSize); // make sure we still work after failure
fails(maxMessageSize + 1024*1024);
works(maxMessageSize);
}
}
go();
|