blob: 5ed5b9b0e04a34a5e840d65fdddd82c8accce1f4 [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
38namespace repo {
39namespace tests {
40
41using ndn::time::milliseconds;
weijia yuan3aa8d2b2018-03-06 15:35:57 -080042
Davide Pesavento49f3a5f2017-09-23 01:36:33 -040043// All the test cases in this test suite should be run at once.
Shuo Chenca329182014-03-19 18:05:18 -070044BOOST_AUTO_TEST_SUITE(TestBasicCommandInsertDelete)
45
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -040046const uint8_t CONTENT[] = {3, 1, 4, 1, 5, 9, 2, 6};
Shuo Chenca329182014-03-19 18:05:18 -070047
48template<class Dataset>
Junxiao Shi047a6fb2017-06-08 16:16:05 +000049class Fixture : public CommandFixture, public RepoStorageFixture, public Dataset
Shuo Chenca329182014-03-19 18:05:18 -070050{
51public:
52 Fixture()
weijia yuan82cf9142018-10-21 12:25:02 -070053 : writeHandle(repoFace, *handle, dispatcher, scheduler, validator)
54 , deleteHandle(repoFace, *handle, dispatcher, scheduler, validator)
Shuo Chenca329182014-03-19 18:05:18 -070055 , insertFace(repoFace.getIoService())
56 , deleteFace(repoFace.getIoService())
weijia yuan3aa8d2b2018-03-06 15:35:57 -080057 , signer(keyChain)
Shuo Chenca329182014-03-19 18:05:18 -070058 {
Junxiao Shi2b7b8312017-06-16 03:43:24 +000059 Name cmdPrefix("/repo/command");
60 repoFace.registerPrefix(cmdPrefix, nullptr,
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -040061 [] (const Name&, const std::string& reason) {
Junxiao Shi2b7b8312017-06-16 03:43:24 +000062 BOOST_FAIL("Command prefix registration error: " << reason);
63 });
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;
Davide Pesavento9a8d7d82019-03-15 20:14:25 -0400110 std::map<Name, ndn::scheduler::EventId> insertEvents;
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800111 std::map<Name, Name> deleteNamePairs;
Davide Pesavento75e8d462021-05-16 17:00:42 -0400112 ndn::security::InterestSigner signer;
Shuo Chenca329182014-03-19 18:05:18 -0700113};
114
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400115template<class T>
116void
Shuo Chenca329182014-03-19 18:05:18 -0700117Fixture<T>::onInsertInterest(const Interest& interest)
118{
119 Data data(Name(interest.getName()));
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400120 data.setContent(CONTENT);
weijia yuan82cf9142018-10-21 12:25:02 -0700121 data.setFreshnessPeriod(0_ms);
Junxiao Shi047a6fb2017-06-08 16:16:05 +0000122 keyChain.sign(data);
Shuo Chenca329182014-03-19 18:05:18 -0700123 insertFace.put(data);
Davide Pesavento9a8d7d82019-03-15 20:14:25 -0400124 auto eventIt = insertEvents.find(interest.getName());
125 if (eventIt != insertEvents.end()) {
126 eventIt->second.cancel();
127 insertEvents.erase(eventIt);
Shuo Chenca329182014-03-19 18:05:18 -0700128 }
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400129
130 // schedule an event to check whether insert is ok
131 scheduler.schedule(500_ms, [=] { this->checkInsertOk(interest); });
Shuo Chenca329182014-03-19 18:05:18 -0700132}
133
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400134template<class T>
135void
Shuo Chenca329182014-03-19 18:05:18 -0700136Fixture<T>::onRegisterFailed(const std::string& reason)
137{
138 BOOST_ERROR("ERROR: Failed to register prefix in local hub's daemon" + reason);
139}
140
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400141template<class T>
142void
Shuo Chenca329182014-03-19 18:05:18 -0700143Fixture<T>::delayedInterest()
144{
145 BOOST_ERROR("Fetching interest does not come. It may be satisfied in CS or something is wrong");
146}
147
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400148template<class T>
149void
150Fixture<T>::onInsertData(const Interest&, const Data& data)
Shuo Chenca329182014-03-19 18:05:18 -0700151{
152 RepoCommandResponse response;
153 response.wireDecode(data.getContent().blockFromValue());
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400154 BOOST_CHECK_EQUAL(response.getCode(), 100);
Shuo Chenca329182014-03-19 18:05:18 -0700155}
156
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400157template<class T>
158void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800159Fixture<T>::onDeleteData(const Interest& interest, const Data& data)
Shuo Chenca329182014-03-19 18:05:18 -0700160{
161 RepoCommandResponse response;
162 response.wireDecode(data.getContent().blockFromValue());
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400163 BOOST_CHECK_EQUAL(response.getCode(), 200);
Shuo Chenca329182014-03-19 18:05:18 -0700164
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400165 // schedule an event to check whether delete is ok
166 scheduler.schedule(100_ms, [=] { this->checkDeleteOk(interest); });
Shuo Chenca329182014-03-19 18:05:18 -0700167}
168
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400169template<class T>
170void
171Fixture<T>::onInsertTimeout(const Interest&)
Shuo Chenca329182014-03-19 18:05:18 -0700172{
Junxiao Shi2b7b8312017-06-16 03:43:24 +0000173 BOOST_ERROR("Insert command timeout");
Shuo Chenca329182014-03-19 18:05:18 -0700174}
175
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400176template<class T>
177void
178Fixture<T>::onDeleteTimeout(const Interest&)
Shuo Chenca329182014-03-19 18:05:18 -0700179{
Junxiao Shi2b7b8312017-06-16 03:43:24 +0000180 BOOST_ERROR("Delete command timeout");
Shuo Chenca329182014-03-19 18:05:18 -0700181}
182
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400183template<class T>
184void
Shuo Chenca329182014-03-19 18:05:18 -0700185Fixture<T>::sendInsertInterest(const Interest& insertInterest)
186{
187 insertFace.expressInterest(insertInterest,
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800188 std::bind(&Fixture<T>::onInsertData, this, _1, _2),
189 std::bind(&Fixture<T>::onInsertTimeout, this, _1), // Nack
190 std::bind(&Fixture<T>::onInsertTimeout, this, _1));
Shuo Chenca329182014-03-19 18:05:18 -0700191}
192
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400193template<class T>
194void
Shuo Chenca329182014-03-19 18:05:18 -0700195Fixture<T>::sendDeleteInterest(const Interest& deleteInterest)
196{
197 deleteFace.expressInterest(deleteInterest,
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800198 std::bind(&Fixture<T>::onDeleteData, this, _1, _2),
199 std::bind(&Fixture<T>::onDeleteTimeout, this, _1), // Nack
200 std::bind(&Fixture<T>::onDeleteTimeout, this, _1));
Shuo Chenca329182014-03-19 18:05:18 -0700201}
202
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400203template<class T>
204void
Shuo Chen028dcd32014-06-21 16:36:44 +0800205Fixture<T>::checkInsertOk(const Interest& interest)
Shuo Chenca329182014-03-19 18:05:18 -0700206{
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400207 BOOST_TEST_CONTEXT("Interest " << interest) {
208 auto data = handle->readData(interest);
209 if (data) {
210 BOOST_TEST(data->getContent().value_bytes() == CONTENT, boost::test_tools::per_element());
211 }
212 else {
213 BOOST_ERROR("Insert check failed");
214 }
Weiqi Shif0330d52014-07-09 10:54:27 -0700215 }
Shuo Chenca329182014-03-19 18:05:18 -0700216}
217
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400218template<class T>
219void
Shuo Chen028dcd32014-06-21 16:36:44 +0800220Fixture<T>::checkDeleteOk(const Interest& interest)
Shuo Chenca329182014-03-19 18:05:18 -0700221{
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400222 auto nameIt = deleteNamePairs.find(interest.getName());
223 BOOST_CHECK_MESSAGE(nameIt != deleteNamePairs.end(), "Delete name not found: " << interest.getName());
224 Interest dataInterest(nameIt->second);
225 auto data = handle->readData(dataInterest);
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800226 BOOST_CHECK(!data);
Shuo Chenca329182014-03-19 18:05:18 -0700227}
228
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400229template<class T>
230void
Shuo Chenca329182014-03-19 18:05:18 -0700231Fixture<T>::scheduleInsertEvent()
232{
233 int timeCount = 1;
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400234 for (auto i = this->data.begin(); i != this->data.end(); ++i) {
Shuo Chenca329182014-03-19 18:05:18 -0700235 Name insertCommandName("/repo/command/insert");
236 RepoCommandParameter insertParameter;
237 insertParameter.setName(Name((*i)->getName())
Davide Pesavento49f3a5f2017-09-23 01:36:33 -0400238 .appendNumber(ndn::random::generateWord64()));
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400239 insertCommandName.append(tlv::GenericNameComponent, insertParameter.wireEncode());
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800240 Interest insertInterest = signer.makeCommandInterest(insertCommandName);
weijia yuan82cf9142018-10-21 12:25:02 -0700241 // schedule a job to express insertInterest every 50ms
Davide Pesavento8891c832019-03-20 23:20:35 -0400242 scheduler.schedule(milliseconds(timeCount * 50 + 1000),
243 std::bind(&Fixture<T>::sendInsertInterest, this, insertInterest));
weijia yuan82cf9142018-10-21 12:25:02 -0700244 // schedule what to do when interest timeout
Davide Pesavento8891c832019-03-20 23:20:35 -0400245 auto delayEventId = scheduler.schedule(milliseconds(5000 + timeCount * 50),
246 std::bind(&Fixture<T>::delayedInterest, this));
Shuo Chenca329182014-03-19 18:05:18 -0700247 insertEvents[insertParameter.getName()] = delayEventId;
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800248 // The delayEvent will be canceled in onInsertInterest
Shuo Chenca329182014-03-19 18:05:18 -0700249 insertFace.setInterestFilter(insertParameter.getName(),
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800250 std::bind(&Fixture<T>::onInsertInterest, this, _2),
Wentao Shang91fb4f22014-05-20 10:55:22 -0700251 ndn::RegisterPrefixSuccessCallback(),
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800252 std::bind(&Fixture<T>::onRegisterFailed, this, _2));
Shuo Chenca329182014-03-19 18:05:18 -0700253 timeCount++;
254 }
255}
256
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400257template<class T>
258void
Shuo Chenca329182014-03-19 18:05:18 -0700259Fixture<T>::scheduleDeleteEvent()
260{
261 int timeCount = 1;
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400262 for (auto i = this->data.begin(); i != this->data.end(); ++i) {
Shuo Chenca329182014-03-19 18:05:18 -0700263 Name deleteCommandName("/repo/command/delete");
264 RepoCommandParameter deleteParameter;
Davide Pesavento49f3a5f2017-09-23 01:36:33 -0400265 deleteParameter.setProcessId(ndn::random::generateWord64());
Shuo Chenca329182014-03-19 18:05:18 -0700266 deleteParameter.setName((*i)->getName());
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400267 deleteCommandName.append(tlv::GenericNameComponent, deleteParameter.wireEncode());
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800268 Interest deleteInterest = signer.makeCommandInterest(deleteCommandName);
269 deleteNamePairs[deleteInterest.getName()] = (*i)->getName();
Davide Pesavento8891c832019-03-20 23:20:35 -0400270 scheduler.schedule(milliseconds(4000 + timeCount * 50),
271 std::bind(&Fixture<T>::sendDeleteInterest, this, deleteInterest));
Shuo Chenca329182014-03-19 18:05:18 -0700272 timeCount++;
273 }
274}
275
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800276using Datasets = boost::mpl::vector<BasicDataset,
277 FetchByPrefixDataset,
278 SamePrefixDataset<10>>;
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700279
280BOOST_FIXTURE_TEST_CASE_TEMPLATE(InsertDelete, T, Datasets, Fixture<T>)
Shuo Chenca329182014-03-19 18:05:18 -0700281{
Shuo Chenca329182014-03-19 18:05:18 -0700282 // schedule events
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400283 this->scheduler.schedule(0_s, [this] { this->scheduleInsertEvent(); });
284 this->scheduler.schedule(10_s, [this] { this->scheduleDeleteEvent(); });
Shuo Chenca329182014-03-19 18:05:18 -0700285
weijia yuan82cf9142018-10-21 12:25:02 -0700286 this->repoFace.processEvents(30_s);
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