blob: 55d6e6552f4ee73e2a793158213de22463a7cbdd [file] [log] [blame]
Shuo Chenca329182014-03-19 18:05:18 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento49f3a5f2017-09-23 01:36:33 -04002/*
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -04003 * Copyright (c) 2014-2022, 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
Shuo Chenca329182014-03-19 18:05:18 -070020#include "handles/delete-handle.hpp"
weijia yuan82cf9142018-10-21 12:25:02 -070021#include "handles/write-handle.hpp"
22
Weiqi Shif0330d52014-07-09 10:54:27 -070023#include "storage/repo-storage.hpp"
weijia yuan82cf9142018-10-21 12:25:02 -070024#include "storage/sqlite-storage.hpp"
Shuo Chenca329182014-03-19 18:05:18 -070025
Junxiao Shi047a6fb2017-06-08 16:16:05 +000026#include "command-fixture.hpp"
Weiqi Shif0330d52014-07-09 10:54:27 -070027#include "../repo-storage-fixture.hpp"
Shuo Chenca329182014-03-19 18:05:18 -070028#include "../dataset-fixtures.hpp"
29
Davide Pesavento75e8d462021-05-16 17:00:42 -040030#include <ndn-cxx/security/interest-signer.hpp>
weijia yuan82cf9142018-10-21 12:25:02 -070031#include <ndn-cxx/security/signing-helpers.hpp>
Shuo Chen028dcd32014-06-21 16:36:44 +080032#include <ndn-cxx/util/random.hpp>
weijia yuan82cf9142018-10-21 12:25:02 -070033#include <ndn-cxx/util/time.hpp>
Davide Pesavento49f3a5f2017-09-23 01:36:33 -040034
35#include <boost/mpl/vector.hpp>
Shuo Chenca329182014-03-19 18:05:18 -070036#include <boost/test/unit_test.hpp>
37
Davide Pesavento11904062022-04-14 22:33:28 -040038namespace repo::tests {
Shuo Chenca329182014-03-19 18:05:18 -070039
40using ndn::time::milliseconds;
weijia yuan3aa8d2b2018-03-06 15:35:57 -080041
Davide Pesavento49f3a5f2017-09-23 01:36:33 -040042// All the test cases in this test suite should be run at once.
Shuo Chenca329182014-03-19 18:05:18 -070043BOOST_AUTO_TEST_SUITE(TestBasicCommandInsertDelete)
44
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -040045const uint8_t CONTENT[] = {3, 1, 4, 1, 5, 9, 2, 6};
Shuo Chenca329182014-03-19 18:05:18 -070046
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()
weijia yuan82cf9142018-10-21 12:25:02 -070052 : writeHandle(repoFace, *handle, dispatcher, scheduler, validator)
53 , deleteHandle(repoFace, *handle, dispatcher, scheduler, validator)
Shuo Chenca329182014-03-19 18:05:18 -070054 , insertFace(repoFace.getIoService())
55 , deleteFace(repoFace.getIoService())
weijia yuan3aa8d2b2018-03-06 15:35:57 -080056 , signer(keyChain)
Shuo Chenca329182014-03-19 18:05:18 -070057 {
Junxiao Shi2b7b8312017-06-16 03:43:24 +000058 Name cmdPrefix("/repo/command");
59 repoFace.registerPrefix(cmdPrefix, nullptr,
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -040060 [] (const Name&, const std::string& reason) {
Junxiao Shi2b7b8312017-06-16 03:43:24 +000061 BOOST_FAIL("Command prefix registration error: " << reason);
62 });
Shuo Chenca329182014-03-19 18:05:18 -070063 }
64
Shuo Chen028dcd32014-06-21 16:36:44 +080065 void
Shuo Chenca329182014-03-19 18:05:18 -070066 scheduleInsertEvent();
67
68 void
69 scheduleDeleteEvent();
70
71 void
72 onInsertInterest(const Interest& interest);
73
74 void
75 onRegisterFailed(const std::string& reason);
76
77 void
78 delayedInterest();
79
80 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -080081 onInsertData(const Interest& interest, const Data& data);
Shuo Chenca329182014-03-19 18:05:18 -070082
83 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -080084 onDeleteData(const Interest& interest, const Data& data);
Shuo Chenca329182014-03-19 18:05:18 -070085
86 void
87 onInsertTimeout(const Interest& interest);
88
89 void
90 onDeleteTimeout(const Interest& interest);
91
92 void
93 sendInsertInterest(const Interest& interest);
94
95 void
96 sendDeleteInterest(const Interest& deleteInterest);
97
98 void
Shuo Chen028dcd32014-06-21 16:36:44 +080099 checkInsertOk(const Interest& interest);
Shuo Chenca329182014-03-19 18:05:18 -0700100
101 void
Shuo Chen028dcd32014-06-21 16:36:44 +0800102 checkDeleteOk(const Interest& interest);
Shuo Chenca329182014-03-19 18:05:18 -0700103
104public:
Shuo Chenca329182014-03-19 18:05:18 -0700105 WriteHandle writeHandle;
106 DeleteHandle deleteHandle;
107 Face insertFace;
108 Face deleteFace;
Davide Pesavento9a8d7d82019-03-15 20:14:25 -0400109 std::map<Name, ndn::scheduler::EventId> insertEvents;
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800110 std::map<Name, Name> deleteNamePairs;
Davide Pesavento75e8d462021-05-16 17:00:42 -0400111 ndn::security::InterestSigner signer;
Shuo Chenca329182014-03-19 18:05:18 -0700112};
113
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400114template<class T>
115void
Shuo Chenca329182014-03-19 18:05:18 -0700116Fixture<T>::onInsertInterest(const Interest& interest)
117{
118 Data data(Name(interest.getName()));
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400119 data.setContent(CONTENT);
weijia yuan82cf9142018-10-21 12:25:02 -0700120 data.setFreshnessPeriod(0_ms);
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000121 keyChain.sign(data);
Shuo Chenca329182014-03-19 18:05:18 -0700122 insertFace.put(data);
Davide Pesavento9a8d7d82019-03-15 20:14:25 -0400123 auto eventIt = insertEvents.find(interest.getName());
124 if (eventIt != insertEvents.end()) {
125 eventIt->second.cancel();
126 insertEvents.erase(eventIt);
Shuo Chenca329182014-03-19 18:05:18 -0700127 }
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400128
129 // schedule an event to check whether insert is ok
130 scheduler.schedule(500_ms, [=] { this->checkInsertOk(interest); });
Shuo Chenca329182014-03-19 18:05:18 -0700131}
132
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400133template<class T>
134void
Shuo Chenca329182014-03-19 18:05:18 -0700135Fixture<T>::onRegisterFailed(const std::string& reason)
136{
137 BOOST_ERROR("ERROR: Failed to register prefix in local hub's daemon" + reason);
138}
139
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400140template<class T>
141void
Shuo Chenca329182014-03-19 18:05:18 -0700142Fixture<T>::delayedInterest()
143{
144 BOOST_ERROR("Fetching interest does not come. It may be satisfied in CS or something is wrong");
145}
146
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400147template<class T>
148void
149Fixture<T>::onInsertData(const Interest&, const Data& data)
Shuo Chenca329182014-03-19 18:05:18 -0700150{
151 RepoCommandResponse response;
152 response.wireDecode(data.getContent().blockFromValue());
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400153 BOOST_CHECK_EQUAL(response.getCode(), 100);
Shuo Chenca329182014-03-19 18:05:18 -0700154}
155
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400156template<class T>
157void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800158Fixture<T>::onDeleteData(const Interest& interest, const Data& data)
Shuo Chenca329182014-03-19 18:05:18 -0700159{
160 RepoCommandResponse response;
161 response.wireDecode(data.getContent().blockFromValue());
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400162 BOOST_CHECK_EQUAL(response.getCode(), 200);
Shuo Chenca329182014-03-19 18:05:18 -0700163
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400164 // schedule an event to check whether delete is ok
165 scheduler.schedule(100_ms, [=] { this->checkDeleteOk(interest); });
Shuo Chenca329182014-03-19 18:05:18 -0700166}
167
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400168template<class T>
169void
170Fixture<T>::onInsertTimeout(const Interest&)
Shuo Chenca329182014-03-19 18:05:18 -0700171{
Junxiao Shi2b7b8312017-06-16 03:43:24 +0000172 BOOST_ERROR("Insert command timeout");
Shuo Chenca329182014-03-19 18:05:18 -0700173}
174
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400175template<class T>
176void
177Fixture<T>::onDeleteTimeout(const Interest&)
Shuo Chenca329182014-03-19 18:05:18 -0700178{
Junxiao Shi2b7b8312017-06-16 03:43:24 +0000179 BOOST_ERROR("Delete command timeout");
Shuo Chenca329182014-03-19 18:05:18 -0700180}
181
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400182template<class T>
183void
Shuo Chenca329182014-03-19 18:05:18 -0700184Fixture<T>::sendInsertInterest(const Interest& insertInterest)
185{
186 insertFace.expressInterest(insertInterest,
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800187 std::bind(&Fixture<T>::onInsertData, this, _1, _2),
188 std::bind(&Fixture<T>::onInsertTimeout, this, _1), // Nack
189 std::bind(&Fixture<T>::onInsertTimeout, this, _1));
Shuo Chenca329182014-03-19 18:05:18 -0700190}
191
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400192template<class T>
193void
Shuo Chenca329182014-03-19 18:05:18 -0700194Fixture<T>::sendDeleteInterest(const Interest& deleteInterest)
195{
196 deleteFace.expressInterest(deleteInterest,
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800197 std::bind(&Fixture<T>::onDeleteData, this, _1, _2),
198 std::bind(&Fixture<T>::onDeleteTimeout, this, _1), // Nack
199 std::bind(&Fixture<T>::onDeleteTimeout, this, _1));
Shuo Chenca329182014-03-19 18:05:18 -0700200}
201
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400202template<class T>
203void
Shuo Chen028dcd32014-06-21 16:36:44 +0800204Fixture<T>::checkInsertOk(const Interest& interest)
Shuo Chenca329182014-03-19 18:05:18 -0700205{
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400206 BOOST_TEST_CONTEXT("Interest " << interest) {
207 auto data = handle->readData(interest);
208 if (data) {
209 BOOST_TEST(data->getContent().value_bytes() == CONTENT, boost::test_tools::per_element());
210 }
211 else {
212 BOOST_ERROR("Insert check failed");
213 }
Weiqi Shif0330d52014-07-09 10:54:27 -0700214 }
Shuo Chenca329182014-03-19 18:05:18 -0700215}
216
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400217template<class T>
218void
Shuo Chen028dcd32014-06-21 16:36:44 +0800219Fixture<T>::checkDeleteOk(const Interest& interest)
Shuo Chenca329182014-03-19 18:05:18 -0700220{
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400221 auto nameIt = deleteNamePairs.find(interest.getName());
222 BOOST_CHECK_MESSAGE(nameIt != deleteNamePairs.end(), "Delete name not found: " << interest.getName());
223 Interest dataInterest(nameIt->second);
224 auto data = handle->readData(dataInterest);
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800225 BOOST_CHECK(!data);
Shuo Chenca329182014-03-19 18:05:18 -0700226}
227
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400228template<class T>
229void
Shuo Chenca329182014-03-19 18:05:18 -0700230Fixture<T>::scheduleInsertEvent()
231{
232 int timeCount = 1;
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400233 for (auto i = this->data.begin(); i != this->data.end(); ++i) {
Shuo Chenca329182014-03-19 18:05:18 -0700234 Name insertCommandName("/repo/command/insert");
235 RepoCommandParameter insertParameter;
236 insertParameter.setName(Name((*i)->getName())
Davide Pesavento49f3a5f2017-09-23 01:36:33 -0400237 .appendNumber(ndn::random::generateWord64()));
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400238 insertCommandName.append(tlv::GenericNameComponent, insertParameter.wireEncode());
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800239 Interest insertInterest = signer.makeCommandInterest(insertCommandName);
weijia yuan82cf9142018-10-21 12:25:02 -0700240 // schedule a job to express insertInterest every 50ms
Davide Pesavento8891c832019-03-20 23:20:35 -0400241 scheduler.schedule(milliseconds(timeCount * 50 + 1000),
242 std::bind(&Fixture<T>::sendInsertInterest, this, insertInterest));
weijia yuan82cf9142018-10-21 12:25:02 -0700243 // schedule what to do when interest timeout
Davide Pesavento8891c832019-03-20 23:20:35 -0400244 auto delayEventId = scheduler.schedule(milliseconds(5000 + timeCount * 50),
245 std::bind(&Fixture<T>::delayedInterest, this));
Shuo Chenca329182014-03-19 18:05:18 -0700246 insertEvents[insertParameter.getName()] = delayEventId;
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800247 // The delayEvent will be canceled in onInsertInterest
Shuo Chenca329182014-03-19 18:05:18 -0700248 insertFace.setInterestFilter(insertParameter.getName(),
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800249 std::bind(&Fixture<T>::onInsertInterest, this, _2),
Wentao Shang91fb4f22014-05-20 10:55:22 -0700250 ndn::RegisterPrefixSuccessCallback(),
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800251 std::bind(&Fixture<T>::onRegisterFailed, this, _2));
Shuo Chenca329182014-03-19 18:05:18 -0700252 timeCount++;
253 }
254}
255
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400256template<class T>
257void
Shuo Chenca329182014-03-19 18:05:18 -0700258Fixture<T>::scheduleDeleteEvent()
259{
260 int timeCount = 1;
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400261 for (auto i = this->data.begin(); i != this->data.end(); ++i) {
Shuo Chenca329182014-03-19 18:05:18 -0700262 Name deleteCommandName("/repo/command/delete");
263 RepoCommandParameter deleteParameter;
Davide Pesavento49f3a5f2017-09-23 01:36:33 -0400264 deleteParameter.setProcessId(ndn::random::generateWord64());
Shuo Chenca329182014-03-19 18:05:18 -0700265 deleteParameter.setName((*i)->getName());
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400266 deleteCommandName.append(tlv::GenericNameComponent, deleteParameter.wireEncode());
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800267 Interest deleteInterest = signer.makeCommandInterest(deleteCommandName);
268 deleteNamePairs[deleteInterest.getName()] = (*i)->getName();
Davide Pesavento8891c832019-03-20 23:20:35 -0400269 scheduler.schedule(milliseconds(4000 + timeCount * 50),
270 std::bind(&Fixture<T>::sendDeleteInterest, this, deleteInterest));
Shuo Chenca329182014-03-19 18:05:18 -0700271 timeCount++;
272 }
273}
274
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800275using Datasets = boost::mpl::vector<BasicDataset,
276 FetchByPrefixDataset,
277 SamePrefixDataset<10>>;
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700278
279BOOST_FIXTURE_TEST_CASE_TEMPLATE(InsertDelete, T, Datasets, Fixture<T>)
Shuo Chenca329182014-03-19 18:05:18 -0700280{
Shuo Chenca329182014-03-19 18:05:18 -0700281 // schedule events
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400282 this->scheduler.schedule(0_s, [this] { this->scheduleInsertEvent(); });
283 this->scheduler.schedule(10_s, [this] { this->scheduleDeleteEvent(); });
Shuo Chenca329182014-03-19 18:05:18 -0700284
weijia yuan82cf9142018-10-21 12:25:02 -0700285 this->repoFace.processEvents(30_s);
Shuo Chenca329182014-03-19 18:05:18 -0700286}
287
288BOOST_AUTO_TEST_SUITE_END()
289
Davide Pesavento11904062022-04-14 22:33:28 -0400290} // namespace repo::tests