diff options
Diffstat (limited to 'jstests/core/batch_write_command_insert.js')
| -rw-r--r-- | jstests/core/batch_write_command_insert.js | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/jstests/core/batch_write_command_insert.js b/jstests/core/batch_write_command_insert.js new file mode 100644 index 00000000000..79ac259275b --- /dev/null +++ b/jstests/core/batch_write_command_insert.js @@ -0,0 +1,304 @@ +// +// Ensures that mongod respects the batch write protocol for inserts +// + +var coll = db.getCollection( "batch_write_insert" ); +coll.drop(); + +assert(coll.getDB().getMongo().useWriteCommands(), "test is not running with write commands") + +jsTest.log("Starting insert tests..."); + +var request; +var result; +var batch; + +var maxWriteBatchSize = 1000; + +function resultOK( result ) { + return result.ok && + !( 'code' in result ) && + !( 'errmsg' in result ) && + !( 'errInfo' in result ) && + !( 'writeErrors' in result ); +}; + +function resultNOK( result ) { + return !result.ok && + typeof( result.code ) == 'number' && + typeof( result.errmsg ) == 'string'; +}; + +// EACH TEST BELOW SHOULD BE SELF-CONTAINED, FOR EASIER DEBUGGING + +// +// NO DOCS, illegal command +coll.remove({}); +printjson( request = {insert : coll.getName()} ); +printjson( result = coll.runCommand(request) ); +assert(resultNOK(result)); + +// +// Single document insert, no write concern specified +coll.remove({}); +printjson( request = {insert : coll.getName(), documents: [{a:1}]} ); +printjson( result = coll.runCommand(request) ); +assert(resultOK(result)); +assert.eq(1, result.n); +assert.eq(coll.count(), 1); + +// +// Single document insert, w:0 write concern specified, missing ordered +coll.remove({}); +printjson( request = {insert : coll.getName(), documents: [{a:1}], writeConcern:{w:0}} ); +printjson( result = coll.runCommand(request) ); +assert(resultOK(result)); +assert.eq(coll.count(), 1); + +for (var field in result) { + assert.eq('ok', field, 'unexpected field found in result: ' + field); +} + +// +// Single document insert, w:1 write concern specified, ordered:true +coll.remove({}); +printjson( request = {insert : coll.getName(), documents: [{a:1}], writeConcern:{w:1}, ordered:true} ); +printjson( result = coll.runCommand(request) ); +assert(resultOK(result)); +assert.eq(1, result.n); +assert.eq(coll.count(), 1); + +// +// Single document insert, w:1 write concern specified, ordered:false +coll.remove({}); +printjson( request = {insert : coll.getName(), documents: [{a:1}], writeConcern:{w:1}, ordered:false} ); +printjson( result = coll.runCommand(request) ); +assert(resultOK(result)); +assert.eq(1, result.n); +assert.eq(coll.count(), 1); + +// +// Document with illegal key should fail +coll.remove({}); +printjson( request = {insert : coll.getName(), documents: [{$set:{a:1}}], writeConcern:{w:1}, ordered:false} ); +printjson( result = coll.runCommand(request) ); +assert(result.ok); +assert(result.writeErrors != null); +assert.eq(1, result.writeErrors.length); +assert.eq(0, result.n); +assert.eq(coll.count(), 0); + +// +// Document with valid nested key should insert (op log format) +coll.remove({}); +printjson( request = {insert : coll.getName(), documents: [{o: {$set:{a:1}}}], writeConcern:{w:1}, ordered:false} ); +printjson( result = coll.runCommand(request) ); +assert(resultOK(result)); +assert.eq(1, result.n); +assert.eq(coll.count(), 1); + +// +// Large batch under the size threshold should insert successfully +coll.remove({}); +batch = []; +for (var i = 0; i < maxWriteBatchSize; ++i) { + batch.push({}); +} +printjson( request = {insert : coll.getName(), documents: batch, writeConcern:{w:1}, ordered:false} ); +printjson( result = coll.runCommand(request) ); +assert(resultOK(result)); +assert.eq(batch.length, result.n); +assert.eq(coll.count(), batch.length); + +// +// Large batch above the size threshold should fail to insert +coll.remove({}); +batch = []; +for (var i = 0; i < maxWriteBatchSize + 1; ++i) { + batch.push({}); +} +printjson( request = {insert : coll.getName(), documents: batch, writeConcern:{w:1}, ordered:false} ); +printjson( result = coll.runCommand(request) ); +assert(resultNOK(result)); +assert.eq(coll.count(), 0); + +// +// Batch of size zero should fail to insert +coll.remove({}); +printjson( request = {insert : coll.getName(), + documents: [] } ); +printjson( result = coll.runCommand(request) ); +assert(resultNOK(result)); + +// +// +// Unique index tests +coll.remove({}); +coll.ensureIndex({a : 1}, {unique : true}); + +// +// Should fail single insert due to duplicate key +coll.remove({}); +coll.insert({a:1}); +print( coll.count() ); +printjson( coll.findOne() ); +printjson( request = {insert : coll.getName(), documents: [{a:1}]} ); +printjson( result = coll.runCommand(request) ); +assert(result.ok); +assert.eq(1, result.writeErrors.length); +assert.eq(0, result.n); +assert.eq(coll.count(), 1); + +// +// Fail with duplicate key error on multiple document inserts, ordered false +coll.remove({}); +printjson( request = {insert : coll.getName(), documents: [{a:1}, {a:1}, {a:1}], writeConcern:{w:1}, ordered:false} ); +printjson( result = coll.runCommand(request) ); +assert(result.ok); +assert.eq(1, result.n); +assert.eq(2, result.writeErrors.length); +assert.eq(coll.count(), 1); + +assert.eq(1, result.writeErrors[0].index); +assert.eq('number', typeof result.writeErrors[0].code); +assert.eq('string', typeof result.writeErrors[0].errmsg); + +assert.eq(2, result.writeErrors[1].index); +assert.eq('number', typeof result.writeErrors[1].code); +assert.eq('string', typeof result.writeErrors[1].errmsg); + +assert.eq(coll.count(), 1); + +// +// Fail with duplicate key error on multiple document inserts, ordered true +coll.remove({}); +printjson( request = {insert : coll.getName(), documents: [{a:1}, {a:1}, {a:1}], writeConcern:{w:1}, ordered:true} ); +printjson( result = coll.runCommand(request) ); +assert(result.ok); +assert.eq(1, result.n); +assert.eq(1, result.writeErrors.length); + +assert.eq(1, result.writeErrors[0].index); +assert.eq('number', typeof result.writeErrors[0].code); +assert.eq('string', typeof result.writeErrors[0].errmsg); + +assert.eq(coll.count(), 1); + +// +// Ensure _id is the first field in all documents +coll.remove({}); +printjson(request = {insert : coll.getName(), documents : [{a : 1}, {a : 2, _id : 2}]}); +printjson(result = coll.runCommand(request)); +assert.eq(2, coll.count()); +coll.find().forEach(function(doc) { + var firstKey = null; + for ( var key in doc) { + firstKey = key; + break; + } + assert.eq("_id", firstKey, tojson(doc)); +}); + +// +// +// Index insertion tests - currently supported via bulk write commands + +// +// Successful index creation +coll.drop(); +printjson(request = {insert : "system.indexes", + documents : [{ns : coll.toString(), key : {x : 1}, name : "x_1"}]}); +printjson( result = coll.runCommand(request) ); +assert(result.ok); +assert.eq(1, result.n); +assert.eq(coll.getIndexes().length, 2); + +// +// Duplicate index insertion gives n = 0 +coll.drop(); +coll.ensureIndex({x : 1}, {unique : true}); +printjson(request = {insert : "system.indexes", + documents : [{ns : coll.toString(), + key : {x : 1}, name : "x_1", unique : true}]}); +printjson(result = coll.runCommand(request)); +assert(result.ok); +assert.eq(0, result.n); +assert(!('writeErrors' in result)); +assert.eq(coll.getIndexes().length, 2); + +// +// Invalid index insertion with mismatched collection db +coll.drop(); +printjson(request = {insert : "system.indexes", + documents : [{ns : "invalid." + coll.getName(), + key : {x : 1}, name : "x_1", unique : true}]}); +printjson(result = coll.runCommand(request)); +assert(!result.ok); +assert.eq(coll.getIndexes().length, 0); + +// +// Empty index insertion +coll.drop(); +printjson(request = {insert : "system.indexes", documents : [{}]}); +printjson(result = coll.runCommand(request)); +assert(!result.ok); +assert.eq(coll.getIndexes().length, 0); + +// +// Invalid index desc +coll.drop(); +printjson(request = {insert : "system.indexes", documents : [{ns : coll.toString()}]}); +printjson(result = coll.runCommand(request)); +assert(result.ok); +assert.eq(0, result.n); +assert.eq(0, result.writeErrors[0].index); +assert.eq(coll.getIndexes().length, 1); + +// +// Invalid index desc +coll.drop(); +printjson(request = {insert : "system.indexes", + documents : [{ns : coll.toString(), key : {x : 1}}]}); +printjson(result = coll.runCommand(request)); +assert(result.ok); +assert.eq(0, result.n); +assert.eq(0, result.writeErrors[0].index); +assert.eq(coll.getIndexes().length, 1); + +// +// Invalid index desc +coll.drop(); +printjson(request = {insert : "system.indexes", + documents : [{ns : coll.toString(), name : "x_1"}]}); +printjson(result = coll.runCommand(request)); +assert(result.ok); +assert.eq(0, result.n); +assert.eq(0, result.writeErrors[0].index); +assert.eq(coll.getIndexes().length, 1); + +// +// Cannot insert more than one index at a time through the batch writes +coll.drop(); +printjson(request = {insert : "system.indexes", + documents : [{ns : coll.toString(), key : {x : 1}, name : "x_1"}, + {ns : coll.toString(), key : {y : 1}, name : "y_1"}]}); +printjson(result = coll.runCommand(request)); +assert(!result.ok); +assert.eq(coll.getIndexes().length, 0); + +// +// Background index creation +// Note: due to SERVER-13304 this test is at the end of this file, and we don't drop +// the collection afterwards. +coll.drop(); +coll.insert({ x : 1 }); +printjson(request = {insert : "system.indexes", + documents : [{ns : coll.toString(), + key : {x : 1}, + name : "x_1", + background : true}]}); +printjson( result = coll.runCommand(request) ); +assert(result.ok); +assert.eq(1, result.n); +assert.eq(coll.getIndexes().length, 2); + |
