261 lines
8.8 KiB
JavaScript
261 lines
8.8 KiB
JavaScript
// Makes sure all commands which are supposed to take statement ids do. This should test all
|
|
// commands that are allowed in transactions.
|
|
// @tags: [uses_transactions, uses_prepare_transaction]
|
|
(function() {
|
|
"use strict";
|
|
|
|
const dbName = "test";
|
|
const collName = "statement_ids_accepted";
|
|
const testDB = db.getSiblingDB(dbName);
|
|
const testColl = testDB[collName];
|
|
|
|
testDB.runCommand({drop: collName, writeConcern: {w: "majority"}});
|
|
|
|
assert.commandWorked(
|
|
testDB.createCollection(testColl.getName(), {writeConcern: {w: "majority"}}));
|
|
|
|
const sessionOptions = {causalConsistency: false};
|
|
const session = db.getMongo().startSession(sessionOptions);
|
|
const sessionDb = session.getDatabase(dbName);
|
|
let txnNumber = 0;
|
|
|
|
jsTestLog("Check that abortTransaction accepts a statement ID");
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
find: collName,
|
|
readConcern: {level: "snapshot"},
|
|
txnNumber: NumberLong(txnNumber),
|
|
stmtId: NumberInt(0),
|
|
startTransaction: true,
|
|
autocommit: false
|
|
}));
|
|
// abortTransaction can only be run on the admin database.
|
|
assert.commandWorked(sessionDb.adminCommand({
|
|
abortTransaction: 1,
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(1),
|
|
autocommit: false
|
|
}));
|
|
|
|
jsTestLog("Check that aggregate accepts a statement ID");
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
aggregate: collName,
|
|
cursor: {},
|
|
pipeline: [{$match: {}}],
|
|
readConcern: {level: "snapshot"},
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(0),
|
|
startTransaction: true,
|
|
autocommit: false
|
|
}));
|
|
|
|
// The applyOps command is intentionally left out.
|
|
|
|
jsTestLog("Check that commitTransaction accepts a statement ID");
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
find: collName,
|
|
readConcern: {level: "snapshot"},
|
|
txnNumber: NumberLong(txnNumber),
|
|
stmtId: NumberInt(0),
|
|
startTransaction: true,
|
|
autocommit: false
|
|
}));
|
|
// commitTransaction can only be run on the admin database.
|
|
assert.commandWorked(sessionDb.adminCommand({
|
|
commitTransaction: 1,
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(1),
|
|
autocommit: false
|
|
}));
|
|
|
|
jsTestLog("Check that delete accepts a statement ID");
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
delete: collName,
|
|
deletes: [{q: {}, limit: 1}],
|
|
readConcern: {level: "snapshot"},
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(0),
|
|
startTransaction: true,
|
|
autocommit: false
|
|
}));
|
|
|
|
jsTestLog("Check that distinct accepts a statement ID");
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
distinct: collName,
|
|
key: "x",
|
|
readConcern: {level: "snapshot"},
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(0),
|
|
startTransaction: true,
|
|
autocommit: false
|
|
}));
|
|
|
|
// The doTxn command is intentionally left out.
|
|
|
|
jsTestLog("Check that find and getmore accept a statement ID");
|
|
// Put in some data to find so getMore has a cursor to use.
|
|
assert.writeOK(testColl.insert([{_id: 0}, {_id: 1}], {writeConcern: {w: "majority"}}));
|
|
let res = assert.commandWorked(sessionDb.runCommand({
|
|
find: collName,
|
|
batchSize: 1,
|
|
filter: {},
|
|
readConcern: {level: "snapshot"},
|
|
txnNumber: NumberLong(txnNumber),
|
|
stmtId: NumberInt(0),
|
|
startTransaction: true,
|
|
autocommit: false
|
|
}));
|
|
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
getMore: res.cursor.id,
|
|
collection: collName,
|
|
batchSize: 1,
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(1),
|
|
autocommit: false
|
|
}));
|
|
|
|
jsTestLog("Check that findandmodify accepts a statement ID");
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
findandmodify: collName,
|
|
remove: true,
|
|
readConcern: {level: "snapshot"},
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(0),
|
|
startTransaction: true,
|
|
autocommit: false
|
|
}));
|
|
|
|
jsTestLog("Check that findAndModify accepts a statement ID");
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
findAndModify: collName,
|
|
remove: true,
|
|
readConcern: {level: "snapshot"},
|
|
txnNumber: NumberLong(txnNumber),
|
|
stmtId: NumberInt(0),
|
|
startTransaction: true,
|
|
autocommit: false
|
|
}));
|
|
|
|
// Abort the transaction to release locks.
|
|
// abortTransaction can only be run on the admin database.
|
|
assert.commandWorked(sessionDb.adminCommand({
|
|
abortTransaction: 1,
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(0),
|
|
autocommit: false
|
|
}));
|
|
|
|
jsTestLog("Check that insert accepts a statement ID");
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
insert: collName,
|
|
documents: [{_id: "doc1"}],
|
|
readConcern: {level: "snapshot"},
|
|
txnNumber: NumberLong(txnNumber),
|
|
stmtId: NumberInt(0),
|
|
startTransaction: true,
|
|
autocommit: false
|
|
}));
|
|
|
|
// Abort the transaction to release locks.
|
|
// abortTransaction can only be run on the admin database.
|
|
assert.commandWorked(sessionDb.adminCommand({
|
|
abortTransaction: 1,
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(1),
|
|
autocommit: false
|
|
}));
|
|
|
|
const isMongos = assert.commandWorked(db.runCommand("ismaster")).msg === "isdbgrid";
|
|
if (!isMongos) {
|
|
// Skip commands that do not exist on mongos.
|
|
|
|
jsTestLog("Check that geoSearch accepts a statement ID");
|
|
assert.writeOK(testColl.insert({geo: {type: "Point", coordinates: [0, 0]}, a: 0}),
|
|
{writeConcern: {w: "majority"}});
|
|
assert.writeOK(testColl.insert({geoh: {lat: 0, long: 0}, b: 0}),
|
|
{writeConcern: {w: "majority"}});
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
createIndexes: collName,
|
|
indexes: [
|
|
{name: "geo", key: {geo: "2dsphere"}},
|
|
{name: "geoh", key: {geoh: "geoHaystack", b: 1}, bucketSize: 1}
|
|
],
|
|
writeConcern: {w: "majority"}
|
|
}));
|
|
// Ensure the snapshot is available following the index creation.
|
|
assert.soonNoExcept(function() {
|
|
testColl.find({}, {readConcern: {level: "snapshot"}});
|
|
return true;
|
|
});
|
|
|
|
jsTestLog("Check that geoSearch accepts a statement ID");
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
geoSearch: collName,
|
|
search: {b: 0},
|
|
near: [0, 0],
|
|
maxDistance: 1,
|
|
readConcern: {level: "snapshot"},
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(0),
|
|
startTransaction: true,
|
|
autocommit: false
|
|
}));
|
|
|
|
jsTestLog("Check that prepareTransaction accepts a statement ID");
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
insert: collName,
|
|
documents: [{_id: "doc2"}],
|
|
readConcern: {level: "snapshot"},
|
|
txnNumber: NumberLong(txnNumber),
|
|
stmtId: NumberInt(0),
|
|
startTransaction: true,
|
|
autocommit: false
|
|
}));
|
|
// prepareTransaction can only be run on the admin database.
|
|
assert.commandWorked(sessionDb.adminCommand({
|
|
prepareTransaction: 1,
|
|
txnNumber: NumberLong(txnNumber),
|
|
stmtId: NumberInt(1),
|
|
autocommit: false
|
|
}));
|
|
assert.commandWorked(sessionDb.adminCommand({
|
|
abortTransaction: 1,
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(2),
|
|
autocommit: false
|
|
}));
|
|
assert.commandFailedWithCode(sessionDb.runCommand({
|
|
prepareTransaction: 1,
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(0),
|
|
autocommit: false
|
|
}),
|
|
ErrorCodes.Unauthorized);
|
|
}
|
|
|
|
// refreshLogicalSessionCacheNow is intentionally omitted.
|
|
|
|
jsTestLog("Check that update accepts a statement ID");
|
|
assert.commandWorked(sessionDb.runCommand({
|
|
update: collName,
|
|
updates: [{q: {_id: "doc1"}, u: {$inc: {a: 1}}}],
|
|
readConcern: {level: "snapshot"},
|
|
txnNumber: NumberLong(txnNumber),
|
|
stmtId: NumberInt(0),
|
|
startTransaction: true,
|
|
autocommit: false
|
|
}));
|
|
|
|
// Abort the last transaction because it appears the system stalls during shutdown if
|
|
// a transaction is open.
|
|
// abortTransaction can only be run on the admin database.
|
|
assert.commandWorked(sessionDb.adminCommand({
|
|
abortTransaction: 1,
|
|
txnNumber: NumberLong(txnNumber++),
|
|
stmtId: NumberInt(1),
|
|
autocommit: false
|
|
}));
|
|
|
|
session.endSession();
|
|
}());
|