summaryrefslogtreecommitdiff
path: root/jstests/libs/override_methods/override_helpers.js
blob: 437f1a07669e2e57a22acb24c821781d666e05c8 (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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/**
 * The OverrideHelpers object defines convenience methods for overriding commands and functions in
 * the mongo shell.
 */
var OverrideHelpers = (function() {
    "use strict";

    function makeIsAggregationWithFirstStage(stageName) {
        return function(commandName, commandObj) {
            if (commandName !== "aggregate" || typeof commandObj !== "object" ||
                commandObj === null) {
                return false;
            }

            if (!Array.isArray(commandObj.pipeline) || commandObj.pipeline.length === 0) {
                return false;
            }

            const firstStage = commandObj.pipeline[0];
            if (typeof firstStage !== "object" || firstStage === null) {
                return false;
            }

            return Object.keys(firstStage)[0] === stageName;
        };
    }

    function isAggregationWithOutStage(commandName, commandObj) {
        if (commandName !== "aggregate" || typeof commandObj !== "object" || commandObj === null) {
            return false;
        }

        if (!Array.isArray(commandObj.pipeline) || commandObj.pipeline.length === 0) {
            return false;
        }

        const lastStage = commandObj.pipeline[commandObj.pipeline.length - 1];
        if (typeof lastStage !== "object" || lastStage === null) {
            return false;
        }

        return Object.keys(lastStage)[0] === "$out";
    }

    function isMapReduceWithInlineOutput(commandName, commandObj) {
        if ((commandName !== "mapReduce" && commandName !== "mapreduce") ||
            typeof commandObj !== "object" || commandObj === null) {
            return false;
        }

        if (typeof commandObj.out !== "object") {
            return false;
        }

        return commandObj.out.hasOwnProperty("inline");
    }

    function prependOverrideInParallelShell(overrideFile) {
        const startParallelShellOriginal = startParallelShell;

        startParallelShell = function(jsCode, port, noConnect) {
            let newCode;
            if (typeof jsCode === "function") {
                // Load the override file and immediately invoke the supplied function.
                newCode = `load("${overrideFile}"); (${jsCode})();`;
            } else {
                newCode = `load("${overrideFile}"); ${jsCode};`;
            }

            return startParallelShellOriginal(newCode, port, noConnect);
        };
    }

    function overrideRunCommand(overrideFunc) {
        const mongoRunCommandOriginal = Mongo.prototype.runCommand;
        const mongoRunCommandWithMetadataOriginal = Mongo.prototype.runCommandWithMetadata;

        Mongo.prototype.runCommand = function(dbName, commandObj, options) {
            const commandName = Object.keys(commandObj)[0];
            return overrideFunc(this,
                                dbName,
                                commandName,
                                commandObj,
                                mongoRunCommandOriginal,
                                (commandObj) => [dbName, commandObj, options]);
        };

        Mongo.prototype.runCommandWithMetadata = function(dbName, metadata, commandArgs) {
            const commandName = Object.keys(commandArgs)[0];
            return overrideFunc(this,
                                dbName,
                                commandName,
                                commandArgs,
                                mongoRunCommandWithMetadataOriginal,
                                (commandArgs) => [dbName, metadata, commandArgs]);
        };
    }

    return {
        isAggregationWithListLocalCursorsStage:
            makeIsAggregationWithFirstStage("$listLocalCursors"),
        isAggregationWithListLocalSessionsStage:
            makeIsAggregationWithFirstStage("$listLocalSessions"),
        isAggregationWithOutStage: isAggregationWithOutStage,
        isMapReduceWithInlineOutput: isMapReduceWithInlineOutput,
        prependOverrideInParallelShell: prependOverrideInParallelShell,
        overrideRunCommand: overrideRunCommand,
    };
})();