blob: 92fb516ddf70f8d57d2a1c7b0ea56d23f2c4631c [file] [log] [blame]
Zhenkai Zhud1756272013-02-01 17:02:18 -08001#include "fs-watcher.h"
2#include <boost/make_shared.hpp>
3#include <boost/filesystem.hpp>
4#include <boost/test/unit_test.hpp>
5#include <boost/thread/thread.hpp>
6#include <boost/bind.hpp>
7#include <boost/lexical_cast.hpp>
8#include <fstream>
9#include <set>
10#include <QtGui>
11
12using namespace std;
13using namespace boost;
14namespace fs = boost::filesystem;
15
Alexander Afanasyeva3230632013-02-07 16:24:30 -080016BOOST_AUTO_TEST_SUITE(TestFsWatcher)
Zhenkai Zhud1756272013-02-01 17:02:18 -080017
18void
19onChange(set<string> &files, const fs::path &file)
20{
21 files.insert(file.string());
22}
23
24void
25onDelete(set<string> &files, const fs::path &file)
26{
27 files.erase(file.string());
28}
29
30void create_file( const fs::path & ph, const std::string & contents )
31{
32 std::ofstream f( ph.string().c_str() );
33 if ( !f )
34 {
35 abort();
36 }
37 if ( !contents.empty() )
38 {
39 f << contents;
40 }
41}
42
43void run(fs::path dir, FsWatcher::LocalFile_Change_Callback c, FsWatcher::LocalFile_Change_Callback d)
44{
45 int x = 0;
46 QCoreApplication app (x, 0);
47 FsWatcher watcher (dir.string().c_str(), c, d);
48 app.exec();
49 sleep(100);
50}
51
52BOOST_AUTO_TEST_CASE (TestFsWatcher)
53{
54 fs::path dir = fs::absolute(fs::path("TestFsWatcher"));
55 if (fs::exists(dir))
56 {
57 fs::remove_all(dir);
58 }
59
60 fs::create_directory(dir);
61
62 set<string> files;
63
64 FsWatcher::LocalFile_Change_Callback fileChange = boost::bind(onChange,ref(files), _1);
65 FsWatcher::LocalFile_Change_Callback fileDelete = boost::bind(onDelete, ref(files), _1);
66
67 thread workThread(run, dir, fileChange, fileDelete);
68 //FsWatcher watcher (dir.string().c_str(), fileChange, fileDelete);
69
70 // ============ check create file detection ================
71 create_file(dir / "test.txt", "hello");
72 // have to at least wait 0.5 seconds
73 usleep(600000);
74 // test.txt
75 BOOST_CHECK_EQUAL(files.size(), 1);
76 BOOST_CHECK(files.find("test.txt") != files.end());
77
78 // =========== check create a bunch of files in sub dir =============
79 fs::path subdir = dir / "sub";
80 fs::create_directory(subdir);
81 for (int i = 0; i < 10; i++)
82 {
83 string filename = boost::lexical_cast<string>(i);
84 create_file(subdir / filename.c_str(), boost::lexical_cast<string>(i));
85 }
86 // have to at least wait 0.5 * 2 seconds
87 usleep(1100000);
88 // test.txt
89 // sub/0..9
90 BOOST_CHECK_EQUAL(files.size(), 11);
91 for (int i = 0; i < 10; i++)
92 {
93 string filename = boost::lexical_cast<string>(i);
94 BOOST_CHECK(files.find("sub/" +filename) != files.end());
95 }
96
97 // ============== check copy directory with files to two levels of sub dirs =================
98 fs::create_directory(dir / "sub1");
99 fs::path subdir1 = dir / "sub1" / "sub2";
100 fs::copy_directory(subdir, subdir1);
101 for (int i = 0; i < 5; i++)
102 {
103 string filename = boost::lexical_cast<string>(i);
104 fs::copy_file(subdir / filename.c_str(), subdir1 / filename.c_str());
105 }
106 // have to at least wait 0.5 * 2 seconds
107 usleep(1100000);
108 // test.txt
109 // sub/0..9
110 // sub1/sub2/0..4
111 BOOST_CHECK_EQUAL(files.size(), 16);
112 for (int i = 0; i < 5; i++)
113 {
114 string filename = boost::lexical_cast<string>(i);
115 BOOST_CHECK(files.find("sub1/sub2/" + filename) != files.end());
116 }
117
118 // =============== check remove files =========================
119 for (int i = 0; i < 7; i++)
120 {
121 string filename = boost::lexical_cast<string>(i);
122 fs::remove(subdir / filename.c_str());
123 }
124 usleep(1100000);
125 // test.txt
126 // sub/7..9
127 // sub1/sub2/0..4
128 BOOST_CHECK_EQUAL(files.size(), 9);
129 for (int i = 0; i < 10; i++)
130 {
131 string filename = boost::lexical_cast<string>(i);
132 if (i < 7)
133 BOOST_CHECK(files.find("sub/" + filename) == files.end());
134 else
135 BOOST_CHECK(files.find("sub/" + filename) != files.end());
136 }
137
138 // =================== check remove files again, remove the whole dir this time ===================
139 // before remove check
140 for (int i = 0; i < 5; i++)
141 {
142 string filename = boost::lexical_cast<string>(i);
143 BOOST_CHECK(files.find("sub1/sub2/" + filename) != files.end());
144 }
145 fs::remove_all(subdir1);
146 usleep(1100000);
147 BOOST_CHECK_EQUAL(files.size(), 4);
148 // test.txt
149 // sub/7..9
150 for (int i = 0; i < 5; i++)
151 {
152 string filename = boost::lexical_cast<string>(i);
153 BOOST_CHECK(files.find("sub1/sub2/" + filename) == files.end());
154 }
155
156 // =================== check rename files =======================
157 for (int i = 7; i < 10; i++)
158 {
159 string filename = boost::lexical_cast<string>(i);
160 fs::rename(subdir / filename.c_str(), dir / filename.c_str());
161 }
162 usleep(1100000);
163 // test.txt
164 // 7
165 // 8
166 // 9
167 // sub
168 BOOST_CHECK_EQUAL(files.size(), 4);
169 for (int i = 7; i < 10; i++)
170 {
171 string filename = boost::lexical_cast<string>(i);
172 BOOST_CHECK(files.find("sub/" + filename) == files.end());
173 BOOST_CHECK(files.find(filename) != files.end());
174 }
175
Alexander Afanasyeva3230632013-02-07 16:24:30 -0800176 create_file(dir / "add-removal-check.txt", "add-removal-check");
177 usleep(1200000);
178 BOOST_CHECK (files.find("add-removal-check.txt") != files.end());
Zhenkai Zhud1756272013-02-01 17:02:18 -0800179
Alexander Afanasyeva3230632013-02-07 16:24:30 -0800180 fs::remove (dir / "add-removal-check.txt");
181 usleep(1200000);
182 BOOST_CHECK (files.find("add-removal-check.txt") == files.end());
183
184 create_file(dir / "add-removal-check.txt", "add-removal-check");
185 usleep(1200000);
186 BOOST_CHECK (files.find("add-removal-check.txt") != files.end());
187
188 fs::remove (dir / "add-removal-check.txt");
189 usleep(1200000);
190 BOOST_CHECK (files.find("add-removal-check.txt") == files.end());
191
192 create_file(dir / "add-removal-check.txt", "add-removal-check");
193 usleep(1200000);
194 BOOST_CHECK (files.find("add-removal-check.txt") != files.end());
195
196 fs::remove (dir / "add-removal-check.txt");
197 usleep(1200000);
198 BOOST_CHECK (files.find("add-removal-check.txt") == files.end());
199
200 // cleanup
201 if (fs::exists(dir))
202 {
203 fs::remove_all(dir);
204 }
Zhenkai Zhud1756272013-02-01 17:02:18 -0800205}
206
207BOOST_AUTO_TEST_SUITE_END()