summaryrefslogtreecommitdiff
path: root/src/mongo/db/storage/storage_engine_lock_file_test.cpp
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2014-12-29 16:47:59 -0500
committerBenety Goh <benety@mongodb.com>2015-01-05 15:52:47 -0500
commitd9ce31ea2237d4aa78656fed785e7e5b91c93843 (patch)
treefafb16c58e74b57fdb3387ea51a98f2d029c8369 /src/mongo/db/storage/storage_engine_lock_file_test.cpp
parent9bfa0cc0f41dc8d425263cbf841f62b3e9d484da (diff)
downloadmongo-d9ce31ea2237d4aa78656fed785e7e5b91c93843.tar.gz
SERVER-16677 added platform-dependent class to management creation/locking of mongod.lock in data directory.
Diffstat (limited to 'src/mongo/db/storage/storage_engine_lock_file_test.cpp')
-rw-r--r--src/mongo/db/storage/storage_engine_lock_file_test.cpp173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/mongo/db/storage/storage_engine_lock_file_test.cpp b/src/mongo/db/storage/storage_engine_lock_file_test.cpp
new file mode 100644
index 00000000000..2ca432d0d71
--- /dev/null
+++ b/src/mongo/db/storage/storage_engine_lock_file_test.cpp
@@ -0,0 +1,173 @@
+/**
+ * Copyright 2014 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include <boost/filesystem.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <fstream>
+#include <ostream>
+
+#include "mongo/db/storage/storage_engine_lock_file.h"
+#include "mongo/platform/process_id.h"
+#include "mongo/unittest/temp_dir.h"
+#include "mongo/unittest/unittest.h"
+
+namespace {
+
+ using std::string;
+ using mongo::unittest::TempDir;
+
+ using namespace mongo;
+
+ TEST(StorageEngineLockFileTest, UncleanShutdownNoExistingFile) {
+ TempDir tempDir("StorageEngineLockFileTest_UncleanShutdownNoExistingFile");
+ StorageEngineLockFile lockFile(tempDir.path());
+ ASSERT_FALSE(lockFile.createdByUncleanShutdown());
+ }
+
+ TEST(StorageEngineLockFileTest, UncleanShutdownEmptyExistingFile) {
+ TempDir tempDir("StorageEngineLockFileTest_UncleanShutdownEmptyExistingFile");
+ {
+ std::string filename(tempDir.path() + "/mongod.lock");
+ std::ofstream(filename.c_str());
+ }
+ StorageEngineLockFile lockFile(tempDir.path());
+ ASSERT_FALSE(lockFile.createdByUncleanShutdown());
+ }
+
+ TEST(StorageEngineLockFileTest, UncleanShutdownNonEmptyExistingFile) {
+ TempDir tempDir("StorageEngineLockFileTest_UncleanShutdownNonEmptyExistingFile");
+ {
+ std::string filename(tempDir.path() + "/mongod.lock");
+ std::ofstream ofs(filename.c_str());
+ ofs << 12345 << std::endl;
+ }
+ StorageEngineLockFile lockFile(tempDir.path());
+ ASSERT_TRUE(lockFile.createdByUncleanShutdown());
+ }
+
+ TEST(StorageEngineLockFileTest, OpenInvalidDirectory) {
+ StorageEngineLockFile lockFile("no_such_directory");
+ ASSERT_EQUALS((boost::filesystem::path("no_such_directory") / "mongod.lock").string(),
+ lockFile.getFilespec());
+ Status status = lockFile.open();
+ ASSERT_NOT_OK(status);
+ ASSERT_EQUALS(ErrorCodes::NonExistentPath, status.code());
+ }
+
+ // Cause ::open() to fail by providing a regular file instead of a directory for 'dbpath'.
+ TEST(StorageEngineLockFileTest, OpenInvalidFilename) {
+ TempDir tempDir("StorageEngineLockFileTest_OpenInvalidFilename");
+ std::string filename(tempDir.path() + "/some_file");
+ std::ofstream(filename.c_str());
+ StorageEngineLockFile lockFile(filename);
+ Status status = lockFile.open();
+ ASSERT_NOT_OK(status);
+ ASSERT_EQUALS(ErrorCodes::DBPathInUse, status.code());
+ }
+
+ TEST(StorageEngineLockFileTest, OpenNoExistingLockFile) {
+ TempDir tempDir("StorageEngineLockFileTest_OpenNoExistingLockFile");
+ StorageEngineLockFile lockFile(tempDir.path());
+ ASSERT_OK(lockFile.open());
+ lockFile.close();
+ }
+
+ TEST(StorageEngineLockFileTest, OpenEmptyLockFile) {
+ TempDir tempDir("StorageEngineLockFileTest_OpenEmptyLockFile");
+ StorageEngineLockFile lockFile(tempDir.path());
+ std::string filename(lockFile.getFilespec());
+ std::ofstream(filename.c_str());
+ ASSERT_OK(lockFile.open());
+ lockFile.close();
+ }
+
+ TEST(StorageEngineLockFileTest, WritePidFileNotOpened) {
+ TempDir tempDir("StorageEngineLockFileTest_WritePidFileNotOpened");
+ StorageEngineLockFile lockFile(tempDir.path());
+ Status status = lockFile.writePid();
+ ASSERT_NOT_OK(status);
+ ASSERT_EQUALS(ErrorCodes::FileNotOpen, status.code());
+ }
+
+ TEST(StorageEngineLockFileTest, WritePidFileOpened) {
+ TempDir tempDir("StorageEngineLockFileTest_WritePidFileOpened");
+ StorageEngineLockFile lockFile(tempDir.path());
+ ASSERT_OK(lockFile.open());
+ ASSERT_OK(lockFile.writePid());
+ lockFile.close();
+
+ // Read PID from lock file.
+ std::string filename(lockFile.getFilespec());
+ std::ifstream ifs(filename.c_str());
+ int64_t pidFromLockFile = 0;
+ ASSERT_TRUE(ifs >> pidFromLockFile);
+ ASSERT_EQUALS(ProcessId::getCurrent().asInt64(), pidFromLockFile);
+ }
+
+ // Existing data in lock file must be removed before writing process ID.
+ TEST(StorageEngineLockFileTest, WritePidTruncateExistingFile) {
+ TempDir tempDir("StorageEngineLockFileTest_WritePidTruncateExistingFile");
+ StorageEngineLockFile lockFile(tempDir.path());
+ {
+ std::string filename(tempDir.path() + "/mongod.lock");
+ std::ofstream ofs(filename.c_str());
+ std::string currentPidStr = ProcessId::getCurrent().toString();
+ ASSERT_FALSE(currentPidStr.empty());
+ ofs << std::string(currentPidStr.size() * 100, 'X') << std::endl;
+ }
+ ASSERT_OK(lockFile.open());
+ ASSERT_OK(lockFile.writePid());
+ lockFile.close();
+
+ // Read PID from lock file.
+ std::string filename(lockFile.getFilespec());
+ std::ifstream ifs(filename.c_str());
+ int64_t pidFromLockFile = 0;
+ ASSERT_TRUE(ifs >> pidFromLockFile);
+ ASSERT_EQUALS(ProcessId::getCurrent().asInt64(), pidFromLockFile);
+
+ // There should not be any data in the file after the process ID.
+ std::string extraData;
+ ASSERT_FALSE(ifs >> extraData);
+ }
+
+ TEST(StorageEngineLockFileTest, ClearPidAndUnlock) {
+ TempDir tempDir("StorageEngineLockFileTest_ClearPidAndUnlock");
+ StorageEngineLockFile lockFile(tempDir.path());
+ ASSERT_OK(lockFile.open());
+ ASSERT_OK(lockFile.writePid());
+
+ // Clear lock file contents.
+ lockFile.clearPidAndUnlock();
+ ASSERT_TRUE(boost::filesystem::exists(lockFile.getFilespec()));
+ ASSERT_EQUALS(0U, boost::filesystem::file_size(lockFile.getFilespec()));
+ }
+
+} // namespace