blob: d7a0b4f51a372623bebb7cce9a73090524e647bf [file] [log] [blame]
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Davide Pesaventoc407dee2022-07-21 23:56:05 -04003 * 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/>.
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
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050027#include <ndn-cxx/name.hpp>
28#include <ndn-cxx/util/dummy-client-face.hpp>
29
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050030namespace psync {
31
32using namespace ndn;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050033
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -040034class PartialSyncFixture : public tests::IoFixture, public tests::KeyChainFixture
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050035{
36public:
37 PartialSyncFixture()
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050038 {
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -040039 producer = make_shared<PartialProducer>(face, m_keyChain, 40, syncPrefix, userPrefix);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050040 addUserNodes("testUser", 10);
41 }
42
Davide Pesaventof91d1df2020-11-25 14:50:41 -050043 ~PartialSyncFixture() override
Ashlesh Gawandeec43b362018-08-01 15:15:01 -050044 {
Davide Pesaventof91d1df2020-11-25 14:50:41 -050045 for (const auto& consumer : consumers) {
Ashlesh Gawandeec43b362018-08-01 15:15:01 -050046 if (consumer) {
47 consumer->stop();
48 }
49 }
50 }
51
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050052 void
Davide Pesavento5b3cf762020-04-03 16:20:04 -040053 addConsumer(int id, const std::vector<std::string>& subscribeTo, bool linkToProducer = true)
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050054 {
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -040055 consumerFaces[id] = std::make_shared<util::DummyClientFace>(m_io, m_keyChain,
56 util::DummyClientFace::Options{true, true});
Ashlesh Gawandeec43b362018-08-01 15:15:01 -050057 if (linkToProducer) {
58 face.linkTo(*consumerFaces[id]);
59 }
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050060
Davide Pesavento5b3cf762020-04-03 16:20:04 -040061 consumers[id] = std::make_shared<Consumer>(syncPrefix, *consumerFaces[id],
Davide Pesaventof91d1df2020-11-25 14:50:41 -050062 [&, id] (const auto& availableSubs) {
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050063 numHelloDataRcvd++;
Ashlesh Gawandedeb73f82018-08-09 11:08:02 -050064 BOOST_CHECK(checkSubList(availableSubs));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050065
66 checkIBFUpdated(id);
67
68 for (const auto& sub : subscribeTo) {
Ashlesh Gawandecbdc0122020-07-13 21:13:00 -070069 auto it = availableSubs.find(sub);
70 consumers[id]->addSubscription(sub, it->second);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050071 }
72 consumers[id]->sendSyncInterest();
73 },
Ashlesh Gawandecbdc0122020-07-13 21:13:00 -070074 [&, id] (const auto& updates) {
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050075 numSyncDataRcvd++;
76
77 checkIBFUpdated(id);
78
79 for (const auto& update : updates) {
80 BOOST_CHECK(consumers[id]->isSubscribed(update.prefix));
81 BOOST_CHECK_EQUAL(oldSeqMap.at(update.prefix) + 1, update.lowSeq);
82 BOOST_CHECK_EQUAL(producer->m_prefixes.at(update.prefix), update.highSeq);
83 BOOST_CHECK_EQUAL(consumers[id]->getSeqNo(update.prefix).value(), update.highSeq);
84 }
85 }, 40, 0.001);
86
87 advanceClocks(ndn::time::milliseconds(10));
88 }
89
90 void
91 checkIBFUpdated(int id)
92 {
93 Name emptyName;
94 producer->m_iblt.appendToName(emptyName);
95 BOOST_CHECK_EQUAL(consumers[id]->m_iblt, emptyName);
96 }
97
98 bool
Ashlesh Gawandecbdc0122020-07-13 21:13:00 -070099 checkSubList(const std::map<Name, uint64_t>& availableSubs) const
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500100 {
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400101 for (const auto& prefix : producer->m_prefixes) {
Ashlesh Gawandecbdc0122020-07-13 21:13:00 -0700102 auto it = availableSubs.find(prefix.first);
103 if (it == availableSubs.end()) {
Ashlesh Gawandedeb73f82018-08-09 11:08:02 -0500104 return false;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500105 }
106 }
107 return true;
108 }
109
110 void
111 addUserNodes(const std::string& prefix, int numOfUserNodes)
112 {
113 // zeroth is added through constructor
114 for (int i = 1; i < numOfUserNodes; i++) {
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400115 producer->addUserNode(prefix + "-" + std::to_string(i));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500116 }
117 }
118
119 void
120 publishUpdateFor(const std::string& prefix)
121 {
122 oldSeqMap = producer->m_prefixes;
123 producer->publishName(prefix);
124 advanceClocks(ndn::time::milliseconds(10));
125 }
126
127 void
128 updateSeqFor(const std::string& prefix, uint64_t seq)
129 {
130 oldSeqMap = producer->m_prefixes;
131 producer->updateSeqNo(prefix, seq);
132 }
133
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -0400134protected:
135 util::DummyClientFace face{m_io, m_keyChain, {true, true}};
Davide Pesaventof91d1df2020-11-25 14:50:41 -0500136 Name syncPrefix{"psync"};
137 Name userPrefix{"testUser-0"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500138
139 shared_ptr<PartialProducer> producer;
Davide Pesaventof91d1df2020-11-25 14:50:41 -0500140 std::map<Name, uint64_t> oldSeqMap;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500141
142 shared_ptr<Consumer> consumers[3];
143 shared_ptr<util::DummyClientFace> consumerFaces[3];
Davide Pesaventof91d1df2020-11-25 14:50:41 -0500144 int numHelloDataRcvd = 0;
145 int numSyncDataRcvd = 0;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500146};
147
Ashlesh Gawande6a5157f2019-12-09 11:49:07 -0600148BOOST_FIXTURE_TEST_SUITE(TestPartialSync, PartialSyncFixture)
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500149
150BOOST_AUTO_TEST_CASE(Simple)
151{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400152 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500153 addConsumer(0, subscribeTo);
154
155 consumers[0]->sendHelloInterest();
156 advanceClocks(ndn::time::milliseconds(10));
157 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
158
159 publishUpdateFor("testUser-2");
160 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
161 publishUpdateFor("testUser-3");
162 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
163 publishUpdateFor("testUser-2");
164 BOOST_CHECK_EQUAL(numSyncDataRcvd, 2);
165}
166
167BOOST_AUTO_TEST_CASE(MissedUpdate)
168{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400169 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500170 addConsumer(0, subscribeTo);
171
172 consumers[0]->sendHelloInterest();
173 advanceClocks(ndn::time::milliseconds(10));
174 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
175
176 updateSeqFor("testUser-2", 3);
177 BOOST_CHECK_EQUAL(numSyncDataRcvd, 0);
178
179 // The sync interest sent after hello will timeout
Ashlesh Gawande8ab75722020-08-02 22:42:28 -0700180 advanceClocks(ndn::time::milliseconds(999));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500181 BOOST_CHECK_EQUAL(numSyncDataRcvd, 0);
182
183 // Next sync interest will bring back the sync data
Ashlesh Gawande8ab75722020-08-02 22:42:28 -0700184 advanceClocks(ndn::time::milliseconds(1));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500185 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
186}
187
188BOOST_AUTO_TEST_CASE(LateSubscription)
189{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400190 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500191 addConsumer(0, subscribeTo);
192
193 consumers[0]->sendHelloInterest();
194 advanceClocks(ndn::time::milliseconds(10));
195
196 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
197 publishUpdateFor("testUser-2");
198 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
199
Ashlesh Gawandecbdc0122020-07-13 21:13:00 -0700200 consumers[0]->addSubscription("testUser-3", 0);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500201 consumers[0]->sendSyncInterest();
202 publishUpdateFor("testUser-3");
203 BOOST_CHECK_EQUAL(numSyncDataRcvd, 2);
204}
205
206BOOST_AUTO_TEST_CASE(ConsumerSyncTimeout)
207{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400208 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500209 addConsumer(0, subscribeTo);
210
211 consumers[0]->sendHelloInterest();
212 BOOST_CHECK_EQUAL(producer->m_pendingEntries.size(), 0);
213 advanceClocks(ndn::time::milliseconds(10));
214 BOOST_CHECK_EQUAL(producer->m_pendingEntries.size(), 1);
215 advanceClocks(ndn::time::milliseconds(10), 100);
Ashlesh Gawande8ab75722020-08-02 22:42:28 -0700216 // The next Interest is sent after the first one immediately
217 BOOST_CHECK_EQUAL(producer->m_pendingEntries.size(), 1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500218 advanceClocks(ndn::time::milliseconds(10), 100);
219
220 int numSyncInterests = 0;
221 for (const auto& interest : consumerFaces[0]->sentInterests) {
222 if (interest.getName().getSubName(0, 2) == Name("/psync/sync")) {
223 numSyncInterests++;
224 }
225 }
Ashlesh Gawande8ab75722020-08-02 22:42:28 -0700226 BOOST_CHECK_EQUAL(numSyncInterests, 3);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500227 BOOST_CHECK_EQUAL(numSyncDataRcvd, 0);
228}
229
230BOOST_AUTO_TEST_CASE(MultipleConsumersWithSameSubList)
231{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400232 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500233 addConsumer(0, subscribeTo);
234 addConsumer(1, subscribeTo);
235 addConsumer(2, subscribeTo);
236
237 consumers[0]->sendHelloInterest();
238 consumers[1]->sendHelloInterest();
239 consumers[2]->sendHelloInterest();
240 advanceClocks(ndn::time::milliseconds(10));
241
242 BOOST_CHECK_EQUAL(numHelloDataRcvd, 3);
243
244 publishUpdateFor("testUser-2");
245 BOOST_CHECK_EQUAL(numSyncDataRcvd, 3);
246
247 publishUpdateFor("testUser-3");
248 BOOST_CHECK_EQUAL(numSyncDataRcvd, 3);
249}
250
251BOOST_AUTO_TEST_CASE(MultipleConsumersWithDifferentSubList)
252{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400253 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500254 addConsumer(0, subscribeTo);
255
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400256 std::vector<std::string> subscribeTo1{"testUser-1", "testUser-3", "testUser-5"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500257 addConsumer(1, subscribeTo1);
258
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400259 std::vector<std::string> subscribeTo2{"testUser-2", "testUser-3"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500260 addConsumer(2, subscribeTo2);
261
262 consumers[0]->sendHelloInterest();
263 consumers[1]->sendHelloInterest();
264 consumers[2]->sendHelloInterest();
265 advanceClocks(ndn::time::milliseconds(10));
266
267 BOOST_CHECK_EQUAL(numHelloDataRcvd, 3);
268
269 publishUpdateFor("testUser-2");
270 BOOST_CHECK_EQUAL(numSyncDataRcvd, 2);
271
272 numSyncDataRcvd = 0;
273 publishUpdateFor("testUser-3");
274 BOOST_CHECK_EQUAL(numSyncDataRcvd, 2);
275}
276
277BOOST_AUTO_TEST_CASE(ReplicatedProducer)
278{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400279 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500280 addConsumer(0, subscribeTo);
281
282 consumers[0]->sendHelloInterest();
283 advanceClocks(ndn::time::milliseconds(10));
284 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
285
286 publishUpdateFor("testUser-2");
287 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
288
289 // Link to first producer goes down
290 face.unlink();
291
Davide Pesaventoc45a4ea2022-09-19 02:10:53 -0400292 util::DummyClientFace face2(m_io, m_keyChain, {true, true});
293 PartialProducer replicatedProducer(face2, m_keyChain, 40, syncPrefix, userPrefix);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500294 for (int i = 1; i < 10; i++) {
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400295 replicatedProducer.addUserNode("testUser-" + std::to_string(i));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500296 }
297 advanceClocks(ndn::time::milliseconds(10));
298 replicatedProducer.publishName("testUser-2");
299 // Link to a replicated producer comes up
300 face2.linkTo(*consumerFaces[0]);
301
302 BOOST_CHECK_EQUAL(face2.sentData.size(), 0);
303
304 // Update in first producer as well so consumer on sync data
305 // callback checks still pass
306 publishUpdateFor("testUser-2");
307 replicatedProducer.publishName("testUser-2");
308 advanceClocks(ndn::time::milliseconds(15), 100);
309 BOOST_CHECK_EQUAL(numSyncDataRcvd, 2);
310 BOOST_CHECK_EQUAL(face2.sentData.size(), 1);
311}
312
313BOOST_AUTO_TEST_CASE(ApplicationNack)
314{
315 // 50 is more than expected number of entries of 40 in the producer's IBF
316 addUserNodes("testUser", 50);
317
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400318 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500319 addConsumer(0, subscribeTo);
320
321 consumers[0]->sendHelloInterest();
322 advanceClocks(ndn::time::milliseconds(10));
323 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
324
325 publishUpdateFor("testUser-2");
326 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
327
328 oldSeqMap = producer->m_prefixes;
329 for (int i = 0; i < 50; i++) {
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400330 Name prefix("testUser-" + std::to_string(i));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500331 producer->updateSeqNo(prefix, producer->getSeqNo(prefix).value() + 1);
332 }
333 // Next sync interest should trigger the nack
334 advanceClocks(ndn::time::milliseconds(15), 100);
335
Ashlesh Gawandea9296472018-08-04 08:21:39 -0500336 // Application should have been notified that new data is available
337 // from the hello itself.
338 BOOST_CHECK_EQUAL(numSyncDataRcvd, 2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500339
340 bool nackRcvd = false;
341 for (const auto& data : face.sentData) {
Davide Pesaventof91d1df2020-11-25 14:50:41 -0500342 if (data.getContentType() == tlv::ContentType_Nack) {
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500343 nackRcvd = true;
344 break;
345 }
346 }
347 BOOST_CHECK(nackRcvd);
348
Ashlesh Gawandea9296472018-08-04 08:21:39 -0500349 publishUpdateFor("testUser-4");
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500350 advanceClocks(ndn::time::milliseconds(10));
Ashlesh Gawandea9296472018-08-04 08:21:39 -0500351 BOOST_CHECK_EQUAL(numSyncDataRcvd, 3);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500352}
353
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500354BOOST_AUTO_TEST_CASE(SegmentedHello)
355{
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400356 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4", "testUser-6"};
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500357 addConsumer(0, subscribeTo);
358
359 addUserNodes("testUser", 400);
360
361 consumers[0]->sendHelloInterest();
362 advanceClocks(ndn::time::milliseconds(10));
363 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600364
365 // Simulate sending delayed interest for second segment
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400366 BOOST_REQUIRE(!face.sentData.empty());
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600367 Name dataName = face.sentData.back().getName();
368 face.sentData.clear();
369 BOOST_CHECK_EQUAL(producer->m_segmentPublisher.m_ims.size(), 2);
370
371 advanceClocks(ndn::time::milliseconds(1000));
372 BOOST_CHECK_EQUAL(producer->m_segmentPublisher.m_ims.size(), 0);
373
374 producer->onHelloInterest(consumers[0]->m_helloInterestPrefix, Interest(dataName));
375 advanceClocks(ndn::time::milliseconds(10));
376 BOOST_CHECK_EQUAL(producer->m_segmentPublisher.m_ims.size(), 2);
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400377 BOOST_REQUIRE(!face.sentData.empty());
378 BOOST_CHECK_EQUAL(face.sentData.front().getName().at(-1).toSegment(), 1);
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500379}
380
381BOOST_AUTO_TEST_CASE(SegmentedSync)
382{
Davide Pesaventof91d1df2020-11-25 14:50:41 -0500383 Name longNameToExceedDataSize;
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500384 for (int i = 0; i < 100; i++) {
385 longNameToExceedDataSize.append("test-" + std::to_string(i));
386 }
387 addUserNodes(longNameToExceedDataSize.toUri(), 10);
388
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400389 std::vector<std::string> subscribeTo;
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500390 for (int i = 1; i < 10; i++) {
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400391 subscribeTo.push_back(longNameToExceedDataSize.toUri() + "-" + std::to_string(i));
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500392 }
393 addConsumer(0, subscribeTo);
394
395 consumers[0]->sendHelloInterest();
396 advanceClocks(ndn::time::milliseconds(10));
397 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
398
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600399 // To be used later to simulate sending delayed segmented interest
Davide Pesaventof91d1df2020-11-25 14:50:41 -0500400 Name syncInterestName(consumers[0]->m_syncInterestPrefix);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600401 consumers[0]->m_bloomFilter.appendToName(syncInterestName);
402 syncInterestName.append(consumers[0]->m_iblt);
403 syncInterestName.appendVersion();
404 syncInterestName.appendSegment(1);
405
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500406 oldSeqMap = producer->m_prefixes;
407 for (int i = 1; i < 10; i++) {
Davide Pesaventoc407dee2022-07-21 23:56:05 -0400408 producer->updateSeqNo(longNameToExceedDataSize.toUri() + "-" + std::to_string(i), 1);
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500409 }
410
Ashlesh Gawande8ab75722020-08-02 22:42:28 -0700411 advanceClocks(ndn::time::milliseconds(999));
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500412 BOOST_CHECK_EQUAL(numSyncDataRcvd, 0);
413
Ashlesh Gawande8ab75722020-08-02 22:42:28 -0700414 advanceClocks(ndn::time::milliseconds(1));
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500415 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
Ashlesh Gawande2e82df12018-12-08 21:42:29 -0600416
417 // Simulate sending delayed interest for second segment
418 face.sentData.clear();
419 consumerFaces[0]->sentData.clear();
420
421 BOOST_CHECK_EQUAL(producer->m_segmentPublisher.m_ims.size(), 2);
422
423 advanceClocks(ndn::time::milliseconds(2000));
424 BOOST_CHECK_EQUAL(producer->m_segmentPublisher.m_ims.size(), 0);
425
426 producer->onSyncInterest(consumers[0]->m_syncInterestPrefix, Interest(syncInterestName));
427 advanceClocks(ndn::time::milliseconds(10));
428 BOOST_CHECK_EQUAL(producer->m_segmentPublisher.m_ims.size(), 2);
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400429 BOOST_REQUIRE(!face.sentData.empty());
430 BOOST_CHECK_EQUAL(face.sentData.front().getName().at(-1).toSegment(), 1);
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500431}
432
Ashlesh Gawandecbdc0122020-07-13 21:13:00 -0700433BOOST_AUTO_TEST_CASE(DelayedSubscription) // #5122
434{
435 publishUpdateFor("testUser-2");
436 std::vector<std::string> subscribeTo{"testUser-2", "testUser-4"};
437 addConsumer(0, subscribeTo);
438
439 consumers[0]->sendHelloInterest();
440 advanceClocks(ndn::time::milliseconds(10));
441 BOOST_CHECK_EQUAL(numHelloDataRcvd, 1);
442
443 // Application came up late and subscribed to testUser-2
444 // after Producer had already published the first update.
445 // So by default Consumer will let the application know that
446 // the prefix it subscribed to has already some updates
447 BOOST_CHECK_EQUAL(numSyncDataRcvd, 1);
448}
449
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500450BOOST_AUTO_TEST_SUITE_END()
451
Ashlesh Gawande6a5157f2019-12-09 11:49:07 -0600452} // namespace psync