blob: f1a9110ad2ad8bd768eba8a85e772cc79042db81 [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 Pesaventob5e57652023-09-17 15:18:08 -04003 * Copyright (c) 2014-2023, 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
Shuo Chenca329182014-03-19 18:05:18 -070035#include <boost/test/unit_test.hpp>
36
Davide Pesavento11904062022-04-14 22:33:28 -040037namespace repo::tests {
Shuo Chenca329182014-03-19 18:05:18 -070038
39using ndn::time::milliseconds;
weijia yuan3aa8d2b2018-03-06 15:35:57 -080040
Davide Pesavento49f3a5f2017-09-23 01:36:33 -040041// All the test cases in this test suite should be run at once.
Shuo Chenca329182014-03-19 18:05:18 -070042BOOST_AUTO_TEST_SUITE(TestBasicCommandInsertDelete)
43
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -040044const uint8_t CONTENT[] = {3, 1, 4, 1, 5, 9, 2, 6};
Shuo Chenca329182014-03-19 18:05:18 -070045
46template<class Dataset>
Junxiao Shi047a6fb2017-06-08 16:16:05 +000047class Fixture : public CommandFixture, public RepoStorageFixture, public Dataset
Shuo Chenca329182014-03-19 18:05:18 -070048{
49public:
50 Fixture()
weijia yuan82cf9142018-10-21 12:25:02 -070051 : writeHandle(repoFace, *handle, dispatcher, scheduler, validator)
52 , deleteHandle(repoFace, *handle, dispatcher, scheduler, validator)
Davide Pesavento164ae3b2023-11-11 22:00:23 -050053 , insertFace(repoFace.getIoContext())
54 , deleteFace(repoFace.getIoContext())
55 , signer(m_keyChain)
Shuo Chenca329182014-03-19 18:05:18 -070056 {
Junxiao Shi2b7b8312017-06-16 03:43:24 +000057 Name cmdPrefix("/repo/command");
58 repoFace.registerPrefix(cmdPrefix, nullptr,
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -040059 [] (const Name&, const std::string& reason) {
Junxiao Shi2b7b8312017-06-16 03:43:24 +000060 BOOST_FAIL("Command prefix registration error: " << reason);
61 });
Shuo Chenca329182014-03-19 18:05:18 -070062 }
63
Shuo Chen028dcd32014-06-21 16:36:44 +080064 void
Shuo Chenca329182014-03-19 18:05:18 -070065 scheduleInsertEvent();
66
67 void
68 scheduleDeleteEvent();
69
70 void
71 onInsertInterest(const Interest& interest);
72
73 void
74 onRegisterFailed(const std::string& reason);
75
76 void
77 delayedInterest();
78
79 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -080080 onInsertData(const Interest& interest, const Data& data);
Shuo Chenca329182014-03-19 18:05:18 -070081
82 void
Alexander Afanasyev42290b22017-03-09 12:58:29 -080083 onDeleteData(const Interest& interest, const Data& data);
Shuo Chenca329182014-03-19 18:05:18 -070084
85 void
86 onInsertTimeout(const Interest& interest);
87
88 void
89 onDeleteTimeout(const Interest& interest);
90
91 void
92 sendInsertInterest(const Interest& interest);
93
94 void
95 sendDeleteInterest(const Interest& deleteInterest);
96
97 void
Shuo Chen028dcd32014-06-21 16:36:44 +080098 checkInsertOk(const Interest& interest);
Shuo Chenca329182014-03-19 18:05:18 -070099
100 void
Shuo Chen028dcd32014-06-21 16:36:44 +0800101 checkDeleteOk(const Interest& interest);
Shuo Chenca329182014-03-19 18:05:18 -0700102
103public:
Shuo Chenca329182014-03-19 18:05:18 -0700104 WriteHandle writeHandle;
105 DeleteHandle deleteHandle;
106 Face insertFace;
107 Face deleteFace;
Davide Pesavento9a8d7d82019-03-15 20:14:25 -0400108 std::map<Name, ndn::scheduler::EventId> insertEvents;
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800109 std::map<Name, Name> deleteNamePairs;
Davide Pesavento75e8d462021-05-16 17:00:42 -0400110 ndn::security::InterestSigner signer;
Shuo Chenca329182014-03-19 18:05:18 -0700111};
112
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400113template<class T>
114void
Shuo Chenca329182014-03-19 18:05:18 -0700115Fixture<T>::onInsertInterest(const Interest& interest)
116{
Davide Pesavento164ae3b2023-11-11 22:00:23 -0500117 Data data(interest.getName());
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400118 data.setContent(CONTENT);
Davide Pesavento164ae3b2023-11-11 22:00:23 -0500119 m_keyChain.sign(data);
Shuo Chenca329182014-03-19 18:05:18 -0700120 insertFace.put(data);
Davide Pesavento164ae3b2023-11-11 22:00:23 -0500121
Davide Pesavento9a8d7d82019-03-15 20:14:25 -0400122 auto eventIt = insertEvents.find(interest.getName());
123 if (eventIt != insertEvents.end()) {
124 eventIt->second.cancel();
125 insertEvents.erase(eventIt);
Shuo Chenca329182014-03-19 18:05:18 -0700126 }
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400127
128 // schedule an event to check whether insert is ok
129 scheduler.schedule(500_ms, [=] { this->checkInsertOk(interest); });
Shuo Chenca329182014-03-19 18:05:18 -0700130}
131
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400132template<class T>
133void
Shuo Chenca329182014-03-19 18:05:18 -0700134Fixture<T>::onRegisterFailed(const std::string& reason)
135{
136 BOOST_ERROR("ERROR: Failed to register prefix in local hub's daemon" + reason);
137}
138
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400139template<class T>
140void
Shuo Chenca329182014-03-19 18:05:18 -0700141Fixture<T>::delayedInterest()
142{
143 BOOST_ERROR("Fetching interest does not come. It may be satisfied in CS or something is wrong");
144}
145
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400146template<class T>
147void
148Fixture<T>::onInsertData(const Interest&, const Data& data)
Shuo Chenca329182014-03-19 18:05:18 -0700149{
150 RepoCommandResponse response;
151 response.wireDecode(data.getContent().blockFromValue());
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400152 BOOST_CHECK_EQUAL(response.getCode(), 100);
Shuo Chenca329182014-03-19 18:05:18 -0700153}
154
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400155template<class T>
156void
Alexander Afanasyev42290b22017-03-09 12:58:29 -0800157Fixture<T>::onDeleteData(const Interest& interest, const Data& data)
Shuo Chenca329182014-03-19 18:05:18 -0700158{
159 RepoCommandResponse response;
160 response.wireDecode(data.getContent().blockFromValue());
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400161 BOOST_CHECK_EQUAL(response.getCode(), 200);
Shuo Chenca329182014-03-19 18:05:18 -0700162
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400163 // schedule an event to check whether delete is ok
164 scheduler.schedule(100_ms, [=] { this->checkDeleteOk(interest); });
Shuo Chenca329182014-03-19 18:05:18 -0700165}
166
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400167template<class T>
168void
169Fixture<T>::onInsertTimeout(const Interest&)
Shuo Chenca329182014-03-19 18:05:18 -0700170{
Junxiao Shi2b7b8312017-06-16 03:43:24 +0000171 BOOST_ERROR("Insert command timeout");
Shuo Chenca329182014-03-19 18:05:18 -0700172}
173
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400174template<class T>
175void
176Fixture<T>::onDeleteTimeout(const Interest&)
Shuo Chenca329182014-03-19 18:05:18 -0700177{
Junxiao Shi2b7b8312017-06-16 03:43:24 +0000178 BOOST_ERROR("Delete command timeout");
Shuo Chenca329182014-03-19 18:05:18 -0700179}
180
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400181template<class T>
182void
Shuo Chenca329182014-03-19 18:05:18 -0700183Fixture<T>::sendInsertInterest(const Interest& insertInterest)
184{
185 insertFace.expressInterest(insertInterest,
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800186 std::bind(&Fixture<T>::onInsertData, this, _1, _2),
187 std::bind(&Fixture<T>::onInsertTimeout, this, _1), // Nack
188 std::bind(&Fixture<T>::onInsertTimeout, this, _1));
Shuo Chenca329182014-03-19 18:05:18 -0700189}
190
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400191template<class T>
192void
Shuo Chenca329182014-03-19 18:05:18 -0700193Fixture<T>::sendDeleteInterest(const Interest& deleteInterest)
194{
195 deleteFace.expressInterest(deleteInterest,
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800196 std::bind(&Fixture<T>::onDeleteData, this, _1, _2),
197 std::bind(&Fixture<T>::onDeleteTimeout, this, _1), // Nack
198 std::bind(&Fixture<T>::onDeleteTimeout, this, _1));
Shuo Chenca329182014-03-19 18:05:18 -0700199}
200
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400201template<class T>
202void
Shuo Chen028dcd32014-06-21 16:36:44 +0800203Fixture<T>::checkInsertOk(const Interest& interest)
Shuo Chenca329182014-03-19 18:05:18 -0700204{
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400205 BOOST_TEST_CONTEXT("Interest " << interest) {
206 auto data = handle->readData(interest);
207 if (data) {
208 BOOST_TEST(data->getContent().value_bytes() == CONTENT, boost::test_tools::per_element());
209 }
210 else {
211 BOOST_ERROR("Insert check failed");
212 }
Weiqi Shif0330d52014-07-09 10:54:27 -0700213 }
Shuo Chenca329182014-03-19 18:05:18 -0700214}
215
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400216template<class T>
217void
Shuo Chen028dcd32014-06-21 16:36:44 +0800218Fixture<T>::checkDeleteOk(const Interest& interest)
Shuo Chenca329182014-03-19 18:05:18 -0700219{
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400220 auto nameIt = deleteNamePairs.find(interest.getName());
221 BOOST_CHECK_MESSAGE(nameIt != deleteNamePairs.end(), "Delete name not found: " << interest.getName());
222 Interest dataInterest(nameIt->second);
223 auto data = handle->readData(dataInterest);
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800224 BOOST_CHECK(!data);
Shuo Chenca329182014-03-19 18:05:18 -0700225}
226
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400227template<class T>
228void
Shuo Chenca329182014-03-19 18:05:18 -0700229Fixture<T>::scheduleInsertEvent()
230{
231 int timeCount = 1;
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400232 for (auto i = this->data.begin(); i != this->data.end(); ++i) {
Shuo Chenca329182014-03-19 18:05:18 -0700233 Name insertCommandName("/repo/command/insert");
234 RepoCommandParameter insertParameter;
235 insertParameter.setName(Name((*i)->getName())
Davide Pesavento49f3a5f2017-09-23 01:36:33 -0400236 .appendNumber(ndn::random::generateWord64()));
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400237 insertCommandName.append(tlv::GenericNameComponent, insertParameter.wireEncode());
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800238 Interest insertInterest = signer.makeCommandInterest(insertCommandName);
weijia yuan82cf9142018-10-21 12:25:02 -0700239 // schedule a job to express insertInterest every 50ms
Davide Pesavento8891c832019-03-20 23:20:35 -0400240 scheduler.schedule(milliseconds(timeCount * 50 + 1000),
241 std::bind(&Fixture<T>::sendInsertInterest, this, insertInterest));
weijia yuan82cf9142018-10-21 12:25:02 -0700242 // schedule what to do when interest timeout
Davide Pesavento8891c832019-03-20 23:20:35 -0400243 auto delayEventId = scheduler.schedule(milliseconds(5000 + timeCount * 50),
244 std::bind(&Fixture<T>::delayedInterest, this));
Shuo Chenca329182014-03-19 18:05:18 -0700245 insertEvents[insertParameter.getName()] = delayEventId;
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800246 // The delayEvent will be canceled in onInsertInterest
Shuo Chenca329182014-03-19 18:05:18 -0700247 insertFace.setInterestFilter(insertParameter.getName(),
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800248 std::bind(&Fixture<T>::onInsertInterest, this, _2),
Wentao Shang91fb4f22014-05-20 10:55:22 -0700249 ndn::RegisterPrefixSuccessCallback(),
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800250 std::bind(&Fixture<T>::onRegisterFailed, this, _2));
Shuo Chenca329182014-03-19 18:05:18 -0700251 timeCount++;
252 }
253}
254
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400255template<class T>
256void
Shuo Chenca329182014-03-19 18:05:18 -0700257Fixture<T>::scheduleDeleteEvent()
258{
259 int timeCount = 1;
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400260 for (auto i = this->data.begin(); i != this->data.end(); ++i) {
Shuo Chenca329182014-03-19 18:05:18 -0700261 Name deleteCommandName("/repo/command/delete");
262 RepoCommandParameter deleteParameter;
Davide Pesavento49f3a5f2017-09-23 01:36:33 -0400263 deleteParameter.setProcessId(ndn::random::generateWord64());
Shuo Chenca329182014-03-19 18:05:18 -0700264 deleteParameter.setName((*i)->getName());
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400265 deleteCommandName.append(tlv::GenericNameComponent, deleteParameter.wireEncode());
weijia yuan3aa8d2b2018-03-06 15:35:57 -0800266 Interest deleteInterest = signer.makeCommandInterest(deleteCommandName);
267 deleteNamePairs[deleteInterest.getName()] = (*i)->getName();
Davide Pesavento8891c832019-03-20 23:20:35 -0400268 scheduler.schedule(milliseconds(4000 + timeCount * 50),
269 std::bind(&Fixture<T>::sendDeleteInterest, this, deleteInterest));
Shuo Chenca329182014-03-19 18:05:18 -0700270 timeCount++;
271 }
272}
273
Davide Pesaventob5e57652023-09-17 15:18:08 -0400274using Datasets = boost::mp11::mp_list<BasicDataset, FetchByPrefixDataset, SamePrefixDataset<10>>;
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700275
276BOOST_FIXTURE_TEST_CASE_TEMPLATE(InsertDelete, T, Datasets, Fixture<T>)
Shuo Chenca329182014-03-19 18:05:18 -0700277{
Shuo Chenca329182014-03-19 18:05:18 -0700278 // schedule events
Davide Pesavento9c0bd8d2022-03-14 16:48:12 -0400279 this->scheduler.schedule(0_s, [this] { this->scheduleInsertEvent(); });
280 this->scheduler.schedule(10_s, [this] { this->scheduleDeleteEvent(); });
Shuo Chenca329182014-03-19 18:05:18 -0700281
weijia yuan82cf9142018-10-21 12:25:02 -0700282 this->repoFace.processEvents(30_s);
Shuo Chenca329182014-03-19 18:05:18 -0700283}
284
285BOOST_AUTO_TEST_SUITE_END()
286
Davide Pesavento11904062022-04-14 22:33:28 -0400287} // namespace repo::tests