blob: 415f24d193b2eb5ff056244433b939a274ae4a50 [file] [log] [blame]
Yukai Tu73287f52017-02-06 15:46:40 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2017 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21#define BOOST_TEST_MAIN 1
22#define BOOST_TEST_DYN_LINK 1
23#define BOOST_TEST_MODULE ChronoShare Integrated Tests (ChronoShare)
24
25#include "gui/chronosharegui.hpp"
26#include "test-common.hpp"
27#include "dummy-forwarder.hpp"
28
29#include <boost/make_shared.hpp>
30#include <boost/test/unit_test.hpp>
31#include <boost/bind.hpp>
32#include <boost/filesystem.hpp>
33#include <boost/filesystem/fstream.hpp>
34#include <boost/lexical_cast.hpp>
35#include <thread>
36#include <chrono>
37
38namespace ndn {
39namespace chronoshare {
40namespace tests {
41
42using namespace std;
43namespace fs = boost::filesystem;
44
45_LOG_INIT(Test.Integrated.ChronoShare);
46
47class ChronoShareFixture : public IdentityManagementFixture
48{
49public:
50 ChronoShareFixture()
51 : forwarder(m_io, m_keyChain)
52 , folder("sharefolder")
53 , dir1(fs::path(fs::path(UNIT_TEST_CONFIG_PATH) / "sharefolder1"))
54 , dir2(fs::path(fs::path(UNIT_TEST_CONFIG_PATH) / "sharefolder2"))
55 , argc(0)
56 {
57
58 if (fs::exists(dir1)) {
59 fs::remove_all(dir1);
60 }
61
62 if (fs::exists(dir2)) {
63 fs::remove_all(dir2);
64 }
65
66 fs::create_directory(dir1);
67 fs::create_directory(dir2);
68 }
69
70 ~ChronoShareFixture()
71 {
72 //delete app;
73 // cleanup
74 if (fs::exists(dir1)) {
75 fs::remove_all(dir1);
76 }
77
78 // cleanup
79 if (fs::exists(dir2)) {
80 fs::remove_all(dir2);
81 }
82 }
83
84 void
85 advanceClocks(std::chrono::seconds delay)
86 {
87 std::chrono::milliseconds step = delay;
88 step /= 50;
89 for (int i = 0; i < 50; ++i) {
90 std::this_thread::sleep_for(step);
91 m_io.poll();
92 m_io.reset();
93 }
94 }
95
96 void
97 create_file(const fs::path& ph, const std::string& contents)
98 {
99 std::ofstream f(ph.string().c_str());
100 if (!f) {
101 abort();
102 }
103 if (!contents.empty()) {
104 f << contents;
105 }
106 }
107
108 void
109 run()
110 {
111 std::this_thread::sleep_for(std::chrono::seconds(5));
112
113 _LOG_DEBUG("======created files===========");
114 create_file(dir1 / folder / "test.txt", "hello");
115
116 std::this_thread::sleep_for(std::chrono::seconds(10));
117
118
119 BOOST_REQUIRE_MESSAGE(fs::exists(dir2 / folder / "test.txt"), "user1 failed to notify user2 about test.txt");
120 BOOST_CHECK_EQUAL(fs::file_size(dir1 / folder / "test.txt"), fs::file_size(dir2 / folder / "test.txt"));
121
122
123 fs::path subdir1 = dir1 / folder / "sub";
124 fs::path subdir2 = dir2 / folder / "sub";
125 fs::create_directory(subdir1);
126 for (int i = 0; i < 10; i++) {
127 string filename = boost::lexical_cast<string>(i);
128 create_file(subdir1 / filename.c_str(), boost::lexical_cast<string>(i));
129 }
130
131 std::this_thread::sleep_for(std::chrono::seconds(10));
132 for (int i = 0; i < 10; i++) {
133 string filename = boost::lexical_cast<string>(i);
134 BOOST_REQUIRE_MESSAGE(fs::exists(subdir2 / filename), "user1 failed to notify user2 about"<< filename);
135 }
136
137 //=========check copy file to sub directory==========
138 fs::create_directory(dir1 / folder / "sub1");
139 fs::path subsubdir1 = dir1 / folder / "sub1" / "sub2";
140 fs::path subsubdir2 = dir2 / folder / "sub1" / "sub2";
141 fs::copy_directory(subdir1, subsubdir1);
142 for (int i = 0; i < 5; i++) {
143 string filename = boost::lexical_cast<string>(i);
144 fs::copy(subdir1 / filename.c_str(), subsubdir1 / filename.c_str());
145 }
146
147 std::this_thread::sleep_for(std::chrono::seconds(10));
148 // test.txt
149 // sub/0..9
150 // sub1/sub2/0..4
151 for (int i = 0; i < 5; i++) {
152 string filename = boost::lexical_cast<string>(i);
153 BOOST_REQUIRE_MESSAGE(fs::exists(subsubdir2 / filename), "user1 failed to notify user2 about"<< filename);
154 }
155
156 // =============== check remove files =========================
157 for (int i = 0; i < 7; i++) {
158 string filename = boost::lexical_cast<string>(i);
159 fs::remove(subdir1 / filename.c_str());
160 }
161
162 std::this_thread::sleep_for(std::chrono::seconds(10));
163 // test.txt
164 // sub/7..9
165 // sub1/sub2/0..4
166 for (int i = 0; i < 10; i++) {
167 string filename = boost::lexical_cast<string>(i);
168 if (i < 7)
169 BOOST_REQUIRE_MESSAGE(!fs::exists(subdir2 / filename), "user1 failed to notify user2 about"<< filename);
170 else
171 BOOST_REQUIRE_MESSAGE(fs::exists(subdir2 / filename), "user1 failed to notify user2 about"<< filename);
172 }
173
174 // =================== check remove files again, remove the whole dir this time
175 // ===================
176 // before remove check
177 for (int i = 0; i < 5; i++) {
178 string filename = boost::lexical_cast<string>(i);
179 BOOST_REQUIRE_MESSAGE(fs::exists(subsubdir2 / filename), "user1 failed to notify user2 about"<< filename);
180 }
181 fs::remove_all(subsubdir1);
182
183 std::this_thread::sleep_for(std::chrono::seconds(10));
184 // test.txt
185 // sub/7..9
186 BOOST_REQUIRE_MESSAGE(!fs::exists(subsubdir2), "user1 failed to notify user2 about sub1/sub2");
187
188 // =================== check rename files =======================
189 for (int i = 7; i < 10; i++) {
190 string filename = boost::lexical_cast<string>(i);
191 fs::rename(subdir1 / filename.c_str(), dir1 / folder / filename.c_str());
192 }
193 std::this_thread::sleep_for(std::chrono::seconds(10));
194 // test.txt
195 // 7
196 // 8
197 // 9
198 // sub
199 for (int i = 7; i < 10; i++) {
200 string filename = boost::lexical_cast<string>(i);
201
202 BOOST_REQUIRE_MESSAGE(!fs::exists(subdir2 / filename), "user1 failed to notify user2 about"<< filename);
203 BOOST_REQUIRE_MESSAGE(fs::exists(dir2 / folder / filename), "user1 failed to notify user2 about"<< filename);
204 }
205
206 create_file(dir1 / folder / "add-removal-check.txt", "add-removal-check");
207 std::this_thread::sleep_for(std::chrono::seconds(4));
208 BOOST_REQUIRE_MESSAGE(fs::exists(dir2 / folder / "add-removal-check.txt"),
209 "user1 failed to notify user2 about add-removal-check.txt");
210
211 fs::remove(dir1 / folder / "add-removal-check.txt");
212 std::this_thread::sleep_for(std::chrono::seconds(4));
213 BOOST_REQUIRE_MESSAGE(!fs::exists(dir2 / folder / "add-removal-check.txt"),
214 "user1 failed to notify user2 about add-removal-check.txt");
215
216 create_file(dir1 / folder / "add-removal-check.txt", "add-removal-check");
217 std::this_thread::sleep_for(std::chrono::seconds(4));
218 BOOST_REQUIRE_MESSAGE(fs::exists(dir2 / folder / "add-removal-check.txt"),
219 "user1 failed to notify user2 about add-removal-check.txt");
220
221 fs::remove(dir1 / folder / "add-removal-check.txt");
222 std::this_thread::sleep_for(std::chrono::seconds(4));
223 BOOST_REQUIRE_MESSAGE(!fs::exists(dir2 / folder / "add-removal-check.txt"),
224 "user1 failed to notify user2 about add-removal-check.txt");
225
226 create_file(dir1 / folder / "add-removal-check.txt", "add-removal-check");
227 std::this_thread::sleep_for(std::chrono::seconds(4));
228 BOOST_REQUIRE_MESSAGE(fs::exists(dir2 / folder / "add-removal-check.txt"),
229 "user1 failed to notify user2 about add-removal-check.txt");
230
231 fs::remove(dir1 / folder / "add-removal-check.txt");
232 std::this_thread::sleep_for(std::chrono::seconds(4));
233 BOOST_REQUIRE_MESSAGE(!fs::exists(dir2 / folder / "add-removal-check.txt"),
234 "user1 failed to notify user2 about add-removal-check.txt");
235
236 _LOG_DEBUG("======finish thread===========");
237 }
238
239public:
240 DummyForwarder forwarder;
241 std::string folder;
242 fs::path dir1;
243 fs::path dir2;
244
245 int argc;
246 //TestApp* app;
247};
248
249BOOST_FIXTURE_TEST_SUITE(TestChronoShare, ChronoShareFixture)
250
251BOOST_AUTO_TEST_CASE(Chronoshare)
252{
253 QApplication app(argc, nullptr);
254
255 // do not quit when last window closes
256 app.setQuitOnLastWindowClosed(false);
257 // invoke gui
258 ndn::chronoshare::ChronoShareGui gui1(QString::fromStdString(dir1.generic_string()),
259 QString::fromStdString("user1"),
260 QString::fromStdString("sharefolder"));
261
262 // invoke gui
263 ndn::chronoshare::ChronoShareGui gui2(QString::fromStdString(dir2.generic_string()),
264 QString::fromStdString("user2"),
265 QString::fromStdString("sharefolder"));
266
267 QTimer::singleShot(95000, &app, SLOT(quit()));
268
269 _LOG_DEBUG("run thread");
270 std::thread workThread(boost::bind(&ChronoShareFixture::run, this));
271
272 app.exec();
273 workThread.join();
274 _LOG_DEBUG("thread finished");
275}
276
277BOOST_AUTO_TEST_SUITE_END()
278
279} // namespace tests
280} // namespace chronoshare
281} // namespace ndn