blob: 16ba4bc9a2fdb7d9347703e07a714561ea2d22b3 [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;
Junxiao Shifadcde52022-02-28 00:38:45 +000033using ndn::util::DummyClientFace;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050034
Junxiao Shifadcde52022-02-28 00:38:45 +000035class FullSyncFixture : public ndn::tests::IoFixture
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050036{
Davide Pesavento5b3cf762020-04-03 16:20:04 -040037protected:
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050038 void
39 addNode(int id)
40 {
Junxiao Shifadcde52022-02-28 00:38:45 +000041 BOOST_ASSERT(id >= 0 && id < MAX_NODES);
42 faces[id] = std::make_shared<DummyClientFace>(m_io, DummyClientFace::Options{true, true});
43 userPrefixes[id] = "/userPrefix" + std::to_string(id);
44 nodes[id] = std::make_shared<FullProducer>(40, *faces[id], syncPrefix, userPrefixes[id],
45 [] (const auto&) {});
46 }
Davide Pesaventof91d1df2020-11-25 14:50:41 -050047
Junxiao Shifadcde52022-02-28 00:38:45 +000048 void
49 clearNodes()
50 {
51 faces.fill(nullptr);
52 userPrefixes.fill(Name());
53 nodes.fill(nullptr);
54 }
55
56 /**
57 * @brief Return a user prefix in the form /userNode<id>-<i>.
58 * @param id update originator node index.
59 * @param i user prefix index.
60 */
61 Name
62 makeSubPrefix(int id, int i) const
63 {
64 return "/userNode" + std::to_string(id) + "-" + std::to_string(i);
65 }
66
67 /**
68 * @brief Publish a batch of updates.
69 * @param id node index.
70 * @param min minimum user prefix index.
71 * @param min maximum user prefix index.
72 * @param seq update sequence number.
73 * @post nodes[id] has user nodes /userNode<id>-<i> āˆ€iāˆˆ[min,max] , with sequence number
74 * set to @p seq ; only one sync Data may be sent after the last update.
75 */
76 void
77 batchUpdate(int id, int min, int max, uint64_t seq)
78 {
79 FullProducer& node = *nodes.at(id);
80 for (int i = min; i <= max; i++) {
81 auto userPrefix = makeSubPrefix(id, i);
82 node.addUserNode(userPrefix);
83 if (i < max) {
84 node.updateSeqNo(userPrefix, seq);
85 }
86 else {
87 node.publishName(userPrefix, seq);
88 }
89 }
90 }
91
92 /**
93 * @brief Check sequence number on a batch of user prefixes.
94 * @param id node index where the check is performed.
95 * @param origin update originator node index for deriving user prefixes.
96 * @param min minimum user prefix index.
97 * @param max maximum user prefix index.
98 * @param seq expected sequence number.
99 */
100 void
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400101 batchCheck(int id, int origin, int min, int max, std::optional<uint64_t> seq)
Junxiao Shifadcde52022-02-28 00:38:45 +0000102 {
103 uint64_t expected = seq.value_or(NOT_EXIST);
104 FullProducer& node = *nodes.at(id);
105 for (int i = min; i <= max; i++) {
106 auto userPrefix = makeSubPrefix(origin, i);
107 BOOST_TEST_CONTEXT("node=" << id << " userPrefix=" << userPrefix) {
108 BOOST_CHECK_EQUAL(node.getSeqNo(userPrefix).value_or(NOT_EXIST), expected);
109 }
110 }
111 }
112
113 struct IbfDecodeFailureCounts
114 {
115 size_t aboveThreshold = 0;
116 size_t belowThreshold = 0;
117 };
118
119 /**
120 * @brief Return the sum of IBF decode failure counters among created nodes.
121 */
122 IbfDecodeFailureCounts
123 countIbfDecodeFailures() const
124 {
125 IbfDecodeFailureCounts result;
126 for (const auto& node : nodes) {
127 if (node == nullptr) {
128 continue;
129 }
130 result.aboveThreshold += node->nIbfDecodeFailuresAboveThreshold;
131 result.belowThreshold += node->nIbfDecodeFailuresBelowThreshold;
132 }
133 return result;
134 }
135
136 /**
137 * @brief Repeat a test function until there are IBF decode failures.
138 * @param minTotalUpdates minimum totalUpdates parameter.
139 * @param maxTotalUpdates maximum totalUpdates parameter.
140 * @param f test function.
141 *
142 * This method searches for totalUpdatesāˆˆ[minTotalUpdates,maxTotalUpdates] until there is
143 * at least one execution that caused an IBF decode failure above threshold.
144 * If such an execution is never achieved within the range, fail the test case.
145 *
146 * Current FullSync logic cannot reliably recover from an IBF decode failure below threshold.
147 * Hence, that condition is not tested.
148 */
149 void
150 searchIbfDecodeFailures(int minTotalUpdates, int maxTotalUpdates, std::function<void(int totalUpdates)> f)
151 {
152 bool hasAboveThreshold = false;
153 for (int totalUpdates = minTotalUpdates; totalUpdates <= maxTotalUpdates; ++totalUpdates) {
154 clearNodes();
155 BOOST_TEST_CONTEXT("totalUpdates=" << totalUpdates) {
156 f(totalUpdates);
157
158 auto cnt = countIbfDecodeFailures();
159 BOOST_TEST_MESSAGE("aboveThreshold=" << cnt.aboveThreshold << " "
160 "belowThreshold=" << cnt.belowThreshold);
161 hasAboveThreshold = hasAboveThreshold || cnt.aboveThreshold > 0;
162 if (hasAboveThreshold) {
163 return;
164 }
165 }
166 }
167 BOOST_TEST_FAIL("cannot find viable totalUpdates for IBF decode failures");
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500168 }
169
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400170protected:
171 const Name syncPrefix = "/psync";
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400172 static constexpr int MAX_NODES = 4;
Junxiao Shifadcde52022-02-28 00:38:45 +0000173 std::array<std::shared_ptr<DummyClientFace>, MAX_NODES> faces;
174 std::array<Name, MAX_NODES> userPrefixes;
175 std::array<std::shared_ptr<FullProducer>, MAX_NODES> nodes;
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400176 static constexpr uint64_t NOT_EXIST = std::numeric_limits<uint64_t>::max();
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500177};
178
Ashlesh Gawande6a5157f2019-12-09 11:49:07 -0600179BOOST_FIXTURE_TEST_SUITE(TestFullSync, FullSyncFixture)
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500180
181BOOST_AUTO_TEST_CASE(TwoNodesSimple)
182{
183 addNode(0);
184 addNode(1);
185
186 faces[0]->linkTo(*faces[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000187 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500188
189 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000190 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500191
Junxiao Shifadcde52022-02-28 00:38:45 +0000192 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
193 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500194
195 nodes[1]->publishName(userPrefixes[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000196 advanceClocks(10_ms, 100);
197 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
198 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500199
200 nodes[1]->publishName(userPrefixes[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000201 advanceClocks(10_ms, 100);
202 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
203 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500204}
205
206BOOST_AUTO_TEST_CASE(TwoNodesForceSeqNo)
207{
208 addNode(0);
209 addNode(1);
210
211 faces[0]->linkTo(*faces[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000212 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500213
214 nodes[0]->publishName(userPrefixes[0], 3);
Junxiao Shifadcde52022-02-28 00:38:45 +0000215 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500216
Junxiao Shifadcde52022-02-28 00:38:45 +0000217 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 3);
218 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 3);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500219}
220
221BOOST_AUTO_TEST_CASE(TwoNodesWithMultipleUserNodes)
222{
223 addNode(0);
224 addNode(1);
225
226 faces[0]->linkTo(*faces[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000227 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500228
Junxiao Shifadcde52022-02-28 00:38:45 +0000229 Name nodeZeroExtraUser("/userPrefix0-1");
230 Name nodeOneExtraUser("/userPrefix1-1");
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500231
232 nodes[0]->addUserNode(nodeZeroExtraUser);
233 nodes[1]->addUserNode(nodeOneExtraUser);
234
235 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000236 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500237
Junxiao Shifadcde52022-02-28 00:38:45 +0000238 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
239 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500240
241 nodes[0]->publishName(nodeZeroExtraUser);
Junxiao Shifadcde52022-02-28 00:38:45 +0000242 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500243
Junxiao Shifadcde52022-02-28 00:38:45 +0000244 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(nodeZeroExtraUser).value_or(NOT_EXIST), 1);
245 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(nodeZeroExtraUser).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500246
247 nodes[1]->publishName(nodeOneExtraUser);
Junxiao Shifadcde52022-02-28 00:38:45 +0000248 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500249
Junxiao Shifadcde52022-02-28 00:38:45 +0000250 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(nodeOneExtraUser).value_or(NOT_EXIST), 1);
251 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(nodeOneExtraUser).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500252}
253
254BOOST_AUTO_TEST_CASE(MultipleNodes)
255{
256 for (int i = 0; i < 4; i++) {
257 addNode(i);
258 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500259 for (int i = 0; i < 3; i++) {
260 faces[i]->linkTo(*faces[i + 1]);
261 }
262
263 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000264 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500265 for (int i = 0; i < 4; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000266 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500267 }
268
269 nodes[1]->publishName(userPrefixes[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000270 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500271 for (int i = 0; i < 4; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000272 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500273 }
274
275 nodes[1]->publishName(userPrefixes[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000276 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500277 for (int i = 0; i < 4; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000278 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500279 }
280}
281
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400282BOOST_AUTO_TEST_CASE(MultipleNodesSimultaneousPublish)
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500283{
284 for (int i = 0; i < 4; i++) {
285 addNode(i);
286 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500287 for (int i = 0; i < 3; i++) {
288 faces[i]->linkTo(*faces[i + 1]);
289 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500290 for (int i = 0; i < 4; i++) {
291 nodes[i]->publishName(userPrefixes[i]);
292 }
293
Junxiao Shifadcde52022-02-28 00:38:45 +0000294 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500295 for (int i = 0; i < 4; i++) {
296 for (int j = 0; j < 4; j++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000297 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500298 }
299 }
300
301 for (int i = 0; i < 4; i++) {
302 nodes[i]->publishName(userPrefixes[i], 4);
303 }
304
Junxiao Shifadcde52022-02-28 00:38:45 +0000305 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500306 for (int i = 0; i < 4; i++) {
307 for (int j = 0; j < 4; j++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000308 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(NOT_EXIST), 4);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500309 }
310 }
311}
312
313BOOST_AUTO_TEST_CASE(NetworkPartition)
314{
315 for (int i = 0; i < 4; i++) {
316 addNode(i);
317 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500318 for (int i = 0; i < 3; i++) {
319 faces[i]->linkTo(*faces[i + 1]);
320 }
321
322 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000323 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500324 for (int i = 0; i < 4; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000325 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500326 }
327
328 for (int i = 0; i < 3; i++) {
329 faces[i]->unlink();
330 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500331 faces[0]->linkTo(*faces[1]);
332 faces[2]->linkTo(*faces[3]);
333
334 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000335 advanceClocks(10_ms, 100);
336 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 2);
337 BOOST_CHECK_EQUAL(nodes[2]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
338 BOOST_CHECK_EQUAL(nodes[3]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500339
340 nodes[1]->publishName(userPrefixes[1], 2);
Junxiao Shifadcde52022-02-28 00:38:45 +0000341 advanceClocks(10_ms, 100);
342 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500343
344 nodes[2]->publishName(userPrefixes[2], 2);
Junxiao Shifadcde52022-02-28 00:38:45 +0000345 advanceClocks(10_ms, 100);
346 BOOST_CHECK_EQUAL(nodes[3]->getSeqNo(userPrefixes[2]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500347
348 nodes[3]->publishName(userPrefixes[3], 2);
Junxiao Shifadcde52022-02-28 00:38:45 +0000349 advanceClocks(10_ms, 100);
350 BOOST_CHECK_EQUAL(nodes[2]->getSeqNo(userPrefixes[3]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500351
Junxiao Shifadcde52022-02-28 00:38:45 +0000352 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[3]).value_or(NOT_EXIST), NOT_EXIST);
353 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[3]).value_or(NOT_EXIST), NOT_EXIST);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500354
355 for (int i = 0; i < 3; i++) {
356 faces[i]->unlink();
357 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500358 for (int i = 0; i < 3; i++) {
359 faces[i]->linkTo(*faces[i + 1]);
360 }
361
Junxiao Shifadcde52022-02-28 00:38:45 +0000362 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500363 for (int i = 0; i < 4; i++) {
364 for (int j = 0; j < 4; j++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000365 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500366 }
367 }
368}
369
370BOOST_AUTO_TEST_CASE(IBFOverflow)
371{
372 addNode(0);
373 addNode(1);
374
375 faces[0]->linkTo(*faces[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000376 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500377
378 // 50 > 40 (expected number of entries in IBF)
379 for (int i = 0; i < 50; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000380 nodes[0]->addUserNode(makeSubPrefix(0, i));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500381 }
Junxiao Shifadcde52022-02-28 00:38:45 +0000382 batchUpdate(0, 0, 20, 1);
383 advanceClocks(10_ms, 100);
384 batchCheck(1, 0, 0, 20, 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500385
Junxiao Shifadcde52022-02-28 00:38:45 +0000386 batchUpdate(0, 21, 49, 1);
387 advanceClocks(10_ms, 100);
388 batchCheck(1, 0, 21, 49, 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500389}
390
391BOOST_AUTO_TEST_CASE(DiffIBFDecodeFailureSimple)
392{
Junxiao Shifadcde52022-02-28 00:38:45 +0000393 searchIbfDecodeFailures(46, 52, [this] (int totalUpdates) {
394 addNode(0);
395 addNode(1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500396
Junxiao Shifadcde52022-02-28 00:38:45 +0000397 faces[0]->linkTo(*faces[1]);
398 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500399
Junxiao Shifadcde52022-02-28 00:38:45 +0000400 batchUpdate(0, 0, totalUpdates, 1);
401 advanceClocks(10_ms, 100);
402 batchCheck(1, 0, 0, totalUpdates, 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500403
Junxiao Shifadcde52022-02-28 00:38:45 +0000404 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), NOT_EXIST);
405 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), NOT_EXIST);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500406
Junxiao Shifadcde52022-02-28 00:38:45 +0000407 nodes[1]->publishName(userPrefixes[1]);
408 advanceClocks(10_ms, 100);
409 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500410
Junxiao Shifadcde52022-02-28 00:38:45 +0000411 nodes[0]->publishName(userPrefixes[0]);
412 advanceClocks(10_ms, 100);
413 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
414 });
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500415}
416
417BOOST_AUTO_TEST_CASE(DiffIBFDecodeFailureSimpleSegmentedRecovery)
418{
Junxiao Shifadcde52022-02-28 00:38:45 +0000419 searchIbfDecodeFailures(46, 52, [this] (int totalUpdates) {
420 addNode(0);
421 addNode(1);
422 faces[0]->linkTo(*faces[1]);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500423
Junxiao Shifadcde52022-02-28 00:38:45 +0000424 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500425
Junxiao Shifadcde52022-02-28 00:38:45 +0000426 batchUpdate(0, 0, totalUpdates, 1);
427 advanceClocks(10_ms, 100);
428 batchCheck(1, 0, 0, totalUpdates, 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500429
Junxiao Shifadcde52022-02-28 00:38:45 +0000430 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), NOT_EXIST);
431 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), NOT_EXIST);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500432
Junxiao Shifadcde52022-02-28 00:38:45 +0000433 nodes[1]->publishName(userPrefixes[1]);
434 advanceClocks(10_ms, 100);
435 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500436
Junxiao Shifadcde52022-02-28 00:38:45 +0000437 nodes[0]->publishName(userPrefixes[0]);
438 advanceClocks(10_ms, 100);
439 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
440 });
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500441}
442
443BOOST_AUTO_TEST_CASE(DiffIBFDecodeFailureMultipleNodes)
444{
Junxiao Shifadcde52022-02-28 00:38:45 +0000445 searchIbfDecodeFailures(46, 52, [this] (int totalUpdates) {
446 for (int i = 0; i < 4; i++) {
447 addNode(i);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500448 }
Junxiao Shifadcde52022-02-28 00:38:45 +0000449 for (int i = 0; i < 3; i++) {
450 faces[i]->linkTo(*faces[i + 1]);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500451 }
Junxiao Shifadcde52022-02-28 00:38:45 +0000452
453 batchUpdate(0, 0, totalUpdates, 1);
454 advanceClocks(10_ms, 100);
455 for (int i = 0; i < 4; i++) {
456 batchCheck(i, 0, 0, totalUpdates, 1);
457 }
458 });
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500459}
460
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600461BOOST_AUTO_TEST_CASE(DelayedSecondSegment)
462{
463 addNode(0);
464
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800465 int i = 0;
Davide Pesaventodb789562020-12-19 23:01:08 -0500466 detail::State state;
Junxiao Shifadcde52022-02-28 00:38:45 +0000467 std::shared_ptr<ndn::Buffer> compressed;
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800468 do {
Junxiao Shifadcde52022-02-28 00:38:45 +0000469 auto prefixToPublish = makeSubPrefix(0, i++);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600470 nodes[0]->addUserNode(prefixToPublish);
471 nodes[0]->publishName(prefixToPublish);
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800472
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400473 state.addContent(Name(prefixToPublish).appendNumber(nodes[0]->m_prefixes[prefixToPublish]));
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800474
475 auto block = state.wireEncode();
Davide Pesaventof6fd2fb2022-03-18 21:00:36 -0400476 compressed = detail::compress(nodes[0]->m_contentCompression, block);
Junxiao Shifadcde52022-02-28 00:38:45 +0000477 } while (compressed->size() < (ndn::MAX_NDN_PACKET_SIZE >> 1));
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600478
Junxiao Shifadcde52022-02-28 00:38:45 +0000479 advanceClocks(10_ms, 100);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600480
481 Name syncInterestName(syncPrefix);
Davide Pesaventodb789562020-12-19 23:01:08 -0500482 detail::IBLT iblt(40, nodes[0]->m_ibltCompression);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600483 iblt.appendToName(syncInterestName);
484
Junxiao Shifadcde52022-02-28 00:38:45 +0000485 nodes[0]->onSyncInterest(syncPrefix, ndn::Interest(syncInterestName));
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600486
Junxiao Shifadcde52022-02-28 00:38:45 +0000487 advanceClocks(10_ms);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600488
489 BOOST_CHECK_EQUAL(nodes[0]->m_segmentPublisher.m_ims.size(), 2);
490 // Expire contents from segmentPublisher
Junxiao Shifadcde52022-02-28 00:38:45 +0000491 advanceClocks(10_ms, 100);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600492 BOOST_CHECK_EQUAL(nodes[0]->m_segmentPublisher.m_ims.size(), 0);
493
494 // Get data name from face and increase segment number to form next interest
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400495 BOOST_REQUIRE(!faces[0]->sentData.empty());
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600496 Name dataName = faces[0]->sentData.front().getName();
Ashlesh Gawanded51690a2019-11-11 22:51:06 -0600497 Name interestName = dataName.getSubName(0, dataName.size() - 2);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600498 interestName.appendSegment(1);
499 faces[0]->sentData.clear();
500
Junxiao Shifadcde52022-02-28 00:38:45 +0000501 nodes[0]->onSyncInterest(syncPrefix, ndn::Interest(interestName));
502 advanceClocks(10_ms);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600503
504 // Should have repopulated SegmentPublisher
505 BOOST_CHECK_EQUAL(nodes[0]->m_segmentPublisher.m_ims.size(), 2);
506 // Should have received the second data segment this time
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400507 BOOST_REQUIRE(!faces[0]->sentData.empty());
508 BOOST_CHECK_EQUAL(faces[0]->sentData.front().getName().at(-1).toSegment(), 1);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600509}
510
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500511BOOST_AUTO_TEST_SUITE_END()
512
Ashlesh Gawanded51690a2019-11-11 22:51:06 -0600513} // namespace psync