blob: e5ce12faa9579d7d4fed648489065ab451d98e24 [file] [log] [blame]
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Junxiao Shi32ccfc42022-01-09 21:26:22 +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/detail/iblt.hpp"
21#include "PSync/detail/util.hpp"
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050022
Davide Pesavento5b3cf762020-04-03 16:20:04 -040023#include "tests/boost-test.hpp"
24
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050025namespace psync {
Davide Pesaventodb789562020-12-19 23:01:08 -050026namespace detail {
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050027
28using namespace ndn;
29
30BOOST_AUTO_TEST_SUITE(TestIBLT)
31
32BOOST_AUTO_TEST_CASE(Equal)
33{
Davide Pesaventodb789562020-12-19 23:01:08 -050034 const size_t size = 10;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050035
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -080036 IBLT iblt1(size, CompressionScheme::DEFAULT);
37 IBLT iblt2(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050038 BOOST_CHECK_EQUAL(iblt1, iblt2);
39
Junxiao Shi32ccfc42022-01-09 21:26:22 +000040 auto prefix = Name("/test/memphis").appendNumber(1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050041 uint32_t newHash = murmurHash3(11, prefix);
42 iblt1.insert(newHash);
43 iblt2.insert(newHash);
44
45 BOOST_CHECK_EQUAL(iblt1, iblt2);
46
47 Name ibfName1("sync"), ibfName2("sync");
48 iblt1.appendToName(ibfName1);
49 iblt2.appendToName(ibfName2);
50 BOOST_CHECK_EQUAL(ibfName1, ibfName2);
51}
52
Ashlesh Gawande79c5baf2020-02-16 12:29:52 -080053static const uint8_t IBF[] = {
54 // Header
55 0x08, 0xB4,
56 // Uncompressed IBF
Junxiao Shi32ccfc42022-01-09 21:26:22 +000057 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5C, 0x5B, 0xF2, 0x67,
59 0x42, 0x24, 0xEE, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x5C, 0x5B, 0xF2, 0x67,
62 0x42, 0x24, 0xEE, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Ashlesh Gawande79c5baf2020-02-16 12:29:52 -080063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Junxiao Shi32ccfc42022-01-09 21:26:22 +000066 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
67 0x5C, 0x5B, 0xF2, 0x67, 0x42, 0x24, 0xEE, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Ashlesh Gawande79c5baf2020-02-16 12:29:52 -080068 0x00, 0x00, 0x00, 0x00
69};
70
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050071BOOST_AUTO_TEST_CASE(NameAppendAndExtract)
72{
Davide Pesavento5b3cf762020-04-03 16:20:04 -040073 const int size = 10;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050074
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -080075 IBLT iblt(size, CompressionScheme::DEFAULT);
Junxiao Shi32ccfc42022-01-09 21:26:22 +000076 auto prefix = Name("/test/memphis").appendNumber(1);
Davide Pesavento5b3cf762020-04-03 16:20:04 -040077 auto hash = murmurHash3(11, prefix);
78 iblt.insert(hash);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050079
Davide Pesavento5b3cf762020-04-03 16:20:04 -040080 Name ibltName("/sync");
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050081 iblt.appendToName(ibltName);
82
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -080083 IBLT rcvd(size, CompressionScheme::DEFAULT);
Davide Pesavento5b3cf762020-04-03 16:20:04 -040084 rcvd.initialize(ibltName.at(-1));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050085 BOOST_CHECK_EQUAL(iblt, rcvd);
86
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -080087 IBLT rcvdDiffSize(20, CompressionScheme::DEFAULT);
Davide Pesavento5b3cf762020-04-03 16:20:04 -040088 BOOST_CHECK_THROW(rcvdDiffSize.initialize(ibltName.at(-1)), IBLT::Error);
Ashlesh Gawande79c5baf2020-02-16 12:29:52 -080089
Davide Pesavento5b3cf762020-04-03 16:20:04 -040090 IBLT iblt2(size, CompressionScheme::NONE);
91 iblt2.insert(hash);
92 Name ibltName2("/sync");
93 iblt2.appendToName(ibltName2);
Davide Pesaventoc407dee2022-07-21 23:56:05 -040094 BOOST_TEST(ibltName2.at(-1).wireEncode() == IBF, boost::test_tools::per_element());
Davide Pesavento5b3cf762020-04-03 16:20:04 -040095
96 Name malformedName("/test");
Ashlesh Gawande79c5baf2020-02-16 12:29:52 -080097 auto compressed = compress(CompressionScheme::DEFAULT,
Davide Pesaventof6fd2fb2022-03-18 21:00:36 -040098 malformedName.wireEncode().value_bytes());
99 malformedName.append(name::Component(std::move(compressed)));
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400100 IBLT rcvd2(size, CompressionScheme::DEFAULT);
101 BOOST_CHECK_THROW(rcvd2.initialize(malformedName.at(-1)), IBLT::Error);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500102}
103
104BOOST_AUTO_TEST_CASE(CopyInsertErase)
105{
Davide Pesaventodb789562020-12-19 23:01:08 -0500106 const size_t size = 10;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500107
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800108 IBLT iblt1(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500109
Junxiao Shi32ccfc42022-01-09 21:26:22 +0000110 auto prefix = Name("/test/memphis").appendNumber(1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500111 uint32_t hash1 = murmurHash3(11, prefix);
112 iblt1.insert(hash1);
113
114 IBLT iblt2(iblt1);
115 iblt2.erase(hash1);
Junxiao Shi32ccfc42022-01-09 21:26:22 +0000116 prefix = Name("/test/memphis").appendNumber(2);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500117 uint32_t hash3 = murmurHash3(11, prefix);
118 iblt2.insert(hash3);
119
120 iblt1.erase(hash1);
Junxiao Shi32ccfc42022-01-09 21:26:22 +0000121 prefix = Name("/test/memphis").appendNumber(5);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500122 uint32_t hash5 = murmurHash3(11, prefix);
123 iblt1.insert(hash5);
124
125 iblt2.erase(hash3);
126 iblt2.insert(hash5);
127
128 BOOST_CHECK_EQUAL(iblt1, iblt2);
129}
130
131BOOST_AUTO_TEST_CASE(HigherSeqTest)
132{
133 // The case where we can't recognize if the rcvd IBF has higher sequence number
134 // Relevant to full sync case
Davide Pesaventodb789562020-12-19 23:01:08 -0500135
136 const size_t size = 10;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500137
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800138 IBLT ownIBF(size, CompressionScheme::DEFAULT);
139 IBLT rcvdIBF(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500140
Junxiao Shi32ccfc42022-01-09 21:26:22 +0000141 auto prefix = Name("/test/memphis").appendNumber(3);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500142 uint32_t hash1 = murmurHash3(11, prefix);
143 ownIBF.insert(hash1);
144
Junxiao Shi32ccfc42022-01-09 21:26:22 +0000145 auto prefix2 = Name("/test/memphis").appendNumber(4);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500146 uint32_t hash2 = murmurHash3(11, prefix2);
147 rcvdIBF.insert(hash2);
148
149 IBLT diff = ownIBF - rcvdIBF;
150 std::set<uint32_t> positive;
151 std::set<uint32_t> negative;
152
153 BOOST_CHECK(diff.listEntries(positive, negative));
154 BOOST_CHECK(*positive.begin() == hash1);
155 BOOST_CHECK(*negative.begin() == hash2);
156}
157
158BOOST_AUTO_TEST_CASE(Difference)
159{
Davide Pesaventodb789562020-12-19 23:01:08 -0500160 const size_t size = 10;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500161
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800162 IBLT ownIBF(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500163 IBLT rcvdIBF = ownIBF;
164
165 IBLT diff = ownIBF - rcvdIBF;
166
167 std::set<uint32_t> positive; // non-empty Positive means we have some elements that the others don't
168 std::set<uint32_t> negative;
169
170 BOOST_CHECK(diff.listEntries(positive, negative));
171 BOOST_CHECK_EQUAL(positive.size(), 0);
172 BOOST_CHECK_EQUAL(negative.size(), 0);
173
Junxiao Shi32ccfc42022-01-09 21:26:22 +0000174 auto prefix = Name("/test/memphis").appendNumber(1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500175 uint32_t newHash = murmurHash3(11, prefix);
176 ownIBF.insert(newHash);
177
178 diff = ownIBF - rcvdIBF;
179 BOOST_CHECK(diff.listEntries(positive, negative));
180 BOOST_CHECK_EQUAL(positive.size(), 1);
181 BOOST_CHECK_EQUAL(negative.size(), 0);
182
Junxiao Shi32ccfc42022-01-09 21:26:22 +0000183 prefix = Name("/test/csu").appendNumber(1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500184 newHash = murmurHash3(11, prefix);
185 rcvdIBF.insert(newHash);
186
187 diff = ownIBF - rcvdIBF;
188 BOOST_CHECK(diff.listEntries(positive, negative));
189 BOOST_CHECK_EQUAL(positive.size(), 1);
190 BOOST_CHECK_EQUAL(negative.size(), 1);
191}
192
193BOOST_AUTO_TEST_CASE(DifferenceBwOversizedIBFs)
194{
195 // Insert 50 elements into IBF of size 10
196 // Check that we can still list the difference
197 // even though we can't list the IBFs itself
198
Davide Pesaventodb789562020-12-19 23:01:08 -0500199 const size_t size = 10;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500200
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800201 IBLT ownIBF(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500202
203 for (int i = 0; i < 50; i++) {
Junxiao Shi32ccfc42022-01-09 21:26:22 +0000204 auto prefix = Name("/test/memphis" + std::to_string(i)).appendNumber(1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500205 uint32_t newHash = murmurHash3(11, prefix);
206 ownIBF.insert(newHash);
207 }
208
209 IBLT rcvdIBF = ownIBF;
210
Junxiao Shi32ccfc42022-01-09 21:26:22 +0000211 auto prefix = Name("/test/ucla").appendNumber(1);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500212 uint32_t newHash = murmurHash3(11, prefix);
213 ownIBF.insert(newHash);
214
215 IBLT diff = ownIBF - rcvdIBF;
216
217 std::set<uint32_t> positive;
218 std::set<uint32_t> negative;
219 BOOST_CHECK(diff.listEntries(positive, negative));
220 BOOST_CHECK_EQUAL(positive.size(), 1);
221 BOOST_CHECK_EQUAL(*positive.begin(), newHash);
222 BOOST_CHECK_EQUAL(negative.size(), 0);
223
224 BOOST_CHECK(!ownIBF.listEntries(positive, negative));
225 BOOST_CHECK(!rcvdIBF.listEntries(positive, negative));
226}
227
228BOOST_AUTO_TEST_SUITE_END()
229
Davide Pesaventodb789562020-12-19 23:01:08 -0500230} // namespace detail
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400231} // namespace psync