From a23149fa7627a96fbbf3e38353bcdad496f0adda Mon Sep 17 00:00:00 2001 From: Sergey Yakubov <sergey.yakubov@desy.de> Date: Wed, 5 Sep 2018 17:39:05 +0200 Subject: [PATCH] continue windows folder monitor --- common/cpp/include/io/io.h | 2 +- common/cpp/include/unittests/MockIO.h | 13 ++- common/cpp/src/system_io/system_io.h | 2 +- .../event_monitor_producer/CMakeLists.txt | 8 +- .../src/single_folder_monitor.cpp | 13 --- .../src/single_folder_monitor.h | 19 ---- .../src/single_folder_watch_windows.cpp | 30 +++++ .../src/single_folder_watch_windows.h | 26 +++++ .../src/system_folder_watch_windows.cpp | 17 +-- .../src/system_folder_watch_windows.h | 4 +- .../event_monitor_producer/src/watch_io.cpp | 24 ++++ .../event_monitor_producer/src/watch_io.h | 22 ++++ .../unittests/mock_watch_io.h | 26 +++++ .../test_single_folder_watch_windows.cpp | 107 ++++++++++++++++++ 14 files changed, 261 insertions(+), 52 deletions(-) delete mode 100644 producer/event_monitor_producer/src/single_folder_monitor.cpp delete mode 100644 producer/event_monitor_producer/src/single_folder_monitor.h create mode 100644 producer/event_monitor_producer/src/single_folder_watch_windows.cpp create mode 100644 producer/event_monitor_producer/src/single_folder_watch_windows.h create mode 100644 producer/event_monitor_producer/src/watch_io.cpp create mode 100644 producer/event_monitor_producer/src/watch_io.h create mode 100644 producer/event_monitor_producer/unittests/mock_watch_io.h create mode 100644 producer/event_monitor_producer/unittests/test_single_folder_watch_windows.cpp diff --git a/common/cpp/include/io/io.h b/common/cpp/include/io/io.h index 6d5c7e5c8..d40a2cb86 100644 --- a/common/cpp/include/io/io.h +++ b/common/cpp/include/io/io.h @@ -101,7 +101,7 @@ class IO { virtual SubDirList GetSubDirectories(const std::string& path, Error* err) const = 0; virtual std::vector<FileInfo> FilesInFolder (const std::string& folder, Error* err) const = 0; virtual std::string ReadFileToString (const std::string& fname, Error* err) const = 0; - + virtual Error GetLastError() const = 0; }; } diff --git a/common/cpp/include/unittests/MockIO.h b/common/cpp/include/unittests/MockIO.h index 2e374027c..c7a9ed8db 100644 --- a/common/cpp/include/unittests/MockIO.h +++ b/common/cpp/include/unittests/MockIO.h @@ -173,7 +173,15 @@ class MockIO : public IO { MOCK_CONST_METHOD3(GetDataFromFile_t, uint8_t* (const std::string& fname, uint64_t* fsize, ErrorInterface** err)); - Error WriteDataToFile(const std::string& root_folder, const std::string& fname, const FileData& data, + + Error GetLastError() const override { + return Error{GetLastError_t()}; + } + + MOCK_CONST_METHOD0(GetLastError_t, ErrorInterface* ()); + + + Error WriteDataToFile(const std::string& root_folder, const std::string& fname, const FileData& data, size_t length, bool create_directories) const override { return Error{WriteDataToFile_t(root_folder, fname, data.get(), length, create_directories)}; @@ -223,6 +231,9 @@ class MockIO : public IO { return data; } MOCK_CONST_METHOD2(ReadFileToString_t, std::string(const std::string& fname, ErrorInterface** err)); + + + }; } diff --git a/common/cpp/src/system_io/system_io.h b/common/cpp/src/system_io/system_io.h index 314eb74ca..00ff32d82 100644 --- a/common/cpp/src/system_io/system_io.h +++ b/common/cpp/src/system_io/system_io.h @@ -25,7 +25,6 @@ class SystemIO final : public IO { //void CollectFileInformationRecursively(const std::string& path, std::vector<FileInfo>* files, IOErrors* err) const; int FileOpenModeToPosixFileOpenMode(int open_flags) const; - Error GetLastError() const; short AddressFamilyToPosixFamily (AddressFamilies address_family) const; int SocketTypeToPosixType (SocketTypes socket_type) const; @@ -111,6 +110,7 @@ class SystemIO final : public IO { SubDirList GetSubDirectories(const std::string& path, Error* err) const override; std::string ReadFileToString(const std::string& fname, Error* err) const override; Error RemoveFile(const std::string& fname) const override; + Error GetLastError() const override; }; } diff --git a/producer/event_monitor_producer/CMakeLists.txt b/producer/event_monitor_producer/CMakeLists.txt index 8809a6224..c817b0eaf 100644 --- a/producer/event_monitor_producer/CMakeLists.txt +++ b/producer/event_monitor_producer/CMakeLists.txt @@ -7,7 +7,10 @@ set(SOURCE_FILES ) IF(WIN32) - set(SOURCE_FILES ${SOURCE_FILES} src/system_folder_watch_windows.cpp src/single_folder_monitor.cpp) + set(SOURCE_FILES ${SOURCE_FILES} src/system_folder_watch_windows.cpp + src/single_folder_watch_windows.cpp + src/watch_io.cpp + ) ELSEIF(UNIX) set(SOURCE_FILES ${SOURCE_FILES} src/system_folder_watch_linux.cpp src/inotify_event.cpp src/inotify_linux.cpp) ENDIF(WIN32) @@ -56,7 +59,8 @@ set(TEST_SOURCE_FILES IF(UNIX) set(TEST_SOURCE_FILES ${TEST_SOURCE_FILES} unittests/test_system_folder_watch_linux.cpp) ELSE() -set(TEST_SOURCE_FILES ${TEST_SOURCE_FILES} unittests/test_system_folder_watch_windows.cpp) +set(TEST_SOURCE_FILES ${TEST_SOURCE_FILES} unittests/test_system_folder_watch_windows.cpp + unittests/test_single_folder_watch_windows.cpp) ENDIF(UNIX) diff --git a/producer/event_monitor_producer/src/single_folder_monitor.cpp b/producer/event_monitor_producer/src/single_folder_monitor.cpp deleted file mode 100644 index 390e0fef8..000000000 --- a/producer/event_monitor_producer/src/single_folder_monitor.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "single_folder_monitor.h" - -namespace asapo { - -SingleFolderMonitor::SingleFolderMonitor(std::string root_folder, std::string folder) : root_folder_{std::move(root_folder)}, - folder_{std::move(folder)} { - -} - -void SingleFolderMonitor::Monitor() { -} - -} diff --git a/producer/event_monitor_producer/src/single_folder_monitor.h b/producer/event_monitor_producer/src/single_folder_monitor.h deleted file mode 100644 index 0a537984d..000000000 --- a/producer/event_monitor_producer/src/single_folder_monitor.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef ASAPO_SINGLE_FOLDER_MONITOR_H -#define ASAPO_SINGLE_FOLDER_MONITOR_H - -#include <string> - -namespace asapo { - -class SingleFolderMonitor { - public: - explicit SingleFolderMonitor(std::string root_folder,std::string folder); - void Monitor(); - private: - std::string root_folder_; - std::string folder_; -}; - -} - -#endif //ASAPO_SINGLE_FOLDER_MONITOR_H diff --git a/producer/event_monitor_producer/src/single_folder_watch_windows.cpp b/producer/event_monitor_producer/src/single_folder_watch_windows.cpp new file mode 100644 index 000000000..e0c3300f4 --- /dev/null +++ b/producer/event_monitor_producer/src/single_folder_watch_windows.cpp @@ -0,0 +1,30 @@ +#include "single_folder_watch_windows.h" + +#include "eventmon_logger.h" +namespace asapo { + +SingleFolderWatch::SingleFolderWatch(std::string root_folder, std::string folder) : watch_io__{new WatchIO()}, + log__{GetDefaultEventMonLogger()}, + root_folder_{std::move(root_folder)}, + folder_{std::move(folder)} + { +} + +Error SingleFolderWatch::Init() { + std::string full_path = this->root_folder_ + kPathSeparator + this->folder_; + Error err; + handle_ = this->watch_io__->Init(full_path.c_str(), &err); + if (err) { + this->log__->Error("cannot add folder watch for "+full_path+": "+err->Explain()); + return err; + } + return nullptr; +} + +void SingleFolderWatch::Watch() { + if (!Init()) { + return; + } +} + +} diff --git a/producer/event_monitor_producer/src/single_folder_watch_windows.h b/producer/event_monitor_producer/src/single_folder_watch_windows.h new file mode 100644 index 000000000..f2fef6262 --- /dev/null +++ b/producer/event_monitor_producer/src/single_folder_watch_windows.h @@ -0,0 +1,26 @@ +#ifndef ASAPO_SINGLE_FOLDER_MONITOR_H +#define ASAPO_SINGLE_FOLDER_MONITOR_H + +#include <string> + +#include "watch_io.h" +#include "logger/logger.h" + +namespace asapo { + +class SingleFolderWatch { + public: + explicit SingleFolderWatch(std::string root_folder,std::string folder); + void Watch(); + std::unique_ptr<WatchIO> watch_io__; + const AbstractLogger* log__; + private: + std::string root_folder_; + std::string folder_; + Error Init(); + HANDLE handle_; +}; + +} + +#endif //ASAPO_SINGLE_FOLDER_MONITOR_H diff --git a/producer/event_monitor_producer/src/system_folder_watch_windows.cpp b/producer/event_monitor_producer/src/system_folder_watch_windows.cpp index 7c9367877..0157164d9 100644 --- a/producer/event_monitor_producer/src/system_folder_watch_windows.cpp +++ b/producer/event_monitor_producer/src/system_folder_watch_windows.cpp @@ -4,7 +4,7 @@ #include <memory> #include "io/io_factory.h" -#include "single_folder_monitor.h" +#include "single_folder_watch_windows.h" namespace asapo { @@ -12,24 +12,15 @@ Error SystemFolderWatch::StartFolderMonitor(const std::string& root_folder, const std::vector<std::string>& monitored_folders) { for (auto& folder:monitored_folders ) { auto thread = io__->NewThread([root_folder, folder] { - auto folder_monitor = std::unique_ptr<SingleFolderMonitor>(new SingleFolderMonitor(root_folder, folder)); - folder_monitor->Monitor(); + auto folder_watch = std::unique_ptr<SingleFolderWatch>(new SingleFolderWatch(root_folder, folder)); + folder_watch->Watch(); }); if (thread) { thread->detach(); } } -/* - HANDLE hDir = CreateFile( - root_folder.c_str(), - FILE_LIST_DIRECTORY, - FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); -*/ + return nullptr; } diff --git a/producer/event_monitor_producer/src/system_folder_watch_windows.h b/producer/event_monitor_producer/src/system_folder_watch_windows.h index b4d936e30..a302b98a9 100644 --- a/producer/event_monitor_producer/src/system_folder_watch_windows.h +++ b/producer/event_monitor_producer/src/system_folder_watch_windows.h @@ -18,8 +18,8 @@ class SystemFolderWatch { SystemFolderWatch(); VIRTUAL Error StartFolderMonitor(const std::string& root_folder, const std::vector<std::string>& monitored_folders); - VIRTUAL FilesToSend GetFileList(Error* err); - std::unique_ptr<IO> io__; + VIRTUAL FilesToSend GetFileList(Error* err); + std::unique_ptr<IO> io__; private: }; diff --git a/producer/event_monitor_producer/src/watch_io.cpp b/producer/event_monitor_producer/src/watch_io.cpp new file mode 100644 index 000000000..d484a95b3 --- /dev/null +++ b/producer/event_monitor_producer/src/watch_io.cpp @@ -0,0 +1,24 @@ +#include "watch_io.h" +#include "io/io_factory.h" +namespace asapo { + +HANDLE WatchIO::Init(const char* folder, Error* err) { + HANDLE hDir = CreateFile( + folder, + FILE_LIST_DIRECTORY, + FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (hDir == INVALID_HANDLE_VALUE ) { + *err = io_->GetLastError(); + } + return hDir; +} + +WatchIO::WatchIO() :io_{GenerateDefaultIO()}{ + +} + +} \ No newline at end of file diff --git a/producer/event_monitor_producer/src/watch_io.h b/producer/event_monitor_producer/src/watch_io.h new file mode 100644 index 000000000..aa60c7ee0 --- /dev/null +++ b/producer/event_monitor_producer/src/watch_io.h @@ -0,0 +1,22 @@ +#ifndef ASAPO_WATCH_IO_H +#define ASAPO_WATCH_IO_H + +#include <windows.h> + +#include "preprocessor/definitions.h" +#include "common/error.h" +#include "io/io.h" + +namespace asapo { + +class WatchIO { + public: + explicit WatchIO(); + VIRTUAL HANDLE Init(const char* folder, Error* err); + private: + std::unique_ptr<IO>io_; +}; + +} + +#endif //ASAPO_WATCH_IO_H diff --git a/producer/event_monitor_producer/unittests/mock_watch_io.h b/producer/event_monitor_producer/unittests/mock_watch_io.h new file mode 100644 index 000000000..dd08c057a --- /dev/null +++ b/producer/event_monitor_producer/unittests/mock_watch_io.h @@ -0,0 +1,26 @@ +#ifndef ASAPO_MOCKSYSTEMFOLDERWATCH_H +#define ASAPO_MOCKSYSTEMFOLDERWATCH_H + +#include <gtest/gtest.h> +#include <gmock/gmock.h> + +#include "../src/watch_io.h" + +namespace asapo { + +class MockWatchIO : public WatchIO { + public: + HANDLE Init(const char* folder, Error* err) override { + ErrorInterface* error = nullptr; + auto handle = Init_t(folder,&error); + err->reset(error); + return handle; + } + + MOCK_METHOD2(Init_t, HANDLE (const char* folder, ErrorInterface** err)); +}; + +} + + +#endif //ASAPO_MOCKSYSTEMFOLDERWATCH_H diff --git a/producer/event_monitor_producer/unittests/test_single_folder_watch_windows.cpp b/producer/event_monitor_producer/unittests/test_single_folder_watch_windows.cpp new file mode 100644 index 000000000..f7887c6f7 --- /dev/null +++ b/producer/event_monitor_producer/unittests/test_single_folder_watch_windows.cpp @@ -0,0 +1,107 @@ +#include <gtest/gtest.h> +#include <gmock/gmock.h> + +#include "../src/single_folder_watch_windows.h" +#include "../src/event_monitor_error.h" +#include "../src/common.h" + +#include "preprocessor/definitions.h" + +#include "unittests/MockIO.h" +#include "unittests/MockLogger.h" + +#include "mock_watch_io.h" + +using ::testing::Return; +using ::testing::_; +using ::testing::DoAll; +using ::testing::SetArgReferee; +using ::testing::SetArgPointee; +using ::testing::Gt; +using ::testing::Eq; +using ::testing::Ne; +using ::testing::Mock; +using ::testing::InSequence; +using ::testing::HasSubstr; +using testing::StrEq; + +using ::asapo::Error; +using ::asapo::ErrorInterface; +using asapo::FilesToSend; +using asapo::SingleFolderWatch; +using asapo::FileInfos; +using asapo::FileInfo; + +namespace { + + +TEST(SingleFolderWatch, Constructor) { + SingleFolderWatch watch{"",""}; + ASSERT_THAT(dynamic_cast<asapo::WatchIO*>(watch.watch_io__.get()), Ne(nullptr)); +} + +FileInfos CreateTestFileInfos() { + FileInfos file_infos; + FileInfo fi; + fi.size = 100; + fi.name = "file1"; + file_infos.push_back(fi); + fi.name = "subfolder/file2"; + file_infos.push_back(fi); + return file_infos; +} + + +class SingleFolderWatchTests : public testing::Test { + public: + Error err; + ::testing::NiceMock<asapo::MockWatchIO> mock_watch_io; + testing::NiceMock<asapo::MockLogger> mock_logger; + std::string expected_root_folder = "c:\\tmp"; + std::string expected_folder{"test1"}; + HANDLE expected_handle = HANDLE(1); + SingleFolderWatch watch{expected_root_folder,expected_folder}; + void SetUp() override { + watch.watch_io__ = std::unique_ptr<asapo::WatchIO> {&mock_watch_io}; + watch.log__ = &mock_logger; + } + void TearDown() override { + watch.watch_io__.release(); + } +}; + + +TEST_F(SingleFolderWatchTests, InitWatchOnWatch) { + EXPECT_CALL(mock_watch_io, Init_t(StrEq(expected_root_folder+asapo::kPathSeparator+expected_folder),_)). + WillOnce(DoAll( + SetArgPointee<1>(nullptr), + Return(expected_handle) + ) + ); + + watch.Watch(); +} + +TEST_F(SingleFolderWatchTests, InitErrorOnWatch) { + EXPECT_CALL(mock_watch_io, Init_t(StrEq(expected_root_folder+asapo::kPathSeparator+expected_folder),_)). + WillOnce(DoAll( + SetArgPointee<1>(asapo::IOErrorTemplates::kFileNotFound.Generate().release()), + Return(INVALID_HANDLE_VALUE) + ) + ); + + EXPECT_CALL(mock_logger, Error(AllOf( + HasSubstr("cannot add"), + HasSubstr(expected_root_folder), + HasSubstr(expected_folder), + HasSubstr("file") + ) + )); + + watch.Watch(); +} + + + + +} \ No newline at end of file -- GitLab