fs-watcher: Switch code to use ndn-cxx
Implementation moved to ndn::chronoshare namespace
Change-Id: I78a7f08dc2aafe7a2d578f78d99c72db7ea414b6
diff --git a/tests/unit-tests/fs-watcher.t.cpp b/tests/integrated-tests/fs-watcher.t.cpp
similarity index 62%
rename from tests/unit-tests/fs-watcher.t.cpp
rename to tests/integrated-tests/fs-watcher.t.cpp
index 22b1838..05f9764 100644
--- a/tests/unit-tests/fs-watcher.t.cpp
+++ b/tests/integrated-tests/fs-watcher.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016, Regents of the University of California.
+ * Copyright (c) 2013-2017, Regents of the University of California.
*
* This file is part of ChronoShare, a decentralized file sharing application over NDN.
*
@@ -17,79 +17,129 @@
*
* See AUTHORS.md for complete list of ChronoShare authors and contributors.
*/
+
#include "fs-watcher.hpp"
+#include "test-common.hpp"
+
#include <boost/bind.hpp>
#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/make_shared.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/thread/thread.hpp>
-#include <QtGui>
#include <fstream>
+#include <iostream>
+#include <thread>
#include <set>
+#include "fs-watcher.t.hpp"
+
using namespace std;
-using namespace boost;
namespace fs = boost::filesystem;
-BOOST_AUTO_TEST_SUITE(TestFsWatcher)
+_LOG_INIT(Test.FSWatcher);
-void
-onChange(set<string>& files, const fs::path& file)
+namespace ndn {
+namespace chronoshare {
+namespace tests {
+
+fsWatcherApp::fsWatcherApp(int& argc, char** argv)
+ : QCoreApplication(argc, argv)
{
- cerr << "onChange called" << endl;
- files.insert(file.string());
+ connect(this, SIGNAL(stopApp()), this, SLOT(quit()), Qt::QueuedConnection);
}
-void
-onDelete(set<string>& files, const fs::path& file)
-{
- files.erase(file.string());
-}
+fsWatcherApp::~fsWatcherApp() = default;
-void
-create_file(const fs::path& ph, const std::string& contents)
+class TestFSWatcherFixture : public IdentityManagementFixture
{
- std::ofstream f(ph.string().c_str());
- if (!f) {
- abort();
+public:
+ TestFSWatcherFixture()
+ : dir(fs::path(UNIT_TEST_CONFIG_PATH) / "TestFsWatcher")
+ , argc(0)
+ {
+ if (fs::exists(dir)) {
+ fs::remove_all(dir);
+ }
+
+ fs::create_directory(dir);
}
- if (!contents.empty()) {
- f << contents;
- }
-}
-void
-run(fs::path dir, FsWatcher::LocalFile_Change_Callback c, FsWatcher::LocalFile_Change_Callback d)
-{
- int x = 0;
- QCoreApplication app(x, 0);
- FsWatcher watcher(dir.string().c_str(), c, d);
- app.exec();
- sleep(100);
-}
+ ~TestFSWatcherFixture(){
+ // cleanup
+ if (fs::exists(dir)) {
+ _LOG_DEBUG("clean all");
+ fs::remove_all(dir);
+ }
+ }
+
+ void
+ advanceClocks(std::chrono::seconds delay)
+ {
+ std::chrono::milliseconds step = delay;
+ step /= 50;
+ for (int i = 0; i < 50; ++i) {
+ std::this_thread::sleep_for(step);
+ m_io.poll();
+ m_io.reset();
+ }
+ }
+
+ void
+ onChange(set<string>& files, const fs::path& file)
+ {
+ _LOG_DEBUG("on change, file: " << file);
+ files.insert(file.string());
+ }
+
+ void
+ onDelete(set<string>& files, const fs::path& file)
+ {
+ _LOG_DEBUG("on delete, file: " << file);
+ files.erase(file.string());
+ }
+
+ void
+ create_file(const fs::path& ph, const std::string& contents)
+ {
+ std::ofstream f(ph.string().c_str());
+ if (!f) {
+ abort();
+ }
+ if (!contents.empty()) {
+ f << contents;
+ }
+ }
+
+ void
+ run()
+ {
+ app = new fsWatcherApp(argc, nullptr);
+ new FsWatcher(m_io, dir.string().c_str(),
+ std::bind(&TestFSWatcherFixture::onChange, this, std::ref(files), _1),
+ std::bind(&TestFSWatcherFixture::onDelete, this, std::ref(files), _1),
+ app);
+ app->exec();
+ }
+
+public:
+ fs::path dir;
+ set<string> files;
+ int argc;
+ fsWatcherApp* app;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestFsWatcher, TestFSWatcherFixture)
BOOST_AUTO_TEST_CASE(TestFsWatcher)
{
- fs::path dir = fs::absolute(fs::path("TestFsWatcher"));
- if (fs::exists(dir)) {
- fs::remove_all(dir);
- }
-
- fs::create_directory(dir);
-
- set<string> files;
-
- FsWatcher::LocalFile_Change_Callback fileChange = boost::bind(onChange, ref(files), _1);
- FsWatcher::LocalFile_Change_Callback fileDelete = boost::bind(onDelete, ref(files), _1);
-
- thread workThread(run, dir, fileChange, fileDelete);
- //FsWatcher watcher (dir.string().c_str(), fileChange, fileDelete);
+ std::thread workThread(boost::bind(&TestFSWatcherFixture::run, this));
+ this->advanceClocks(std::chrono::seconds(2));
// ============ check create file detection ================
create_file(dir / "test.txt", "hello");
- // have to at least wait 0.5 seconds
- usleep(1000000);
+ this->advanceClocks(std::chrono::seconds(2));
// test.txt
BOOST_CHECK_EQUAL(files.size(), 1);
BOOST_CHECK(files.find("test.txt") != files.end());
@@ -101,8 +151,7 @@
string filename = boost::lexical_cast<string>(i);
create_file(subdir / filename.c_str(), boost::lexical_cast<string>(i));
}
- // have to at least wait 0.5 * 2 seconds
- usleep(1100000);
+ this->advanceClocks(std::chrono::seconds(2));
// test.txt
// sub/0..9
BOOST_CHECK_EQUAL(files.size(), 11);
@@ -117,10 +166,9 @@
fs::copy_directory(subdir, subdir1);
for (int i = 0; i < 5; i++) {
string filename = boost::lexical_cast<string>(i);
- fs::copy_file(subdir / filename.c_str(), subdir1 / filename.c_str());
+ fs::copy(subdir / filename.c_str(), subdir1 / filename.c_str());
}
- // have to at least wait 0.5 * 2 seconds
- usleep(1100000);
+ this->advanceClocks(std::chrono::seconds(2));
// test.txt
// sub/0..9
// sub1/sub2/0..4
@@ -135,7 +183,7 @@
string filename = boost::lexical_cast<string>(i);
fs::remove(subdir / filename.c_str());
}
- usleep(1100000);
+ this->advanceClocks(std::chrono::seconds(2));
// test.txt
// sub/7..9
// sub1/sub2/0..4
@@ -148,14 +196,15 @@
BOOST_CHECK(files.find("sub/" + filename) != files.end());
}
- // =================== check remove files again, remove the whole dir this time ===================
+ // =================== check remove files again, remove the whole dir this time
+ // ===================
// before remove check
for (int i = 0; i < 5; i++) {
string filename = boost::lexical_cast<string>(i);
BOOST_CHECK(files.find("sub1/sub2/" + filename) != files.end());
}
fs::remove_all(subdir1);
- usleep(1100000);
+ this->advanceClocks(std::chrono::seconds(2));
BOOST_CHECK_EQUAL(files.size(), 4);
// test.txt
// sub/7..9
@@ -169,7 +218,7 @@
string filename = boost::lexical_cast<string>(i);
fs::rename(subdir / filename.c_str(), dir / filename.c_str());
}
- usleep(1100000);
+ this->advanceClocks(std::chrono::seconds(2));
// test.txt
// 7
// 8
@@ -183,33 +232,36 @@
}
create_file(dir / "add-removal-check.txt", "add-removal-check");
- usleep(1200000);
+ this->advanceClocks(std::chrono::seconds(2));
BOOST_CHECK(files.find("add-removal-check.txt") != files.end());
fs::remove(dir / "add-removal-check.txt");
- usleep(1200000);
+ this->advanceClocks(std::chrono::seconds(2));
BOOST_CHECK(files.find("add-removal-check.txt") == files.end());
create_file(dir / "add-removal-check.txt", "add-removal-check");
- usleep(1200000);
+ this->advanceClocks(std::chrono::seconds(2));
BOOST_CHECK(files.find("add-removal-check.txt") != files.end());
fs::remove(dir / "add-removal-check.txt");
- usleep(1200000);
+ this->advanceClocks(std::chrono::seconds(2));
BOOST_CHECK(files.find("add-removal-check.txt") == files.end());
create_file(dir / "add-removal-check.txt", "add-removal-check");
- usleep(1200000);
+ this->advanceClocks(std::chrono::seconds(2));
BOOST_CHECK(files.find("add-removal-check.txt") != files.end());
fs::remove(dir / "add-removal-check.txt");
- usleep(1200000);
+ this->advanceClocks(std::chrono::seconds(2));
BOOST_CHECK(files.find("add-removal-check.txt") == files.end());
- // cleanup
- if (fs::exists(dir)) {
- fs::remove_all(dir);
- }
+ emit app->stopApp();
+
+ workThread.join();
}
BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace chronoshare
+} // namespace ndn
diff --git a/tests/integrated-tests/fs-watcher.t.hpp b/tests/integrated-tests/fs-watcher.t.hpp
new file mode 100644
index 0000000..40c524b
--- /dev/null
+++ b/tests/integrated-tests/fs-watcher.t.hpp
@@ -0,0 +1,42 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2017, Regents of the University of California.
+ *
+ * This file is part of ChronoShare, a decentralized file sharing application over NDN.
+ *
+ * ChronoShare is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * ChronoShare is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License along with
+ * ChronoShare, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ChronoShare authors and contributors.
+ */
+
+#include <QtWidgets>
+
+namespace ndn {
+namespace chronoshare {
+namespace tests {
+
+class fsWatcherApp : public QCoreApplication
+{
+Q_OBJECT
+
+signals:
+ void
+ stopApp();
+
+public:
+ fsWatcherApp(int& argc, char** argv);
+ ~fsWatcherApp();
+};
+
+} // namespace tests
+} // namespace chronoshare
+} // namespace ndn
diff --git a/tests/unit-tests/fs-watcher-delay.t.cpp b/tests/unit-tests/fs-watcher-delay.t.cpp
deleted file mode 100644
index 0ccd5cc..0000000
--- a/tests/unit-tests/fs-watcher-delay.t.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016, Regents of the University of California.
- *
- * This file is part of ChronoShare, a decentralized file sharing application over NDN.
- *
- * ChronoShare is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation, either
- * version 3 of the License, or (at your option) any later version.
- *
- * ChronoShare is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received copies of the GNU General Public License along with
- * ChronoShare, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ChronoShare authors and contributors.
- */
-
-#include "fs-watcher.h"
-#include <boost/bind.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/filesystem/fstream.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/test/unit_test.hpp>
-#include <boost/thread/thread.hpp>
-#include <QtGui>
-#include <fstream>
-#include <iostream>
-#include <set>
-
-using namespace std;
-using namespace boost;
-namespace fs = boost::filesystem;
-
-BOOST_AUTO_TEST_SUITE(TestFsWatcherDelay)
-
-void
-onChange(const fs::path& file)
-{
- cerr << "onChange called" << endl;
-}
-
-void
-onDelete(const fs::path& file)
-{
- cerr << "onDelete called" << endl;
-}
-
-void
-run(fs::path dir, FsWatcher::LocalFile_Change_Callback c, FsWatcher::LocalFile_Change_Callback d)
-{
- int x = 0;
- QCoreApplication app(x, 0);
- FsWatcher watcher(dir.string().c_str(), c, d);
- app.exec();
- sleep(100);
-}
-
-void
-SlowWrite(fs::path& file)
-{
- fs::ofstream off(file, std::ios::out);
-
- for (int i = 0; i < 10; i++) {
- off << i << endl;
- usleep(200000);
- }
-}
-
-BOOST_AUTO_TEST_CASE(TestFsWatcherDelay)
-{
- fs::path dir = fs::absolute(fs::path("TestFsWatcher"));
- if (fs::exists(dir)) {
- fs::remove_all(dir);
- }
-
- fs::create_directory(dir);
-
- FsWatcher::LocalFile_Change_Callback fileChange = boost::bind(onChange, _1);
- FsWatcher::LocalFile_Change_Callback fileDelete = boost::bind(onDelete, _1);
-
- fs::path file = dir / "test.text";
-
- thread watcherThread(run, dir, fileChange, fileDelete);
-
- thread writeThread(SlowWrite, file);
-
-
- usleep(10000000);
-
- // cleanup
- if (fs::exists(dir)) {
- fs::remove_all(dir);
- }
-
- usleep(1000000);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/wscript b/tests/wscript
index 3cb795b..e900761 100644
--- a/tests/wscript
+++ b/tests/wscript
@@ -8,32 +8,32 @@
if not bld.env['WITH_TESTS']:
return
- Logs.error("Many unit tests are temporary disabled")
-
bld(features='cxx',
- target='unit-tests-main',
- name='unit-tests-main',
- source='main.cpp',
- use='BOOST',
+ target='tests-base',
+ name='tests-base',
+ source=bld.path.ant_glob(['*.cpp'], excl='main.cpp'),
+ use='core-objects',
includes='.. .',
- defines=['BOOST_TEST_MODULE=ChronoShare Unit Tests'])
+ defines='UNIT_TEST_CONFIG_PATH=\"%s/tmp-files/\"' % (bld.bldnode)
+ )
- unit_tests = bld.program(
- target='../unit-tests',
- features='cxx cxxprogram',
- source=bld.path.ant_glob(['*.cpp',
- 'unit-tests/dummy-forwarder.cpp',
- 'unit-tests/sync-*.t.cpp',
- 'unit-tests/action-log.t.cpp',
- 'unit-tests/object-*.t.cpp',
- 'unit-tests/fetch*.t.cpp',
- 'unit-tests/serve-and-fetch.t.cpp',
- 'unit-tests/content-server.t.cpp',
- 'unit-tests/dispatcher.t.cpp',
- ],
- excl=['main.cpp']),
- use='chronoshare core-objects unit-tests-main',
+ for module, name in {"unit": "Unit Tests",
+ "integrated": "Integrated Tests"}.items():
+ bld(target='%s-tests-main' % module,
+ name='%s-tests-main' % module,
+ features='cxx',
+ use='core-objects BOOST',
+ source='main.cpp',
+ defines=['BOOST_TEST_MODULE=%s' % name]
+ )
+
+ tests = bld.program(
+ target='../%s-tests' % module,
+ features='qt5 cxx cxxprogram',
+ moc='' if module == 'unit' else 'integrated-tests/fs-watcher.t.hpp',
+ source=bld.path.ant_glob(['%s-tests/*.cpp' % module]),
+ use='chronoshare core-objects fs-watcher tests-base %s-tests-main QT5CORE QT5WIDGETS' % module,
install_path=None,
- defines='UNIT_TEST_CONFIG_PATH=\"%s/tmp-files/\"' % (bld.bldnode),
+ defines=['UNIT_TEST_CONFIG_PATH=\"%s/tmp-files/\"' % (bld.bldnode)],
includes='.. ../src .',
- )
+ )