diff options
author | Jan Korous <jkorous@apple.com> | 2019-07-12 19:54:36 +0000 |
---|---|---|
committer | Jan Korous <jkorous@apple.com> | 2019-07-12 19:54:36 +0000 |
commit | de63fff9046d6771c5093d36f2e83ec4e9721153 (patch) | |
tree | 25be875804c4763e53882e44245d064aa4996676 /unittests/DirectoryWatcher | |
parent | aafc4dca1f2e4496e8baca651480a80e46f0ff61 (diff) | |
download | clang-de63fff9046d6771c5093d36f2e83ec4e9721153.tar.gz |
Revert "Reland [clang] DirectoryWatcher"
This reverts commit fdcb7f47e783933e0af8a5fae91132269a208268.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@365948 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/DirectoryWatcher')
-rw-r--r-- | unittests/DirectoryWatcher/CMakeLists.txt | 17 | ||||
-rw-r--r-- | unittests/DirectoryWatcher/DirectoryWatcherTest.cpp | 426 |
2 files changed, 0 insertions, 443 deletions
diff --git a/unittests/DirectoryWatcher/CMakeLists.txt b/unittests/DirectoryWatcher/CMakeLists.txt deleted file mode 100644 index fc93323b37..0000000000 --- a/unittests/DirectoryWatcher/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Linux") - - set(LLVM_LINK_COMPONENTS - Support - ) - - add_clang_unittest(DirectoryWatcherTests - DirectoryWatcherTest.cpp - ) - - target_link_libraries(DirectoryWatcherTests - PRIVATE - clangDirectoryWatcher - clangBasic - ) - -endif()
\ No newline at end of file diff --git a/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp b/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp deleted file mode 100644 index a2c50fc7d0..0000000000 --- a/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp +++ /dev/null @@ -1,426 +0,0 @@ -//===- unittests/DirectoryWatcher/DirectoryWatcherTest.cpp ----------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "clang/DirectoryWatcher/DirectoryWatcher.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Mutex.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" -#include "gtest/gtest.h" -#include <condition_variable> -#include <future> -#include <mutex> -#include <thread> - -using namespace llvm; -using namespace llvm::sys; -using namespace llvm::sys::fs; -using namespace clang; - -namespace clang { -static bool operator==(const DirectoryWatcher::Event &lhs, - const DirectoryWatcher::Event &rhs) { - return lhs.Filename == rhs.Filename && - static_cast<int>(lhs.Kind) == static_cast<int>(rhs.Kind); -} -} // namespace clang - -namespace { - -struct DirectoryWatcherTestFixture { - std::string TestRootDir; - std::string TestWatchedDir; - - DirectoryWatcherTestFixture() { - SmallString<128> pathBuf; - std::error_code UniqDirRes = createUniqueDirectory("dirwatcher", pathBuf); - assert(!UniqDirRes); - TestRootDir = pathBuf.str(); - path::append(pathBuf, "watch"); - TestWatchedDir = pathBuf.str(); - std::error_code CreateDirRes = create_directory(TestWatchedDir, false); - assert(!CreateDirRes); - } - - ~DirectoryWatcherTestFixture() { remove_directories(TestRootDir); } - - SmallString<128> getPathInWatched(const std::string &testFile) { - SmallString<128> pathBuf; - pathBuf = TestWatchedDir; - path::append(pathBuf, testFile); - return pathBuf; - } - - void addFile(const std::string &testFile) { - Expected<file_t> ft = openNativeFileForWrite(getPathInWatched(testFile), - CD_CreateNew, OF_None); - if (ft) { - closeFile(*ft); - } else { - llvm::errs() << llvm::toString(ft.takeError()) << "\n"; - llvm::errs() << getPathInWatched(testFile) << "\n"; - llvm_unreachable("Couldn't create test file."); - } - } - - void deleteFile(const std::string &testFile) { - std::error_code EC = - remove(getPathInWatched(testFile), /*IgnoreNonExisting=*/false); - ASSERT_FALSE(EC); - } -}; - -std::string eventKindToString(const DirectoryWatcher::Event::EventKind K) { - switch (K) { - case DirectoryWatcher::Event::EventKind::Removed: - return "Removed"; - case DirectoryWatcher::Event::EventKind::Modified: - return "Modified"; - case DirectoryWatcher::Event::EventKind::WatchedDirRemoved: - return "WatchedDirRemoved"; - case DirectoryWatcher::Event::EventKind::WatcherGotInvalidated: - return "WatcherGotInvalidated"; - } - llvm_unreachable("unknown event kind"); -} - -struct VerifyingConsumer { - std::vector<DirectoryWatcher::Event> ExpectedInitial; - std::vector<DirectoryWatcher::Event> ExpectedNonInitial; - std::vector<DirectoryWatcher::Event> OptionalNonInitial; - std::vector<DirectoryWatcher::Event> UnexpectedInitial; - std::vector<DirectoryWatcher::Event> UnexpectedNonInitial; - std::mutex Mtx; - std::condition_variable ResultIsReady; - - VerifyingConsumer( - const std::vector<DirectoryWatcher::Event> &ExpectedInitial, - const std::vector<DirectoryWatcher::Event> &ExpectedNonInitial, - const std::vector<DirectoryWatcher::Event> &OptionalNonInitial = {}) - : ExpectedInitial(ExpectedInitial), - ExpectedNonInitial(ExpectedNonInitial), - OptionalNonInitial(OptionalNonInitial) {} - - // This method is used by DirectoryWatcher. - void consume(DirectoryWatcher::Event E, bool IsInitial) { - if (IsInitial) - consumeInitial(E); - else - consumeNonInitial(E); - } - - void consumeInitial(DirectoryWatcher::Event E) { - std::unique_lock<std::mutex> L(Mtx); - auto It = std::find(ExpectedInitial.begin(), ExpectedInitial.end(), E); - if (It == ExpectedInitial.end()) { - UnexpectedInitial.push_back(E); - } else { - ExpectedInitial.erase(It); - } - if (result()) - ResultIsReady.notify_one(); - } - - void consumeNonInitial(DirectoryWatcher::Event E) { - std::unique_lock<std::mutex> L(Mtx); - auto It = - std::find(ExpectedNonInitial.begin(), ExpectedNonInitial.end(), E); - if (It == ExpectedNonInitial.end()) { - auto OptIt = - std::find(OptionalNonInitial.begin(), OptionalNonInitial.end(), E); - if (OptIt != OptionalNonInitial.end()) { - OptionalNonInitial.erase(OptIt); - } else { - UnexpectedNonInitial.push_back(E); - } - } else { - ExpectedNonInitial.erase(It); - } - if (result()) - ResultIsReady.notify_one(); - } - - // This method is used by DirectoryWatcher. - void consume(llvm::ArrayRef<DirectoryWatcher::Event> Es, bool IsInitial) { - for (const auto &E : Es) - consume(E, IsInitial); - } - - // Not locking - caller has to lock Mtx. - llvm::Optional<bool> result() const { - if (ExpectedInitial.empty() && ExpectedNonInitial.empty() && - UnexpectedInitial.empty() && UnexpectedNonInitial.empty()) - return true; - if (!UnexpectedInitial.empty() || !UnexpectedNonInitial.empty()) - return false; - return llvm::None; - } - - // This method is used by tests. - // \returns true on success - bool blockUntilResult() { - std::unique_lock<std::mutex> L(Mtx); - while (true) { - if (result()) - return *result(); - - ResultIsReady.wait(L, [this]() { return result().hasValue(); }); - } - return false; // Just to make compiler happy. - } - - void printUnmetExpectations(llvm::raw_ostream &OS) { - if (!ExpectedInitial.empty()) { - OS << "Expected but not seen initial events: \n"; - for (const auto &E : ExpectedInitial) { - OS << eventKindToString(E.Kind) << " " << E.Filename << "\n"; - } - } - if (!ExpectedNonInitial.empty()) { - OS << "Expected but not seen non-initial events: \n"; - for (const auto &E : ExpectedNonInitial) { - OS << eventKindToString(E.Kind) << " " << E.Filename << "\n"; - } - } - if (!UnexpectedInitial.empty()) { - OS << "Unexpected initial events seen: \n"; - for (const auto &E : UnexpectedInitial) { - OS << eventKindToString(E.Kind) << " " << E.Filename << "\n"; - } - } - if (!UnexpectedNonInitial.empty()) { - OS << "Unexpected non-initial events seen: \n"; - for (const auto &E : UnexpectedNonInitial) { - OS << eventKindToString(E.Kind) << " " << E.Filename << "\n"; - } - } - } -}; - -void checkEventualResultWithTimeout(VerifyingConsumer &TestConsumer) { - std::packaged_task<int(void)> task( - [&TestConsumer]() { return TestConsumer.blockUntilResult(); }); - std::future<int> WaitForExpectedStateResult = task.get_future(); - std::thread worker(std::move(task)); - worker.detach(); - - EXPECT_TRUE(WaitForExpectedStateResult.wait_for(std::chrono::seconds(3)) == - std::future_status::ready) - << "The expected result state wasn't reached before the time-out."; - EXPECT_TRUE(TestConsumer.result().hasValue()); - if (TestConsumer.result().hasValue()) { - EXPECT_TRUE(*TestConsumer.result()); - } - if ((TestConsumer.result().hasValue() && !TestConsumer.result().getValue()) || - !TestConsumer.result().hasValue()) - TestConsumer.printUnmetExpectations(llvm::outs()); -} - -} // namespace - -TEST(DirectoryWatcherTest, InitialScanSync) { - DirectoryWatcherTestFixture fixture; - - fixture.addFile("a"); - fixture.addFile("b"); - fixture.addFile("c"); - - VerifyingConsumer TestConsumer{ - {{DirectoryWatcher::Event::EventKind::Modified, "a"}, - {DirectoryWatcher::Event::EventKind::Modified, "b"}, - {DirectoryWatcher::Event::EventKind::Modified, "c"}}, - {}}; - - auto DW = DirectoryWatcher::create( - fixture.TestWatchedDir, - [&TestConsumer](llvm::ArrayRef<DirectoryWatcher::Event> Events, - bool IsInitial) { - TestConsumer.consume(Events, IsInitial); - }, - /*waitForInitialSync=*/true); - - checkEventualResultWithTimeout(TestConsumer); -} - -TEST(DirectoryWatcherTest, InitialScanAsync) { - DirectoryWatcherTestFixture fixture; - - fixture.addFile("a"); - fixture.addFile("b"); - fixture.addFile("c"); - - VerifyingConsumer TestConsumer{ - {{DirectoryWatcher::Event::EventKind::Modified, "a"}, - {DirectoryWatcher::Event::EventKind::Modified, "b"}, - {DirectoryWatcher::Event::EventKind::Modified, "c"}}, - {}}; - - auto DW = DirectoryWatcher::create( - fixture.TestWatchedDir, - [&TestConsumer](llvm::ArrayRef<DirectoryWatcher::Event> Events, - bool IsInitial) { - TestConsumer.consume(Events, IsInitial); - }, - /*waitForInitialSync=*/false); - - checkEventualResultWithTimeout(TestConsumer); -} - -TEST(DirectoryWatcherTest, AddFiles) { - DirectoryWatcherTestFixture fixture; - - VerifyingConsumer TestConsumer{ - {}, - {{DirectoryWatcher::Event::EventKind::Modified, "a"}, - {DirectoryWatcher::Event::EventKind::Modified, "b"}, - {DirectoryWatcher::Event::EventKind::Modified, "c"}}}; - - auto DW = DirectoryWatcher::create( - fixture.TestWatchedDir, - [&TestConsumer](llvm::ArrayRef<DirectoryWatcher::Event> Events, - bool IsInitial) { - TestConsumer.consume(Events, IsInitial); - }, - /*waitForInitialSync=*/true); - - fixture.addFile("a"); - fixture.addFile("b"); - fixture.addFile("c"); - - checkEventualResultWithTimeout(TestConsumer); -} - -TEST(DirectoryWatcherTest, ModifyFile) { - DirectoryWatcherTestFixture fixture; - - fixture.addFile("a"); - - VerifyingConsumer TestConsumer{ - {{DirectoryWatcher::Event::EventKind::Modified, "a"}}, - {{DirectoryWatcher::Event::EventKind::Modified, "a"}}}; - - auto DW = DirectoryWatcher::create( - fixture.TestWatchedDir, - [&TestConsumer](llvm::ArrayRef<DirectoryWatcher::Event> Events, - bool IsInitial) { - TestConsumer.consume(Events, IsInitial); - }, - /*waitForInitialSync=*/true); - - // modify the file - { - std::error_code error; - llvm::raw_fd_ostream bStream(fixture.getPathInWatched("a"), error, - CD_OpenExisting); - assert(!error); - bStream << "foo"; - } - - checkEventualResultWithTimeout(TestConsumer); -} - -TEST(DirectoryWatcherTest, DeleteFile) { - DirectoryWatcherTestFixture fixture; - - fixture.addFile("a"); - - VerifyingConsumer TestConsumer{ - {{DirectoryWatcher::Event::EventKind::Modified, "a"}}, - {{DirectoryWatcher::Event::EventKind::Removed, "a"}}}; - - auto DW = DirectoryWatcher::create( - fixture.TestWatchedDir, - [&TestConsumer](llvm::ArrayRef<DirectoryWatcher::Event> Events, - bool IsInitial) { - TestConsumer.consume(Events, IsInitial); - }, - /*waitForInitialSync=*/true); - - fixture.deleteFile("a"); - - checkEventualResultWithTimeout(TestConsumer); -} - -TEST(DirectoryWatcherTest, DeleteWatchedDir) { - DirectoryWatcherTestFixture fixture; - - VerifyingConsumer TestConsumer{ - {}, - {{DirectoryWatcher::Event::EventKind::WatchedDirRemoved, ""}, - {DirectoryWatcher::Event::EventKind::WatcherGotInvalidated, ""}}}; - - auto DW = DirectoryWatcher::create( - fixture.TestWatchedDir, - [&TestConsumer](llvm::ArrayRef<DirectoryWatcher::Event> Events, - bool IsInitial) { - TestConsumer.consume(Events, IsInitial); - }, - /*waitForInitialSync=*/true); - - remove_directories(fixture.TestWatchedDir); - - checkEventualResultWithTimeout(TestConsumer); -} - -TEST(DirectoryWatcherTest, InvalidatedWatcher) { - DirectoryWatcherTestFixture fixture; - - VerifyingConsumer TestConsumer{ - {}, {{DirectoryWatcher::Event::EventKind::WatcherGotInvalidated, ""}}}; - - { - auto DW = DirectoryWatcher::create( - fixture.TestWatchedDir, - [&TestConsumer](llvm::ArrayRef<DirectoryWatcher::Event> Events, - bool IsInitial) { - TestConsumer.consume(Events, IsInitial); - }, - /*waitForInitialSync=*/true); - } // DW is destructed here. - - checkEventualResultWithTimeout(TestConsumer); -} - -TEST(DirectoryWatcherTest, ChangeMetadata) { - DirectoryWatcherTestFixture fixture; - fixture.addFile("a"); - - VerifyingConsumer TestConsumer{ - {{DirectoryWatcher::Event::EventKind::Modified, "a"}}, - // We don't expect any notification for file having access file changed. - {}, - // Given the timing we are ok with receiving the duplicate event. - {{DirectoryWatcher::Event::EventKind::Modified, "a"}}}; - - auto DW = DirectoryWatcher::create( - fixture.TestWatchedDir, - [&TestConsumer](llvm::ArrayRef<DirectoryWatcher::Event> Events, - bool IsInitial) { - TestConsumer.consume(Events, IsInitial); - }, - /*waitForInitialSync=*/true); - - { // Change access and modification time of file a. - Expected<file_t> HopefullyTheFD = llvm::sys::fs::openNativeFileForWrite( - fixture.getPathInWatched("a"), CD_OpenExisting, OF_None); - if (!HopefullyTheFD) { - llvm::outs() << HopefullyTheFD.takeError(); - } - - const int FD = HopefullyTheFD.get(); - const TimePoint<> NewTimePt = - std::chrono::system_clock::now() - std::chrono::minutes(1); - - std::error_code setTimeRes = - llvm::sys::fs::setLastAccessAndModificationTime(FD, NewTimePt, - NewTimePt); - assert(!setTimeRes); - } - - checkEventualResultWithTimeout(TestConsumer); -} |