summaryrefslogtreecommitdiff
path: root/jstests/concurrency/fsm_workloads/profile_command.js
blob: dd85296aa8d40531a443f709ff37415eaaa2fb40 (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
87
88
89
90
91
92
'use strict';

/**
 * profile_command.js
 *
 * Sets the profile level and filter to different values, and asserts that they take effect
 * simultaneously:
 *   1. The profile command never returns an inconsistent combination of {level, filter}.
 *   2. We never log or profile based on an inconsistent combination of {level, filter}.
 *
 * @tags: [
 *   requires_profiling,
 * ]
 */

var $config = (function() {
    const data = {
        numDocs: 1000,
        checkProfileResult: function(result) {
            // After init(), these are the only profile settings we set.
            // For example, we never set { level: 1, filter {millis: {$gt: 1}} }.
            assert.contains({level: result.was, filter: result.filter}, [
                {level: 0, filter: {$expr: {$const: false}}},
                {level: 0, filter: {nreturned: {$gt: 0}}},
                {level: 1, filter: {nModified: {$gt: 0}}},
            ]);
        },
    };
    const states = {
        init: function(db, collName) {},

        logReads: function(db, collName) {
            const result = db.setProfilingLevel(0, {filter: {nreturned: {$gt: 0}}});
            this.checkProfileResult(result);
        },
        profileUpdates: function(db, collName) {
            const result = db.setProfilingLevel(1, {filter: {nModified: {$gt: 0}}});
            this.checkProfileResult(result);
        },

        readSomething: function(db, collName) {
            assert.eq(this.numDocs, db[collName].count());
            const numDocs = Random.randInt(this.numDocs);
            const n = db[collName].find({_id: {$lt: numDocs}}).comment('readSomething').itcount();
            assert.eq(n, numDocs);
        },
        updateSomething: function(db, collName) {
            assert.eq(this.numDocs, db[collName].count());
            const numDocs = Random.randInt(this.numDocs);
            const resp = assert.commandWorked(db[collName].updateMany(
                {_id: {$lt: numDocs}}, {$inc: {i: 1}}, {comment: 'updateSomething'}));
            assert.eq(numDocs, resp.matchedCount);
            assert.eq(numDocs, resp.modifiedCount);
        },

    };
    const setup = function(db, collName) {
        Random.setRandomSeed();
        db.setProfilingLevel(0, {filter: {$expr: false}});
        const docs = Array.from({length: this.numDocs}, (_, i) => ({_id: i}));
        assert.commandWorked(db[collName].insert(docs));
    };
    const teardown = function(db, collName) {
        db.setProfilingLevel(0, {filter: 'unset'});
        // We never profiled a read.
        assert.eq(0, db.system.profile.find({comment: 'readSomething'}).itcount());
    };

    // Just let every state go to every other state with equal probability.
    const weights = {
        logReads: 0.25,
        profileUpdates: 0.25,
        readSomething: 0.25,
        updateSomething: 0.25,
    };
    const transitions = {
        init: weights,
        logReads: weights,
        profileUpdates: weights,
        readSomething: weights,
        updateSomething: weights,
    };
    return {
        data,
        threadCount: 4,
        iterations: 100,
        states,
        transitions,
        setup,
        teardown,
    };
})();