SERVER-121067 Tests should not depend on the locking implementation of dropCollection (#49152)

GitOrigin-RevId: ea72118583bdd7d014872c79943578facd747d61
This commit is contained in:
Joan Bruguera Micó (at MongoDB) 2026-03-10 21:15:44 +00:00 committed by MongoDB Bot
parent 44e57c8253
commit a75e866a43
11 changed files with 37 additions and 29 deletions

View File

@ -25,7 +25,7 @@ const rst = new ReplSetTest({
wiredTigerConcurrentWriteTransactions: kNumWriteTickets,
// Setting a transaction lifetime of 20 seconds works fine locally because the
// threads which attempt to run the drop command are spawned quickly enough. This
// threads which attempt to run the sleep command are spawned quickly enough. This
// might not be the case for Evergreen hosts and may need to be tuned accordingly.
transactionLifetimeLimitSeconds: 20,
},
@ -57,9 +57,15 @@ for (let i = 0; i < kNumWriteTickets; ++i) {
const conn = new Mongo(host);
const db = conn.getDB("test");
// Dropping a collection requires a database X lock and therefore blocks behind the
// transaction committing or aborting.
db.mycoll.drop();
// Enqueue a collection X lock blocking behind the transaction committing or aborting.
assert.commandWorked(
db.adminCommand({
sleep: 1,
millis: 1,
lock: "w",
lockTarget: "test.mycoll",
}),
);
return {ok: 1};
} catch (e) {
@ -71,15 +77,16 @@ for (let i = 0; i < kNumWriteTickets; ++i) {
thread.start();
}
// We wait until all of the drop commands are waiting for a lock to know that we've exhausted
// We wait until all of the sleep commands are waiting for a lock to know that we've exhausted
// all of the available write tickets.
let ops;
assert.soon(
() => {
const ops = db.currentOp({"command.drop": "mycoll", waitingForLock: true});
ops = db.currentOp({"command.lockTarget": "test.mycoll", waitingForLock: true});
return ops.inprog.length === kNumWriteTickets;
},
() => {
return `Didn't find ${kNumWriteTickets} drop commands running: ` + tojson(db.currentOp());
return `Didn't find ${kNumWriteTickets} sleep commands running: ` + tojson(db.currentOp());
},
);
@ -87,7 +94,7 @@ assert.soon(
jsTestLog("Committing transaction");
assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
jsTestLog("Waiting for drop command to join");
jsTestLog("Waiting for sleep command to join");
for (let thread of threads) {
thread.join();
}

View File

@ -50,9 +50,15 @@ for (let i = 0; i < kNumWriteTickets; ++i) {
const conn = new Mongo(host);
const db = conn.getDB("test");
// Dropping a collection requires a database X lock and therefore blocks behind the
// transaction committing or aborting.
db.mycoll.drop();
// Enqueue a collection X lock blocking behind the transaction committing or aborting.
assert.commandWorked(
db.adminCommand({
sleep: 1,
millis: 1,
lock: "w",
lockTarget: "test.mycoll",
}),
);
return {ok: 1};
} catch (e) {
@ -64,15 +70,16 @@ for (let i = 0; i < kNumWriteTickets; ++i) {
thread.start();
}
// We wait until all of the drop commands are waiting for a lock to know that we've exhausted
// We wait until all of the sleep commands are waiting for a lock to know that we've exhausted
// all of the available write tickets.
let ops;
assert.soon(
() => {
const ops = db.currentOp({"command.drop": "mycoll", waitingForLock: true});
ops = db.currentOp({"command.lockTarget": "test.mycoll", waitingForLock: true});
return ops.inprog.length === kNumWriteTickets;
},
() => {
return `Didn't find ${kNumWriteTickets} drop commands running: ` + tojson(db.currentOp());
return `Didn't find ${kNumWriteTickets} sleep commands running: ` + tojson(db.currentOp());
},
);

View File

@ -86,7 +86,6 @@ public:
// Ensure N is significantly larger then internalQueryPlanEvaluationWorks.
ASSERT_GTE(N, internalQueryPlanEvaluationWorks.load() + 1000);
dbtests::WriteContextForTests ctx(&_opCtx, nss.ns_forTest());
_client.dropCollection(nss);
}

View File

@ -219,15 +219,18 @@ private:
* Test dropping the collection while an agg PlanExecutor is doing an index scan.
*/
TEST_F(PlanExecutorTest, DropIndexScanAgg) {
dbtests::WriteContextForTests ctx(&_opCtx, nss.ns_forTest());
insert(BSON("_id" << 1 << "a" << 6));
insert(BSON("_id" << 2 << "a" << 7));
insert(BSON("_id" << 3 << "a" << 8));
BSONObj indexSpec = BSON("a" << 1);
addIndex(indexSpec);
{
dbtests::WriteContextForTests ctx(&_opCtx, nss.ns_forTest());
insert(BSON("_id" << 1 << "a" << 6));
insert(BSON("_id" << 2 << "a" << 7));
insert(BSON("_id" << 3 << "a" << 8));
addIndex(indexSpec);
}
auto outerExec = [&]() {
dbtests::WriteContextForTests ctx(&_opCtx, nss.ns_forTest());
const auto collection = ctx.getCollection();
// Create the aggregation pipeline.

View File

@ -117,7 +117,6 @@ public:
}
~QueryStageCollectionScanTest() override {
dbtests::WriteContextForTests ctx(&_opCtx, kNss.ns_forTest());
_client.dropCollection(kNss);
}

View File

@ -62,7 +62,6 @@ public:
CountBase() : _client(&_opCtx) {}
virtual ~CountBase() {
dbtests::WriteContextForTests ctx(&_opCtx, ns().ns_forTest());
_client.dropCollection(ns());
}

View File

@ -89,7 +89,6 @@ public:
}
virtual ~QueryStageDeleteBase() {
dbtests::WriteContextForTests ctx(&_opCtx, nss.ns_forTest());
_client.dropCollection(nss);
}

View File

@ -84,7 +84,6 @@ public:
QueryStageMergeSortTestBase() : _client(&_opCtx) {}
virtual ~QueryStageMergeSortTestBase() {
dbtests::WriteContextForTests ctx(&_opCtx, ns());
_client.dropCollection(nss());
}

View File

@ -80,7 +80,6 @@ public:
QueryStageSubplanTest() : _client(_opCtx.get()) {}
~QueryStageSubplanTest() override {
dbtests::WriteContextForTests ctx(opCtx(), nss.ns_forTest());
_client.dropCollection(nss);
}

View File

@ -87,7 +87,6 @@ public:
}
virtual ~IndexScanBase() {
dbtests::WriteContextForTests ctx(&_opCtx, ns());
_client.dropCollection(nss());
}

View File

@ -86,13 +86,11 @@ static const NamespaceString nss =
class QueryStageUpdateBase {
public:
QueryStageUpdateBase() : _client(&_opCtx) {
dbtests::WriteContextForTests ctx(&_opCtx, nss.ns_forTest());
_client.dropCollection(nss);
_client.createCollection(nss);
}
virtual ~QueryStageUpdateBase() {
dbtests::WriteContextForTests ctx(&_opCtx, nss.ns_forTest());
_client.dropCollection(nss);
}