blob: e0b9bc972f002d9514d798c3cb5198604e2785f8 [file] [log] [blame]
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Junxiao Shifadcde52022-02-28 00:38:45 +00003 * Copyright (c) 2014-2022, The University of Memphis
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -05004 *
5 * This file is part of PSync.
6 * See AUTHORS.md for complete list of PSync authors and contributors.
7 *
8 * PSync is free software: you can redistribute it and/or modify it under the terms
Ashlesh Gawande0cf4b602019-01-18 15:58:17 -06009 * of the GNU Lesser General Public License as published by the Free Software Foundation,
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050010 * either version 3 of the License, or (at your option) any later version.
11 *
12 * PSync 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
Ashlesh Gawande0cf4b602019-01-18 15:58:17 -060014 * PURPOSE. See the GNU Lesser General Public License for more details.
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050015 *
Ashlesh Gawande0cf4b602019-01-18 15:58:17 -060016 * You should have received a copy of the GNU Lesser General Public License along with
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050017 * PSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
19
Ashlesh Gawande78b94ad2018-12-13 15:29:19 -060020#include "PSync/full-producer.hpp"
21#include "PSync/consumer.hpp"
22#include "PSync/detail/state.hpp"
Davide Pesaventodb789562020-12-19 23:01:08 -050023#include "PSync/detail/util.hpp"
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050024
Davide Pesavento5b3cf762020-04-03 16:20:04 -040025#include "tests/boost-test.hpp"
Davide Pesaventof91d1df2020-11-25 14:50:41 -050026#include "tests/io-fixture.hpp"
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -040027#include "tests/key-chain-fixture.hpp"
Davide Pesavento5b3cf762020-04-03 16:20:04 -040028
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -040029#include <array>
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050030#include <ndn-cxx/util/dummy-client-face.hpp>
31
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050032namespace psync {
33
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -040034using namespace ndn;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050035
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -040036class FullSyncFixture : public tests::IoFixture, public tests::KeyChainFixture
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050037{
Davide Pesavento5b3cf762020-04-03 16:20:04 -040038protected:
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050039 void
40 addNode(int id)
41 {
Junxiao Shifadcde52022-02-28 00:38:45 +000042 BOOST_ASSERT(id >= 0 && id < MAX_NODES);
Junxiao Shifadcde52022-02-28 00:38:45 +000043 userPrefixes[id] = "/userPrefix" + std::to_string(id);
Davide Pesavento03426ef2022-09-23 19:49:10 -040044 faces[id] = std::make_unique<util::DummyClientFace>(m_io, m_keyChain,
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -040045 util::DummyClientFace::Options{true, true});
Davide Pesavento03426ef2022-09-23 19:49:10 -040046 nodes[id] = std::make_unique<FullProducer>(*faces[id], m_keyChain, 40, syncPrefix, userPrefixes[id],
Junxiao Shifadcde52022-02-28 00:38:45 +000047 [] (const auto&) {});
48 }
Davide Pesaventof91d1df2020-11-25 14:50:41 -050049
Junxiao Shifadcde52022-02-28 00:38:45 +000050 void
51 clearNodes()
52 {
Davide Pesavento03426ef2022-09-23 19:49:10 -040053 nodes = {};
54 faces = {};
55 userPrefixes = {};
Junxiao Shifadcde52022-02-28 00:38:45 +000056 }
57
58 /**
59 * @brief Return a user prefix in the form /userNode<id>-<i>.
60 * @param id update originator node index.
61 * @param i user prefix index.
62 */
Davide Pesavento03426ef2022-09-23 19:49:10 -040063 static Name
64 makeSubPrefix(int id, int i)
Junxiao Shifadcde52022-02-28 00:38:45 +000065 {
66 return "/userNode" + std::to_string(id) + "-" + std::to_string(i);
67 }
68
69 /**
70 * @brief Publish a batch of updates.
71 * @param id node index.
72 * @param min minimum user prefix index.
73 * @param min maximum user prefix index.
74 * @param seq update sequence number.
75 * @post nodes[id] has user nodes /userNode<id>-<i> āˆ€iāˆˆ[min,max] , with sequence number
76 * set to @p seq ; only one sync Data may be sent after the last update.
77 */
78 void
79 batchUpdate(int id, int min, int max, uint64_t seq)
80 {
81 FullProducer& node = *nodes.at(id);
82 for (int i = min; i <= max; i++) {
83 auto userPrefix = makeSubPrefix(id, i);
84 node.addUserNode(userPrefix);
85 if (i < max) {
86 node.updateSeqNo(userPrefix, seq);
87 }
88 else {
89 node.publishName(userPrefix, seq);
90 }
91 }
92 }
93
94 /**
95 * @brief Check sequence number on a batch of user prefixes.
96 * @param id node index where the check is performed.
97 * @param origin update originator node index for deriving user prefixes.
98 * @param min minimum user prefix index.
99 * @param max maximum user prefix index.
100 * @param seq expected sequence number.
101 */
102 void
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400103 batchCheck(int id, int origin, int min, int max, std::optional<uint64_t> seq)
Junxiao Shifadcde52022-02-28 00:38:45 +0000104 {
105 uint64_t expected = seq.value_or(NOT_EXIST);
106 FullProducer& node = *nodes.at(id);
107 for (int i = min; i <= max; i++) {
108 auto userPrefix = makeSubPrefix(origin, i);
109 BOOST_TEST_CONTEXT("node=" << id << " userPrefix=" << userPrefix) {
110 BOOST_CHECK_EQUAL(node.getSeqNo(userPrefix).value_or(NOT_EXIST), expected);
111 }
112 }
113 }
114
115 struct IbfDecodeFailureCounts
116 {
117 size_t aboveThreshold = 0;
118 size_t belowThreshold = 0;
119 };
120
121 /**
122 * @brief Return the sum of IBF decode failure counters among created nodes.
123 */
124 IbfDecodeFailureCounts
125 countIbfDecodeFailures() const
126 {
127 IbfDecodeFailureCounts result;
128 for (const auto& node : nodes) {
129 if (node == nullptr) {
130 continue;
131 }
132 result.aboveThreshold += node->nIbfDecodeFailuresAboveThreshold;
133 result.belowThreshold += node->nIbfDecodeFailuresBelowThreshold;
134 }
135 return result;
136 }
137
138 /**
139 * @brief Repeat a test function until there are IBF decode failures.
140 * @param minTotalUpdates minimum totalUpdates parameter.
141 * @param maxTotalUpdates maximum totalUpdates parameter.
142 * @param f test function.
143 *
Davide Pesavento03426ef2022-09-23 19:49:10 -0400144 * This method searches for totalUpdates āˆˆ [minTotalUpdates,maxTotalUpdates] until
145 * there is at least one execution that caused an IBF decode failure above threshold.
146 * If such an execution never occurs within the range, the test case fails.
Junxiao Shifadcde52022-02-28 00:38:45 +0000147 *
148 * Current FullSync logic cannot reliably recover from an IBF decode failure below threshold.
149 * Hence, that condition is not tested.
150 */
151 void
Davide Pesavento03426ef2022-09-23 19:49:10 -0400152 searchIbfDecodeFailures(int minTotalUpdates, int maxTotalUpdates,
153 const std::function<void(int totalUpdates)>& f)
Junxiao Shifadcde52022-02-28 00:38:45 +0000154 {
155 bool hasAboveThreshold = false;
156 for (int totalUpdates = minTotalUpdates; totalUpdates <= maxTotalUpdates; ++totalUpdates) {
157 clearNodes();
158 BOOST_TEST_CONTEXT("totalUpdates=" << totalUpdates) {
159 f(totalUpdates);
160
161 auto cnt = countIbfDecodeFailures();
162 BOOST_TEST_MESSAGE("aboveThreshold=" << cnt.aboveThreshold << " "
163 "belowThreshold=" << cnt.belowThreshold);
164 hasAboveThreshold = hasAboveThreshold || cnt.aboveThreshold > 0;
165 if (hasAboveThreshold) {
166 return;
167 }
168 }
169 }
170 BOOST_TEST_FAIL("cannot find viable totalUpdates for IBF decode failures");
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500171 }
172
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400173protected:
174 const Name syncPrefix = "/psync";
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400175 static constexpr int MAX_NODES = 4;
Junxiao Shifadcde52022-02-28 00:38:45 +0000176 std::array<Name, MAX_NODES> userPrefixes;
Davide Pesavento03426ef2022-09-23 19:49:10 -0400177 std::array<std::unique_ptr<util::DummyClientFace>, MAX_NODES> faces;
178 std::array<std::unique_ptr<FullProducer>, MAX_NODES> nodes;
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400179 static constexpr uint64_t NOT_EXIST = std::numeric_limits<uint64_t>::max();
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500180};
181
Ashlesh Gawande6a5157f2019-12-09 11:49:07 -0600182BOOST_FIXTURE_TEST_SUITE(TestFullSync, FullSyncFixture)
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500183
184BOOST_AUTO_TEST_CASE(TwoNodesSimple)
185{
186 addNode(0);
187 addNode(1);
188
189 faces[0]->linkTo(*faces[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000190 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500191
192 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000193 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500194
Junxiao Shifadcde52022-02-28 00:38:45 +0000195 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
196 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500197
198 nodes[1]->publishName(userPrefixes[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000199 advanceClocks(10_ms, 100);
200 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
201 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500202
203 nodes[1]->publishName(userPrefixes[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000204 advanceClocks(10_ms, 100);
205 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
206 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500207}
208
209BOOST_AUTO_TEST_CASE(TwoNodesForceSeqNo)
210{
211 addNode(0);
212 addNode(1);
213
214 faces[0]->linkTo(*faces[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000215 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500216
217 nodes[0]->publishName(userPrefixes[0], 3);
Junxiao Shifadcde52022-02-28 00:38:45 +0000218 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500219
Junxiao Shifadcde52022-02-28 00:38:45 +0000220 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 3);
221 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 3);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500222}
223
224BOOST_AUTO_TEST_CASE(TwoNodesWithMultipleUserNodes)
225{
226 addNode(0);
227 addNode(1);
228
229 faces[0]->linkTo(*faces[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000230 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500231
Junxiao Shifadcde52022-02-28 00:38:45 +0000232 Name nodeZeroExtraUser("/userPrefix0-1");
233 Name nodeOneExtraUser("/userPrefix1-1");
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500234
235 nodes[0]->addUserNode(nodeZeroExtraUser);
236 nodes[1]->addUserNode(nodeOneExtraUser);
237
238 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000239 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500240
Junxiao Shifadcde52022-02-28 00:38:45 +0000241 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
242 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500243
244 nodes[0]->publishName(nodeZeroExtraUser);
Junxiao Shifadcde52022-02-28 00:38:45 +0000245 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500246
Junxiao Shifadcde52022-02-28 00:38:45 +0000247 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(nodeZeroExtraUser).value_or(NOT_EXIST), 1);
248 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(nodeZeroExtraUser).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500249
250 nodes[1]->publishName(nodeOneExtraUser);
Junxiao Shifadcde52022-02-28 00:38:45 +0000251 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500252
Junxiao Shifadcde52022-02-28 00:38:45 +0000253 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(nodeOneExtraUser).value_or(NOT_EXIST), 1);
254 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(nodeOneExtraUser).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500255}
256
257BOOST_AUTO_TEST_CASE(MultipleNodes)
258{
259 for (int i = 0; i < 4; i++) {
260 addNode(i);
261 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500262 for (int i = 0; i < 3; i++) {
263 faces[i]->linkTo(*faces[i + 1]);
264 }
265
266 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000267 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500268 for (int i = 0; i < 4; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000269 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500270 }
271
272 nodes[1]->publishName(userPrefixes[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000273 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500274 for (int i = 0; i < 4; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000275 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500276 }
277
278 nodes[1]->publishName(userPrefixes[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000279 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500280 for (int i = 0; i < 4; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000281 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500282 }
283}
284
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400285BOOST_AUTO_TEST_CASE(MultipleNodesSimultaneousPublish)
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500286{
287 for (int i = 0; i < 4; i++) {
288 addNode(i);
289 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500290 for (int i = 0; i < 3; i++) {
291 faces[i]->linkTo(*faces[i + 1]);
292 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500293 for (int i = 0; i < 4; i++) {
294 nodes[i]->publishName(userPrefixes[i]);
295 }
296
Junxiao Shifadcde52022-02-28 00:38:45 +0000297 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500298 for (int i = 0; i < 4; i++) {
299 for (int j = 0; j < 4; j++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000300 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500301 }
302 }
303
304 for (int i = 0; i < 4; i++) {
305 nodes[i]->publishName(userPrefixes[i], 4);
306 }
307
Junxiao Shifadcde52022-02-28 00:38:45 +0000308 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500309 for (int i = 0; i < 4; i++) {
310 for (int j = 0; j < 4; j++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000311 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(NOT_EXIST), 4);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500312 }
313 }
314}
315
316BOOST_AUTO_TEST_CASE(NetworkPartition)
317{
318 for (int i = 0; i < 4; i++) {
319 addNode(i);
320 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500321 for (int i = 0; i < 3; i++) {
322 faces[i]->linkTo(*faces[i + 1]);
323 }
324
325 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000326 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500327 for (int i = 0; i < 4; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000328 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500329 }
330
331 for (int i = 0; i < 3; i++) {
332 faces[i]->unlink();
333 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500334 faces[0]->linkTo(*faces[1]);
335 faces[2]->linkTo(*faces[3]);
336
337 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000338 advanceClocks(10_ms, 100);
339 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 2);
340 BOOST_CHECK_EQUAL(nodes[2]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
341 BOOST_CHECK_EQUAL(nodes[3]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500342
343 nodes[1]->publishName(userPrefixes[1], 2);
Junxiao Shifadcde52022-02-28 00:38:45 +0000344 advanceClocks(10_ms, 100);
345 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500346
347 nodes[2]->publishName(userPrefixes[2], 2);
Junxiao Shifadcde52022-02-28 00:38:45 +0000348 advanceClocks(10_ms, 100);
349 BOOST_CHECK_EQUAL(nodes[3]->getSeqNo(userPrefixes[2]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500350
351 nodes[3]->publishName(userPrefixes[3], 2);
Junxiao Shifadcde52022-02-28 00:38:45 +0000352 advanceClocks(10_ms, 100);
353 BOOST_CHECK_EQUAL(nodes[2]->getSeqNo(userPrefixes[3]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500354
Junxiao Shifadcde52022-02-28 00:38:45 +0000355 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[3]).value_or(NOT_EXIST), NOT_EXIST);
356 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[3]).value_or(NOT_EXIST), NOT_EXIST);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500357
358 for (int i = 0; i < 3; i++) {
359 faces[i]->unlink();
360 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500361 for (int i = 0; i < 3; i++) {
362 faces[i]->linkTo(*faces[i + 1]);
363 }
364
Junxiao Shifadcde52022-02-28 00:38:45 +0000365 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500366 for (int i = 0; i < 4; i++) {
367 for (int j = 0; j < 4; j++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000368 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500369 }
370 }
371}
372
373BOOST_AUTO_TEST_CASE(IBFOverflow)
374{
375 addNode(0);
376 addNode(1);
377
378 faces[0]->linkTo(*faces[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000379 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500380
381 // 50 > 40 (expected number of entries in IBF)
382 for (int i = 0; i < 50; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000383 nodes[0]->addUserNode(makeSubPrefix(0, i));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500384 }
Junxiao Shifadcde52022-02-28 00:38:45 +0000385 batchUpdate(0, 0, 20, 1);
386 advanceClocks(10_ms, 100);
387 batchCheck(1, 0, 0, 20, 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500388
Junxiao Shifadcde52022-02-28 00:38:45 +0000389 batchUpdate(0, 21, 49, 1);
390 advanceClocks(10_ms, 100);
391 batchCheck(1, 0, 21, 49, 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500392}
393
394BOOST_AUTO_TEST_CASE(DiffIBFDecodeFailureSimple)
395{
Junxiao Shifadcde52022-02-28 00:38:45 +0000396 searchIbfDecodeFailures(46, 52, [this] (int totalUpdates) {
397 addNode(0);
398 addNode(1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500399
Junxiao Shifadcde52022-02-28 00:38:45 +0000400 faces[0]->linkTo(*faces[1]);
401 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500402
Junxiao Shifadcde52022-02-28 00:38:45 +0000403 batchUpdate(0, 0, totalUpdates, 1);
404 advanceClocks(10_ms, 100);
405 batchCheck(1, 0, 0, totalUpdates, 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500406
Junxiao Shifadcde52022-02-28 00:38:45 +0000407 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), NOT_EXIST);
408 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), NOT_EXIST);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500409
Junxiao Shifadcde52022-02-28 00:38:45 +0000410 nodes[1]->publishName(userPrefixes[1]);
411 advanceClocks(10_ms, 100);
412 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500413
Junxiao Shifadcde52022-02-28 00:38:45 +0000414 nodes[0]->publishName(userPrefixes[0]);
415 advanceClocks(10_ms, 100);
416 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
417 });
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500418}
419
420BOOST_AUTO_TEST_CASE(DiffIBFDecodeFailureSimpleSegmentedRecovery)
421{
Junxiao Shifadcde52022-02-28 00:38:45 +0000422 searchIbfDecodeFailures(46, 52, [this] (int totalUpdates) {
423 addNode(0);
424 addNode(1);
425 faces[0]->linkTo(*faces[1]);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500426
Junxiao Shifadcde52022-02-28 00:38:45 +0000427 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500428
Junxiao Shifadcde52022-02-28 00:38:45 +0000429 batchUpdate(0, 0, totalUpdates, 1);
430 advanceClocks(10_ms, 100);
431 batchCheck(1, 0, 0, totalUpdates, 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500432
Junxiao Shifadcde52022-02-28 00:38:45 +0000433 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), NOT_EXIST);
434 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), NOT_EXIST);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500435
Junxiao Shifadcde52022-02-28 00:38:45 +0000436 nodes[1]->publishName(userPrefixes[1]);
437 advanceClocks(10_ms, 100);
438 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500439
Junxiao Shifadcde52022-02-28 00:38:45 +0000440 nodes[0]->publishName(userPrefixes[0]);
441 advanceClocks(10_ms, 100);
442 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
443 });
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500444}
445
446BOOST_AUTO_TEST_CASE(DiffIBFDecodeFailureMultipleNodes)
447{
Junxiao Shifadcde52022-02-28 00:38:45 +0000448 searchIbfDecodeFailures(46, 52, [this] (int totalUpdates) {
449 for (int i = 0; i < 4; i++) {
450 addNode(i);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500451 }
Junxiao Shifadcde52022-02-28 00:38:45 +0000452 for (int i = 0; i < 3; i++) {
453 faces[i]->linkTo(*faces[i + 1]);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500454 }
Junxiao Shifadcde52022-02-28 00:38:45 +0000455
456 batchUpdate(0, 0, totalUpdates, 1);
457 advanceClocks(10_ms, 100);
458 for (int i = 0; i < 4; i++) {
459 batchCheck(i, 0, 0, totalUpdates, 1);
460 }
461 });
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500462}
463
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600464BOOST_AUTO_TEST_CASE(DelayedSecondSegment)
465{
466 addNode(0);
467
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800468 int i = 0;
Davide Pesaventodb789562020-12-19 23:01:08 -0500469 detail::State state;
Davide Pesavento03426ef2022-09-23 19:49:10 -0400470 std::shared_ptr<Buffer> compressed;
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800471 do {
Junxiao Shifadcde52022-02-28 00:38:45 +0000472 auto prefixToPublish = makeSubPrefix(0, i++);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600473 nodes[0]->addUserNode(prefixToPublish);
474 nodes[0]->publishName(prefixToPublish);
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800475
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400476 state.addContent(Name(prefixToPublish).appendNumber(nodes[0]->m_prefixes[prefixToPublish]));
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800477
478 auto block = state.wireEncode();
Davide Pesaventof6fd2fb2022-03-18 21:00:36 -0400479 compressed = detail::compress(nodes[0]->m_contentCompression, block);
Davide Pesavento03426ef2022-09-23 19:49:10 -0400480 } while (compressed->size() < (MAX_NDN_PACKET_SIZE >> 1));
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600481
Junxiao Shifadcde52022-02-28 00:38:45 +0000482 advanceClocks(10_ms, 100);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600483
484 Name syncInterestName(syncPrefix);
Davide Pesaventodb789562020-12-19 23:01:08 -0500485 detail::IBLT iblt(40, nodes[0]->m_ibltCompression);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600486 iblt.appendToName(syncInterestName);
487
Davide Pesavento03426ef2022-09-23 19:49:10 -0400488 nodes[0]->onSyncInterest(syncPrefix, Interest(syncInterestName));
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600489
Junxiao Shifadcde52022-02-28 00:38:45 +0000490 advanceClocks(10_ms);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600491
492 BOOST_CHECK_EQUAL(nodes[0]->m_segmentPublisher.m_ims.size(), 2);
493 // Expire contents from segmentPublisher
Junxiao Shifadcde52022-02-28 00:38:45 +0000494 advanceClocks(10_ms, 100);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600495 BOOST_CHECK_EQUAL(nodes[0]->m_segmentPublisher.m_ims.size(), 0);
496
497 // Get data name from face and increase segment number to form next interest
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400498 BOOST_REQUIRE(!faces[0]->sentData.empty());
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600499 Name dataName = faces[0]->sentData.front().getName();
Ashlesh Gawanded51690a2019-11-11 22:51:06 -0600500 Name interestName = dataName.getSubName(0, dataName.size() - 2);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600501 interestName.appendSegment(1);
502 faces[0]->sentData.clear();
503
Davide Pesavento03426ef2022-09-23 19:49:10 -0400504 nodes[0]->onSyncInterest(syncPrefix, Interest(interestName));
Junxiao Shifadcde52022-02-28 00:38:45 +0000505 advanceClocks(10_ms);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600506
507 // Should have repopulated SegmentPublisher
508 BOOST_CHECK_EQUAL(nodes[0]->m_segmentPublisher.m_ims.size(), 2);
509 // Should have received the second data segment this time
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400510 BOOST_REQUIRE(!faces[0]->sentData.empty());
511 BOOST_CHECK_EQUAL(faces[0]->sentData.front().getName().at(-1).toSegment(), 1);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600512}
513
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500514BOOST_AUTO_TEST_SUITE_END()
515
Ashlesh Gawanded51690a2019-11-11 22:51:06 -0600516} // namespace psync