From e6a135273d9a95da710e2b5987910d1243e084fd Mon Sep 17 00:00:00 2001 From: Duncan Mac-Vicar P Date: Fri, 18 Mar 2011 01:14:45 +0100 Subject: - introduce a tmp dir class and rm-rf util function - start a testcase for the folder watcher part --- CMakeLists.txt | 3 ++- src/CMakeLists.txt | 12 ++++++---- src/mirall/fileutils.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++ src/mirall/fileutils.h | 18 ++++++++++++++ src/mirall/folderwatcher.cpp | 37 +++++++++++++++++----------- src/mirall/folderwatcher.h | 8 +++---- src/mirall/inotify.cpp | 3 +-- src/mirall/temporarydir.cpp | 35 +++++++++++++++++++++++++++ src/mirall/temporarydir.h | 24 +++++++++++++++++++ test/CMakeLists.txt | 9 +++++++ test/testfolderwatcher.cpp | 38 +++++++++++++++++++++++++++++ test/testfolderwatcher.h | 27 +++++++++++++++++++++ 12 files changed, 245 insertions(+), 26 deletions(-) create mode 100644 src/mirall/fileutils.cpp create mode 100644 src/mirall/fileutils.h create mode 100644 src/mirall/temporarydir.cpp create mode 100644 src/mirall/temporarydir.h create mode 100644 test/CMakeLists.txt create mode 100644 test/testfolderwatcher.cpp create mode 100644 test/testfolderwatcher.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d27173622..cb0d83eec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 2.8) project(mirall) -find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtXml REQUIRED ) +find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtXml QtTest REQUIRED ) add_subdirectory(src) +add_subdirectory(test) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ea1bec3d8..4bc594057 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,14 +5,18 @@ include(${QT_USE_FILE}) set(mirall_SRCS mirall/application.cpp +mirall/fileutils.cpp mirall/folder.cpp -mirall/gitfolder.cpp mirall/folderwatcher.cpp +mirall/gitfolder.cpp mirall/inotify.cpp -main.cpp) - +mirall/temporarydir.cpp +) qt4_automoc(${mirall_SRCS}) -add_executable(mirall ${mirall_SRCS}) +add_library(mirall_static STATIC ${mirall_SRCS}) + +add_executable(mirall main.cpp) +target_link_libraries(mirall mirall_static) target_link_libraries(mirall ${QT_LIBRARIES}) diff --git a/src/mirall/fileutils.cpp b/src/mirall/fileutils.cpp new file mode 100644 index 000000000..9bdff4f97 --- /dev/null +++ b/src/mirall/fileutils.cpp @@ -0,0 +1,57 @@ +/* +Copyright (c) 2009 John Schember + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE +*/ + +#include "mirall/fileutils.h" + +#include +#include +#include +#include + +namespace Mirall +{ + +bool FileUtils::removeDir(const QString &path) +{ + bool result = true; + QDir dir(path); + + if (dir.exists(path)) { + Q_FOREACH(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) { + if (info.isDir()) { + result = removeDir(info.absoluteFilePath()); + } + else { + result = QFile::remove(info.absoluteFilePath()); + } + + if (!result) { + return result; + } + } + result = dir.rmdir(path); + } + + return result; +} + +} diff --git a/src/mirall/fileutils.h b/src/mirall/fileutils.h new file mode 100644 index 000000000..8ef798175 --- /dev/null +++ b/src/mirall/fileutils.h @@ -0,0 +1,18 @@ + +#ifndef MIRALL_FILEUTILS_H +#define MIRALL_FILEUTILS_H + +#include + +namespace Mirall +{ + +class FileUtils +{ +public: + static bool removeDir(const QString &path); +}; + +} + +#endif diff --git a/src/mirall/folderwatcher.cpp b/src/mirall/folderwatcher.cpp index aa1154dc6..db51cb1f7 100644 --- a/src/mirall/folderwatcher.cpp +++ b/src/mirall/folderwatcher.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -14,9 +13,12 @@ #include "mirall/folderwatcher.h" static const uint32_t standard_event_mask = - IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE | - IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM | - IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR; + IN_MODIFY | IN_ATTRIB | IN_MOVE | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | IN_ISDIR | IN_DONT_FOLLOW; + +// IN_ONESHOT +// IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE | +// IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM | +// IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR; namespace Mirall { @@ -49,26 +51,23 @@ static QStringList subFoldersList(QString folder, FolderWatcher::FolderWatcher(const QString &path, QObject *parent) : QObject(parent) { - _watcher = new QFileSystemWatcher(this); _inotify = new INotify(standard_event_mask); - //_inotify->addPath(path); + _inotify->addPath(path); // watch the path and all subdirectories { QMutexLocker locker(&_mutex); QStringList subfolders(subFoldersList(path, SubFolderRecursive)); - qDebug() << "adding watchers for " << subfolders; + if (! subfolders.empty() ) { + qDebug() << "adding watchers for " << subfolders; - QStringListIterator subfoldersIt(subfolders); - while (subfoldersIt.hasNext()) { - _watcher->addPath(subfoldersIt.next()); - _inotify->addPath(subfoldersIt.next()); + QStringListIterator subfoldersIt(subfolders); + while (subfoldersIt.hasNext()) { + _inotify->addPath(subfoldersIt.next()); + } } - } -// QObject::connect(_watcher, SIGNAL(directoryChanged(const QString &)), -// SLOT(slotDirectoryChanged(const QString &))); QObject::connect(_inotify, SIGNAL(notifyEvent(int, const QString &)), SLOT(slotDirectoryChanged(int, const QString &))); } @@ -78,6 +77,11 @@ FolderWatcher::~FolderWatcher() } +QStringList FolderWatcher::folders() const +{ + return _inotify->directories(); +} + void FolderWatcher::slotDirectoryChanged(int mask, const QString &path) { QMutexLocker locker(&_mutex); @@ -97,6 +101,8 @@ void FolderWatcher::slotDirectoryChanged(int mask, const QString &path) } } + //qDebug() << "Removing " << folder.path(); + QStringListIterator subfoldersIt(subFoldersList(path, SubFolderRecursive)); while (subfoldersIt.hasNext()) { QDir folder (subfoldersIt.next()); @@ -104,6 +110,9 @@ void FolderWatcher::slotDirectoryChanged(int mask, const QString &path) qDebug() << "Adding " << folder.path(); _inotify->addPath(folder.path()); } + else + qDebug() << "discarding " << folder.path(); + // Look if some of the subdirectories disappeared diff --git a/src/mirall/folderwatcher.h b/src/mirall/folderwatcher.h index 830cfabf5..9f7e3c0e7 100644 --- a/src/mirall/folderwatcher.h +++ b/src/mirall/folderwatcher.h @@ -7,9 +7,6 @@ #include #include -#include "mirall/inotify.h" - -class QFileSystemWatcher; class INotify; namespace Mirall { @@ -20,13 +17,14 @@ Q_OBJECT public: FolderWatcher(const QString &path, QObject *parent = 0L); ~FolderWatcher(); + + QStringList folders() const; + signals: void folderChanged(const QString &path); protected slots: - //void slotDirectoryChanged(const QString &path); void slotDirectoryChanged(int mask, const QString &path); private: - QFileSystemWatcher *_watcher; QMutex _mutex; INotify *_inotify; }; diff --git a/src/mirall/inotify.cpp b/src/mirall/inotify.cpp index 57c4e2424..091f7ff4f 100644 --- a/src/mirall/inotify.cpp +++ b/src/mirall/inotify.cpp @@ -50,8 +50,6 @@ void INotify::addPath(const QString &path) qDebug() << path; path.toAscii().constData(); - return; - int wd = inotify_add_watch(s_fd, path.toAscii().constData(), _mask); _wds[path] = wd; @@ -64,6 +62,7 @@ void INotify::removePath(const QString &path) { // Remove the inotify watch. inotify_rm_watch(s_fd, _wds[path]); + _wds.remove(path); } QStringList INotify::directories() const diff --git a/src/mirall/temporarydir.cpp b/src/mirall/temporarydir.cpp new file mode 100644 index 000000000..0a0ac6220 --- /dev/null +++ b/src/mirall/temporarydir.cpp @@ -0,0 +1,35 @@ +#include +#include +#include + +#include + +#include "mirall/temporarydir.h" +#include "mirall/fileutils.h" + +namespace Mirall +{ + +static char dir_template[] = "/tmp/mirall-XXXXXX"; + +TemporaryDir::TemporaryDir() +{ + char *tmp = ::mkdtemp(dir_template); + _path = QString((const char *) tmp); + + //qDebug() << "tmp:" << _path; + //qDebug() << strerror(errno); + +} + +TemporaryDir::~TemporaryDir() +{ + FileUtils::removeDir(_path); +} + +QString TemporaryDir::path() const +{ + return _path; +} + +} diff --git a/src/mirall/temporarydir.h b/src/mirall/temporarydir.h new file mode 100644 index 000000000..c4b414f12 --- /dev/null +++ b/src/mirall/temporarydir.h @@ -0,0 +1,24 @@ + +#ifndef MIRALL_TEMPORARYDIR_H +#define MIRALL_TEMPORARYDIR_H + +#include + +namespace Mirall +{ + +class TemporaryDir +{ +public: + TemporaryDir(); + ~TemporaryDir(); + + QString path() const; + +private: + QString _path; +}; + +} + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 000000000..5c43ca45c --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,9 @@ +include_directories(${CMAKE_SOURCE_DIR}/src) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include(${QT_USE_FILE}) + +qt4_automoc(testfolderwatcher.cpp) +add_executable(testfolderwatcher testfolderwatcher.cpp) +target_link_libraries(testfolderwatcher ${QT_LIBRARIES} mirall_static) + diff --git a/test/testfolderwatcher.cpp b/test/testfolderwatcher.cpp new file mode 100644 index 000000000..8f9092ce3 --- /dev/null +++ b/test/testfolderwatcher.cpp @@ -0,0 +1,38 @@ +#include +#include +#include + +#include +#include + +#include "mirall/inotify.h" +#include "mirall/folderwatcher.h" +#include "mirall/temporarydir.h" +#include "testfolderwatcher.h" + +static char dir_template[] = "/tmp/miralXXXXXX"; + +void TestFolderWatcher::initTestCase() +{ + Mirall::INotify::initialize(); +} + +void TestFolderWatcher::cleanupTestCase() +{ + Mirall::INotify::cleanup(); +} + +void TestFolderWatcher::testFilesAdded() +{ + Mirall::TemporaryDir tmp; + Mirall::FolderWatcher watcher(tmp.path()); + + qDebug() << "Monitored: " << watcher.folders(); + + QDir subdir = QDir(tmp.path() + "/sub1/sub2"); + QVERIFY(subdir.mkpath(tmp.path() + "/sub1/sub2")); + +} + +QTEST_MAIN(TestFolderWatcher) +#include "testfolderwatcher.moc" diff --git a/test/testfolderwatcher.h b/test/testfolderwatcher.h new file mode 100644 index 000000000..7df7a82a4 --- /dev/null +++ b/test/testfolderwatcher.h @@ -0,0 +1,27 @@ + +#ifndef MIRALL_TEST_FOLDERWATCHER_H +#define MIRALL_TEST_FOLDERWATCHER_H + +#include + +class Mirall::FolderWatcher; + +class TestFolderWatcher : public QObject +{ + Q_OBJECT +public: + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void testFilesAdded(); + +private: + Mirall::FolderWatcher *_watcher; +}; + + +#endif + + -- cgit v1.2.3