summaryrefslogtreecommitdiff
path: root/jstests/concurrency/fsm_workloads/create_collection_and_view.js
blob: 5a17b8b3b7cbd12c32a343d9344d08748695e12b (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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
"use strict";

/**
 * Repeatedly creates a collection and a view with the same namespace. Validates that we never
 * manage to have both a Collection and View created on the same namespace at the same time.
 *
 * @tags: [catches_command_failures]
 */

var $config = (function() {
    const prefix = "create_collection_and_view";

    // We'll use a single unique collection for all operations executed by this test. The
    // convention is that each FSM workload is given a unique 'collName' as input to increase
    // separation between different tests running in parallel. Otherwise we could just use a fixed
    // name, but we want to play nice.
    const getCollectionName = (collName) => {
        return prefix + "_" + collName;
    };

    const getBaseCollectionName = (collName) => {
        return prefix + "_" + collName + "_base";
    };

    const setup = (db, collName) => {
        assertAlways.commandWorked(db.createCollection(getBaseCollectionName(collName)));
    };

    const teardown = (db, collName) => {
        db.getCollection(getCollectionName(collName)).drop();
        db.getCollection(getBaseCollectionName(collName)).drop();
    };

    const states = {
        init: (db, collName) => {},
        createView: (db, collName) => {
            // In a sharded collection, we may sometimes get a NamespaceNotFound error, as we
            // attempt to to do some additional validation on the creation options after we get back
            // the NamespaceExists error, and the namespace may have been dropped in the meantime.
            assertAlways.commandWorkedOrFailedWithCode(
                db.createCollection(
                    getCollectionName(collName),
                    {viewOn: getBaseCollectionName(collName), pipeline: [{$match: {}}]}),
                [ErrorCodes.NamespaceExists, ErrorCodes.NamespaceNotFound]);
        },
        createCollection: (db, collName) => {
            // In a sharded collection, we may sometimes get a NamespaceNotFound error. See above.
            assertAlways.commandWorkedOrFailedWithCode(
                db.createCollection(getCollectionName(collName)),
                [ErrorCodes.NamespaceExists, ErrorCodes.NamespaceNotFound]);
        },
        verifyNoDuplicates: (db, collName) => {
            // Check how many collections/views match our namespace.
            const res =
                db.runCommand("listCollections", {filter: {name: getCollectionName(collName)}});
            assertAlways.commandWorked(res);
            // We expect that we only ever find 0 or 1. If we find 2 or more, then we managed to
            // create a view and collection on the same namespace simultaneously, which is a bug.
            assertAlways.lte(res.cursor.firstBatch.length, 1);
        },
        dropNamespace: (db, collName) => {
            db.getCollection(getCollectionName(collName)).drop();
        },
    };

    const transitions = {
        init: {createCollection: 0.5, createView: 0.5},

        // Always verify after creation because there's no point in creating an invalid situation
        // (view and collection simultaneously on the same namespace) if we don't observe it.
        createCollection: {verifyNoDuplicates: 1.0},
        createView: {verifyNoDuplicates: 1.0},

        verifyNoDuplicates: {dropNamespace: 1.0},
        dropNamespace: {createCollection: 0.5, createView: 0.5}
    };

    return {
        threadCount: 10,
        iterations: 200,
        setup,
        states,
        teardown,
        transitions,
    };
})();