0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 01:21:03 +01:00
mongodb/jstests/noPassthrough/change_stream_concurrent_implicit_db_create.js
2019-07-27 11:02:23 -04:00

52 lines
2.1 KiB
JavaScript

// Tests that concurrent change streams requests that would create the database will take locks in
// an order that avoids a deadlock.
// This test was designed to reproduce SERVER-34333.
// This test uses the WiredTiger storage engine, which does not support running without journaling.
// @tags: [requires_replication,requires_journaling]
(function() {
"use strict";
load("jstests/replsets/rslib.js"); // For startSetIfSupportsReadMajority.
const rst = new ReplSetTest({nodes: 1});
if (!startSetIfSupportsReadMajority(rst)) {
jsTestLog("Skipping test since storage engine doesn't support majority read concern.");
rst.stopSet();
return;
}
rst.initiate();
const db = rst.getPrimary().getDB("test");
let unique_dbName = jsTestName();
const sleepShell = startParallelShell(() => {
assert.commandFailedWithCode(db.adminCommand({sleep: 1, lock: "w", seconds: 600}),
ErrorCodes.Interrupted);
}, rst.getPrimary().port);
assert.soon(
() =>
db.getSiblingDB("admin").currentOp({"command.sleep": 1, active: true}).inprog.length === 1);
const sleepOps = db.getSiblingDB("admin").currentOp({"command.sleep": 1, active: true}).inprog;
assert.eq(sleepOps.length, 1);
const sleepOpId = sleepOps[0].opid;
// Start two concurrent shells which will both attempt to create the database which does not yet
// exist.
const openChangeStreamCode = `const cursor = db.getSiblingDB("${unique_dbName}").test.watch();`;
const changeStreamShell1 = startParallelShell(openChangeStreamCode, rst.getPrimary().port);
const changeStreamShell2 = startParallelShell(openChangeStreamCode, rst.getPrimary().port);
// Wait until we can see both change streams have started and are waiting to acquire the lock
// held by the sleep command.
assert.soon(
() => db.currentOp({"command.aggregate": "test", waitingForLock: true}).inprog.length === 2);
assert.commandWorked(db.adminCommand({killOp: 1, op: sleepOpId}));
sleepShell();
// Before the fix for SERVER-34333, the operations in these shells would be deadlocked with each
// other and never complete.
changeStreamShell1();
changeStreamShell2();
rst.stopSet();
}());