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