blob: 6c5c1fd0d351ae235f67238c11d5de083249fed2 [file] [log] [blame]
Alexander Afanasyev8722d872014-07-02 13:00:29 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -07002/*
Alexander Afanasyev8722d872014-07-02 13:00:29 -07003 * Copyright (c) 2012-2014 University of California, Los Angeles
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -07004 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -07005 * This file is part of ChronoSync, synchronization library for distributed realtime
6 * applications for NDN.
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -07007 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -07008 * 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.
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -070011 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -070012 * 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.
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -070015 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -070016 * 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/>.
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -070018 */
19
20#include <boost/test/unit_test.hpp>
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070021#include <boost/test/output_test_stream.hpp>
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -070022#include <map>
23using boost::test_tools::output_test_stream;
24
25#include <boost/make_shared.hpp>
26
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070027#include <ndn-cxx/security/validator-null.hpp>
Alexander Afanasyev158ec0d2012-04-05 13:48:55 -070028#include "sync-logic.h"
29#include "sync-seq-no.h"
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -070030
31using namespace std;
32using namespace boost;
33using namespace Sync;
34
35struct Handler
36{
37 string instance;
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070038
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -070039 Handler (const string &_instance)
40 : instance (_instance)
41 {
42 }
Zhenkai Zhu1cb29292012-05-31 22:54:34 -070043
Zhenkai Zhu43ae5c72012-05-31 23:18:45 -070044 void wrapper (const vector<MissingDataInfo> &v) {
Zhenkai Zhu1cb29292012-05-31 22:54:34 -070045 int n = v.size();
46 for (int i = 0; i < n; i++) {
47 onUpdate (v[i].prefix, v[i].high, v[i].low);
48 }
49 }
50
Alexander Afanasyev1b449c42012-03-13 20:24:07 -070051 void onUpdate (const string &p/*prefix*/, const SeqNo &seq/*newSeq*/, const SeqNo &oldSeq/*oldSeq*/)
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -070052 {
Alexander Afanasyev1b449c42012-03-13 20:24:07 -070053 m_map[p] = seq.getSeq ();
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070054
Alexander Afanasyev4f9ea482012-03-15 11:57:29 -070055 // cout << instance << "\t";
56 // if (!oldSeq.isValid ())
57 // cout << "Inserted: " << p << " (" << seq << ")" << endl;
58 // else
59 // cout << "Updated: " << p << " ( " << oldSeq << ".." << seq << ")" << endl;
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -070060 }
61
62 void onRemove (const string &p/*prefix*/)
63 {
Alexander Afanasyev4f9ea482012-03-15 11:57:29 -070064 // cout << instance << "\tRemoved: " << p << endl;
Alexander Afanasyev1b449c42012-03-13 20:24:07 -070065 m_map.erase (p);
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -070066 }
Alexander Afanasyev1b449c42012-03-13 20:24:07 -070067
68 map<string, uint32_t> m_map;
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -070069};
70
Yingdi Yu280bb962014-01-30 09:52:43 -080071class TestCore
72{
73public:
74 TestCore(ndn::shared_ptr<boost::asio::io_service> ioService)
75 : m_ioService(ioService)
76 {
77 m_l[0] = 0;
78 m_l[1] = 0;
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070079
Yingdi Yu280bb962014-01-30 09:52:43 -080080 m_validator = ndn::make_shared<ndn::ValidatorNull>();
81 }
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070082
Yingdi Yu280bb962014-01-30 09:52:43 -080083 ~TestCore()
84 {
85 if(m_l[0] != 0)
86 delete m_l[0];
87
88 if(m_l[1] != 0)
89 delete m_l[1];
90 }
91
92 void
Yingdi Yu6e1c9cd2014-03-25 10:26:54 -070093 finish(ndn::shared_ptr<boost::asio::io_service> ioService)
Yingdi Yu280bb962014-01-30 09:52:43 -080094 {
Yingdi Yu6e1c9cd2014-03-25 10:26:54 -070095 ioService->stop();
Yingdi Yu280bb962014-01-30 09:52:43 -080096 }
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070097
Yingdi Yu280bb962014-01-30 09:52:43 -080098 void
Yingdi Yu7c64e5c2014-04-30 14:06:37 -070099 createSyncLogic(int index,
Yingdi Yu280bb962014-01-30 09:52:43 -0800100 ndn::shared_ptr<Handler> h)
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700101 {
Yingdi Yu6e1c9cd2014-03-25 10:26:54 -0700102 ndn::Name identity("/tmp-" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800103 ndn::shared_ptr<ndn::IdentityCertificate> cert = m_keyChain.getCertificate(m_keyChain.createIdentity(identity));
Yingdi Yu280bb962014-01-30 09:52:43 -0800104 m_faces[index] = ndn::make_shared<ndn::Face>(m_ioService);
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700105 m_l[index] = new SyncLogic(ndn::Name("/bcast"),
Yingdi Yu3da10fe2014-02-27 16:37:34 -0800106 *cert,
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700107 m_validator, m_faces[index],
108 bind (&Handler::wrapper, &*h, _1),
109 bind (&Handler::onRemove, &*h, _1));
Yingdi Yu280bb962014-01-30 09:52:43 -0800110 }
111
112 void
113 getOldDigestForOne()
114 {
115 m_oldDigest = m_l[0]->getRootDigest();
116 }
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700117
Yingdi Yu280bb962014-01-30 09:52:43 -0800118 void
119 getNewDigestForOne()
120 {
121 m_newDigest = m_l[0]->getRootDigest();
122 }
123
124 void
125 addLocalNamesForOne(ndn::Name name, uint64_t session, uint64_t seq)
126 {
127 m_l[0]->addLocalNames(name, session, seq);
128 }
129
130 void
131 removeForOne(ndn::Name name)
132 {
133 m_l[0]->remove(name);
134 }
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700135
Yingdi Yu280bb962014-01-30 09:52:43 -0800136 void
137 checkDigest()
138 {
139 BOOST_CHECK(m_oldDigest != m_newDigest);
140 }
141
142
143public:
Yingdi Yu0eee6002014-02-11 15:54:17 -0800144 ndn::KeyChain m_keyChain;
Yingdi Yu280bb962014-01-30 09:52:43 -0800145 ndn::shared_ptr<boost::asio::io_service> m_ioService;
146 SyncLogic* m_l[2];
147 ndn::shared_ptr<ndn::Face> m_faces[2];
148 ndn::shared_ptr<ndn::ValidatorNull> m_validator;
149 string m_oldDigest;
150 string m_newDigest;
151};
152
153void
154checkMapSize(ndn::shared_ptr<Handler> h, int size)
155{ BOOST_CHECK_EQUAL (h->m_map.size (), size); }
156
157
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -0700158BOOST_AUTO_TEST_CASE (SyncLogicTest)
159{
Yingdi Yu280bb962014-01-30 09:52:43 -0800160 ndn::shared_ptr<boost::asio::io_service> ioService = ndn::make_shared<boost::asio::io_service>();
161 ndn::Scheduler scheduler(*ioService);
162 TestCore testCore(ioService);
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -0700163
Yingdi Yu280bb962014-01-30 09:52:43 -0800164 ndn::shared_ptr<Handler> h1 = ndn::make_shared<Handler>("1");
165 ndn::shared_ptr<Handler> h2 = ndn::make_shared<Handler>("2");
Yingdi Yu43e71612013-10-30 22:19:31 -0700166
Yingdi Yu6e1c9cd2014-03-25 10:26:54 -0700167 scheduler.scheduleEvent(ndn::time::milliseconds(0), ndn::bind(&TestCore::createSyncLogic, &testCore, 0, h1));
168 scheduler.scheduleEvent(ndn::time::milliseconds(100), ndn::bind(&TestCore::getOldDigestForOne, &testCore));
169 scheduler.scheduleEvent(ndn::time::milliseconds(200), ndn::bind(&TestCore::addLocalNamesForOne, &testCore, "/one", 1, 2));
170 scheduler.scheduleEvent(ndn::time::milliseconds(300), ndn::bind(&checkMapSize, h1, 0));
171 scheduler.scheduleEvent(ndn::time::milliseconds(400), ndn::bind(&TestCore::createSyncLogic, &testCore, 1, h2));
172 scheduler.scheduleEvent(ndn::time::milliseconds(500), ndn::bind(&checkMapSize, h1, 0));
173 scheduler.scheduleEvent(ndn::time::milliseconds(600), ndn::bind(&checkMapSize, h2, 1));
174 scheduler.scheduleEvent(ndn::time::milliseconds(700), ndn::bind(&TestCore::removeForOne, &testCore, "/one"));
175 scheduler.scheduleEvent(ndn::time::milliseconds(800), ndn::bind(&TestCore::getNewDigestForOne, &testCore));
176 scheduler.scheduleEvent(ndn::time::milliseconds(900), ndn::bind(&TestCore::checkDigest, &testCore));
177 scheduler.scheduleEvent(ndn::time::milliseconds(1000), ndn::bind(&TestCore::finish, &testCore, ioService));
Yingdi Yu7c64e5c2014-04-30 14:06:37 -0700178
Yingdi Yu280bb962014-01-30 09:52:43 -0800179 ioService->run();
Alexander Afanasyev1b449c42012-03-13 20:24:07 -0700180
Alexander Afanasyevbf2b4362012-03-12 23:55:09 -0700181}