82 lines
3.1 KiB
JavaScript
82 lines
3.1 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* update_upsert_multi.js
|
|
*
|
|
* Tests updates that specify both multi=true and upsert=true.
|
|
* The 'insert' state uses a query that will match no documents, causing an upsert.
|
|
* The 'update' state uses a query that will match one or more documents, causing a multi-update.
|
|
* Both states use { multi: true, upsert: true }, but only one option will ever take effect,
|
|
* depending on whether 0 or more than 0 documents match the query.
|
|
*/
|
|
var $config = (function() {
|
|
|
|
var states = {
|
|
insert: function insert(db, collName) {
|
|
var query, update, options;
|
|
var res = db[collName].update(
|
|
// The counter ensures that the query will not match any existing document.
|
|
query = {tid: this.tid, i: this.counter++},
|
|
update = {$inc: {n: 1}},
|
|
options = {multi: true, upsert: true});
|
|
var debugDoc = tojson({query: query, update: update, options: options, result: res});
|
|
assertWhenOwnColl.eq(1, res.nUpserted, debugDoc);
|
|
assertWhenOwnColl.eq(0, res.nMatched, debugDoc);
|
|
if (db.getMongo().writeMode() === 'commands') {
|
|
assertWhenOwnColl.eq(0, res.nModified, debugDoc);
|
|
}
|
|
},
|
|
|
|
update: function update(db, collName) {
|
|
var res = db[collName].update(
|
|
// This query will match an existing document, since the 'insert' state
|
|
// always runs first.
|
|
{tid: this.tid},
|
|
{$inc: {n: 1}},
|
|
{multi: true, upsert: true});
|
|
|
|
assertWhenOwnColl.eq(0, res.nUpserted, tojson(res));
|
|
assertWhenOwnColl.lte(1, res.nMatched, tojson(res));
|
|
if (db.getMongo().writeMode() === 'commands') {
|
|
assertWhenOwnColl.eq(res.nMatched, res.nModified, tojson(res));
|
|
}
|
|
},
|
|
|
|
assertConsistency: function assertConsistency(db, collName) {
|
|
// Since each update operation either:
|
|
// - inserts a new doc { tid: tid, i: counter++, n: 0 }
|
|
// - updates any doc matching { tid: tid } with { $inc: { n: 1 } }
|
|
// Then within each tid, as you walk from lower to higher values of i,
|
|
// the value of n should be non-increasing. (This should be true
|
|
// because docs with lower i are newer, so they have had fewer
|
|
// opportunities to have n incremented.)
|
|
var prevN = Infinity;
|
|
db[collName].find({tid: this.tid}).sort({i: 1}).forEach(function(doc) {
|
|
assertWhenOwnColl.gte(prevN, doc.n);
|
|
prevN = doc.n;
|
|
});
|
|
}
|
|
};
|
|
|
|
var transitions = {
|
|
insert: {update: 0.875, assertConsistency: 0.125},
|
|
update: {insert: 0.875, assertConsistency: 0.125},
|
|
assertConsistency: {insert: 0.5, update: 0.5}
|
|
};
|
|
|
|
function setup(db, collName, cluster) {
|
|
assertAlways.commandWorked(db[collName].ensureIndex({tid: 1, i: 1}));
|
|
}
|
|
|
|
return {
|
|
threadCount: 10,
|
|
iterations: 20,
|
|
states: states,
|
|
startState: 'insert',
|
|
transitions: transitions,
|
|
data: {counter: 0},
|
|
setup: setup
|
|
};
|
|
|
|
})();
|