mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
98 lines
4.7 KiB
JavaScript
98 lines
4.7 KiB
JavaScript
/**
|
|
* Tests that view creation and modification is correctly persisted.
|
|
*
|
|
* This test requires persistence to ensure data survives a restart.
|
|
* @tags: [requires_persistence]
|
|
*/
|
|
(function() {
|
|
'use strict';
|
|
|
|
// The following test verifies that writeConcern: {j: true} ensures that the view catalog is
|
|
// durable.
|
|
let dbpath = MongoRunner.dataPath + '_durable_view_catalog';
|
|
resetDbpath(dbpath);
|
|
|
|
let mongodArgs = {dbpath: dbpath, noCleanData: true, journal: ''};
|
|
|
|
// Start a mongod.
|
|
let conn = MongoRunner.runMongod(mongodArgs);
|
|
assert.neq(null, conn, 'mongod was unable to start up');
|
|
|
|
// Now connect to the mongod, create, remove and modify views and then abruptly stop the server.
|
|
let viewsDB = conn.getDB('test');
|
|
let pipe = [{$match: {}}];
|
|
assert.commandWorked(
|
|
viewsDB.runCommand({create: "view1", viewOn: "collection", pipeline: pipe}));
|
|
assert.commandWorked(
|
|
viewsDB.runCommand({create: "view2", viewOn: "collection", pipeline: pipe}));
|
|
assert.commandWorked(
|
|
viewsDB.runCommand({create: "view3", viewOn: "collection", pipeline: pipe}));
|
|
assert.commandWorked(viewsDB.runCommand({collMod: "view3", viewOn: "view2"}));
|
|
// On the final modification, require a sync to ensure durability.
|
|
assert.commandWorked(viewsDB.runCommand({drop: "view1", writeConcern: {j: 1}}));
|
|
|
|
// Hard kill the mongod to ensure the data was indeed synced to durable storage.
|
|
MongoRunner.stopMongod(conn, 9, {allowedExitCode: MongoRunner.EXIT_SIGKILL});
|
|
|
|
// Restart the mongod.
|
|
conn = MongoRunner.runMongod(mongodArgs);
|
|
assert.neq(null, conn, 'mongod was unable to restart after receiving a SIGKILL');
|
|
|
|
// Check that our journaled write still is present.
|
|
viewsDB = conn.getDB('test');
|
|
let actualViews = viewsDB.system.views.find().toArray();
|
|
let expectedViews = [
|
|
{"_id": "test.view2", "viewOn": "collection", "pipeline": pipe},
|
|
{"_id": "test.view3", "viewOn": "view2", "pipeline": pipe}
|
|
];
|
|
assert.eq(actualViews, expectedViews, "view definitions not correctly persisted");
|
|
let listedViews = viewsDB.runCommand({listCollections: 1, filter: {type: "view"}})
|
|
.cursor.firstBatch.map((function(x) {
|
|
return {
|
|
_id: "test." + x.name,
|
|
viewOn: x.options.viewOn,
|
|
pipeline: x.options.pipeline
|
|
};
|
|
}));
|
|
assert.sameMembers(
|
|
listedViews, expectedViews, "persisted view definitions not correctly loaded");
|
|
|
|
// Insert an invalid view definition directly into system.views to bypass normal validation.
|
|
assert.writeOK(viewsDB.system.views.insert({_id: "badView", pipeline: "badType"}));
|
|
|
|
// Skip collection validation during stopMongod if invalid views exists.
|
|
TestData.skipValidationOnInvalidViewDefinitions = true;
|
|
|
|
// Restarting the mongod should succeed despite the presence of invalid view definitions.
|
|
MongoRunner.stopMongod(conn);
|
|
conn = MongoRunner.runMongod(mongodArgs);
|
|
assert.neq(
|
|
null,
|
|
conn,
|
|
"after inserting bad views, failed to restart mongod with options: " + tojson(mongodArgs));
|
|
|
|
// Now that the database's view catalog has been marked as invalid, all view operations in that
|
|
// database should fail.
|
|
viewsDB = conn.getDB("test");
|
|
assert.commandFailedWithCode(viewsDB.runCommand({find: "view2"}),
|
|
ErrorCodes.InvalidViewDefinition);
|
|
assert.commandFailedWithCode(viewsDB.runCommand({create: "view4", viewOn: "collection"}),
|
|
ErrorCodes.InvalidViewDefinition);
|
|
assert.commandFailedWithCode(viewsDB.runCommand({collMod: "view2", viewOn: "view4"}),
|
|
ErrorCodes.InvalidViewDefinition);
|
|
assert.commandFailedWithCode(viewsDB.runCommand({drop: "view4"}),
|
|
ErrorCodes.InvalidViewDefinition);
|
|
assert.commandFailedWithCode(viewsDB.runCommand({listCollections: 1}),
|
|
ErrorCodes.InvalidViewDefinition);
|
|
|
|
// Manually remove the invalid view definition from system.views, and then verify that view
|
|
// operations work successfully without requiring a server restart.
|
|
assert.writeOK(viewsDB.system.views.remove({_id: "badView"}));
|
|
assert.commandWorked(viewsDB.runCommand({find: "view2"}));
|
|
assert.commandWorked(viewsDB.runCommand({create: "view4", viewOn: "collection"}));
|
|
assert.commandWorked(viewsDB.runCommand({collMod: "view2", viewOn: "view4"}));
|
|
assert.commandWorked(viewsDB.runCommand({drop: "view4"}));
|
|
assert.commandWorked(viewsDB.runCommand({listCollections: 1}));
|
|
MongoRunner.stopMongod(conn);
|
|
})();
|