blob: 775a16d3b43c047499657492342a44642faf8c49 [file] [log] [blame]
Shuo Chenca329182014-03-19 18:05:18 -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.
Shuo Chenca329182014-03-19 18:05:18 -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/write-handle.hpp"
21#include "handles/delete-handle.hpp"
Weiqi Shif0330d52014-07-09 10:54:27 -070022#include "storage/sqlite-storage.hpp"
23#include "storage/repo-storage.hpp"
Shuo Chenca329182014-03-19 18:05:18 -070024
Junxiao Shi047a6fb2017-06-08 16:16:05 +000025#include "command-fixture.hpp"
Weiqi Shif0330d52014-07-09 10:54:27 -070026#include "../repo-storage-fixture.hpp"
Shuo Chenca329182014-03-19 18:05:18 -070027#include "../dataset-fixtures.hpp"
28
Shuo Chen028dcd32014-06-21 16:36:44 +080029#include <ndn-cxx/util/random.hpp>
Weiqi Shif0330d52014-07-09 10:54:27 -070030#include <boost/preprocessor/comparison/not_equal.hpp>
Shuo Chenca329182014-03-19 18:05:18 -070031#include <boost/test/unit_test.hpp>
Shuo Chen028dcd32014-06-21 16:36:44 +080032#include <fstream>
Shuo Chenca329182014-03-19 18:05:18 -070033
34namespace repo {
35namespace tests {
36
37using ndn::time::milliseconds;
38using ndn::time::seconds;
39using ndn::EventId;
40namespace random=ndn::random;
41
42//All the test cases in this test suite should be run at once.
43BOOST_AUTO_TEST_SUITE(TestBasicCommandInsertDelete)
44
45const static uint8_t content[8] = {3, 1, 4, 1, 5, 9, 2, 6};
46
47template<class Dataset>
Junxiao Shi047a6fb2017-06-08 16:16:05 +000048class Fixture : public CommandFixture, public RepoStorageFixture, public Dataset
Shuo Chenca329182014-03-19 18:05:18 -070049{
50public:
51 Fixture()
Junxiao Shi047a6fb2017-06-08 16:16:05 +000052 : writeHandle(repoFace, *handle, keyChain, scheduler, validator)
Shuo Chenca329182014-03-19 18:05:18 -070053 , deleteHandle(repoFace, *handle, keyChain, scheduler, validator)
54 , insertFace(repoFace.getIoService())
55 , deleteFace(repoFace.getIoService())
56 {
Shuo Chenca329182014-03-19 18:05:18 -070057 writeHandle.listen(Name("/repo/command"));
58 deleteHandle.listen(Name("/repo/command"));
59 }
60
Shuo Chen028dcd32014-06-21 16:36:44 +080061 void
Shuo Chenca329182014-03-19 18:05:18 -070062 scheduleInsertEvent();
63
64 void
65 scheduleDeleteEvent();
66
67 void
68 onInsertInterest(const Interest& interest);
69
70 void
71 onRegisterFailed(const std::string& reason);
72
73 void
74 delayedInterest();
75
76 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -080077 onInsertData(const Interest& interest, const Data& data);
Shuo Chenca329182014-03-19 18:05:18 -070078
79 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -080080 onDeleteData(const Interest& interest, const Data& data);
Shuo Chenca329182014-03-19 18:05:18 -070081
82 void
83 onInsertTimeout(const Interest& interest);
84
85 void
86 onDeleteTimeout(const Interest& interest);
87
88 void
89 sendInsertInterest(const Interest& interest);
90
91 void
92 sendDeleteInterest(const Interest& deleteInterest);
93
94 void
Shuo Chen028dcd32014-06-21 16:36:44 +080095 checkInsertOk(const Interest& interest);
Shuo Chenca329182014-03-19 18:05:18 -070096
97 void
Shuo Chen028dcd32014-06-21 16:36:44 +080098 checkDeleteOk(const Interest& interest);
Shuo Chenca329182014-03-19 18:05:18 -070099
100public:
Shuo Chenca329182014-03-19 18:05:18 -0700101 WriteHandle writeHandle;
102 DeleteHandle deleteHandle;
103 Face insertFace;
104 Face deleteFace;
105 std::map<Name, EventId> insertEvents;
106};
107
108template<class T> void
109Fixture<T>::onInsertInterest(const Interest& interest)
110{
111 Data data(Name(interest.getName()));
112 data.setContent(content, sizeof(content));
113 data.setFreshnessPeriod(milliseconds(0));
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000114 keyChain.sign(data);
Shuo Chenca329182014-03-19 18:05:18 -0700115 insertFace.put(data);
Shuo Chenca329182014-03-19 18:05:18 -0700116 std::map<Name, EventId>::iterator event = insertEvents.find(interest.getName());
117 if (event != insertEvents.end()) {
118 scheduler.cancelEvent(event->second);
119 insertEvents.erase(event);
120 }
Shuo Chen028dcd32014-06-21 16:36:44 +0800121 // schedule an event 50ms later to check whether insert is Ok
Weiqi Shif0330d52014-07-09 10:54:27 -0700122 scheduler.scheduleEvent(milliseconds(500),
Shuo Chen028dcd32014-06-21 16:36:44 +0800123 bind(&Fixture<T>::checkInsertOk, this, interest));
Shuo Chenca329182014-03-19 18:05:18 -0700124
125}
126
127
128template<class T> void
129Fixture<T>::onRegisterFailed(const std::string& reason)
130{
131 BOOST_ERROR("ERROR: Failed to register prefix in local hub's daemon" + reason);
132}
133
134template<class T> void
135Fixture<T>::delayedInterest()
136{
137 BOOST_ERROR("Fetching interest does not come. It may be satisfied in CS or something is wrong");
138}
139
140template<class T> void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800141Fixture<T>::onInsertData(const Interest& interest, const Data& data)
Shuo Chenca329182014-03-19 18:05:18 -0700142{
143 RepoCommandResponse response;
144 response.wireDecode(data.getContent().blockFromValue());
145 int statusCode = response.getStatusCode();
146 BOOST_CHECK_EQUAL(statusCode, 100);
Weiqi Shif0330d52014-07-09 10:54:27 -0700147 // std::cout<<"statuse code of insert name = "<<response.getName()<<std::endl;
Shuo Chenca329182014-03-19 18:05:18 -0700148}
149
150template<class T> void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800151Fixture<T>::onDeleteData(const Interest& interest, const Data& data)
Shuo Chenca329182014-03-19 18:05:18 -0700152{
153 RepoCommandResponse response;
154 response.wireDecode(data.getContent().blockFromValue());
155 int statusCode = response.getStatusCode();
156 BOOST_CHECK_EQUAL(statusCode, 200);
157
Shuo Chen028dcd32014-06-21 16:36:44 +0800158 //schedlute an event to check whether delete is Ok.
Shuo Chenca329182014-03-19 18:05:18 -0700159 scheduler.scheduleEvent(milliseconds(100),
Shuo Chen028dcd32014-06-21 16:36:44 +0800160 bind(&Fixture<T>::checkDeleteOk, this, interest));
Shuo Chenca329182014-03-19 18:05:18 -0700161}
162
163template<class T> void
164Fixture<T>::onInsertTimeout(const Interest& interest)
165{
166 BOOST_ERROR("Inserert command timeout");
167}
168
169template<class T> void
170Fixture<T>::onDeleteTimeout(const Interest& interest)
171{
172 BOOST_ERROR("delete command timeout");
173}
174
175template<class T> void
176Fixture<T>::sendInsertInterest(const Interest& insertInterest)
177{
178 insertFace.expressInterest(insertInterest,
179 bind(&Fixture<T>::onInsertData, this, _1, _2),
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800180 bind(&Fixture<T>::onInsertTimeout, this, _1), // Nack
Shuo Chenca329182014-03-19 18:05:18 -0700181 bind(&Fixture<T>::onInsertTimeout, this, _1));
182}
183
184template<class T> void
185Fixture<T>::sendDeleteInterest(const Interest& deleteInterest)
186{
187 deleteFace.expressInterest(deleteInterest,
188 bind(&Fixture<T>::onDeleteData, this, _1, _2),
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800189 bind(&Fixture<T>::onDeleteTimeout, this, _1), // Nack
Shuo Chenca329182014-03-19 18:05:18 -0700190 bind(&Fixture<T>::onDeleteTimeout, this, _1));
191}
192
193template<class T> void
Shuo Chen028dcd32014-06-21 16:36:44 +0800194Fixture<T>::checkInsertOk(const Interest& interest)
Shuo Chenca329182014-03-19 18:05:18 -0700195{
Shuo Chenca329182014-03-19 18:05:18 -0700196 BOOST_TEST_MESSAGE(interest);
Weiqi Shif0330d52014-07-09 10:54:27 -0700197 shared_ptr<Data> data = handle->readData(interest);
198 if (data) {
199 int rc = memcmp(data->getContent().value(), content, sizeof(content));
200 BOOST_CHECK_EQUAL(rc, 0);
201 }
202 else {
203 std::cerr<<"Check Insert Failed"<<std::endl;
204 }
Shuo Chenca329182014-03-19 18:05:18 -0700205}
206
207template<class T> void
Shuo Chen028dcd32014-06-21 16:36:44 +0800208Fixture<T>::checkDeleteOk(const Interest& interest)
Shuo Chenca329182014-03-19 18:05:18 -0700209{
Weiqi Shif0330d52014-07-09 10:54:27 -0700210 shared_ptr<Data> data = handle->readData(interest);
211 BOOST_CHECK_EQUAL(data, shared_ptr<Data>());
Shuo Chenca329182014-03-19 18:05:18 -0700212}
213
Shuo Chenca329182014-03-19 18:05:18 -0700214template<class T> void
215Fixture<T>::scheduleInsertEvent()
216{
217 int timeCount = 1;
218 for (typename T::DataContainer::iterator i = this->data.begin();
219 i != this->data.end(); ++i) {
220 Name insertCommandName("/repo/command/insert");
221 RepoCommandParameter insertParameter;
222 insertParameter.setName(Name((*i)->getName())
223 .appendNumber(random::generateWord64()));
224
225 insertCommandName.append(insertParameter.wireEncode());
226 Interest insertInterest(insertCommandName);
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000227 keyChain.sign(insertInterest);
Shuo Chenca329182014-03-19 18:05:18 -0700228 //schedule a job to express insertInterest every 50ms
229 scheduler.scheduleEvent(milliseconds(timeCount * 50 + 1000),
230 bind(&Fixture<T>::sendInsertInterest, this, insertInterest));
231 //schedule what to do when interest timeout
232
233 EventId delayEventId = scheduler.scheduleEvent(milliseconds(5000 + timeCount * 50),
234 bind(&Fixture<T>::delayedInterest, this));
235 insertEvents[insertParameter.getName()] = delayEventId;
236
237 //The delayEvent will be canceled in onInsertInterest
238 insertFace.setInterestFilter(insertParameter.getName(),
239 bind(&Fixture<T>::onInsertInterest, this, _2),
Wentao Shang91fb4f22014-05-20 10:55:22 -0700240 ndn::RegisterPrefixSuccessCallback(),
Shuo Chenca329182014-03-19 18:05:18 -0700241 bind(&Fixture<T>::onRegisterFailed, this, _2));
242 timeCount++;
243 }
244}
245
Shuo Chenca329182014-03-19 18:05:18 -0700246template<class T> void
247Fixture<T>::scheduleDeleteEvent()
248{
249 int timeCount = 1;
250 for (typename T::DataContainer::iterator i = this->data.begin();
251 i != this->data.end(); ++i) {
252 Name deleteCommandName("/repo/command/delete");
253 RepoCommandParameter deleteParameter;
254 static boost::random::mt19937_64 gen;
255 static boost::random::uniform_int_distribution<uint64_t> dist(0, 0xFFFFFFFFFFFFFFFFLL);
256 deleteParameter.setProcessId(dist(gen));
257 deleteParameter.setName((*i)->getName());
258 deleteCommandName.append(deleteParameter.wireEncode());
259 Interest deleteInterest(deleteCommandName);
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000260 keyChain.sign(deleteInterest);
Shuo Chenca329182014-03-19 18:05:18 -0700261 scheduler.scheduleEvent(milliseconds(4000 + timeCount * 50),
262 bind(&Fixture<T>::sendDeleteInterest, this, deleteInterest));
263 timeCount++;
264 }
265}
266
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700267typedef boost::mpl::vector< BasicDataset,
268 FetchByPrefixDataset,
269 BasicChildSelectorDataset,
270 ExtendedChildSelectorDataset,
271 SamePrefixDataset<10> > Datasets;
272
273BOOST_FIXTURE_TEST_CASE_TEMPLATE(InsertDelete, T, Datasets, Fixture<T>)
Shuo Chenca329182014-03-19 18:05:18 -0700274{
Shuo Chenca329182014-03-19 18:05:18 -0700275 // schedule events
276 this->scheduler.scheduleEvent(seconds(0),
277 bind(&Fixture<T>::scheduleInsertEvent, this));
278 this->scheduler.scheduleEvent(seconds(10),
279 bind(&Fixture<T>::scheduleDeleteEvent, this));
280
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000281 this->repoFace.processEvents(seconds(30));
Shuo Chenca329182014-03-19 18:05:18 -0700282}
283
284BOOST_AUTO_TEST_SUITE_END()
285
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800286} // namespace tests
287} // namespace repo