248 lines
6.6 KiB
JavaScript
248 lines
6.6 KiB
JavaScript
// Cannot implicitly shard accessed collections because of following errmsg: A single
|
|
// update/delete on a sharded collection must contain an exact match on _id or contain the shard
|
|
// key.
|
|
// @tags: [assumes_unsharded_collection, requires_non_retryable_writes]
|
|
|
|
//
|
|
// Ensures that mongod respects the batch write protocols for delete
|
|
//
|
|
|
|
var coll = db.getCollection("batch_write_delete");
|
|
coll.drop();
|
|
|
|
assert(coll.getDB().getMongo().useWriteCommands(), "test is not running with write commands");
|
|
|
|
var request;
|
|
var result;
|
|
var batch;
|
|
|
|
var maxWriteBatchSize = db.isMaster().maxWriteBatchSize;
|
|
|
|
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({});
|
|
coll.insert({a: 1});
|
|
request = {
|
|
delete: coll.getName()
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert(resultNOK(result), tojson(result));
|
|
assert.eq(1, coll.count());
|
|
|
|
//
|
|
// Single document remove, default write concern specified
|
|
coll.remove({});
|
|
coll.insert({a: 1});
|
|
request = {
|
|
delete: coll.getName(),
|
|
deletes: [{q: {a: 1}, limit: 1}]
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert(resultOK(result), tojson(result));
|
|
assert.eq(1, result.n);
|
|
assert.eq(0, coll.count());
|
|
|
|
//
|
|
// Single document delete, w:0 write concern specified
|
|
coll.remove({});
|
|
coll.insert({a: 1});
|
|
request = {
|
|
delete: coll.getName(),
|
|
deletes: [{q: {a: 1}, limit: 1}],
|
|
writeConcern: {w: 0}
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert(resultOK(result), tojson(result));
|
|
assert.eq(0, coll.count());
|
|
|
|
var fields = ['ok'];
|
|
assert.hasFields(result, fields, 'fields in result do not match: ' + tojson(fields));
|
|
|
|
//
|
|
// Single document remove, w:1 write concern specified, ordered:true
|
|
coll.remove({});
|
|
coll.insert([{a: 1}, {a: 1}]);
|
|
request = {
|
|
delete: coll.getName(),
|
|
deletes: [{q: {a: 1}, limit: 1}],
|
|
writeConcern: {w: 1},
|
|
ordered: false
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert(resultOK(result), tojson(result));
|
|
assert.eq(1, result.n);
|
|
assert.eq(1, coll.count());
|
|
|
|
//
|
|
// Multiple document remove, w:1 write concern specified, ordered:true, default top
|
|
coll.remove({});
|
|
coll.insert([{a: 1}, {a: 1}]);
|
|
request = {
|
|
delete: coll.getName(),
|
|
deletes: [{q: {a: 1}, limit: 0}],
|
|
writeConcern: {w: 1},
|
|
ordered: false
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert(resultOK(result), tojson(result));
|
|
assert.eq(2, result.n);
|
|
assert.eq(0, coll.count());
|
|
|
|
//
|
|
// Multiple document remove, w:1 write concern specified, ordered:true, top:0
|
|
coll.remove({});
|
|
coll.insert([{a: 1}, {a: 1}]);
|
|
request = {
|
|
delete: coll.getName(),
|
|
deletes: [{q: {a: 1}, limit: 0}],
|
|
writeConcern: {w: 1},
|
|
ordered: false
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert(resultOK(result), tojson(result));
|
|
assert.eq(2, result.n);
|
|
assert.eq(0, coll.count());
|
|
|
|
//
|
|
// Large batch under the size threshold should delete successfully
|
|
coll.remove({});
|
|
batch = [];
|
|
var insertBatch = coll.initializeUnorderedBulkOp();
|
|
for (var i = 0; i < maxWriteBatchSize; ++i) {
|
|
insertBatch.insert({_id: i});
|
|
batch.push({q: {_id: i}, limit: 0});
|
|
}
|
|
assert.writeOK(insertBatch.execute());
|
|
request = {
|
|
delete: coll.getName(),
|
|
deletes: batch,
|
|
writeConcern: {w: 1},
|
|
ordered: false
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert(resultOK(result), tojson(result));
|
|
assert.eq(batch.length, result.n);
|
|
assert.eq(0, coll.count());
|
|
|
|
//
|
|
// Large batch above the size threshold should fail to delete
|
|
coll.remove({});
|
|
batch = [];
|
|
var insertBatch = coll.initializeUnorderedBulkOp();
|
|
for (var i = 0; i < maxWriteBatchSize + 1; ++i) {
|
|
insertBatch.insert({_id: i});
|
|
batch.push({q: {_id: i}, limit: 0});
|
|
}
|
|
assert.writeOK(insertBatch.execute());
|
|
request = {
|
|
delete: coll.getName(),
|
|
deletes: batch,
|
|
writeConcern: {w: 1},
|
|
ordered: false
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert(resultNOK(result), tojson(result));
|
|
assert.eq(batch.length, coll.count());
|
|
|
|
//
|
|
// Cause remove error using ordered:true
|
|
coll.remove({});
|
|
coll.insert({a: 1});
|
|
request = {
|
|
delete: coll.getName(),
|
|
deletes: [{q: {a: 1}, limit: 0}, {q: {$set: {a: 1}}, limit: 0}, {q: {$set: {a: 1}}, limit: 0}],
|
|
writeConcern: {w: 1},
|
|
ordered: true
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert.commandWorkedIgnoringWriteErrors(result);
|
|
assert.eq(1, result.n);
|
|
assert(result.writeErrors != null);
|
|
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(0, coll.count());
|
|
|
|
//
|
|
// Cause remove error using ordered:false
|
|
coll.remove({});
|
|
coll.insert({a: 1});
|
|
request = {
|
|
delete: coll.getName(),
|
|
deletes: [{q: {$set: {a: 1}}, limit: 0}, {q: {$set: {a: 1}}, limit: 0}, {q: {a: 1}, limit: 0}],
|
|
writeConcern: {w: 1},
|
|
ordered: false
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert.commandWorkedIgnoringWriteErrors(result);
|
|
assert.eq(1, result.n);
|
|
assert.eq(2, result.writeErrors.length);
|
|
|
|
assert.eq(0, result.writeErrors[0].index);
|
|
assert.eq('number', typeof result.writeErrors[0].code);
|
|
assert.eq('string', typeof result.writeErrors[0].errmsg);
|
|
|
|
assert.eq(1, result.writeErrors[1].index);
|
|
assert.eq('number', typeof result.writeErrors[1].code);
|
|
assert.eq('string', typeof result.writeErrors[1].errmsg);
|
|
assert.eq(0, coll.count());
|
|
|
|
//
|
|
// Cause remove error using ordered:false and w:0
|
|
coll.remove({});
|
|
coll.insert({a: 1});
|
|
request = {
|
|
delete: coll.getName(),
|
|
deletes: [{q: {$set: {a: 1}}, limit: 0}, {q: {$set: {a: 1}}, limit: 0}, {q: {a: 1}, limit: 0}],
|
|
writeConcern: {w: 0},
|
|
ordered: false
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert.commandWorked(result);
|
|
assert.eq(0, coll.count());
|
|
|
|
assert.hasFields(result, fields, 'fields in result do not match: ' + tojson(fields));
|
|
|
|
//
|
|
// Cause remove error using ordered:true and w:0
|
|
coll.remove({});
|
|
coll.insert({a: 1});
|
|
request = {
|
|
delete: coll.getName(),
|
|
deletes:
|
|
[{q: {$set: {a: 1}}, limit: 0}, {q: {$set: {a: 1}}, limit: 0}, {q: {a: 1}, limit: (1)}],
|
|
writeConcern: {w: 0},
|
|
ordered: true
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert.commandWorked(result);
|
|
assert.eq(1, coll.count());
|
|
|
|
assert.hasFields(result, fields, 'fields in result do not match: ' + tojson(fields));
|
|
|
|
//
|
|
// When limit is not 0 and 1
|
|
coll.remove({});
|
|
coll.insert({a: 1});
|
|
request = {
|
|
delete: coll.getName(),
|
|
deletes: [{q: {a: 1}, limit: 2}],
|
|
writeConcern: {w: 0},
|
|
ordered: false
|
|
};
|
|
result = coll.runCommand(request);
|
|
assert(resultNOK(result), tojson(result));
|