blob: 8aa9c8ec28ed246181ed19764fa63e7b68207dab [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 Pesavento5b3cf762020-04-03 16:20:04 -040027
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050028#include <ndn-cxx/util/dummy-client-face.hpp>
29
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050030namespace psync {
31
Junxiao Shifadcde52022-02-28 00:38:45 +000032using ndn::Name;
33using ndn::optional;
34using ndn::util::DummyClientFace;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050035
Junxiao Shifadcde52022-02-28 00:38:45 +000036class FullSyncFixture : public ndn::tests::IoFixture
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);
43 faces[id] = std::make_shared<DummyClientFace>(m_io, DummyClientFace::Options{true, true});
44 userPrefixes[id] = "/userPrefix" + std::to_string(id);
45 nodes[id] = std::make_shared<FullProducer>(40, *faces[id], syncPrefix, userPrefixes[id],
46 [] (const auto&) {});
47 }
Davide Pesaventof91d1df2020-11-25 14:50:41 -050048
Junxiao Shifadcde52022-02-28 00:38:45 +000049 void
50 clearNodes()
51 {
52 faces.fill(nullptr);
53 userPrefixes.fill(Name());
54 nodes.fill(nullptr);
55 }
56
57 /**
58 * @brief Return a user prefix in the form /userNode<id>-<i>.
59 * @param id update originator node index.
60 * @param i user prefix index.
61 */
62 Name
63 makeSubPrefix(int id, int i) const
64 {
65 return "/userNode" + std::to_string(id) + "-" + std::to_string(i);
66 }
67
68 /**
69 * @brief Publish a batch of updates.
70 * @param id node index.
71 * @param min minimum user prefix index.
72 * @param min maximum user prefix index.
73 * @param seq update sequence number.
74 * @post nodes[id] has user nodes /userNode<id>-<i> ∀i∈[min,max] , with sequence number
75 * set to @p seq ; only one sync Data may be sent after the last update.
76 */
77 void
78 batchUpdate(int id, int min, int max, uint64_t seq)
79 {
80 FullProducer& node = *nodes.at(id);
81 for (int i = min; i <= max; i++) {
82 auto userPrefix = makeSubPrefix(id, i);
83 node.addUserNode(userPrefix);
84 if (i < max) {
85 node.updateSeqNo(userPrefix, seq);
86 }
87 else {
88 node.publishName(userPrefix, seq);
89 }
90 }
91 }
92
93 /**
94 * @brief Check sequence number on a batch of user prefixes.
95 * @param id node index where the check is performed.
96 * @param origin update originator node index for deriving user prefixes.
97 * @param min minimum user prefix index.
98 * @param max maximum user prefix index.
99 * @param seq expected sequence number.
100 */
101 void
102 batchCheck(int id, int origin, int min, int max, optional<uint64_t> seq)
103 {
104 uint64_t expected = seq.value_or(NOT_EXIST);
105 FullProducer& node = *nodes.at(id);
106 for (int i = min; i <= max; i++) {
107 auto userPrefix = makeSubPrefix(origin, i);
108 BOOST_TEST_CONTEXT("node=" << id << " userPrefix=" << userPrefix) {
109 BOOST_CHECK_EQUAL(node.getSeqNo(userPrefix).value_or(NOT_EXIST), expected);
110 }
111 }
112 }
113
114 struct IbfDecodeFailureCounts
115 {
116 size_t aboveThreshold = 0;
117 size_t belowThreshold = 0;
118 };
119
120 /**
121 * @brief Return the sum of IBF decode failure counters among created nodes.
122 */
123 IbfDecodeFailureCounts
124 countIbfDecodeFailures() const
125 {
126 IbfDecodeFailureCounts result;
127 for (const auto& node : nodes) {
128 if (node == nullptr) {
129 continue;
130 }
131 result.aboveThreshold += node->nIbfDecodeFailuresAboveThreshold;
132 result.belowThreshold += node->nIbfDecodeFailuresBelowThreshold;
133 }
134 return result;
135 }
136
137 /**
138 * @brief Repeat a test function until there are IBF decode failures.
139 * @param minTotalUpdates minimum totalUpdates parameter.
140 * @param maxTotalUpdates maximum totalUpdates parameter.
141 * @param f test function.
142 *
143 * This method searches for totalUpdates∈[minTotalUpdates,maxTotalUpdates] until there is
144 * at least one execution that caused an IBF decode failure above threshold.
145 * If such an execution is never achieved within the range, fail the test case.
146 *
147 * Current FullSync logic cannot reliably recover from an IBF decode failure below threshold.
148 * Hence, that condition is not tested.
149 */
150 void
151 searchIbfDecodeFailures(int minTotalUpdates, int maxTotalUpdates, std::function<void(int totalUpdates)> f)
152 {
153 bool hasAboveThreshold = false;
154 for (int totalUpdates = minTotalUpdates; totalUpdates <= maxTotalUpdates; ++totalUpdates) {
155 clearNodes();
156 BOOST_TEST_CONTEXT("totalUpdates=" << totalUpdates) {
157 f(totalUpdates);
158
159 auto cnt = countIbfDecodeFailures();
160 BOOST_TEST_MESSAGE("aboveThreshold=" << cnt.aboveThreshold << " "
161 "belowThreshold=" << cnt.belowThreshold);
162 hasAboveThreshold = hasAboveThreshold || cnt.aboveThreshold > 0;
163 if (hasAboveThreshold) {
164 return;
165 }
166 }
167 }
168 BOOST_TEST_FAIL("cannot find viable totalUpdates for IBF decode failures");
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500169 }
170
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400171protected:
172 const Name syncPrefix = "/psync";
Junxiao Shifadcde52022-02-28 00:38:45 +0000173 static const int MAX_NODES = 4;
174 std::array<std::shared_ptr<DummyClientFace>, MAX_NODES> faces;
175 std::array<Name, MAX_NODES> userPrefixes;
176 std::array<std::shared_ptr<FullProducer>, MAX_NODES> nodes;
177 static const uint64_t NOT_EXIST = std::numeric_limits<uint64_t>::max();
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500178};
179
Junxiao Shifadcde52022-02-28 00:38:45 +0000180const uint64_t FullSyncFixture::NOT_EXIST;
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;
Junxiao Shifadcde52022-02-28 00:38:45 +0000470 std::shared_ptr<ndn::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 Pesaventodb789562020-12-19 23:01:08 -0500479 compressed = detail::compress(nodes[0]->m_contentCompression, block.wire(), block.size());
Junxiao Shifadcde52022-02-28 00:38:45 +0000480 } while (compressed->size() < (ndn::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
Junxiao Shifadcde52022-02-28 00:38:45 +0000488 nodes[0]->onSyncInterest(syncPrefix, ndn::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
Junxiao Shifadcde52022-02-28 00:38:45 +0000504 nodes[0]->onSyncInterest(syncPrefix, ndn::Interest(interestName));
505 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