160 lines
5.3 KiB
JavaScript
160 lines
5.3 KiB
JavaScript
/**
|
|
* Tests the validateDBMetaData commands with various input parameters.
|
|
* @tags: [
|
|
* requires_fcv_49
|
|
* ]
|
|
*/
|
|
(function() {
|
|
"use strict";
|
|
|
|
load("jstests/libs/fixture_helpers.js"); // For FixtureHelpers.
|
|
load("jstests/core/timeseries/libs/timeseries.js"); // For TimeseriesTest.
|
|
|
|
const dbName = jsTestName();
|
|
|
|
const testDB = db.getSiblingDB(dbName);
|
|
assert.commandWorked(testDB.dropDatabase());
|
|
const coll1 = testDB.coll1;
|
|
|
|
// Drop all the unstable data that the other tests might have created. This will ensure that the
|
|
// validateDBMetadata command is validating only the data generated by this test.
|
|
(function dropAllUnstableData() {
|
|
const listDBRes = assert.commandWorked(db.adminCommand({listDatabases: 1, nameOnly: true}));
|
|
for (let listDBOutput of listDBRes.databases) {
|
|
// Skip non-user databases.
|
|
if (Array.contains(["admin", "config", "local", "$external"], listDBOutput.name)) {
|
|
continue;
|
|
}
|
|
const currentDB = db.getSiblingDB(listDBOutput.name);
|
|
for (let collInfo of currentDB.getCollectionInfos()) {
|
|
if (collInfo.type == "collection" && !collInfo.name.startsWith("system")) {
|
|
assert.commandWorked(
|
|
currentDB.runCommand({dropIndexes: collInfo.name, index: "*"}));
|
|
}
|
|
}
|
|
}
|
|
})();
|
|
|
|
// 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"}));
|
|
|
|
validate({apiStrict: false});
|
|
|
|
// All dbs but different collection name.
|
|
validate({coll: "coll2", apiStrict: true});
|
|
|
|
// Different db, and collection which has unstable index should not error.
|
|
validate({dbName: "new", coll: "coll1", apiStrict: true});
|
|
validate({
|
|
dbName: "new",
|
|
apiStrict: true,
|
|
});
|
|
|
|
// Cases where the command returns an error.
|
|
validate({apiStrict: true, error: true});
|
|
validate({coll: "coll1", apiStrict: true, error: true});
|
|
validate({
|
|
dbName: testDB.getName(),
|
|
coll: "coll1",
|
|
apiStrict: true,
|
|
error: {code: ErrorCodes.APIStrictError}
|
|
});
|
|
validate({dbName: testDB.getName(), apiStrict: true, error: true});
|
|
|
|
//
|
|
// Tests for views.
|
|
//
|
|
assert.commandWorked(coll1.dropIndexes());
|
|
validate({apiStrict: true});
|
|
|
|
// Create a view which uses unstable expression and verify that validateDBMetadata commands throws
|
|
// an assertion.
|
|
const view =
|
|
testDB.createView("view1", "coll2", [{$project: {v: {$_testApiVersion: {unstable: true}}}}]);
|
|
|
|
validate({apiStrict: true, error: true});
|
|
validate({dbName: dbName, apiStrict: true, error: true});
|
|
|
|
validate({dbName: "otherDB", apiStrict: true});
|
|
validate({dbName: dbName, coll: "coll", apiStrict: true});
|
|
|
|
// With view name in the input.
|
|
validate({coll: "view1", apiStrict: true, error: {code: ErrorCodes.APIStrictError}});
|
|
validate(
|
|
{dbName: dbName, coll: "view1", apiStrict: true, error: {code: ErrorCodes.APIStrictError}});
|
|
|
|
validate({dbName: "new", coll: "view1", apiStrict: true});
|
|
|
|
// Collection named same as the view name in another db.
|
|
const testDB2 = db.getSiblingDB("testDB2");
|
|
const collWithViewName = testDB2.view1;
|
|
validate({coll: "view1", apiStrict: true, error: {code: ErrorCodes.APIStrictError}});
|
|
|
|
//
|
|
// Tests for validator.
|
|
//
|
|
assert.commandWorked(testDB.dropDatabase());
|
|
|
|
assert.commandWorked(testDB.createCollection(
|
|
"validatorColl", {validator: {$expr: {$_testApiVersion: {unstable: true}}}}));
|
|
|
|
validate({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: "validatorColl"}));
|
|
|
|
//
|
|
// 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() {
|
|
if (!TimeseriesTest.timeseriesCollectionsEnabled(db.getMongo())) {
|
|
jsTestLog("Cannot validate metadata with timeseries collection, feature flag is disabled");
|
|
return;
|
|
}
|
|
|
|
const coll = "timeseriesCollectionMetaDataValidation";
|
|
assert.commandWorked(
|
|
testDB.createCollection(coll, {timeseries: {timeField: "time", metaField: "meta"}}));
|
|
validate({apiStrict: true});
|
|
}());
|
|
}());
|