blob: 2526d2ce0a3dc6d76cb85deed3ad9d53d3a65986 [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/>.
Ashlesh Gawande8ab75722020-08-02 22:42:28 -070018 */
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050019
Ashlesh Gawande78b94ad2018-12-13 15:29:19 -060020#include "PSync/partial-producer.hpp"
21#include "PSync/consumer.hpp"
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050022
Davide Pesavento5b3cf762020-04-03 16:20:04 -040023#include "tests/boost-test.hpp"
Davide Pesaventof91d1df2020-11-25 14:50:41 -050024#include "tests/io-fixture.hpp"
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -040025#include "tests/key-chain-fixture.hpp"
Davide Pesavento5b3cf762020-04-03 16:20:04 -040026
Davide Pesavento03426ef2022-09-23 19:49:10 -040027#include <array>
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 Shic5f5eb12023-08-11 08:05:23 +000032using ndn::Interest;
33using ndn::Name;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050034
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -040035class PartialSyncFixture : public tests::IoFixture, public tests::KeyChainFixture
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050036{
Davide Pesavento03426ef2022-09-23 19:49:10 -040037protected:
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050038 PartialSyncFixture()
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050039 {
Davide Pesavento03426ef2022-09-23 19:49:10 -040040 producer = std::make_unique<PartialProducer>(face, m_keyChain, 40, syncPrefix, userPrefix);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050041 addUserNodes("testUser", 10);
42 }
43
Davide Pesaventof91d1df2020-11-25 14:50:41 -050044 ~PartialSyncFixture() override
Ashlesh Gawandeec43b362018-08-01 15:15:01 -050045 {
Davide Pesaventof91d1df2020-11-25 14:50:41 -050046 for (const auto& consumer : consumers) {
Ashlesh Gawandeec43b362018-08-01 15:15:01 -050047 if (consumer) {
48 consumer->stop();
49 }
50 }
51 }
52
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050053 void
Davide Pesavento5b3cf762020-04-03 16:20:04 -040054 addConsumer(int id, const std::vector<std::string>& subscribeTo, bool linkToProducer = true)
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050055 {
Junxiao Shic5f5eb12023-08-11 08:05:23 +000056 consumerFaces[id] = std::make_unique<ndn::DummyClientFace>(m_io, m_keyChain,
57 ndn::DummyClientFace::Options{true, true});
Ashlesh Gawandeec43b362018-08-01 15:15:01 -050058 if (linkToProducer) {
59 face.linkTo(*consumerFaces[id]);
60 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050061
Davide Pesavento03426ef2022-09-23 19:49:10 -040062 consumers[id] = std::make_unique<Consumer>(syncPrefix, *consumerFaces[id],
Davide Pesaventof91d1df2020-11-25 14:50:41 -050063 [&, id] (const auto& availableSubs) {
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050064 numHelloDataRcvd++;
Ashlesh Gawandedeb73f82018-08-09 11:08:02 -050065 BOOST_CHECK(checkSubList(availableSubs));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050066
67 checkIBFUpdated(id);
68
69 for (const auto& sub : subscribeTo) {
Ashlesh Gawandecbdc0122020-07-13 21:13:00 -070070 auto it = availableSubs.find(sub);
71 consumers[id]->addSubscription(sub, it->second);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050072 }
73 consumers[id]->sendSyncInterest();
74 },
Ashlesh Gawandecbdc0122020-07-13 21:13:00 -070075 [&, id] (const auto& updates) {
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050076 numSyncDataRcvd++;
77
78 checkIBFUpdated(id);
79
80 for (const auto& update : updates) {
81 BOOST_CHECK(consumers[id]->isSubscribed(update.prefix));
82 BOOST_CHECK_EQUAL(oldSeqMap.at(update.prefix) + 1, update.lowSeq);
83 BOOST_CHECK_EQUAL(producer->m_prefixes.at(update.prefix), update.highSeq);
84 BOOST_CHECK_EQUAL(consumers[id]->getSeqNo(update.prefix).value(), update.highSeq);
85 }
86 }, 40, 0.001);
87
88 advanceClocks(ndn::time::milliseconds(10));
89 }
90
91 void
92 checkIBFUpdated(int id)
93 {
94 Name emptyName;
95 producer->m_iblt.appendToName(emptyName);
96 BOOST_CHECK_EQUAL(consumers[id]->m_iblt, emptyName);
97 }
98
99 bool
Ashlesh Gawandecbdc0122020-07-13 21:13:00 -0700100 checkSubList(const std::map<Name, uint64_t>& availableSubs) const
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500101 {
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400102 for (const auto& prefix : producer->m_prefixes) {
Ashlesh Gawandecbdc0122020-07-13 21:13:00 -0700103 auto it = availableSubs.find(prefix.first);
104 if (it == availableSubs.end()) {
Ashlesh Gawandedeb73f82018-08-09 11:08:02 -0500105 return false;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500106 }
107 }
108 return true;
109 }
110
111 void
112 addUserNodes(const std::string& prefix, int numOfUserNodes)
113 {
114 // zeroth is added through constructor
115 for (int i = 1; i < numOfUserNodes; i++) {
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400116 producer->addUserNode(prefix + "-" + std::to_string(i));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500117 }
118 }
119
120 void
121 publishUpdateFor(const std::string& prefix)
122 {
123 oldSeqMap = producer->m_prefixes;
124 producer->publishName(prefix);
125 advanceClocks(ndn::time::milliseconds(10));
126 }
127
128 void
129 updateSeqFor(const std::string& prefix, uint64_t seq)
130 {
131 oldSeqMap = producer->m_prefixes;
132 producer->updateSeqNo(prefix, seq);
133 }
134
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -0400135protected:
Junxiao Shic5f5eb12023-08-11 08:05:23 +0000136 ndn::DummyClientFace face{m_io, m_keyChain, {true, true}};
Davide Pesavento03426ef2022-09-23 19:49:10 -0400137 const Name syncPrefix{"psync"};
138 const Name userPrefix{"testUser-0"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500139
Davide Pesavento03426ef2022-09-23 19:49:10 -0400140 std::unique_ptr<PartialProducer> producer;
Davide Pesaventof91d1df2020-11-25 14:50:41 -0500141 std::map<Name, uint64_t> oldSeqMap;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500142
Davide Pesavento03426ef2022-09-23 19:49:10 -0400143 std::array<std::unique_ptr<Consumer>, 3> consumers;
Junxiao Shic5f5eb12023-08-11 08:05:23 +0000144 std::array<std::unique_ptr<ndn::DummyClientFace>, 3> consumerFaces;
Davide Pesaventof91d1df2020-11-25 14:50:41 -0500145 int numHelloDataRcvd = 0;
146 int numSyncDataRcvd = 0;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500147};
148
Ashlesh Gawande6a5157f2019-12-09 11:49:07 -0600149BOOST_FIXTURE_TEST_SUITE(TestPartialSync, PartialSyncFixture)
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500150
151BOOST_AUTO_TEST_CASE(Simple)
152{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400153 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500154 addConsumer(0, subscribeTo);
155
156 consumers[0]->sendHelloInterest();
157 advanceClocks(ndn::time::milliseconds(10));
158 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
159
160 publishUpdateFor("testUser-2");
161 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
162 publishUpdateFor("testUser-3");
163 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
164 publishUpdateFor("testUser-2");
165 BOOST_CHECK_EQUAL(numSyncDataRcvd, 2);
166}
167
168BOOST_AUTO_TEST_CASE(MissedUpdate)
169{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400170 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500171 addConsumer(0, subscribeTo);
172
173 consumers[0]->sendHelloInterest();
174 advanceClocks(ndn::time::milliseconds(10));
175 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
176
177 updateSeqFor("testUser-2", 3);
178 BOOST_CHECK_EQUAL(numSyncDataRcvd, 0);
179
180 // The sync interest sent after hello will timeout
Ashlesh Gawande8ab75722020-08-02 22:42:28 -0700181 advanceClocks(ndn::time::milliseconds(999));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500182 BOOST_CHECK_EQUAL(numSyncDataRcvd, 0);
183
184 // Next sync interest will bring back the sync data
Ashlesh Gawande8ab75722020-08-02 22:42:28 -0700185 advanceClocks(ndn::time::milliseconds(1));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500186 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
187}
188
189BOOST_AUTO_TEST_CASE(LateSubscription)
190{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400191 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500192 addConsumer(0, subscribeTo);
193
194 consumers[0]->sendHelloInterest();
195 advanceClocks(ndn::time::milliseconds(10));
196
197 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
198 publishUpdateFor("testUser-2");
199 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
200
Ashlesh Gawandecbdc0122020-07-13 21:13:00 -0700201 consumers[0]->addSubscription("testUser-3", 0);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500202 consumers[0]->sendSyncInterest();
203 publishUpdateFor("testUser-3");
204 BOOST_CHECK_EQUAL(numSyncDataRcvd, 2);
205}
206
207BOOST_AUTO_TEST_CASE(ConsumerSyncTimeout)
208{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400209 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500210 addConsumer(0, subscribeTo);
211
212 consumers[0]->sendHelloInterest();
213 BOOST_CHECK_EQUAL(producer->m_pendingEntries.size(), 0);
214 advanceClocks(ndn::time::milliseconds(10));
215 BOOST_CHECK_EQUAL(producer->m_pendingEntries.size(), 1);
216 advanceClocks(ndn::time::milliseconds(10), 100);
Ashlesh Gawande8ab75722020-08-02 22:42:28 -0700217 // The next Interest is sent after the first one immediately
218 BOOST_CHECK_EQUAL(producer->m_pendingEntries.size(), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500219 advanceClocks(ndn::time::milliseconds(10), 100);
220
221 int numSyncInterests = 0;
222 for (const auto& interest : consumerFaces[0]->sentInterests) {
223 if (interest.getName().getSubName(0, 2) == Name("/psync/sync")) {
224 numSyncInterests++;
225 }
226 }
Ashlesh Gawande8ab75722020-08-02 22:42:28 -0700227 BOOST_CHECK_EQUAL(numSyncInterests, 3);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500228 BOOST_CHECK_EQUAL(numSyncDataRcvd, 0);
229}
230
231BOOST_AUTO_TEST_CASE(MultipleConsumersWithSameSubList)
232{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400233 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500234 addConsumer(0, subscribeTo);
235 addConsumer(1, subscribeTo);
236 addConsumer(2, subscribeTo);
237
238 consumers[0]->sendHelloInterest();
239 consumers[1]->sendHelloInterest();
240 consumers[2]->sendHelloInterest();
241 advanceClocks(ndn::time::milliseconds(10));
242
243 BOOST_CHECK_EQUAL(numHelloDataRcvd, 3);
244
245 publishUpdateFor("testUser-2");
246 BOOST_CHECK_EQUAL(numSyncDataRcvd, 3);
247
248 publishUpdateFor("testUser-3");
249 BOOST_CHECK_EQUAL(numSyncDataRcvd, 3);
250}
251
252BOOST_AUTO_TEST_CASE(MultipleConsumersWithDifferentSubList)
253{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400254 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500255 addConsumer(0, subscribeTo);
256
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400257 std::vector<std::string> subscribeTo1{"testUser-1", "testUser-3", "testUser-5"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500258 addConsumer(1, subscribeTo1);
259
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400260 std::vector<std::string> subscribeTo2{"testUser-2", "testUser-3"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500261 addConsumer(2, subscribeTo2);
262
263 consumers[0]->sendHelloInterest();
264 consumers[1]->sendHelloInterest();
265 consumers[2]->sendHelloInterest();
266 advanceClocks(ndn::time::milliseconds(10));
267
268 BOOST_CHECK_EQUAL(numHelloDataRcvd, 3);
269
270 publishUpdateFor("testUser-2");
271 BOOST_CHECK_EQUAL(numSyncDataRcvd, 2);
272
273 numSyncDataRcvd = 0;
274 publishUpdateFor("testUser-3");
275 BOOST_CHECK_EQUAL(numSyncDataRcvd, 2);
276}
277
278BOOST_AUTO_TEST_CASE(ReplicatedProducer)
279{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400280 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500281 addConsumer(0, subscribeTo);
282
283 consumers[0]->sendHelloInterest();
284 advanceClocks(ndn::time::milliseconds(10));
285 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
286
287 publishUpdateFor("testUser-2");
288 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
289
290 // Link to first producer goes down
291 face.unlink();
292
Junxiao Shic5f5eb12023-08-11 08:05:23 +0000293 ndn::DummyClientFace face2(m_io, m_keyChain, {true, true});
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -0400294 PartialProducer replicatedProducer(face2, m_keyChain, 40, syncPrefix, userPrefix);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500295 for (int i = 1; i < 10; i++) {
Davide Pesavento03426ef2022-09-23 19:49:10 -0400296 replicatedProducer.addUserNode("testUser-" + std::to_string(i));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500297 }
298 advanceClocks(ndn::time::milliseconds(10));
299 replicatedProducer.publishName("testUser-2");
300 // Link to a replicated producer comes up
301 face2.linkTo(*consumerFaces[0]);
302
303 BOOST_CHECK_EQUAL(face2.sentData.size(), 0);
304
305 // Update in first producer as well so consumer on sync data
306 // callback checks still pass
307 publishUpdateFor("testUser-2");
308 replicatedProducer.publishName("testUser-2");
309 advanceClocks(ndn::time::milliseconds(15), 100);
310 BOOST_CHECK_EQUAL(numSyncDataRcvd, 2);
311 BOOST_CHECK_EQUAL(face2.sentData.size(), 1);
312}
313
314BOOST_AUTO_TEST_CASE(ApplicationNack)
315{
316 // 50 is more than expected number of entries of 40 in the producer's IBF
317 addUserNodes("testUser", 50);
318
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400319 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500320 addConsumer(0, subscribeTo);
321
322 consumers[0]->sendHelloInterest();
323 advanceClocks(ndn::time::milliseconds(10));
324 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
325
326 publishUpdateFor("testUser-2");
327 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
328
329 oldSeqMap = producer->m_prefixes;
330 for (int i = 0; i < 50; i++) {
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400331 Name prefix("testUser-" + std::to_string(i));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500332 producer->updateSeqNo(prefix, producer->getSeqNo(prefix).value() + 1);
333 }
334 // Next sync interest should trigger the nack
335 advanceClocks(ndn::time::milliseconds(15), 100);
336
Ashlesh Gawandea9296472018-08-04 08:21:39 -0500337 // Application should have been notified that new data is available
338 // from the hello itself.
339 BOOST_CHECK_EQUAL(numSyncDataRcvd, 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500340
341 bool nackRcvd = false;
342 for (const auto& data : face.sentData) {
Junxiao Shic5f5eb12023-08-11 08:05:23 +0000343 if (data.getContentType() == ndn::tlv::ContentType_Nack) {
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500344 nackRcvd = true;
345 break;
346 }
347 }
348 BOOST_CHECK(nackRcvd);
349
Ashlesh Gawandea9296472018-08-04 08:21:39 -0500350 publishUpdateFor("testUser-4");
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500351 advanceClocks(ndn::time::milliseconds(10));
Ashlesh Gawandea9296472018-08-04 08:21:39 -0500352 BOOST_CHECK_EQUAL(numSyncDataRcvd, 3);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500353}
354
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500355BOOST_AUTO_TEST_CASE(SegmentedHello)
356{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400357 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500358 addConsumer(0, subscribeTo);
359
360 addUserNodes("testUser", 400);
361
362 consumers[0]->sendHelloInterest();
363 advanceClocks(ndn::time::milliseconds(10));
364 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600365
366 // Simulate sending delayed interest for second segment
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400367 BOOST_REQUIRE(!face.sentData.empty());
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600368 Name dataName = face.sentData.back().getName();
369 face.sentData.clear();
370 BOOST_CHECK_EQUAL(producer->m_segmentPublisher.m_ims.size(), 2);
371
372 advanceClocks(ndn::time::milliseconds(1000));
373 BOOST_CHECK_EQUAL(producer->m_segmentPublisher.m_ims.size(), 0);
374
375 producer->onHelloInterest(consumers[0]->m_helloInterestPrefix, Interest(dataName));
376 advanceClocks(ndn::time::milliseconds(10));
377 BOOST_CHECK_EQUAL(producer->m_segmentPublisher.m_ims.size(), 2);
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400378 BOOST_REQUIRE(!face.sentData.empty());
379 BOOST_CHECK_EQUAL(face.sentData.front().getName().at(-1).toSegment(), 1);
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500380}
381
382BOOST_AUTO_TEST_CASE(SegmentedSync)
383{
Davide Pesaventof91d1df2020-11-25 14:50:41 -0500384 Name longNameToExceedDataSize;
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500385 for (int i = 0; i < 100; i++) {
386 longNameToExceedDataSize.append("test-" + std::to_string(i));
387 }
388 addUserNodes(longNameToExceedDataSize.toUri(), 10);
389
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400390 std::vector<std::string> subscribeTo;
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500391 for (int i = 1; i < 10; i++) {
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400392 subscribeTo.push_back(longNameToExceedDataSize.toUri() + "-" + std::to_string(i));
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500393 }
394 addConsumer(0, subscribeTo);
395
396 consumers[0]->sendHelloInterest();
397 advanceClocks(ndn::time::milliseconds(10));
398 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
399
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600400 // To be used later to simulate sending delayed segmented interest
Davide Pesaventof91d1df2020-11-25 14:50:41 -0500401 Name syncInterestName(consumers[0]->m_syncInterestPrefix);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600402 consumers[0]->m_bloomFilter.appendToName(syncInterestName);
403 syncInterestName.append(consumers[0]->m_iblt);
404 syncInterestName.appendVersion();
405 syncInterestName.appendSegment(1);
406
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500407 oldSeqMap = producer->m_prefixes;
408 for (int i = 1; i < 10; i++) {
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400409 producer->updateSeqNo(longNameToExceedDataSize.toUri() + "-" + std::to_string(i), 1);
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500410 }
411
Ashlesh Gawande8ab75722020-08-02 22:42:28 -0700412 advanceClocks(ndn::time::milliseconds(999));
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500413 BOOST_CHECK_EQUAL(numSyncDataRcvd, 0);
414
Ashlesh Gawande8ab75722020-08-02 22:42:28 -0700415 advanceClocks(ndn::time::milliseconds(1));
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500416 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600417
418 // Simulate sending delayed interest for second segment
419 face.sentData.clear();
420 consumerFaces[0]->sentData.clear();
421
422 BOOST_CHECK_EQUAL(producer->m_segmentPublisher.m_ims.size(), 2);
423
424 advanceClocks(ndn::time::milliseconds(2000));
425 BOOST_CHECK_EQUAL(producer->m_segmentPublisher.m_ims.size(), 0);
426
427 producer->onSyncInterest(consumers[0]->m_syncInterestPrefix, Interest(syncInterestName));
428 advanceClocks(ndn::time::milliseconds(10));
429 BOOST_CHECK_EQUAL(producer->m_segmentPublisher.m_ims.size(), 2);
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400430 BOOST_REQUIRE(!face.sentData.empty());
431 BOOST_CHECK_EQUAL(face.sentData.front().getName().at(-1).toSegment(), 1);
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500432}
433
Ashlesh Gawandecbdc0122020-07-13 21:13:00 -0700434BOOST_AUTO_TEST_CASE(DelayedSubscription) // #5122
435{
436 publishUpdateFor("testUser-2");
437 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4"};
438 addConsumer(0, subscribeTo);
439
440 consumers[0]->sendHelloInterest();
441 advanceClocks(ndn::time::milliseconds(10));
442 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
443
444 // Application came up late and subscribed to testUser-2
445 // after Producer had already published the first update.
446 // So by default Consumer will let the application know that
447 // the prefix it subscribed to has already some updates
448 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
449}
450
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500451BOOST_AUTO_TEST_SUITE_END()
452
Ashlesh Gawande6a5157f2019-12-09 11:49:07 -0600453} // namespace psync