summaryrefslogtreecommitdiff
path: root/unittests/DirectoryWatcher
diff options
context:
space:
mode:
authorJan Korous <jkorous@apple.com>2019-07-12 19:54:36 +0000
committerJan Korous <jkorous@apple.com>2019-07-12 19:54:36 +0000
commitde63fff9046d6771c5093d36f2e83ec4e9721153 (patch)
tree25be875804c4763e53882e44245d064aa4996676 /unittests/DirectoryWatcher
parentaafc4dca1f2e4496e8baca651480a80e46f0ff61 (diff)
downloadclang-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.txt17
-rw-r--r--unittests/DirectoryWatcher/DirectoryWatcherTest.cpp426
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);
-}