blob: 8c4c13ef16842ab4baa8833b3a811a9f4eaa0d0f [file] [log] [blame]
Weiqi Shi098f91c2014-07-23 17:41:35 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev42290b22017-03-09 12:58:29 -08003 * Copyright (c) 2014-2017, Regents of the University of California.
Weiqi Shi098f91c2014-07-23 17:41:35 -07004 *
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;
Alexander Afanasyev42290b22017-03-09 12:58:29 -080039namespace random = ndn::random;
Weiqi Shi098f91c2014-07-23 17:41:35 -070040
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
Alexander Afanasyev42290b22017-03-09 12:58:29 -080083 onWatchData(const Interest& interest, const Data& data);
Weiqi Shi098f91c2014-07-23 17:41:35 -070084
85 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -080086 onWatchStopData(const Interest& interest, const Data& data);
Weiqi Shi098f91c2014-07-23 17:41:35 -070087
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
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800161Fixture<T>::onWatchData(const Interest& interest, const Data& data)
Weiqi Shi098f91c2014-07-23 17:41:35 -0700162{
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
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800171Fixture<T>::onWatchStopData(const Interest& interest, const Data& data)
Weiqi Shi098f91c2014-07-23 17:41:35 -0700172{
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),
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800191 bind(&Fixture<T>::onWatchTimeout, this, _1), // Nack
Weiqi Shi098f91c2014-07-23 17:41:35 -0700192 bind(&Fixture<T>::onWatchTimeout, this, _1));
193}
194
195template<class T> void
196Fixture<T>::sendWatchStopInterest(const Interest& watchInterest)
197{
198 watchFace.expressInterest(watchInterest,
199 bind(&Fixture<T>::onWatchStopData, this, _1, _2),
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800200 bind(&Fixture<T>::onWatchTimeout, this, _1), // Nack
Weiqi Shi098f91c2014-07-23 17:41:35 -0700201 bind(&Fixture<T>::onWatchTimeout, this, _1));
202}
203
204template<class T> void
205Fixture<T>::checkWatchOk(const Interest& interest)
206{
207 BOOST_TEST_MESSAGE(interest);
208 shared_ptr<Data> data = handle->readData(interest);
209 if (data) {
210 int rc = memcmp(data->getContent().value(), content, sizeof(content));
211 BOOST_CHECK_EQUAL(rc, 0);
212 }
213 else {
214 std::cerr<<"Check Watch Failed"<<std::endl;
215 }
216}
217
218template<class T> void
219Fixture<T>::scheduleWatchEvent()
220{
221 Name watchCommandName("/repo/command/watch/start");
222 RepoCommandParameter watchParameter;
223 watchParameter.setName(Name("/a/b"));
224 watchParameter.setMaxInterestNum(10);
225 watchParameter.setInterestLifetime(milliseconds(50000));
226 watchParameter.setWatchTimeout(milliseconds(1000000000));
227 watchCommandName.append(watchParameter.wireEncode());
228 Interest watchInterest(watchCommandName);
229 keyChain.signByIdentity(watchInterest, keyChain.getDefaultIdentity());
230 //schedule a job to express watchInterest
231 scheduler.scheduleEvent(milliseconds(1000),
232 bind(&Fixture<T>::sendWatchStartInterest, this, watchInterest));
233
234 Name watchStopName("/repo/command/watch/stop");
235 RepoCommandParameter watchStopParameter;
236 watchStopName.append(watchStopParameter.wireEncode());
237 Interest watchStopInterest(watchStopName);
238 keyChain.signByIdentity(watchStopInterest, keyChain.getDefaultIdentity());
239
240 // scheduler.scheduleEvent(milliseconds(10000),
241 // bind(&Fixture<T>::sendWatchStopInterest, this, watchStopInterest));
242 //The delayEvent will be canceled in onWatchInterest
243 watchFace.setInterestFilter(watchParameter.getName(),
244 bind(&Fixture<T>::onWatchInterest, this, _2),
245 ndn::RegisterPrefixSuccessCallback(),
246 bind(&Fixture<T>::onRegisterFailed, this, _2));
247}
248
249typedef boost::mpl::vector< BasicDataset > Dataset;
250
251BOOST_FIXTURE_TEST_CASE_TEMPLATE(WatchDelete, T, Dataset, Fixture<T>)
252{
253 this->generateDefaultCertificateFile();
254 this->validator.load("tests/integrated/insert-delete-validator-config.conf");
255
256 // schedule events
257 this->scheduler.scheduleEvent(seconds(0),
258 bind(&Fixture<T>::scheduleWatchEvent, this));
259
260 // schedule an event to terminate IO
261 this->scheduler.scheduleEvent(seconds(500),
262 bind(&Fixture<T>::stopFaceProcess, this));
263 this->repoFace.getIoService().run();
264}
265
266BOOST_AUTO_TEST_SUITE_END()
267
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800268} // namespace tests
269} // namespace repo