]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/util/filelock_test.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
6 #include "rocksdb/status.h"
7 #include "rocksdb/env.h"
11 #include "util/coding.h"
12 #include "util/testharness.h"
16 class LockTest
: public testing::Test
{
18 static LockTest
* current_
;
23 : file_(test::PerThreadDBPath("db_testlock_file")),
24 env_(rocksdb::Env::Default()) {
31 Status
LockFile(FileLock
** db_lock
) {
32 return env_
->LockFile(file_
, db_lock
);
35 Status
UnlockFile(FileLock
* db_lock
) {
36 return env_
->UnlockFile(db_lock
);
39 bool AssertFileIsLocked(){
40 return CheckFileLock( /* lock_expected = */ true);
43 bool AssertFileIsNotLocked(){
44 return CheckFileLock( /* lock_expected = */ false);
47 bool CheckFileLock(bool lock_expected
){
48 // We need to fork to check the fcntl lock as we need
49 // to open and close the file from a different process
50 // to avoid either releasing the lock on close, or not
51 // contending for it when requesting a lock.
55 // WaitForSingleObject and GetExitCodeProcess can do what waitpid does.
56 // TODO - implement on Windows
64 int exit_val
= EXIT_FAILURE
;
65 int fd
= open(file_
.c_str(), O_RDWR
| O_CREAT
, 0644);
67 // could not open file, could not check if it was locked
68 fprintf( stderr
, "Open on on file %s failed.\n",file_
.c_str());
73 memset(&f
, 0, sizeof(f
));
75 f
.l_whence
= SEEK_SET
;
77 f
.l_len
= 0; // Lock/unlock entire file
78 int value
= fcntl(fd
, F_SETLK
, &f
);
81 exit_val
= EXIT_SUCCESS
;
84 if( ! lock_expected
){
85 exit_val
= EXIT_SUCCESS
;
88 close(fd
); // lock is released for child process
93 while (-1 == waitpid(pid
, &status
, 0));
94 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
95 // child process exited with non success status
101 fprintf( stderr
, "Fork failed\n" );
111 LockTest
* LockTest::current_
;
113 TEST_F(LockTest
, LockBySameThread
) {
117 // acquire a lock on a file
118 ASSERT_OK(LockFile(&lock1
));
120 // check the file is locked
121 ASSERT_TRUE( AssertFileIsLocked() );
123 // re-acquire the lock on the same file. This should fail.
124 ASSERT_TRUE(LockFile(&lock2
).IsIOError());
126 // check the file is locked
127 ASSERT_TRUE( AssertFileIsLocked() );
130 ASSERT_OK(UnlockFile(lock1
));
132 // check the file is not locked
133 ASSERT_TRUE( AssertFileIsNotLocked() );
137 } // namespace rocksdb
139 int main(int argc
, char** argv
) {
140 ::testing::InitGoogleTest(&argc
, argv
);
141 return RUN_ALL_TESTS();