blob: dc7e2ef4ae450875d488975aba63673464eb8b57 [file] [log] [blame]
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -06003 * Copyright (c) 2012-2018 University of California, Los Angeles
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -08004 *
5 * This file is part of ChronoSync, synchronization library for distributed realtime
6 * applications for NDN.
7 *
8 * ChronoSync is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation, either
10 * version 3 of the License, or (at your option) any later version.
11 *
12 * ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "logic.hpp"
Ashlesh Gawande08784d42017-09-06 23:40:21 -050021
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080022#include "boost-test.hpp"
Ashlesh Gawande08784d42017-09-06 23:40:21 -050023#include "../identity-management-fixture.hpp"
24
25#include "dummy-forwarder.hpp"
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080026
27namespace chronosync {
28namespace test {
29
30using std::vector;
Ashlesh Gawande08784d42017-09-06 23:40:21 -050031using ndn::chronosync::DummyForwarder;
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080032
33class Handler
34{
35public:
Ashlesh Gawande08784d42017-09-06 23:40:21 -050036 Handler(ndn::Face& face,
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080037 const Name& syncPrefix,
38 const Name& userPrefix)
39 : logic(face,
40 syncPrefix,
41 userPrefix,
42 bind(&Handler::onUpdate, this, _1))
43 {
44 }
45
46 void
47 onUpdate(const vector<MissingDataInfo>& v)
48 {
49 for (size_t i = 0; i < v.size(); i++) {
50 update(v[i].session, v[i].high, v[i].low);
51 }
52 }
53
54 void
55 update(const Name& p, const SeqNo& high, const SeqNo& low)
56 {
57 map[p] = high;
58 }
59
60 void
61 updateSeqNo(const SeqNo& seqNo)
62 {
63 logic.updateSeqNo(seqNo);
64 }
65
Junxiao Shi0c7f56a2016-07-14 15:27:14 +000066public:
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080067 Logic logic;
68 std::map<Name, SeqNo> map;
69};
70
Ashlesh Gawande08784d42017-09-06 23:40:21 -050071class LogicFixture : public ndn::tests::IdentityManagementTimeFixture
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080072{
73public:
74 LogicFixture()
75 : syncPrefix("/ndn/broadcast/sync")
Ashlesh Gawande08784d42017-09-06 23:40:21 -050076 , fw(io, m_keyChain)
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080077 {
78 syncPrefix.appendVersion();
79 userPrefix[0] = Name("/user0");
80 userPrefix[1] = Name("/user1");
81 userPrefix[2] = Name("/user2");
Sonu Mishra4d3a2e02017-01-18 20:27:51 -080082 userPrefix[3] = Name("/user3");
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080083 }
84
Junxiao Shi0c7f56a2016-07-14 15:27:14 +000085public:
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080086 Name syncPrefix;
Sonu Mishra4d3a2e02017-01-18 20:27:51 -080087 Name userPrefix[4];
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080088
Ashlesh Gawande08784d42017-09-06 23:40:21 -050089 DummyForwarder fw;
90 // std::unique_ptr<DummyClientFace> faces[4];
Sonu Mishra4d3a2e02017-01-18 20:27:51 -080091 shared_ptr<Handler> handler[4];
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080092
Ashlesh Gawande08784d42017-09-06 23:40:21 -050093 // size_t readInterestOffset[4];
94 // size_t readDataOffset[4];
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -080095};
96
97BOOST_FIXTURE_TEST_SUITE(LogicTests, LogicFixture)
98
99void
100onUpdate(const vector<MissingDataInfo>& v)
101{
102}
103
104BOOST_AUTO_TEST_CASE(Constructor)
105{
106 Name syncPrefix("/ndn/broadcast/sync");
107 Name userPrefix("/user");
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500108 ndn::util::DummyClientFace face(io, {true, true});
109 BOOST_REQUIRE_NO_THROW(Logic(face, syncPrefix, userPrefix, bind(onUpdate, _1)));
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800110}
111
112BOOST_AUTO_TEST_CASE(TwoBasic)
113{
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500114 handler[0] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[0]);
115 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800116
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500117 handler[1] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[1]);
118 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800119
120 handler[0]->updateSeqNo(1);
121
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500122 advanceClocks(ndn::time::milliseconds(10), 100);
123
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800124 BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1);
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500125 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800126
127 handler[0]->updateSeqNo(2);
128
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500129 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800130 BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 2);
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500131 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800132
133 handler[1]->updateSeqNo(2);
134
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500135 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800136 BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2);
137}
138
139BOOST_AUTO_TEST_CASE(ThreeBasic)
140{
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500141 handler[0] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[0]);
142 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800143
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500144 handler[1] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[1]);
145 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800146
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500147 handler[2] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[2]);
148 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800149
150 handler[0]->updateSeqNo(1);
151
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500152 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800153 BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1);
154 BOOST_CHECK_EQUAL(handler[2]->map[handler[0]->logic.getSessionName()], 1);
155
156 handler[1]->updateSeqNo(2);
157
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500158 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800159 BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2);
160 BOOST_CHECK_EQUAL(handler[2]->map[handler[1]->logic.getSessionName()], 2);
161
162 handler[2]->updateSeqNo(4);
163
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500164 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800165 BOOST_CHECK_EQUAL(handler[0]->map[handler[2]->logic.getSessionName()], 4);
166 BOOST_CHECK_EQUAL(handler[1]->map[handler[2]->logic.getSessionName()], 4);
167}
168
169BOOST_AUTO_TEST_CASE(ResetRecover)
170{
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500171 handler[0] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[0]);
172 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800173
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500174 handler[1] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[1]);
175 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800176
177 handler[0]->updateSeqNo(1);
178
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500179 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800180 BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1);
181
182 handler[1]->updateSeqNo(2);
183
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500184 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800185 BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2);
186
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500187 advanceClocks(ndn::time::milliseconds(10), 100);
188 handler[2] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[2]);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800189
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500190 advanceClocks(ndn::time::milliseconds(10), 100);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800191 BOOST_CHECK_EQUAL(handler[2]->map[handler[0]->logic.getSessionName()], 1);
192 BOOST_CHECK_EQUAL(handler[2]->map[handler[1]->logic.getSessionName()], 2);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800193
194 handler[2]->updateSeqNo(4);
195
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500196 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800197 BOOST_CHECK_EQUAL(handler[1]->map[handler[2]->logic.getSessionName()], 4);
198 BOOST_CHECK_EQUAL(handler[0]->map[handler[2]->logic.getSessionName()], 4);
199}
200
201BOOST_AUTO_TEST_CASE(RecoverConflict)
202{
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500203 handler[0] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[0]);
204 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800205
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500206 handler[1] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[1]);
207 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800208
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500209 handler[2] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[2]);
210 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800211
212 handler[0]->updateSeqNo(1);
213
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500214 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800215 BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1);
216 BOOST_CHECK_EQUAL(handler[2]->map[handler[0]->logic.getSessionName()], 1);
217
218 handler[1]->updateSeqNo(2);
219 handler[2]->updateSeqNo(4);
220
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500221 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800222 BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2);
223 BOOST_CHECK_EQUAL(handler[0]->map[handler[2]->logic.getSessionName()], 4);
224 BOOST_CHECK_EQUAL(handler[1]->map[handler[2]->logic.getSessionName()], 4);
225 BOOST_CHECK_EQUAL(handler[2]->map[handler[1]->logic.getSessionName()], 2);
226}
227
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800228BOOST_AUTO_TEST_CASE(PartitionRecover)
229{
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500230 handler[0] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[0]);
231 advanceClocks(ndn::time::milliseconds(10), 100);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800232
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500233 handler[1] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[1]);
234 advanceClocks(ndn::time::milliseconds(10), 100);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800235
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500236 handler[2] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[2]);
237 advanceClocks(ndn::time::milliseconds(10), 100);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800238
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500239 handler[3] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[3]);
240 advanceClocks(ndn::time::milliseconds(10), 100);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800241
242 handler[0]->updateSeqNo(1);
243
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500244 advanceClocks(ndn::time::milliseconds(10), 100);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800245 BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1);
246 BOOST_CHECK_EQUAL(handler[2]->map[handler[0]->logic.getSessionName()], 1);
247 BOOST_CHECK_EQUAL(handler[3]->map[handler[0]->logic.getSessionName()], 1);
248
249 handler[2]->updateSeqNo(2);
250
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500251 advanceClocks(ndn::time::milliseconds(10), 100);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800252 BOOST_CHECK_EQUAL(handler[0]->map[handler[2]->logic.getSessionName()], 2);
253 BOOST_CHECK_EQUAL(handler[1]->map[handler[2]->logic.getSessionName()], 2);
254 BOOST_CHECK_EQUAL(handler[3]->map[handler[2]->logic.getSessionName()], 2);
255
256 // Network Partition start
257
258 handler[1]->updateSeqNo(3);
259
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500260 advanceClocks(ndn::time::milliseconds(10), 100);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800261 BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 3);
262 handler[2]->map[handler[1]->logic.getSessionName()] = 0;
263 handler[3]->map[handler[1]->logic.getSessionName()] = 0;
264
265 handler[3]->updateSeqNo(4);
266
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500267 advanceClocks(ndn::time::milliseconds(10), 100);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800268 BOOST_CHECK_EQUAL(handler[2]->map[handler[3]->logic.getSessionName()], 4);
269 handler[0]->map[handler[3]->logic.getSessionName()] = 0;
270 handler[1]->map[handler[3]->logic.getSessionName()] = 0;
271
272 // Network partition over
273
274 handler[0]->updateSeqNo(5);
275
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500276 advanceClocks(ndn::time::milliseconds(10), 100);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800277 BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 5);
278 BOOST_CHECK_EQUAL(handler[2]->map[handler[0]->logic.getSessionName()], 5);
279 BOOST_CHECK_EQUAL(handler[3]->map[handler[0]->logic.getSessionName()], 5);
280
281 handler[2]->updateSeqNo(6);
282
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500283 advanceClocks(ndn::time::milliseconds(10), 100);
Sonu Mishra4d3a2e02017-01-18 20:27:51 -0800284 BOOST_CHECK_EQUAL(handler[0]->map[handler[2]->logic.getSessionName()], 6);
285 BOOST_CHECK_EQUAL(handler[1]->map[handler[2]->logic.getSessionName()], 6);
286 BOOST_CHECK_EQUAL(handler[3]->map[handler[2]->logic.getSessionName()], 6);
287}
288
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800289BOOST_AUTO_TEST_CASE(MultipleUserUnderOneLogic)
290{
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500291 handler[0] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[0]);
292 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800293
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500294 handler[1] = make_shared<Handler>(ref(fw.addFace()), syncPrefix, userPrefix[2]);
295 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800296
297 handler[0]->logic.addUserNode(userPrefix[1]);
298
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500299 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800300
301 handler[0]->updateSeqNo(1);
302
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500303 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800304 BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1);
305
306 handler[0]->logic.updateSeqNo(2, userPrefix[1]);
307
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500308 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800309 BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName(userPrefix[1])], 2);
310
311 handler[1]->updateSeqNo(4);
312
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500313 advanceClocks(ndn::time::milliseconds(10), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800314 BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 4);
315
316 handler[0]->logic.removeUserNode(userPrefix[0]);
317
Ashlesh Gawande08784d42017-09-06 23:40:21 -0500318 advanceClocks(ndn::time::milliseconds(50), 100);
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800319 BOOST_CHECK_EQUAL(handler[1]->logic.getSessionNames().size(), 2);
320}
321
Ashlesh Gawande4a9ecd52018-02-06 14:36:19 -0600322BOOST_FIXTURE_TEST_CASE(ExplodeData, ndn::tests::IdentityManagementTimeFixture)
323{
324 Name syncPrefix("/ndn/broadcast/sync");
325 Name userPrefix("/user");
326 ndn::util::DummyClientFace face;
327 Logic logic(face, syncPrefix, userPrefix, bind(onUpdate, _1));
328
329 State state;
330 int i = 0;
331 while (state.wireEncode().size() < ndn::MAX_NDN_PACKET_SIZE) {
332 Name name("/test1");
333 name.append(std::to_string(i));
334 state.update(name, i++);
335 }
336
337 Data syncReply(syncPrefix);
338 syncReply.setContent(state.wireEncode());
339 m_keyChain.sign(syncReply);
340
341 BOOST_REQUIRE(syncReply.wireEncode().size() > ndn::MAX_NDN_PACKET_SIZE);
342
343 State partialState;
344 auto maxSize = ndn::MAX_NDN_PACKET_SIZE - (syncReply.wireEncode().size() - state.wireEncode().size());
345 logic.trimState(partialState, state, maxSize);
346
347 syncReply.setContent(partialState.wireEncode());
348 BOOST_REQUIRE(syncReply.wireEncode().size() < ndn::MAX_NDN_PACKET_SIZE);
349}
350
Qiuhan Dingfb8c9e02015-01-30 14:04:55 -0800351BOOST_AUTO_TEST_SUITE_END()
352
353} // namespace test
354} // namespace chronosync