From 68b1410c840bcb6031e441ce45d2f2b7124e3916 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 25 Feb 2016 13:51:28 -0800 Subject: [PATCH] Split FileTest to a smaller test and an extended test Summary: FileTest pulls in subprocess and does a lot more than just directly test File.h Reviewed By: yfeldblum Differential Revision: D2971641 fb-gh-sync-id: 16e1096ab3b0f6434a26f84c889ebb082ee3f210 shipit-source-id: 16e1096ab3b0f6434a26f84c889ebb082ee3f210 --- folly/test/FileLockTest.cpp | 111 ++++++++++++++++++++++++++++++++++++ folly/test/FileTest.cpp | 96 +------------------------------ 2 files changed, 112 insertions(+), 95 deletions(-) create mode 100644 folly/test/FileLockTest.cpp diff --git a/folly/test/FileLockTest.cpp b/folly/test/FileLockTest.cpp new file mode 100644 index 00000000..595c28c1 --- /dev/null +++ b/folly/test/FileLockTest.cpp @@ -0,0 +1,111 @@ +/* + * Copyright 2016 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +using namespace folly; +using namespace folly::test; + +DEFINE_bool(s, false, "get shared lock"); +DEFINE_bool(x, false, "get exclusive lock"); + +TEST(File, Locks) { + typedef std::unique_lock Lock; + typedef boost::shared_lock SharedLock; + + // Find out where we are. + static constexpr size_t pathLength = 2048; + char buf[pathLength + 1]; + int r = readlink("/proc/self/exe", buf, pathLength); + CHECK_ERR(r); + buf[r] = '\0'; + + fs::path me(buf); + auto helper_basename = "file_test_lock_helper"; + fs::path helper; + if (fs::exists(me.parent_path() / helper_basename)) { + helper = me.parent_path() / helper_basename; + } else { + throw std::runtime_error( + folly::to("cannot find helper ", helper_basename)); + } + + TemporaryFile tempFile; + File f(tempFile.fd()); + + enum LockMode { EXCLUSIVE, SHARED }; + auto testLock = [&](LockMode mode, bool expectedSuccess) { + auto ret = Subprocess({helper.native(), + mode == SHARED ? "-s" : "-x", + tempFile.path().native()}).wait(); + EXPECT_TRUE(ret.exited()); + if (ret.exited()) { + EXPECT_EQ(expectedSuccess ? 0 : 42, ret.exitStatus()); + } + }; + + // Make sure nothing breaks and things compile. + { Lock lock(f); } + + { SharedLock lock(f); } + + { + Lock lock(f, std::defer_lock); + EXPECT_TRUE(lock.try_lock()); + } + + { + SharedLock lock(f, boost::defer_lock); + EXPECT_TRUE(lock.try_lock()); + } + + // X blocks X + { + Lock lock(f); + testLock(EXCLUSIVE, false); + } + + // X blocks S + { + Lock lock(f); + testLock(SHARED, false); + } + + // S blocks X + { + SharedLock lock(f); + testLock(EXCLUSIVE, false); + } + + // S does not block S + { + SharedLock lock(f); + testLock(SHARED, true); + } +} diff --git a/folly/test/FileTest.cpp b/folly/test/FileTest.cpp index ffe0bc19..d7ac2a48 100644 --- a/folly/test/FileTest.cpp +++ b/folly/test/FileTest.cpp @@ -16,19 +16,11 @@ #include -#include +#include -#include -#include #include -#include -#include -#include -#include - using namespace folly; -using namespace folly::test; namespace { void expectWouldBlock(ssize_t r) { @@ -143,89 +135,3 @@ TEST(File, Truthy) { EXPECT_TRUE(false); } } - -TEST(File, Locks) { - typedef std::unique_lock Lock; - typedef boost::shared_lock SharedLock; - - // Find out where we are. - static constexpr size_t pathLength = 2048; - char buf[pathLength + 1]; - int r = readlink("/proc/self/exe", buf, pathLength); - CHECK_ERR(r); - buf[r] = '\0'; - - // NOTE(agallagher): Our various internal build systems layout built - // binaries differently, so the two layouts below. - fs::path me(buf); - auto helper_basename = "file_test_lock_helper"; - fs::path helper; - if (fs::exists(me.parent_path() / helper_basename)) { - helper = me.parent_path() / helper_basename; - } else if (fs::exists( - me.parent_path().parent_path() / helper_basename / helper_basename)) { - helper = me.parent_path().parent_path() - / helper_basename / helper_basename; - } else { - throw std::runtime_error( - folly::to("cannot find helper ", helper_basename)); - } - - TemporaryFile tempFile; - File f(tempFile.fd()); - - enum LockMode { EXCLUSIVE, SHARED }; - auto testLock = [&] (LockMode mode, bool expectedSuccess) { - auto ret = - Subprocess({helper.native(), - mode == SHARED ? "-s" : "-x", - tempFile.path().native()}).wait(); - EXPECT_TRUE(ret.exited()); - if (ret.exited()) { - EXPECT_EQ(expectedSuccess ? 0 : 42, ret.exitStatus()); - } - }; - - // Make sure nothing breaks and things compile. - { - Lock lock(f); - } - - { - SharedLock lock(f); - } - - { - Lock lock(f, std::defer_lock); - EXPECT_TRUE(lock.try_lock()); - } - - { - SharedLock lock(f, boost::defer_lock); - EXPECT_TRUE(lock.try_lock()); - } - - // X blocks X - { - Lock lock(f); - testLock(EXCLUSIVE, false); - } - - // X blocks S - { - Lock lock(f); - testLock(SHARED, false); - } - - // S blocks X - { - SharedLock lock(f); - testLock(EXCLUSIVE, false); - } - - // S does not block S - { - SharedLock lock(f); - testLock(SHARED, true); - } -} -- 2.34.1