blob: 91f95db73bd304cf9f2fb4d62e6b2247d7ff59da [file] [log] [blame]
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Junxiao Shic5f5eb12023-08-11 08:05:23 +00003 * Copyright (c) 2014-2023, 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
Junxiao Shic5f5eb12023-08-11 08:05:23 +000034using ndn::Interest;
35using ndn::Name;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050036
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -040037class FullSyncFixture : public tests::IoFixture, public tests::KeyChainFixture
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050038{
Davide Pesavento5b3cf762020-04-03 16:20:04 -040039protected:
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050040 void
41 addNode(int id)
42 {
Junxiao Shifadcde52022-02-28 00:38:45 +000043 BOOST_ASSERT(id >= 0 && id < MAX_NODES);
Junxiao Shifadcde52022-02-28 00:38:45 +000044 userPrefixes[id] = "/userPrefix" + std::to_string(id);
Junxiao Shic5f5eb12023-08-11 08:05:23 +000045 faces[id] = std::make_unique<ndn::DummyClientFace>(m_io, m_keyChain,
46 ndn::DummyClientFace::Options{true, true});
Davide Pesavento03426ef2022-09-23 19:49:10 -040047 nodes[id] = std::make_unique<FullProducer>(*faces[id], m_keyChain, 40, syncPrefix, userPrefixes[id],
Junxiao Shifadcde52022-02-28 00:38:45 +000048 [] (const auto&) {});
49 }
Davide Pesaventof91d1df2020-11-25 14:50:41 -050050
Junxiao Shifadcde52022-02-28 00:38:45 +000051 void
52 clearNodes()
53 {
Davide Pesavento03426ef2022-09-23 19:49:10 -040054 nodes = {};
55 faces = {};
56 userPrefixes = {};
Junxiao Shifadcde52022-02-28 00:38:45 +000057 }
58
59 /**
60 * @brief Return a user prefix in the form /userNode<id>-<i>.
61 * @param id update originator node index.
62 * @param i user prefix index.
63 */
Davide Pesavento03426ef2022-09-23 19:49:10 -040064 static Name
65 makeSubPrefix(int id, int i)
Junxiao Shifadcde52022-02-28 00:38:45 +000066 {
67 return "/userNode" + std::to_string(id) + "-" + std::to_string(i);
68 }
69
70 /**
71 * @brief Publish a batch of updates.
72 * @param id node index.
73 * @param min minimum user prefix index.
74 * @param min maximum user prefix index.
75 * @param seq update sequence number.
76 * @post nodes[id] has user nodes /userNode<id>-<i> āˆ€iāˆˆ[min,max] , with sequence number
77 * set to @p seq ; only one sync Data may be sent after the last update.
78 */
79 void
80 batchUpdate(int id, int min, int max, uint64_t seq)
81 {
82 FullProducer& node = *nodes.at(id);
83 for (int i = min; i <= max; i++) {
84 auto userPrefix = makeSubPrefix(id, i);
85 node.addUserNode(userPrefix);
86 if (i < max) {
87 node.updateSeqNo(userPrefix, seq);
88 }
89 else {
90 node.publishName(userPrefix, seq);
91 }
92 }
93 }
94
95 /**
96 * @brief Check sequence number on a batch of user prefixes.
97 * @param id node index where the check is performed.
98 * @param origin update originator node index for deriving user prefixes.
99 * @param min minimum user prefix index.
100 * @param max maximum user prefix index.
101 * @param seq expected sequence number.
102 */
103 void
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400104 batchCheck(int id, int origin, int min, int max, std::optional<uint64_t> seq)
Junxiao Shifadcde52022-02-28 00:38:45 +0000105 {
106 uint64_t expected = seq.value_or(NOT_EXIST);
107 FullProducer& node = *nodes.at(id);
108 for (int i = min; i <= max; i++) {
109 auto userPrefix = makeSubPrefix(origin, i);
110 BOOST_TEST_CONTEXT("node=" << id << " userPrefix=" << userPrefix) {
111 BOOST_CHECK_EQUAL(node.getSeqNo(userPrefix).value_or(NOT_EXIST), expected);
112 }
113 }
114 }
115
116 struct IbfDecodeFailureCounts
117 {
118 size_t aboveThreshold = 0;
119 size_t belowThreshold = 0;
120 };
121
122 /**
123 * @brief Return the sum of IBF decode failure counters among created nodes.
124 */
125 IbfDecodeFailureCounts
126 countIbfDecodeFailures() const
127 {
128 IbfDecodeFailureCounts result;
129 for (const auto& node : nodes) {
130 if (node == nullptr) {
131 continue;
132 }
133 result.aboveThreshold += node->nIbfDecodeFailuresAboveThreshold;
134 result.belowThreshold += node->nIbfDecodeFailuresBelowThreshold;
135 }
136 return result;
137 }
138
139 /**
140 * @brief Repeat a test function until there are IBF decode failures.
141 * @param minTotalUpdates minimum totalUpdates parameter.
142 * @param maxTotalUpdates maximum totalUpdates parameter.
143 * @param f test function.
144 *
Davide Pesavento03426ef2022-09-23 19:49:10 -0400145 * This method searches for totalUpdates āˆˆ [minTotalUpdates,maxTotalUpdates] until
146 * there is at least one execution that caused an IBF decode failure above threshold.
147 * If such an execution never occurs within the range, the test case fails.
Junxiao Shifadcde52022-02-28 00:38:45 +0000148 *
149 * Current FullSync logic cannot reliably recover from an IBF decode failure below threshold.
150 * Hence, that condition is not tested.
151 */
152 void
Davide Pesavento03426ef2022-09-23 19:49:10 -0400153 searchIbfDecodeFailures(int minTotalUpdates, int maxTotalUpdates,
154 const std::function<void(int totalUpdates)>& f)
Junxiao Shifadcde52022-02-28 00:38:45 +0000155 {
156 bool hasAboveThreshold = false;
157 for (int totalUpdates = minTotalUpdates; totalUpdates <= maxTotalUpdates; ++totalUpdates) {
158 clearNodes();
159 BOOST_TEST_CONTEXT("totalUpdates=" << totalUpdates) {
160 f(totalUpdates);
161
162 auto cnt = countIbfDecodeFailures();
163 BOOST_TEST_MESSAGE("aboveThreshold=" << cnt.aboveThreshold << " "
164 "belowThreshold=" << cnt.belowThreshold);
165 hasAboveThreshold = hasAboveThreshold || cnt.aboveThreshold > 0;
166 if (hasAboveThreshold) {
167 return;
168 }
169 }
170 }
171 BOOST_TEST_FAIL("cannot find viable totalUpdates for IBF decode failures");
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500172 }
173
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400174protected:
175 const Name syncPrefix = "/psync";
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400176 static constexpr int MAX_NODES = 4;
Junxiao Shifadcde52022-02-28 00:38:45 +0000177 std::array<Name, MAX_NODES> userPrefixes;
Junxiao Shic5f5eb12023-08-11 08:05:23 +0000178 std::array<std::unique_ptr<ndn::DummyClientFace>, MAX_NODES> faces;
Davide Pesavento03426ef2022-09-23 19:49:10 -0400179 std::array<std::unique_ptr<FullProducer>, MAX_NODES> nodes;
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400180 static constexpr uint64_t NOT_EXIST = std::numeric_limits<uint64_t>::max();
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500181};
182
Ashlesh Gawande6a5157f2019-12-09 11:49:07 -0600183BOOST_FIXTURE_TEST_SUITE(TestFullSync, FullSyncFixture)
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500184
185BOOST_AUTO_TEST_CASE(TwoNodesSimple)
186{
187 addNode(0);
188 addNode(1);
189
190 faces[0]->linkTo(*faces[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000191 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500192
193 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000194 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500195
Junxiao Shifadcde52022-02-28 00:38:45 +0000196 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
197 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500198
199 nodes[1]->publishName(userPrefixes[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000200 advanceClocks(10_ms, 100);
201 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
202 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500203
204 nodes[1]->publishName(userPrefixes[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000205 advanceClocks(10_ms, 100);
206 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
207 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500208}
209
210BOOST_AUTO_TEST_CASE(TwoNodesForceSeqNo)
211{
212 addNode(0);
213 addNode(1);
214
215 faces[0]->linkTo(*faces[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000216 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500217
218 nodes[0]->publishName(userPrefixes[0], 3);
Junxiao Shifadcde52022-02-28 00:38:45 +0000219 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500220
Junxiao Shifadcde52022-02-28 00:38:45 +0000221 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 3);
222 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 3);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500223}
224
225BOOST_AUTO_TEST_CASE(TwoNodesWithMultipleUserNodes)
226{
227 addNode(0);
228 addNode(1);
229
230 faces[0]->linkTo(*faces[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000231 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500232
Junxiao Shifadcde52022-02-28 00:38:45 +0000233 Name nodeZeroExtraUser("/userPrefix0-1");
234 Name nodeOneExtraUser("/userPrefix1-1");
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500235
236 nodes[0]->addUserNode(nodeZeroExtraUser);
237 nodes[1]->addUserNode(nodeOneExtraUser);
238
239 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000240 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500241
Junxiao Shifadcde52022-02-28 00:38:45 +0000242 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
243 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500244
245 nodes[0]->publishName(nodeZeroExtraUser);
Junxiao Shifadcde52022-02-28 00:38:45 +0000246 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500247
Junxiao Shifadcde52022-02-28 00:38:45 +0000248 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(nodeZeroExtraUser).value_or(NOT_EXIST), 1);
249 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(nodeZeroExtraUser).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500250
251 nodes[1]->publishName(nodeOneExtraUser);
Junxiao Shifadcde52022-02-28 00:38:45 +0000252 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500253
Junxiao Shifadcde52022-02-28 00:38:45 +0000254 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(nodeOneExtraUser).value_or(NOT_EXIST), 1);
255 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(nodeOneExtraUser).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500256}
257
258BOOST_AUTO_TEST_CASE(MultipleNodes)
259{
260 for (int i = 0; i < 4; i++) {
261 addNode(i);
262 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500263 for (int i = 0; i < 3; i++) {
264 faces[i]->linkTo(*faces[i + 1]);
265 }
266
267 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000268 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500269 for (int i = 0; i < 4; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000270 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500271 }
272
273 nodes[1]->publishName(userPrefixes[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000274 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500275 for (int i = 0; i < 4; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000276 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500277 }
278
279 nodes[1]->publishName(userPrefixes[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000280 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500281 for (int i = 0; i < 4; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000282 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500283 }
284}
285
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400286BOOST_AUTO_TEST_CASE(MultipleNodesSimultaneousPublish)
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500287{
288 for (int i = 0; i < 4; i++) {
289 addNode(i);
290 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500291 for (int i = 0; i < 3; i++) {
292 faces[i]->linkTo(*faces[i + 1]);
293 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500294 for (int i = 0; i < 4; i++) {
295 nodes[i]->publishName(userPrefixes[i]);
296 }
297
Junxiao Shifadcde52022-02-28 00:38:45 +0000298 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500299 for (int i = 0; i < 4; i++) {
300 for (int j = 0; j < 4; j++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000301 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500302 }
303 }
304
305 for (int i = 0; i < 4; i++) {
306 nodes[i]->publishName(userPrefixes[i], 4);
307 }
308
Junxiao Shifadcde52022-02-28 00:38:45 +0000309 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500310 for (int i = 0; i < 4; i++) {
311 for (int j = 0; j < 4; j++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000312 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(NOT_EXIST), 4);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500313 }
314 }
315}
316
317BOOST_AUTO_TEST_CASE(NetworkPartition)
318{
319 for (int i = 0; i < 4; i++) {
320 addNode(i);
321 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500322 for (int i = 0; i < 3; i++) {
323 faces[i]->linkTo(*faces[i + 1]);
324 }
325
326 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000327 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500328 for (int i = 0; i < 4; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000329 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500330 }
331
332 for (int i = 0; i < 3; i++) {
333 faces[i]->unlink();
334 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500335 faces[0]->linkTo(*faces[1]);
336 faces[2]->linkTo(*faces[3]);
337
338 nodes[0]->publishName(userPrefixes[0]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000339 advanceClocks(10_ms, 100);
340 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 2);
341 BOOST_CHECK_EQUAL(nodes[2]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
342 BOOST_CHECK_EQUAL(nodes[3]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500343
344 nodes[1]->publishName(userPrefixes[1], 2);
Junxiao Shifadcde52022-02-28 00:38:45 +0000345 advanceClocks(10_ms, 100);
346 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500347
348 nodes[2]->publishName(userPrefixes[2], 2);
Junxiao Shifadcde52022-02-28 00:38:45 +0000349 advanceClocks(10_ms, 100);
350 BOOST_CHECK_EQUAL(nodes[3]->getSeqNo(userPrefixes[2]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500351
352 nodes[3]->publishName(userPrefixes[3], 2);
Junxiao Shifadcde52022-02-28 00:38:45 +0000353 advanceClocks(10_ms, 100);
354 BOOST_CHECK_EQUAL(nodes[2]->getSeqNo(userPrefixes[3]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500355
Junxiao Shifadcde52022-02-28 00:38:45 +0000356 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[3]).value_or(NOT_EXIST), NOT_EXIST);
357 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[3]).value_or(NOT_EXIST), NOT_EXIST);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500358
359 for (int i = 0; i < 3; i++) {
360 faces[i]->unlink();
361 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500362 for (int i = 0; i < 3; i++) {
363 faces[i]->linkTo(*faces[i + 1]);
364 }
365
Junxiao Shifadcde52022-02-28 00:38:45 +0000366 advanceClocks(10_ms, 100);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500367 for (int i = 0; i < 4; i++) {
368 for (int j = 0; j < 4; j++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000369 BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(NOT_EXIST), 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500370 }
371 }
372}
373
374BOOST_AUTO_TEST_CASE(IBFOverflow)
375{
376 addNode(0);
377 addNode(1);
378
379 faces[0]->linkTo(*faces[1]);
Junxiao Shifadcde52022-02-28 00:38:45 +0000380 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500381
382 // 50 > 40 (expected number of entries in IBF)
383 for (int i = 0; i < 50; i++) {
Junxiao Shifadcde52022-02-28 00:38:45 +0000384 nodes[0]->addUserNode(makeSubPrefix(0, i));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500385 }
Junxiao Shifadcde52022-02-28 00:38:45 +0000386 batchUpdate(0, 0, 20, 1);
387 advanceClocks(10_ms, 100);
388 batchCheck(1, 0, 0, 20, 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500389
Junxiao Shifadcde52022-02-28 00:38:45 +0000390 batchUpdate(0, 21, 49, 1);
391 advanceClocks(10_ms, 100);
392 batchCheck(1, 0, 21, 49, 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500393}
394
395BOOST_AUTO_TEST_CASE(DiffIBFDecodeFailureSimple)
396{
Junxiao Shifadcde52022-02-28 00:38:45 +0000397 searchIbfDecodeFailures(46, 52, [this] (int totalUpdates) {
398 addNode(0);
399 addNode(1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500400
Junxiao Shifadcde52022-02-28 00:38:45 +0000401 faces[0]->linkTo(*faces[1]);
402 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500403
Junxiao Shifadcde52022-02-28 00:38:45 +0000404 batchUpdate(0, 0, totalUpdates, 1);
405 advanceClocks(10_ms, 100);
406 batchCheck(1, 0, 0, totalUpdates, 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500407
Junxiao Shifadcde52022-02-28 00:38:45 +0000408 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), NOT_EXIST);
409 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), NOT_EXIST);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500410
Junxiao Shifadcde52022-02-28 00:38:45 +0000411 nodes[1]->publishName(userPrefixes[1]);
412 advanceClocks(10_ms, 100);
413 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500414
Junxiao Shifadcde52022-02-28 00:38:45 +0000415 nodes[0]->publishName(userPrefixes[0]);
416 advanceClocks(10_ms, 100);
417 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
418 });
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500419}
420
421BOOST_AUTO_TEST_CASE(DiffIBFDecodeFailureSimpleSegmentedRecovery)
422{
Junxiao Shifadcde52022-02-28 00:38:45 +0000423 searchIbfDecodeFailures(46, 52, [this] (int totalUpdates) {
424 addNode(0);
425 addNode(1);
426 faces[0]->linkTo(*faces[1]);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500427
Junxiao Shifadcde52022-02-28 00:38:45 +0000428 advanceClocks(10_ms);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500429
Junxiao Shifadcde52022-02-28 00:38:45 +0000430 batchUpdate(0, 0, totalUpdates, 1);
431 advanceClocks(10_ms, 100);
432 batchCheck(1, 0, 0, totalUpdates, 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500433
Junxiao Shifadcde52022-02-28 00:38:45 +0000434 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), NOT_EXIST);
435 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), NOT_EXIST);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500436
Junxiao Shifadcde52022-02-28 00:38:45 +0000437 nodes[1]->publishName(userPrefixes[1]);
438 advanceClocks(10_ms, 100);
439 BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500440
Junxiao Shifadcde52022-02-28 00:38:45 +0000441 nodes[0]->publishName(userPrefixes[0]);
442 advanceClocks(10_ms, 100);
443 BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
444 });
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500445}
446
447BOOST_AUTO_TEST_CASE(DiffIBFDecodeFailureMultipleNodes)
448{
Junxiao Shifadcde52022-02-28 00:38:45 +0000449 searchIbfDecodeFailures(46, 52, [this] (int totalUpdates) {
450 for (int i = 0; i < 4; i++) {
451 addNode(i);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500452 }
Junxiao Shifadcde52022-02-28 00:38:45 +0000453 for (int i = 0; i < 3; i++) {
454 faces[i]->linkTo(*faces[i + 1]);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500455 }
Junxiao Shifadcde52022-02-28 00:38:45 +0000456
457 batchUpdate(0, 0, totalUpdates, 1);
458 advanceClocks(10_ms, 100);
459 for (int i = 0; i < 4; i++) {
460 batchCheck(i, 0, 0, totalUpdates, 1);
461 }
462 });
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500463}
464
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600465BOOST_AUTO_TEST_CASE(DelayedSecondSegment)
466{
467 addNode(0);
468
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800469 int i = 0;
Davide Pesaventodb789562020-12-19 23:01:08 -0500470 detail::State state;
Junxiao Shic5f5eb12023-08-11 08:05:23 +0000471 std::shared_ptr<ndn::Buffer> compressed;
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800472 do {
Junxiao Shifadcde52022-02-28 00:38:45 +0000473 auto prefixToPublish = makeSubPrefix(0, i++);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600474 nodes[0]->addUserNode(prefixToPublish);
475 nodes[0]->publishName(prefixToPublish);
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800476
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400477 state.addContent(Name(prefixToPublish).appendNumber(nodes[0]->m_prefixes[prefixToPublish]));
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800478
479 auto block = state.wireEncode();
Davide Pesaventof6fd2fb2022-03-18 21:00:36 -0400480 compressed = detail::compress(nodes[0]->m_contentCompression, block);
Junxiao Shic5f5eb12023-08-11 08:05:23 +0000481 } while (compressed->size() < (ndn::MAX_NDN_PACKET_SIZE >> 1));
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600482
Junxiao Shifadcde52022-02-28 00:38:45 +0000483 advanceClocks(10_ms, 100);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600484
485 Name syncInterestName(syncPrefix);
Davide Pesaventodb789562020-12-19 23:01:08 -0500486 detail::IBLT iblt(40, nodes[0]->m_ibltCompression);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600487 iblt.appendToName(syncInterestName);
488
Davide Pesavento03426ef2022-09-23 19:49:10 -0400489 nodes[0]->onSyncInterest(syncPrefix, Interest(syncInterestName));
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600490
Junxiao Shifadcde52022-02-28 00:38:45 +0000491 advanceClocks(10_ms);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600492
493 BOOST_CHECK_EQUAL(nodes[0]->m_segmentPublisher.m_ims.size(), 2);
494 // Expire contents from segmentPublisher
Junxiao Shifadcde52022-02-28 00:38:45 +0000495 advanceClocks(10_ms, 100);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600496 BOOST_CHECK_EQUAL(nodes[0]->m_segmentPublisher.m_ims.size(), 0);
497
498 // Get data name from face and increase segment number to form next interest
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400499 BOOST_REQUIRE(!faces[0]->sentData.empty());
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600500 Name dataName = faces[0]->sentData.front().getName();
Ashlesh Gawanded51690a2019-11-11 22:51:06 -0600501 Name interestName = dataName.getSubName(0, dataName.size() - 2);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600502 interestName.appendSegment(1);
503 faces[0]->sentData.clear();
504
Davide Pesavento03426ef2022-09-23 19:49:10 -0400505 nodes[0]->onSyncInterest(syncPrefix, Interest(interestName));
Junxiao Shifadcde52022-02-28 00:38:45 +0000506 advanceClocks(10_ms);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600507
508 // Should have repopulated SegmentPublisher
509 BOOST_CHECK_EQUAL(nodes[0]->m_segmentPublisher.m_ims.size(), 2);
510 // Should have received the second data segment this time
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400511 BOOST_REQUIRE(!faces[0]->sentData.empty());
512 BOOST_CHECK_EQUAL(faces[0]->sentData.front().getName().at(-1).toSegment(), 1);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600513}
514
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500515BOOST_AUTO_TEST_SUITE_END()
516
Ashlesh Gawanded51690a2019-11-11 22:51:06 -0600517} // namespace psync