blob: ae06eb1c8cd0df4375bb91fb664ec47b1d0fd381 [file] [log] [blame]
Weiqi Shi098f91c2014-07-23 17:41:35 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014, Regents of the University of California.
4 *
5 * This file is part of NDN repo-ng (Next generation of NDN repository).
6 * See AUTHORS.md for complete list of repo-ng authors and contributors.
7 *
8 * repo-ng 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,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * repo-ng 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 * repo-ng, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "handles/watch-handle.hpp"
21#include "storage/sqlite-storage.hpp"
22#include "common.hpp"
23
24#include "../repo-storage-fixture.hpp"
25#include "../dataset-fixtures.hpp"
26
27#include <ndn-cxx/util/random.hpp>
28#include <ndn-cxx/util/io.hpp>
29
30#include <boost/test/unit_test.hpp>
31#include <fstream>
32
33namespace repo {
34namespace tests {
35
36using ndn::time::milliseconds;
37using ndn::time::seconds;
38using ndn::EventId;
39namespace random=ndn::random;
40
41//All the test cases in this test suite should be run at once.
42BOOST_AUTO_TEST_SUITE(TestBasicCommandWatchDelete)
43
44const static uint8_t content[8] = {3, 1, 4, 1, 5, 9, 2, 6};
45
46template<class Dataset>
47class Fixture : public RepoStorageFixture, public Dataset
48{
49public:
50 Fixture()
51 : scheduler(repoFace.getIoService())
52 , validator(repoFace)
53 , watchHandle(repoFace, *handle, keyChain, scheduler, validator)
54 , watchFace(repoFace.getIoService())
55 {
56 watchHandle.listen(Name("/repo/command"));
57 }
58
59 ~Fixture()
60 {
61 repoFace.getIoService().stop();
62 }
63
64 void
65 generateDefaultCertificateFile();
66
67 void
68 scheduleWatchEvent();
69
70 void
71 onWatchInterest(const Interest& interest);
72
73 void
74 onRegisterFailed(const std::string& reason);
75
76 void
77 delayedInterest();
78
79 void
80 stopFaceProcess();
81
82 void
83 onWatchData(const Interest& interest, Data& data);
84
85 void
86 onWatchStopData(const Interest& interest, Data& data);
87
88 void
89 onWatchTimeout(const Interest& interest);
90
91 void
92 sendWatchStartInterest(const Interest& interest);
93
94 void
95 sendWatchStopInterest(const Interest& interest);
96
97 void
98 checkWatchOk(const Interest& interest);
99
100public:
101 Face repoFace;
102 Scheduler scheduler;
103 ValidatorConfig validator;
104 KeyChain keyChain;
105 WatchHandle watchHandle;
106 Face watchFace;
107 std::map<Name, EventId> watchEvents;
108};
109
110template<class T> void
111Fixture<T>::generateDefaultCertificateFile()
112{
113 Name defaultIdentity = keyChain.getDefaultIdentity();
114 Name defaultKeyname = keyChain.getDefaultKeyNameForIdentity(defaultIdentity);
115 Name defaultCertficateName = keyChain.getDefaultCertificateNameForKey(defaultKeyname);
116 shared_ptr<ndn::IdentityCertificate> defaultCertficate =
117 keyChain.getCertificate(defaultCertficateName);
118 //test-integrated should run in root directory of repo-ng.
119 //certificate file should be removed after tests for security issue.
120 std::fstream certificateFile("tests/integrated/insert-delete-test.cert",
121 std::ios::out | std::ios::binary | std::ios::trunc);
122 ndn::io::save(*defaultCertficate, certificateFile);
123 certificateFile.close();
124}
125
126template<class T> void
127Fixture<T>::onWatchInterest(const Interest& interest)
128{
129 shared_ptr<Data> data = make_shared<Data>(Name(interest.getName()).appendNumber(random::generateWord64()+100));
130 data->setContent(content, sizeof(content));
131 data->setFreshnessPeriod(milliseconds(0));
132 keyChain.signByIdentity(*data, keyChain.getDefaultIdentity());
133 watchFace.put(*data);
134
135 // schedule an event 50ms later to check whether watch is Ok
136 scheduler.scheduleEvent(milliseconds(10000),
137 bind(&Fixture<T>::checkWatchOk, this,
138 Interest(data->getName())));
139}
140
141
142template<class T> void
143Fixture<T>::onRegisterFailed(const std::string& reason)
144{
145 BOOST_ERROR("ERROR: Failed to register prefix in local hub's daemon" + reason);
146}
147
148template<class T> void
149Fixture<T>::delayedInterest()
150{
151 BOOST_ERROR("Fetching interest does not come. It may be satisfied in CS or something is wrong");
152}
153
154template<class T> void
155Fixture<T>::stopFaceProcess()
156{
157 repoFace.getIoService().stop();
158}
159
160template<class T> void
161Fixture<T>::onWatchData(const Interest& interest, Data& data)
162{
163 RepoCommandResponse response;
164 response.wireDecode(data.getContent().blockFromValue());
165
166 int statusCode = response.getStatusCode();
167 BOOST_CHECK_EQUAL(statusCode, 100);
168}
169
170template<class T> void
171Fixture<T>::onWatchStopData(const Interest& interest, Data& data)
172{
173 RepoCommandResponse response;
174 response.wireDecode(data.getContent().blockFromValue());
175
176 int statusCode = response.getStatusCode();
177 BOOST_CHECK_EQUAL(statusCode, 101);
178}
179
180template<class T> void
181Fixture<T>::onWatchTimeout(const Interest& interest)
182{
183 BOOST_ERROR("Watch command timeout");
184}
185
186template<class T> void
187Fixture<T>::sendWatchStartInterest(const Interest& watchInterest)
188{
189 watchFace.expressInterest(watchInterest,
190 bind(&Fixture<T>::onWatchData, this, _1, _2),
191 bind(&Fixture<T>::onWatchTimeout, this, _1));
192}
193
194template<class T> void
195Fixture<T>::sendWatchStopInterest(const Interest& watchInterest)
196{
197 watchFace.expressInterest(watchInterest,
198 bind(&Fixture<T>::onWatchStopData, this, _1, _2),
199 bind(&Fixture<T>::onWatchTimeout, this, _1));
200}
201
202template<class T> void
203Fixture<T>::checkWatchOk(const Interest& interest)
204{
205 BOOST_TEST_MESSAGE(interest);
206 shared_ptr<Data> data = handle->readData(interest);
207 if (data) {
208 int rc = memcmp(data->getContent().value(), content, sizeof(content));
209 BOOST_CHECK_EQUAL(rc, 0);
210 }
211 else {
212 std::cerr<<"Check Watch Failed"<<std::endl;
213 }
214}
215
216template<class T> void
217Fixture<T>::scheduleWatchEvent()
218{
219 Name watchCommandName("/repo/command/watch/start");
220 RepoCommandParameter watchParameter;
221 watchParameter.setName(Name("/a/b"));
222 watchParameter.setMaxInterestNum(10);
223 watchParameter.setInterestLifetime(milliseconds(50000));
224 watchParameter.setWatchTimeout(milliseconds(1000000000));
225 watchCommandName.append(watchParameter.wireEncode());
226 Interest watchInterest(watchCommandName);
227 keyChain.signByIdentity(watchInterest, keyChain.getDefaultIdentity());
228 //schedule a job to express watchInterest
229 scheduler.scheduleEvent(milliseconds(1000),
230 bind(&Fixture<T>::sendWatchStartInterest, this, watchInterest));
231
232 Name watchStopName("/repo/command/watch/stop");
233 RepoCommandParameter watchStopParameter;
234 watchStopName.append(watchStopParameter.wireEncode());
235 Interest watchStopInterest(watchStopName);
236 keyChain.signByIdentity(watchStopInterest, keyChain.getDefaultIdentity());
237
238 // scheduler.scheduleEvent(milliseconds(10000),
239 // bind(&Fixture<T>::sendWatchStopInterest, this, watchStopInterest));
240 //The delayEvent will be canceled in onWatchInterest
241 watchFace.setInterestFilter(watchParameter.getName(),
242 bind(&Fixture<T>::onWatchInterest, this, _2),
243 ndn::RegisterPrefixSuccessCallback(),
244 bind(&Fixture<T>::onRegisterFailed, this, _2));
245}
246
247typedef boost::mpl::vector< BasicDataset > Dataset;
248
249BOOST_FIXTURE_TEST_CASE_TEMPLATE(WatchDelete, T, Dataset, Fixture<T>)
250{
251 this->generateDefaultCertificateFile();
252 this->validator.load("tests/integrated/insert-delete-validator-config.conf");
253
254 // schedule events
255 this->scheduler.scheduleEvent(seconds(0),
256 bind(&Fixture<T>::scheduleWatchEvent, this));
257
258 // schedule an event to terminate IO
259 this->scheduler.scheduleEvent(seconds(500),
260 bind(&Fixture<T>::stopFaceProcess, this));
261 this->repoFace.getIoService().run();
262}
263
264BOOST_AUTO_TEST_SUITE_END()
265
266} //namespace tests
267} //namespace repo