full-sync: cleanup test cases
refs #4659
Change-Id: I5043c1ed7698b7cdf6fc3774f5bfa4b0c05ea204
diff --git a/PSync/full-producer.cpp b/PSync/full-producer.cpp
index 106dc90..ca2ee5a 100644
--- a/PSync/full-producer.cpp
+++ b/PSync/full-producer.cpp
@@ -196,8 +196,15 @@
sendSyncData(interest.getName(), state.wireEncode());
}
+#ifdef PSYNC_WITH_TESTS
+ ++nIbfDecodeFailuresAboveThreshold;
+#endif // PSYNC_WITH_TESTS
return;
}
+
+#ifdef PSYNC_WITH_TESTS
+ ++nIbfDecodeFailuresBelowThreshold;
+#endif // PSYNC_WITH_TESTS
}
detail::State state;
diff --git a/PSync/full-producer.hpp b/PSync/full-producer.hpp
index b12d439..aea5bcb 100644
--- a/PSync/full-producer.hpp
+++ b/PSync/full-producer.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2021, The University of Memphis
+ * Copyright (c) 2014-2022, The University of Memphis
*
* This file is part of PSync.
* See AUTHORS.md for complete list of PSync authors and contributors.
@@ -167,6 +167,12 @@
bool
isFutureHash(const ndn::Name& prefix, const std::set<uint32_t>& negative);
+#ifdef PSYNC_WITH_TESTS
+public:
+ size_t nIbfDecodeFailuresAboveThreshold = 0;
+ size_t nIbfDecodeFailuresBelowThreshold = 0;
+#endif // PSYNC_WITH_TESTS
+
private:
struct PendingEntryInfo
{
diff --git a/tests/test-full-sync.cpp b/tests/test-full-sync.cpp
index 8fd5100..8aa9c8e 100644
--- a/tests/test-full-sync.cpp
+++ b/tests/test-full-sync.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2020, The University of Memphis
+ * Copyright (c) 2014-2022, The University of Memphis
*
* This file is part of PSync.
* See AUTHORS.md for complete list of PSync authors and contributors.
@@ -29,29 +29,156 @@
namespace psync {
-using namespace ndn;
+using ndn::Name;
+using ndn::optional;
+using ndn::util::DummyClientFace;
-class FullSyncFixture : public tests::IoFixture
+class FullSyncFixture : public ndn::tests::IoFixture
{
protected:
void
addNode(int id)
{
- BOOST_ASSERT(id >= 0 && id <= 3);
+ BOOST_ASSERT(id >= 0 && id < MAX_NODES);
+ faces[id] = std::make_shared<DummyClientFace>(m_io, DummyClientFace::Options{true, true});
+ userPrefixes[id] = "/userPrefix" + std::to_string(id);
+ nodes[id] = std::make_shared<FullProducer>(40, *faces[id], syncPrefix, userPrefixes[id],
+ [] (const auto&) {});
+ }
- faces[id] = std::make_shared<util::DummyClientFace>(m_io, util::DummyClientFace::Options{true, true});
- userPrefixes[id] = Name("userPrefix" + to_string(id));
- nodes[id] = make_shared<FullProducer>(40, *faces[id], syncPrefix, userPrefixes[id],
- [] (const auto&) {});
+ void
+ clearNodes()
+ {
+ faces.fill(nullptr);
+ userPrefixes.fill(Name());
+ nodes.fill(nullptr);
+ }
+
+ /**
+ * @brief Return a user prefix in the form /userNode<id>-<i>.
+ * @param id update originator node index.
+ * @param i user prefix index.
+ */
+ Name
+ makeSubPrefix(int id, int i) const
+ {
+ return "/userNode" + std::to_string(id) + "-" + std::to_string(i);
+ }
+
+ /**
+ * @brief Publish a batch of updates.
+ * @param id node index.
+ * @param min minimum user prefix index.
+ * @param min maximum user prefix index.
+ * @param seq update sequence number.
+ * @post nodes[id] has user nodes /userNode<id>-<i> ∀i∈[min,max] , with sequence number
+ * set to @p seq ; only one sync Data may be sent after the last update.
+ */
+ void
+ batchUpdate(int id, int min, int max, uint64_t seq)
+ {
+ FullProducer& node = *nodes.at(id);
+ for (int i = min; i <= max; i++) {
+ auto userPrefix = makeSubPrefix(id, i);
+ node.addUserNode(userPrefix);
+ if (i < max) {
+ node.updateSeqNo(userPrefix, seq);
+ }
+ else {
+ node.publishName(userPrefix, seq);
+ }
+ }
+ }
+
+ /**
+ * @brief Check sequence number on a batch of user prefixes.
+ * @param id node index where the check is performed.
+ * @param origin update originator node index for deriving user prefixes.
+ * @param min minimum user prefix index.
+ * @param max maximum user prefix index.
+ * @param seq expected sequence number.
+ */
+ void
+ batchCheck(int id, int origin, int min, int max, optional<uint64_t> seq)
+ {
+ uint64_t expected = seq.value_or(NOT_EXIST);
+ FullProducer& node = *nodes.at(id);
+ for (int i = min; i <= max; i++) {
+ auto userPrefix = makeSubPrefix(origin, i);
+ BOOST_TEST_CONTEXT("node=" << id << " userPrefix=" << userPrefix) {
+ BOOST_CHECK_EQUAL(node.getSeqNo(userPrefix).value_or(NOT_EXIST), expected);
+ }
+ }
+ }
+
+ struct IbfDecodeFailureCounts
+ {
+ size_t aboveThreshold = 0;
+ size_t belowThreshold = 0;
+ };
+
+ /**
+ * @brief Return the sum of IBF decode failure counters among created nodes.
+ */
+ IbfDecodeFailureCounts
+ countIbfDecodeFailures() const
+ {
+ IbfDecodeFailureCounts result;
+ for (const auto& node : nodes) {
+ if (node == nullptr) {
+ continue;
+ }
+ result.aboveThreshold += node->nIbfDecodeFailuresAboveThreshold;
+ result.belowThreshold += node->nIbfDecodeFailuresBelowThreshold;
+ }
+ return result;
+ }
+
+ /**
+ * @brief Repeat a test function until there are IBF decode failures.
+ * @param minTotalUpdates minimum totalUpdates parameter.
+ * @param maxTotalUpdates maximum totalUpdates parameter.
+ * @param f test function.
+ *
+ * This method searches for totalUpdates∈[minTotalUpdates,maxTotalUpdates] until there is
+ * at least one execution that caused an IBF decode failure above threshold.
+ * If such an execution is never achieved within the range, fail the test case.
+ *
+ * Current FullSync logic cannot reliably recover from an IBF decode failure below threshold.
+ * Hence, that condition is not tested.
+ */
+ void
+ searchIbfDecodeFailures(int minTotalUpdates, int maxTotalUpdates, std::function<void(int totalUpdates)> f)
+ {
+ bool hasAboveThreshold = false;
+ for (int totalUpdates = minTotalUpdates; totalUpdates <= maxTotalUpdates; ++totalUpdates) {
+ clearNodes();
+ BOOST_TEST_CONTEXT("totalUpdates=" << totalUpdates) {
+ f(totalUpdates);
+
+ auto cnt = countIbfDecodeFailures();
+ BOOST_TEST_MESSAGE("aboveThreshold=" << cnt.aboveThreshold << " "
+ "belowThreshold=" << cnt.belowThreshold);
+ hasAboveThreshold = hasAboveThreshold || cnt.aboveThreshold > 0;
+ if (hasAboveThreshold) {
+ return;
+ }
+ }
+ }
+ BOOST_TEST_FAIL("cannot find viable totalUpdates for IBF decode failures");
}
protected:
const Name syncPrefix = "/psync";
- shared_ptr<util::DummyClientFace> faces[4];
- Name userPrefixes[4];
- shared_ptr<FullProducer> nodes[4];
+ static const int MAX_NODES = 4;
+ std::array<std::shared_ptr<DummyClientFace>, MAX_NODES> faces;
+ std::array<Name, MAX_NODES> userPrefixes;
+ std::array<std::shared_ptr<FullProducer>, MAX_NODES> nodes;
+ static const uint64_t NOT_EXIST = std::numeric_limits<uint64_t>::max();
};
+const uint64_t FullSyncFixture::NOT_EXIST;
+
BOOST_FIXTURE_TEST_SUITE(TestFullSync, FullSyncFixture)
BOOST_AUTO_TEST_CASE(TwoNodesSimple)
@@ -60,23 +187,23 @@
addNode(1);
faces[0]->linkTo(*faces[1]);
- advanceClocks(ndn::time::milliseconds(10));
+ advanceClocks(10_ms);
nodes[0]->publishName(userPrefixes[0]);
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(-1), 1);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(-1), 1);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
nodes[1]->publishName(userPrefixes[1]);
- advanceClocks(ndn::time::milliseconds(10), 100);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(-1), 1);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[1]).value_or(-1), 1);
+ advanceClocks(10_ms, 100);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
nodes[1]->publishName(userPrefixes[1]);
- advanceClocks(ndn::time::milliseconds(10), 100);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(-1), 2);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[1]).value_or(-1), 2);
+ advanceClocks(10_ms, 100);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
}
BOOST_AUTO_TEST_CASE(TwoNodesForceSeqNo)
@@ -85,13 +212,13 @@
addNode(1);
faces[0]->linkTo(*faces[1]);
- advanceClocks(ndn::time::milliseconds(10));
+ advanceClocks(10_ms);
nodes[0]->publishName(userPrefixes[0], 3);
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(-1), 3);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(-1), 3);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 3);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 3);
}
BOOST_AUTO_TEST_CASE(TwoNodesWithMultipleUserNodes)
@@ -100,31 +227,31 @@
addNode(1);
faces[0]->linkTo(*faces[1]);
- advanceClocks(ndn::time::milliseconds(10));
+ advanceClocks(10_ms);
- Name nodeZeroExtraUser("userPrefix0-1");
- Name nodeOneExtraUser("userPrefix1-1");
+ Name nodeZeroExtraUser("/userPrefix0-1");
+ Name nodeOneExtraUser("/userPrefix1-1");
nodes[0]->addUserNode(nodeZeroExtraUser);
nodes[1]->addUserNode(nodeOneExtraUser);
nodes[0]->publishName(userPrefixes[0]);
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(-1), 1);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(-1), 1);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
nodes[0]->publishName(nodeZeroExtraUser);
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(nodeZeroExtraUser).value_or(-1), 1);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(nodeZeroExtraUser).value_or(-1), 1);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(nodeZeroExtraUser).value_or(NOT_EXIST), 1);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(nodeZeroExtraUser).value_or(NOT_EXIST), 1);
nodes[1]->publishName(nodeOneExtraUser);
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(nodeOneExtraUser).value_or(-1), 1);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(nodeOneExtraUser).value_or(-1), 1);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(nodeOneExtraUser).value_or(NOT_EXIST), 1);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(nodeOneExtraUser).value_or(NOT_EXIST), 1);
}
BOOST_AUTO_TEST_CASE(MultipleNodes)
@@ -137,21 +264,21 @@
}
nodes[0]->publishName(userPrefixes[0]);
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
for (int i = 0; i < 4; i++) {
- BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[0]).value_or(-1), 1);
+ BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
}
nodes[1]->publishName(userPrefixes[1]);
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
for (int i = 0; i < 4; i++) {
- BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[1]).value_or(-1), 1);
+ BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
}
nodes[1]->publishName(userPrefixes[1]);
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
for (int i = 0; i < 4; i++) {
- BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[1]).value_or(-1), 2);
+ BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
}
}
@@ -167,10 +294,10 @@
nodes[i]->publishName(userPrefixes[i]);
}
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(-1), 1);
+ BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(NOT_EXIST), 1);
}
}
@@ -178,10 +305,10 @@
nodes[i]->publishName(userPrefixes[i], 4);
}
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(-1), 4);
+ BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(NOT_EXIST), 4);
}
}
}
@@ -196,9 +323,9 @@
}
nodes[0]->publishName(userPrefixes[0]);
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
for (int i = 0; i < 4; i++) {
- BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[0]).value_or(-1), 1);
+ BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
}
for (int i = 0; i < 3; i++) {
@@ -208,25 +335,25 @@
faces[2]->linkTo(*faces[3]);
nodes[0]->publishName(userPrefixes[0]);
- advanceClocks(ndn::time::milliseconds(10), 100);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(-1), 2);
- BOOST_CHECK_EQUAL(nodes[2]->getSeqNo(userPrefixes[0]).value_or(-1), 1);
- BOOST_CHECK_EQUAL(nodes[3]->getSeqNo(userPrefixes[0]).value_or(-1), 1);
+ advanceClocks(10_ms, 100);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 2);
+ BOOST_CHECK_EQUAL(nodes[2]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
+ BOOST_CHECK_EQUAL(nodes[3]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
nodes[1]->publishName(userPrefixes[1], 2);
- advanceClocks(ndn::time::milliseconds(10), 100);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(-1), 2);
+ advanceClocks(10_ms, 100);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 2);
nodes[2]->publishName(userPrefixes[2], 2);
- advanceClocks(ndn::time::milliseconds(10), 100);
- BOOST_CHECK_EQUAL(nodes[3]->getSeqNo(userPrefixes[2]).value_or(-1), 2);
+ advanceClocks(10_ms, 100);
+ BOOST_CHECK_EQUAL(nodes[3]->getSeqNo(userPrefixes[2]).value_or(NOT_EXIST), 2);
nodes[3]->publishName(userPrefixes[3], 2);
- advanceClocks(ndn::time::milliseconds(10), 100);
- BOOST_CHECK_EQUAL(nodes[2]->getSeqNo(userPrefixes[3]).value_or(-1), 2);
+ advanceClocks(10_ms, 100);
+ BOOST_CHECK_EQUAL(nodes[2]->getSeqNo(userPrefixes[3]).value_or(NOT_EXIST), 2);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[3]).value_or(-1), -1);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[3]).value_or(-1), -1);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[3]).value_or(NOT_EXIST), NOT_EXIST);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[3]).value_or(NOT_EXIST), NOT_EXIST);
for (int i = 0; i < 3; i++) {
faces[i]->unlink();
@@ -235,10 +362,10 @@
faces[i]->linkTo(*faces[i + 1]);
}
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
- BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(-1), 2);
+ BOOST_CHECK_EQUAL(nodes[i]->getSeqNo(userPrefixes[j]).value_or(NOT_EXIST), 2);
}
}
}
@@ -249,140 +376,89 @@
addNode(1);
faces[0]->linkTo(*faces[1]);
- advanceClocks(ndn::time::milliseconds(10));
+ advanceClocks(10_ms);
// 50 > 40 (expected number of entries in IBF)
for (int i = 0; i < 50; i++) {
- nodes[0]->addUserNode(Name("userNode0-" + to_string(i)));
+ nodes[0]->addUserNode(makeSubPrefix(0, i));
}
+ batchUpdate(0, 0, 20, 1);
+ advanceClocks(10_ms, 100);
+ batchCheck(1, 0, 0, 20, 1);
- for (int i = 0; i < 20; i++) {
- // Suppose all sync data were lost for these:
- nodes[0]->updateSeqNo(Name("userNode0-" + to_string(i)), 1);
- }
- nodes[0]->publishName(Name("userNode0-" + to_string(20)));
- advanceClocks(ndn::time::milliseconds(10), 100);
-
- for (int i = 0; i <= 20; i++) {
- Name userPrefix("userNode0-" + to_string(i));
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefix).value_or(-1), 1);
- }
-
- for (int i = 21; i < 49; i++) {
- nodes[0]->updateSeqNo(Name("userNode0-" + to_string(i)), 1);
- }
- nodes[0]->publishName(Name("userNode0-49"));
- advanceClocks(ndn::time::milliseconds(10), 100);
-
- for (int i = 21; i < 49; i++) {
- Name userPrefix("userNode0-" + to_string(i));
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefix).value_or(-1), 1);
- }
+ batchUpdate(0, 21, 49, 1);
+ advanceClocks(10_ms, 100);
+ batchCheck(1, 0, 21, 49, 1);
}
BOOST_AUTO_TEST_CASE(DiffIBFDecodeFailureSimple)
{
- addNode(0);
- addNode(1);
+ searchIbfDecodeFailures(46, 52, [this] (int totalUpdates) {
+ addNode(0);
+ addNode(1);
- faces[0]->linkTo(*faces[1]);
- advanceClocks(ndn::time::milliseconds(10));
+ faces[0]->linkTo(*faces[1]);
+ advanceClocks(10_ms);
- // Lowest number that triggers a decode failure for IBF size of 40
- int totalUpdates = 47;
+ batchUpdate(0, 0, totalUpdates, 1);
+ advanceClocks(10_ms, 100);
+ batchCheck(1, 0, 0, totalUpdates, 1);
- for (int i = 0; i <= totalUpdates; i++) {
- nodes[0]->addUserNode(Name("userNode0-" + to_string(i)));
- if (i != totalUpdates) {
- nodes[0]->updateSeqNo(Name("userNode0-" + to_string(i)), 1);
- }
- }
- nodes[0]->publishName(Name("userNode0-" + to_string(totalUpdates)));
- advanceClocks(ndn::time::milliseconds(10), 100);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), NOT_EXIST);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), NOT_EXIST);
- // No mechanism to recover yet
- for (int i = 0; i <= totalUpdates; i++) {
- Name userPrefix("userNode0-" + to_string(i));
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefix).value_or(-1), 1);
- }
+ nodes[1]->publishName(userPrefixes[1]);
+ advanceClocks(10_ms, 100);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(-1), -1);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(-1), -1);
-
- nodes[1]->publishName(userPrefixes[1]);
- advanceClocks(ndn::time::milliseconds(10), 100);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(-1), 1);
-
- nodes[0]->publishName(userPrefixes[0]);
- advanceClocks(ndn::time::milliseconds(10), 100);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(-1), 1);
+ nodes[0]->publishName(userPrefixes[0]);
+ advanceClocks(10_ms, 100);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
+ });
}
BOOST_AUTO_TEST_CASE(DiffIBFDecodeFailureSimpleSegmentedRecovery)
{
- addNode(0);
- addNode(1);
- faces[0]->linkTo(*faces[1]);
+ searchIbfDecodeFailures(46, 52, [this] (int totalUpdates) {
+ addNode(0);
+ addNode(1);
+ faces[0]->linkTo(*faces[1]);
- advanceClocks(ndn::time::milliseconds(10));
+ advanceClocks(10_ms);
- // Lowest number that triggers a decode failure for IBF size of 40
- int totalUpdates = 270;
+ batchUpdate(0, 0, totalUpdates, 1);
+ advanceClocks(10_ms, 100);
+ batchCheck(1, 0, 0, totalUpdates, 1);
- for (int i = 0; i <= totalUpdates; i++) {
- nodes[0]->addUserNode(Name("userNode0-" + to_string(i)));
- if (i != totalUpdates) {
- nodes[0]->updateSeqNo(Name("userNode0-" + to_string(i)), 1);
- }
- }
- nodes[0]->publishName(Name("userNode0-" + to_string(totalUpdates)));
- advanceClocks(ndn::time::milliseconds(10), 100);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), NOT_EXIST);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), NOT_EXIST);
- // No mechanism to recover yet
- for (int i = 0; i <= totalUpdates; i++) {
- Name userPrefix("userNode0-" + to_string(i));
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefix).value_or(-1), 1);
- }
+ nodes[1]->publishName(userPrefixes[1]);
+ advanceClocks(10_ms, 100);
+ BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(NOT_EXIST), 1);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(-1), -1);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(-1), -1);
-
- nodes[1]->publishName(userPrefixes[1]);
- advanceClocks(ndn::time::milliseconds(10), 100);
- BOOST_CHECK_EQUAL(nodes[0]->getSeqNo(userPrefixes[1]).value_or(-1), 1);
-
- nodes[0]->publishName(userPrefixes[0]);
- advanceClocks(ndn::time::milliseconds(10), 100);
- BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(-1), 1);
+ nodes[0]->publishName(userPrefixes[0]);
+ advanceClocks(10_ms, 100);
+ BOOST_CHECK_EQUAL(nodes[1]->getSeqNo(userPrefixes[0]).value_or(NOT_EXIST), 1);
+ });
}
BOOST_AUTO_TEST_CASE(DiffIBFDecodeFailureMultipleNodes)
{
- for (int i = 0; i < 4; i++) {
- addNode(i);
- }
- for (int i = 0; i < 3; i++) {
- faces[i]->linkTo(*faces[i + 1]);
- }
-
- // Lowest number that triggers a decode failure for IBF size of 40
- int totalUpdates = 47;
-
- for (int i = 0; i <= totalUpdates; i++) {
- nodes[0]->addUserNode(Name("userNode0-" + to_string(i)));
- if (i != totalUpdates) {
- nodes[0]->updateSeqNo(Name("userNode0-" + to_string(i)), 1);
+ searchIbfDecodeFailures(46, 52, [this] (int totalUpdates) {
+ for (int i = 0; i < 4; i++) {
+ addNode(i);
}
- }
- nodes[0]->publishName(Name("userNode0-" + to_string(totalUpdates)));
- advanceClocks(ndn::time::milliseconds(10), 100);
-
- for (int i = 0; i <= totalUpdates; i++) {
- Name userPrefix("userNode0-" + to_string(i));
- for (int j = 0; j < 4; j++) {
- BOOST_CHECK_EQUAL(nodes[j]->getSeqNo(userPrefix).value_or(-1), 1);
+ for (int i = 0; i < 3; i++) {
+ faces[i]->linkTo(*faces[i + 1]);
}
- }
+
+ batchUpdate(0, 0, totalUpdates, 1);
+ advanceClocks(10_ms, 100);
+ for (int i = 0; i < 4; i++) {
+ batchCheck(i, 0, 0, totalUpdates, 1);
+ }
+ });
}
BOOST_AUTO_TEST_CASE(DelayedSecondSegment)
@@ -391,9 +467,9 @@
int i = 0;
detail::State state;
- std::shared_ptr<Buffer> compressed;
+ std::shared_ptr<ndn::Buffer> compressed;
do {
- Name prefixToPublish("userNode0-" + to_string(i++));
+ auto prefixToPublish = makeSubPrefix(0, i++);
nodes[0]->addUserNode(prefixToPublish);
nodes[0]->publishName(prefixToPublish);
@@ -401,21 +477,21 @@
auto block = state.wireEncode();
compressed = detail::compress(nodes[0]->m_contentCompression, block.wire(), block.size());
- } while (compressed->size() < (MAX_NDN_PACKET_SIZE >> 1));
+ } while (compressed->size() < (ndn::MAX_NDN_PACKET_SIZE >> 1));
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
Name syncInterestName(syncPrefix);
detail::IBLT iblt(40, nodes[0]->m_ibltCompression);
iblt.appendToName(syncInterestName);
- nodes[0]->onSyncInterest(syncPrefix, Interest(syncInterestName));
+ nodes[0]->onSyncInterest(syncPrefix, ndn::Interest(syncInterestName));
- advanceClocks(ndn::time::milliseconds(10));
+ advanceClocks(10_ms);
BOOST_CHECK_EQUAL(nodes[0]->m_segmentPublisher.m_ims.size(), 2);
// Expire contents from segmentPublisher
- advanceClocks(ndn::time::milliseconds(10), 100);
+ advanceClocks(10_ms, 100);
BOOST_CHECK_EQUAL(nodes[0]->m_segmentPublisher.m_ims.size(), 0);
// Get data name from face and increase segment number to form next interest
@@ -425,8 +501,8 @@
interestName.appendSegment(1);
faces[0]->sentData.clear();
- nodes[0]->onSyncInterest(syncPrefix, Interest(interestName));
- advanceClocks(ndn::time::milliseconds(10));
+ nodes[0]->onSyncInterest(syncPrefix, ndn::Interest(interestName));
+ advanceClocks(10_ms);
// Should have repopulated SegmentPublisher
BOOST_CHECK_EQUAL(nodes[0]->m_segmentPublisher.m_ims.size(), 2);