summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/change_stream_concurrent_implicit_db_create.js
blob: 5a1e39291a1fcb0325f4fa14f1a5d23f67cd3661 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// 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, requires_majority_read_concern]
(function() {
"use strict";

const rst = new ReplSetTest({nodes: 1});
rst.startSet();
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();
}());