Skip to content
Snippets Groups Projects
Commit 574a02f3 authored by Sergey Yakubov's avatar Sergey Yakubov
Browse files

start unit testing for inotify

parent 204de983
No related branches found
No related tags found
No related merge requests found
......@@ -9,7 +9,7 @@ set(SOURCE_FILES
IF(WIN32)
set(SOURCE_FILES ${SOURCE_FILES} src/system_folder_watch_windows.cpp)
ELSEIF(UNIX)
set(SOURCE_FILES ${SOURCE_FILES} src/system_folder_watch_linux.cpp src/inotify_event.cpp src/inotify_event.h)
set(SOURCE_FILES ${SOURCE_FILES} src/system_folder_watch_linux.cpp src/inotify_event.cpp src/inotify_linux.cpp)
ENDIF(WIN32)
......@@ -53,6 +53,11 @@ set(TEST_SOURCE_FILES
unittests/test_folder_event_detector.cpp
)
IF(UNIX)
set(TEST_SOURCE_FILES ${TEST_SOURCE_FILES} unittests/test_system_folder_watch_linux.cpp)
ENDIF(WIN32)
set(TEST_LIBRARIES "${TARGET_NAME}")
gtest(${TARGET_NAME} "${TEST_SOURCE_FILES}" "${TEST_LIBRARIES}" ${CMAKE_CURRENT_SOURCE_DIR}/src/eventmon_main.cpp)
......
#include "inotify_linux.h"
#include <sys/inotify.h>
namespace asapo {
int Inotify::Init() {
return inotify_init();
}
int Inotify::AddWatch(int fd, const char* name, uint32_t mask) {
return inotify_add_watch(fd, name, mask);
}
int Inotify::DeleteWatch(int fd, int wd) {
return inotify_rm_watch(fd, wd);
}
ssize_t Inotify::Read(int fd, void* buf, size_t nbytes) {
return read(fd, buf, nbytes);
}
}
\ No newline at end of file
#ifndef ASAPO_INOTIFY_H
#define ASAPO_INOTIFY_H
#include <stdint.h>
#include <unistd.h>
#include "preprocessor/definitions.h"
namespace asapo {
class Inotify {
public:
VIRTUAL int Init();
VIRTUAL int AddWatch(int fd, const char* name, uint32_t mask);
VIRTUAL int DeleteWatch(int fd, int wd);
VIRTUAL ssize_t Read(int fd, void* buf, size_t nbytes);
};
}
#endif //ASAPO_INOTIFY_H
......@@ -3,11 +3,12 @@
#include "event_monitor_error.h"
#include "eventmon_logger.h"
#include "io/io_factory.h"
namespace asapo {
Error SystemFolderWatch::AddFolderToWatch(std::string folder) {
int id = inotify_add_watch(watch_fd_, folder.c_str(), kInotifyWatchFlags);
int id = inotify__->AddWatch(watch_fd_, folder.c_str(), kInotifyWatchFlags);
if (id == -1) {
return EventMonitorErrorTemplates::kSystemError.Generate("cannot add watch for " + folder);
}
......@@ -23,7 +24,7 @@ Error SystemFolderWatch::AddFolderAndSubfoldersToWatch(std::string folder) {
if (err) {
return err;
}
auto subdirs = io_-> GetSubDirectories(folder, &err);
auto subdirs = io__-> GetSubDirectories(folder, &err);
if (err) {
return err;
}
......@@ -40,7 +41,7 @@ Error SystemFolderWatch::AddFolderAndSubfoldersToWatch(std::string folder) {
Error SystemFolderWatch::StartFolderMonitor(const std::string& root_folder,
const std::vector<std::string>& monitored_folders) {
watch_fd_ = inotify_init();
watch_fd_ = inotify__->Init();
if (watch_fd_ == -1) {
return EventMonitorErrorTemplates::kSystemError.Generate("cannot initialize inotify");
}
......@@ -93,7 +94,7 @@ Error SystemFolderWatch::ProcessInotifyEvent(const InotifyEvent& event, FileEven
oldpath += std::string("/") + event.Name();
for (auto val = watched_folders_paths_.begin(); val != watched_folders_paths_.end();) {
if ((oldpath.size() <= val->second.size()) && std::equal(oldpath.begin(), oldpath.end(), val->second.begin())) {
inotify_rm_watch(val->first, watch_fd_);
inotify__->DeleteWatch(val->first, watch_fd_);
GetDefaultEventMonLogger()->Debug("removed folder from monitor: " + val->second);
val = watched_folders_paths_.erase(val);
} else {
......@@ -103,7 +104,7 @@ Error SystemFolderWatch::ProcessInotifyEvent(const InotifyEvent& event, FileEven
}
} else {
inotify_rm_watch(it->first, watch_fd_);
inotify__->DeleteWatch(it->first, watch_fd_);
watched_folders_paths_.erase(it);
GetDefaultEventMonLogger()->Debug("removed folder from monitor: " + oldpath);
}
......@@ -130,7 +131,7 @@ Error SystemFolderWatch::ProcessInotifyEvent(const InotifyEvent& event, FileEven
}
Error SystemFolderWatch::ReadInotifyEvents(int* bytes_read) {
*bytes_read = read(watch_fd_, buffer, sizeof(buffer));
*bytes_read = inotify__->Read(watch_fd_, buffer, sizeof(buffer));
if (*bytes_read < 0) {
return EventMonitorErrorTemplates::kSystemError.Generate("read from inotify fd");
}
......@@ -173,5 +174,8 @@ FileEvents SystemFolderWatch::GetFileEventList(Error* err) {
}
return events;
}
SystemFolderWatch::SystemFolderWatch() : io__{GenerateDefaultIO()}, inotify__{new Inotify()} {
}
}
\ No newline at end of file
......@@ -4,16 +4,16 @@
#include <vector>
#include <string>
#include <map>
#include <unistd.h>
#include "common/error.h"
#include "preprocessor/definitions.h"
#include "asapo_producer.h"
#include "common.h"
#include "io/io.h"
#include "io/io_factory.h"
#include <sys/inotify.h>
#include <unistd.h>
#include "inotify_event.h"
#include "inotify_linux.h"
namespace asapo {
......@@ -34,10 +34,12 @@ class SystemFolderWatch {
public:
VIRTUAL Error StartFolderMonitor(const std::string& root_folder, const std::vector<std::string>& monitored_folders);
VIRTUAL FileEvents GetFileEventList(Error* err);
SystemFolderWatch();
std::unique_ptr<IO> io__;
std::unique_ptr<Inotify> inotify__;
private:
Error AddFolderAndSubfoldersToWatch(std::string folder);
Error AddFolderToWatch(std::string folder);
std::unique_ptr<IO> io_{GenerateDefaultIO()};
Error ProcessInotifyEvent(const InotifyEvent& event, FileEvents* file_events);
private:
char buffer[kBufLen] __attribute__ ((aligned(8)));
......
#ifndef ASAPO_MOCKSYSTEMFOLDERWATCH_H
#define ASAPO_MOCKSYSTEMFOLDERWATCH_H
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "../src/inotify_linux.h"
namespace asapo {
class MockInotify : public Inotify {
public:
MOCK_METHOD0(Init, int ());
MOCK_METHOD3(AddWatch, int (int,const char*,uint32_t));
MOCK_METHOD2(DeleteWatch, int (int,int));
MOCK_METHOD3(Read, ssize_t (int,void*,size_t));
};
}
#endif //ASAPO_MOCKSYSTEMFOLDERWATCH_H
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "../src/system_folder_watch_linux.h"
#include "../src/event_monitor_error.h"
#include "../src/common.h"
#include "mock_inotify.h"
#include <unittests/MockIO.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::FileEvents;
using asapo::FileEvent;
using asapo::SystemFolderWatch;
namespace {
TEST(SystemFolderWatch, Constructor) {
SystemFolderWatch watch;
ASSERT_THAT(dynamic_cast<asapo::IO*>(watch.io__.get()), Ne(nullptr));
ASSERT_THAT(dynamic_cast<asapo::Inotify*>(watch.inotify__.get()), Ne(nullptr));
}
class SystemFolderWatchTests : public testing::Test {
public:
Error err;
::testing::NiceMock<asapo::MockInotify> mock_inotify;
::testing::NiceMock<asapo::MockIO> mock_io;
SystemFolderWatch watch{};
std::string expected_root_folder = "/tmp";
std::vector<std::string> expected_folders{"test1", "test2"};
std::vector<std::string> expected_subfolders1{"/tmp/test1/sub11"};
std::vector<std::string> expected_subfolders2{"/tmp/test2/sub21","/tmp/test2/sub22"};
std::vector<std::string> expected_watches{"/tmp/test1", "/tmp/test2","/tmp/test1/sub11","/tmp/test2/sub21","/tmp/test2/sub22"};
int expected_wd = 1;
int expected_fd = 1;
void MockStartMonitoring();
void SetUp() override {
watch.inotify__ = std::unique_ptr<asapo::Inotify> {&mock_inotify};
watch.io__ = std::unique_ptr<asapo::IO> {&mock_io};
}
void TearDown() override {
watch.inotify__.release();
watch.io__.release();
}
};
void SystemFolderWatchTests::MockStartMonitoring() {
EXPECT_CALL(mock_inotify, Init())
.WillOnce(
Return(expected_wd)
);
EXPECT_CALL(mock_io, GetSubDirectories_t(expected_root_folder+"/"+expected_folders[0],_))
.WillOnce(
Return(expected_subfolders1)
);
EXPECT_CALL(mock_io, GetSubDirectories_t(expected_root_folder+"/"+expected_folders[1],_))
.WillOnce(
Return(expected_subfolders2)
);
for (auto& watch : expected_watches) {
EXPECT_CALL(mock_inotify,AddWatch(expected_wd,StrEq(watch),asapo::kInotifyWatchFlags))
.WillOnce(
Return(expected_fd)
);
}
auto err = watch.StartFolderMonitor(expected_root_folder,expected_folders);
ASSERT_THAT(err, Eq(nullptr));
Mock::VerifyAndClearExpectations(&mock_inotify);
}
TEST_F(SystemFolderWatchTests, ErrorInitInotifyStartMonitoring) {
EXPECT_CALL(mock_inotify, Init())
.WillOnce(
Return(-1)
);
auto err = watch.StartFolderMonitor(expected_root_folder,expected_folders);
ASSERT_THAT(err, Eq(asapo::EventMonitorErrorTemplates::kSystemError));
}
TEST_F(SystemFolderWatchTests, OKInitInotifyStartMonitoring) {
MockStartMonitoring();
}
TEST_F(SystemFolderWatchTests, ErrorGetSubdirsStartMonitoring) {
EXPECT_CALL(mock_inotify, Init())
.WillOnce(
Return(expected_wd)
);
EXPECT_CALL(mock_io, GetSubDirectories_t(expected_root_folder+"/"+expected_folders[0],_))
.WillOnce(DoAll(
SetArgPointee<1>(asapo::IOErrorTemplates::kUnknownIOError.Generate().release()),
Return(asapo::SubDirList{}))
);
auto err = watch.StartFolderMonitor(expected_root_folder,expected_folders);
ASSERT_THAT(err, Eq(asapo::EventMonitorErrorTemplates::kSystemError));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment