summaryrefslogtreecommitdiff
path: root/jstests/core/validate_db_metadata_command.js
blob: c9b0d40df0954352c73d60c114f839963c4a3efc (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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
 * Tests the validateDBMetaData commands with various input parameters.
 * @tags: [
 *   no_selinux,
 * ]
 */
(function() {
"use strict";

load("jstests/libs/fixture_helpers.js");  // For FixtureHelpers.

const dbName = jsTestName();

const testDB = db.getSiblingDB(dbName);
assert.commandWorked(testDB.dropDatabase());
const coll1 = testDB.getCollection(jsTestName());
const coll2 = testDB.getCollection(jsTestName() + "2");

// Verify that the 'apiParameters' field is required.
const res = assert.commandFailedWithCode(testDB.runCommand({validateDBMetadata: 1}), 40414);

function validate({dbName, coll, apiStrict, error}) {
    dbName = dbName ? dbName : null;
    coll = coll ? coll : null;
    const res = assert.commandWorked(testDB.runCommand({
        validateDBMetadata: 1,
        db: dbName,
        collection: coll,
        apiParameters: {version: "1", strict: apiStrict}
    }));

    assert(res.apiVersionErrors);
    const foundError = res.apiVersionErrors.length > 0;

    // Verify that 'apiVersionErrors' is not empty when 'error' is true, and vice versa.
    assert((!error && !foundError) || (error && foundError), res);

    if (error) {
        for (let apiError of res.apiVersionErrors) {
            assert(apiError.ns);
            if (error.code) {
                assert.eq(apiError.code, error.code);
            }

            if (FixtureHelpers.isMongos(testDB)) {
                // Check that every error has an additional 'shard' field on sharded clusters.
                assert(apiError.shard);
            }
        }
    }
}

//
// Tests for indexes.
//
assert.commandWorked(coll1.createIndex({p: "text"}));

// All dbs but different collection name.
validate({coll: coll2.getName(), apiStrict: true});

// Different db, and collection which has unstable index should not error.
validate({dbName: "new", coll: coll1.getName(), apiStrict: true});
validate({
    dbName: "new",
    apiStrict: true,
});

// Cases where the command returns an error.
validate({apiStrict: true, error: true});
validate({coll: coll1.getName(), apiStrict: true, error: true});
validate({
    dbName: testDB.getName(),
    coll: coll1.getName(),
    apiStrict: true,
    error: {code: ErrorCodes.APIStrictError}
});
validate({dbName: testDB.getName(), apiStrict: true, error: true});

//
// Tests for views.
//
assert.commandWorked(coll1.dropIndexes());
validate({coll: coll1.getName(), apiStrict: true});

// Create a view which uses unstable expression and verify that validateDBMetadata commands throws
// an assertion.
const viewName = jsTestName() + "view1";
const view = testDB.createView(
    viewName, coll2.getName(), [{$project: {v: {$_testApiVersion: {unstable: true}}}}]);

validate({coll: viewName, apiStrict: true, error: true});
validate({dbName: dbName, apiStrict: true, error: true});

validate({dbName: "otherDB", apiStrict: true});
validate({dbName: dbName, coll: coll1.getName(), apiStrict: true});

// With view name in the input.
validate({coll: viewName, apiStrict: true, error: {code: ErrorCodes.APIStrictError}});
validate(
    {dbName: dbName, coll: viewName, apiStrict: true, error: {code: ErrorCodes.APIStrictError}});

validate({dbName: "new", coll: viewName, apiStrict: true});

// Collection named same as the view name in another db.
validate({coll: viewName, apiStrict: true, error: {code: ErrorCodes.APIStrictError}});

//
// Tests for validator.
//
assert.commandWorked(testDB.dropDatabase());

const validatorCollName = jsTestName() + "validator";
assert.commandWorked(testDB.createCollection(
    validatorCollName, {validator: {$expr: {$_testApiVersion: {unstable: true}}}}));

validate({dbName: testDB.getName(), apiStrict: true, error: true});

// Drop the collection with validation rules. By not using the 'coll.drop()' shell helper, we can
// avoid implicit collection creation in certain passthrough suites. This should increase the
// coverage of this test on sharded clusters.
assert.commandWorked(testDB.runCommand({drop: validatorCollName}));

//
// Validates the metadata across all the databases and collections after creating a time-series
// collection if time-series collection feature flag is enabled.
//
(function maybeValidateWithTimeseriesCollection() {
    const coll = "timeseriesCollectionMetaDataValidation";
    assert.commandWorked(
        testDB.createCollection(coll, {timeseries: {timeField: "time", metaField: "meta"}}));
    validate({dbName: testDB.getName(), apiStrict: true});
}());

// Clean up all the data for next run.
assert.commandWorked(testDB.dropDatabase());
}());