blob: 28fea81761f8e37d43902179f8bcc3b4faf1a6e9 [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 {
Junxiao Shi2b7b8312017-06-16 03:43:24 +000057 Name cmdPrefix("/repo/command");
58 repoFace.registerPrefix(cmdPrefix, nullptr,
59 [] (const Name& cmdPrefix, const std::string& reason) {
60 BOOST_FAIL("Command prefix registration error: " << reason);
61 });
62 writeHandle.listen(cmdPrefix);
63 deleteHandle.listen(cmdPrefix);
Shuo Chenca329182014-03-19 18:05:18 -070064 }
65
Shuo Chen028dcd32014-06-21 16:36:44 +080066 void
Shuo Chenca329182014-03-19 18:05:18 -070067 scheduleInsertEvent();
68
69 void
70 scheduleDeleteEvent();
71
72 void
73 onInsertInterest(const Interest& interest);
74
75 void
76 onRegisterFailed(const std::string& reason);
77
78 void
79 delayedInterest();
80
81 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -080082 onInsertData(const Interest& interest, const Data& data);
Shuo Chenca329182014-03-19 18:05:18 -070083
84 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -080085 onDeleteData(const Interest& interest, const Data& data);
Shuo Chenca329182014-03-19 18:05:18 -070086
87 void
88 onInsertTimeout(const Interest& interest);
89
90 void
91 onDeleteTimeout(const Interest& interest);
92
93 void
94 sendInsertInterest(const Interest& interest);
95
96 void
97 sendDeleteInterest(const Interest& deleteInterest);
98
99 void
Shuo Chen028dcd32014-06-21 16:36:44 +0800100 checkInsertOk(const Interest& interest);
Shuo Chenca329182014-03-19 18:05:18 -0700101
102 void
Shuo Chen028dcd32014-06-21 16:36:44 +0800103 checkDeleteOk(const Interest& interest);
Shuo Chenca329182014-03-19 18:05:18 -0700104
105public:
Shuo Chenca329182014-03-19 18:05:18 -0700106 WriteHandle writeHandle;
107 DeleteHandle deleteHandle;
108 Face insertFace;
109 Face deleteFace;
110 std::map<Name, EventId> insertEvents;
111};
112
113template<class T> void
114Fixture<T>::onInsertInterest(const Interest& interest)
115{
116 Data data(Name(interest.getName()));
117 data.setContent(content, sizeof(content));
118 data.setFreshnessPeriod(milliseconds(0));
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000119 keyChain.sign(data);
Shuo Chenca329182014-03-19 18:05:18 -0700120 insertFace.put(data);
Shuo Chenca329182014-03-19 18:05:18 -0700121 std::map<Name, EventId>::iterator event = insertEvents.find(interest.getName());
122 if (event != insertEvents.end()) {
123 scheduler.cancelEvent(event->second);
124 insertEvents.erase(event);
125 }
Shuo Chen028dcd32014-06-21 16:36:44 +0800126 // schedule an event 50ms later to check whether insert is Ok
Weiqi Shif0330d52014-07-09 10:54:27 -0700127 scheduler.scheduleEvent(milliseconds(500),
Shuo Chen028dcd32014-06-21 16:36:44 +0800128 bind(&Fixture<T>::checkInsertOk, this, interest));
Shuo Chenca329182014-03-19 18:05:18 -0700129
130}
131
132
133template<class T> void
134Fixture<T>::onRegisterFailed(const std::string& reason)
135{
136 BOOST_ERROR("ERROR: Failed to register prefix in local hub's daemon" + reason);
137}
138
139template<class T> void
140Fixture<T>::delayedInterest()
141{
142 BOOST_ERROR("Fetching interest does not come. It may be satisfied in CS or something is wrong");
143}
144
145template<class T> void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800146Fixture<T>::onInsertData(const Interest& interest, const Data& data)
Shuo Chenca329182014-03-19 18:05:18 -0700147{
148 RepoCommandResponse response;
149 response.wireDecode(data.getContent().blockFromValue());
150 int statusCode = response.getStatusCode();
151 BOOST_CHECK_EQUAL(statusCode, 100);
Weiqi Shif0330d52014-07-09 10:54:27 -0700152 // std::cout<<"statuse code of insert name = "<<response.getName()<<std::endl;
Shuo Chenca329182014-03-19 18:05:18 -0700153}
154
155template<class T> void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800156Fixture<T>::onDeleteData(const Interest& interest, const Data& data)
Shuo Chenca329182014-03-19 18:05:18 -0700157{
158 RepoCommandResponse response;
159 response.wireDecode(data.getContent().blockFromValue());
160 int statusCode = response.getStatusCode();
161 BOOST_CHECK_EQUAL(statusCode, 200);
162
Shuo Chen028dcd32014-06-21 16:36:44 +0800163 //schedlute an event to check whether delete is Ok.
Shuo Chenca329182014-03-19 18:05:18 -0700164 scheduler.scheduleEvent(milliseconds(100),
Shuo Chen028dcd32014-06-21 16:36:44 +0800165 bind(&Fixture<T>::checkDeleteOk, this, interest));
Shuo Chenca329182014-03-19 18:05:18 -0700166}
167
168template<class T> void
169Fixture<T>::onInsertTimeout(const Interest& interest)
170{
Junxiao Shi2b7b8312017-06-16 03:43:24 +0000171 BOOST_ERROR("Insert command timeout");
Shuo Chenca329182014-03-19 18:05:18 -0700172}
173
174template<class T> void
175Fixture<T>::onDeleteTimeout(const Interest& interest)
176{
Junxiao Shi2b7b8312017-06-16 03:43:24 +0000177 BOOST_ERROR("Delete command timeout");
Shuo Chenca329182014-03-19 18:05:18 -0700178}
179
180template<class T> void
181Fixture<T>::sendInsertInterest(const Interest& insertInterest)
182{
183 insertFace.expressInterest(insertInterest,
184 bind(&Fixture<T>::onInsertData, this, _1, _2),
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800185 bind(&Fixture<T>::onInsertTimeout, this, _1), // Nack
Shuo Chenca329182014-03-19 18:05:18 -0700186 bind(&Fixture<T>::onInsertTimeout, this, _1));
187}
188
189template<class T> void
190Fixture<T>::sendDeleteInterest(const Interest& deleteInterest)
191{
192 deleteFace.expressInterest(deleteInterest,
193 bind(&Fixture<T>::onDeleteData, this, _1, _2),
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800194 bind(&Fixture<T>::onDeleteTimeout, this, _1), // Nack
Shuo Chenca329182014-03-19 18:05:18 -0700195 bind(&Fixture<T>::onDeleteTimeout, this, _1));
196}
197
198template<class T> void
Shuo Chen028dcd32014-06-21 16:36:44 +0800199Fixture<T>::checkInsertOk(const Interest& interest)
Shuo Chenca329182014-03-19 18:05:18 -0700200{
Shuo Chenca329182014-03-19 18:05:18 -0700201 BOOST_TEST_MESSAGE(interest);
Weiqi Shif0330d52014-07-09 10:54:27 -0700202 shared_ptr<Data> data = handle->readData(interest);
203 if (data) {
204 int rc = memcmp(data->getContent().value(), content, sizeof(content));
205 BOOST_CHECK_EQUAL(rc, 0);
206 }
207 else {
208 std::cerr<<"Check Insert Failed"<<std::endl;
209 }
Shuo Chenca329182014-03-19 18:05:18 -0700210}
211
212template<class T> void
Shuo Chen028dcd32014-06-21 16:36:44 +0800213Fixture<T>::checkDeleteOk(const Interest& interest)
Shuo Chenca329182014-03-19 18:05:18 -0700214{
Weiqi Shif0330d52014-07-09 10:54:27 -0700215 shared_ptr<Data> data = handle->readData(interest);
216 BOOST_CHECK_EQUAL(data, shared_ptr<Data>());
Shuo Chenca329182014-03-19 18:05:18 -0700217}
218
Shuo Chenca329182014-03-19 18:05:18 -0700219template<class T> void
220Fixture<T>::scheduleInsertEvent()
221{
222 int timeCount = 1;
223 for (typename T::DataContainer::iterator i = this->data.begin();
224 i != this->data.end(); ++i) {
225 Name insertCommandName("/repo/command/insert");
226 RepoCommandParameter insertParameter;
227 insertParameter.setName(Name((*i)->getName())
228 .appendNumber(random::generateWord64()));
229
230 insertCommandName.append(insertParameter.wireEncode());
231 Interest insertInterest(insertCommandName);
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000232 keyChain.sign(insertInterest);
Shuo Chenca329182014-03-19 18:05:18 -0700233 //schedule a job to express insertInterest every 50ms
234 scheduler.scheduleEvent(milliseconds(timeCount * 50 + 1000),
235 bind(&Fixture<T>::sendInsertInterest, this, insertInterest));
236 //schedule what to do when interest timeout
237
238 EventId delayEventId = scheduler.scheduleEvent(milliseconds(5000 + timeCount * 50),
239 bind(&Fixture<T>::delayedInterest, this));
240 insertEvents[insertParameter.getName()] = delayEventId;
241
242 //The delayEvent will be canceled in onInsertInterest
243 insertFace.setInterestFilter(insertParameter.getName(),
244 bind(&Fixture<T>::onInsertInterest, this, _2),
Wentao Shang91fb4f22014-05-20 10:55:22 -0700245 ndn::RegisterPrefixSuccessCallback(),
Shuo Chenca329182014-03-19 18:05:18 -0700246 bind(&Fixture<T>::onRegisterFailed, this, _2));
247 timeCount++;
248 }
249}
250
Shuo Chenca329182014-03-19 18:05:18 -0700251template<class T> void
252Fixture<T>::scheduleDeleteEvent()
253{
254 int timeCount = 1;
255 for (typename T::DataContainer::iterator i = this->data.begin();
256 i != this->data.end(); ++i) {
257 Name deleteCommandName("/repo/command/delete");
258 RepoCommandParameter deleteParameter;
259 static boost::random::mt19937_64 gen;
260 static boost::random::uniform_int_distribution<uint64_t> dist(0, 0xFFFFFFFFFFFFFFFFLL);
261 deleteParameter.setProcessId(dist(gen));
262 deleteParameter.setName((*i)->getName());
263 deleteCommandName.append(deleteParameter.wireEncode());
264 Interest deleteInterest(deleteCommandName);
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000265 keyChain.sign(deleteInterest);
Shuo Chenca329182014-03-19 18:05:18 -0700266 scheduler.scheduleEvent(milliseconds(4000 + timeCount * 50),
267 bind(&Fixture<T>::sendDeleteInterest, this, deleteInterest));
268 timeCount++;
269 }
270}
271
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700272typedef boost::mpl::vector< BasicDataset,
273 FetchByPrefixDataset,
274 BasicChildSelectorDataset,
275 ExtendedChildSelectorDataset,
276 SamePrefixDataset<10> > Datasets;
277
278BOOST_FIXTURE_TEST_CASE_TEMPLATE(InsertDelete, T, Datasets, Fixture<T>)
Shuo Chenca329182014-03-19 18:05:18 -0700279{
Shuo Chenca329182014-03-19 18:05:18 -0700280 // schedule events
281 this->scheduler.scheduleEvent(seconds(0),
282 bind(&Fixture<T>::scheduleInsertEvent, this));
283 this->scheduler.scheduleEvent(seconds(10),
284 bind(&Fixture<T>::scheduleDeleteEvent, this));
285
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000286 this->repoFace.processEvents(seconds(30));
Shuo Chenca329182014-03-19 18:05:18 -0700287}
288
289BOOST_AUTO_TEST_SUITE_END()
290
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800291} // namespace tests
292} // namespace repo