blob: c68959621ee07b273af6a808739fdff410763dd9 [file] [log] [blame]
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Ashlesh Gawande5a895472020-01-25 18:07:32 -08003 * Copyright (c) 2014-2020, 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 -050025#include <ndn-cxx/interest.hpp>
26
27namespace psync {
28
29using namespace ndn;
30
31BOOST_AUTO_TEST_SUITE(TestIBLT)
32
33BOOST_AUTO_TEST_CASE(Equal)
34{
35 int size = 10;
36
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -080037 IBLT iblt1(size, CompressionScheme::DEFAULT);
38 IBLT iblt2(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050039 BOOST_CHECK_EQUAL(iblt1, iblt2);
40
41 std::string prefix = Name("/test/memphis").appendNumber(1).toUri();
42 uint32_t newHash = murmurHash3(11, prefix);
43 iblt1.insert(newHash);
44 iblt2.insert(newHash);
45
46 BOOST_CHECK_EQUAL(iblt1, iblt2);
47
48 Name ibfName1("sync"), ibfName2("sync");
49 iblt1.appendToName(ibfName1);
50 iblt2.appendToName(ibfName2);
51 BOOST_CHECK_EQUAL(ibfName1, ibfName2);
52}
53
Ashlesh Gawande79c5baf2020-02-16 12:29:52 -080054static const uint8_t IBF[] = {
55 // Header
56 0x08, 0xB4,
57 // Uncompressed IBF
58 0x00, 0x00, 0x00, 0x01, 0xF6, 0xA7, 0x7A, 0xBA, 0x6B, 0xA3, 0x4D, 0x63, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF6, 0xA7, 0x7A, 0xBA,
63 0x6B, 0xA3, 0x4D, 0x63, 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,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x01, 0xF6, 0xA7, 0x7A, 0xBA, 0x6B, 0xA3, 0x4D, 0x63, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00
70};
71
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050072BOOST_AUTO_TEST_CASE(NameAppendAndExtract)
73{
Davide Pesavento5b3cf762020-04-03 16:20:04 -040074 const int size = 10;
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050075
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -080076 IBLT iblt(size, CompressionScheme::DEFAULT);
Davide Pesavento5b3cf762020-04-03 16:20:04 -040077 auto prefix = Name("/test/memphis").appendNumber(1).toUri();
78 auto hash = murmurHash3(11, prefix);
79 iblt.insert(hash);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050080
Davide Pesavento5b3cf762020-04-03 16:20:04 -040081 Name ibltName("/sync");
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050082 iblt.appendToName(ibltName);
83
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -080084 IBLT rcvd(size, CompressionScheme::DEFAULT);
Davide Pesavento5b3cf762020-04-03 16:20:04 -040085 rcvd.initialize(ibltName.at(-1));
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050086 BOOST_CHECK_EQUAL(iblt, rcvd);
87
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -080088 IBLT rcvdDiffSize(20, CompressionScheme::DEFAULT);
Davide Pesavento5b3cf762020-04-03 16:20:04 -040089 BOOST_CHECK_THROW(rcvdDiffSize.initialize(ibltName.at(-1)), IBLT::Error);
Ashlesh Gawande79c5baf2020-02-16 12:29:52 -080090
Davide Pesavento5b3cf762020-04-03 16:20:04 -040091 IBLT iblt2(size, CompressionScheme::NONE);
92 iblt2.insert(hash);
93 Name ibltName2("/sync");
94 iblt2.appendToName(ibltName2);
95 BOOST_CHECK_EQUAL_COLLECTIONS(IBF, IBF + sizeof(IBF),
96 ibltName2.at(-1).wireEncode().begin(),
97 ibltName2.at(-1).wireEncode().end());
98
99 Name malformedName("/test");
Ashlesh Gawande79c5baf2020-02-16 12:29:52 -0800100 auto compressed = compress(CompressionScheme::DEFAULT,
101 malformedName.wireEncode().value(),
102 malformedName.wireEncode().value_size());
Ashlesh Gawande79c5baf2020-02-16 12:29:52 -0800103 malformedName.append(compressed->data(), compressed->size());
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400104 IBLT rcvd2(size, CompressionScheme::DEFAULT);
105 BOOST_CHECK_THROW(rcvd2.initialize(malformedName.at(-1)), IBLT::Error);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500106}
107
108BOOST_AUTO_TEST_CASE(CopyInsertErase)
109{
110 int size = 10;
111
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800112 IBLT iblt1(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500113
114 std::string prefix = Name("/test/memphis").appendNumber(1).toUri();
115 uint32_t hash1 = murmurHash3(11, prefix);
116 iblt1.insert(hash1);
117
118 IBLT iblt2(iblt1);
119 iblt2.erase(hash1);
120 prefix = Name("/test/memphis").appendNumber(2).toUri();
121 uint32_t hash3 = murmurHash3(11, prefix);
122 iblt2.insert(hash3);
123
124 iblt1.erase(hash1);
125 prefix = Name("/test/memphis").appendNumber(5).toUri();
126 uint32_t hash5 = murmurHash3(11, prefix);
127 iblt1.insert(hash5);
128
129 iblt2.erase(hash3);
130 iblt2.insert(hash5);
131
132 BOOST_CHECK_EQUAL(iblt1, iblt2);
133}
134
135BOOST_AUTO_TEST_CASE(HigherSeqTest)
136{
137 // The case where we can't recognize if the rcvd IBF has higher sequence number
138 // Relevant to full sync case
139 int size = 10;
140
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800141 IBLT ownIBF(size, CompressionScheme::DEFAULT);
142 IBLT rcvdIBF(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500143
144 std::string prefix = Name("/test/memphis").appendNumber(3).toUri();
145 uint32_t hash1 = murmurHash3(11, prefix);
146 ownIBF.insert(hash1);
147
148 std::string prefix2 = Name("/test/memphis").appendNumber(4).toUri();
149 uint32_t hash2 = murmurHash3(11, prefix2);
150 rcvdIBF.insert(hash2);
151
152 IBLT diff = ownIBF - rcvdIBF;
153 std::set<uint32_t> positive;
154 std::set<uint32_t> negative;
155
156 BOOST_CHECK(diff.listEntries(positive, negative));
157 BOOST_CHECK(*positive.begin() == hash1);
158 BOOST_CHECK(*negative.begin() == hash2);
159}
160
161BOOST_AUTO_TEST_CASE(Difference)
162{
163 int size = 10;
164
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800165 IBLT ownIBF(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500166
167 IBLT rcvdIBF = ownIBF;
168
169 IBLT diff = ownIBF - rcvdIBF;
170
171 std::set<uint32_t> positive; // non-empty Positive means we have some elements that the others don't
172 std::set<uint32_t> negative;
173
174 BOOST_CHECK(diff.listEntries(positive, negative));
175 BOOST_CHECK_EQUAL(positive.size(), 0);
176 BOOST_CHECK_EQUAL(negative.size(), 0);
177
178 std::string prefix = Name("/test/memphis").appendNumber(1).toUri();
179 uint32_t newHash = murmurHash3(11, prefix);
180 ownIBF.insert(newHash);
181
182 diff = ownIBF - rcvdIBF;
183 BOOST_CHECK(diff.listEntries(positive, negative));
184 BOOST_CHECK_EQUAL(positive.size(), 1);
185 BOOST_CHECK_EQUAL(negative.size(), 0);
186
187 prefix = Name("/test/csu").appendNumber(1).toUri();
188 newHash = murmurHash3(11, prefix);
189 rcvdIBF.insert(newHash);
190
191 diff = ownIBF - rcvdIBF;
192 BOOST_CHECK(diff.listEntries(positive, negative));
193 BOOST_CHECK_EQUAL(positive.size(), 1);
194 BOOST_CHECK_EQUAL(negative.size(), 1);
195}
196
197BOOST_AUTO_TEST_CASE(DifferenceBwOversizedIBFs)
198{
199 // Insert 50 elements into IBF of size 10
200 // Check that we can still list the difference
201 // even though we can't list the IBFs itself
202
203 int size = 10;
204
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800205 IBLT ownIBF(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500206
207 for (int i = 0; i < 50; i++) {
208 std::string prefix = Name("/test/memphis" + std::to_string(i)).appendNumber(1).toUri();
209 uint32_t newHash = murmurHash3(11, prefix);
210 ownIBF.insert(newHash);
211 }
212
213 IBLT rcvdIBF = ownIBF;
214
215 std::string prefix = Name("/test/ucla").appendNumber(1).toUri();
216 uint32_t newHash = murmurHash3(11, prefix);
217 ownIBF.insert(newHash);
218
219 IBLT diff = ownIBF - rcvdIBF;
220
221 std::set<uint32_t> positive;
222 std::set<uint32_t> negative;
223 BOOST_CHECK(diff.listEntries(positive, negative));
224 BOOST_CHECK_EQUAL(positive.size(), 1);
225 BOOST_CHECK_EQUAL(*positive.begin(), newHash);
226 BOOST_CHECK_EQUAL(negative.size(), 0);
227
228 BOOST_CHECK(!ownIBF.listEntries(positive, negative));
229 BOOST_CHECK(!rcvdIBF.listEntries(positive, negative));
230}
231
232BOOST_AUTO_TEST_SUITE_END()
233
Davide Pesavento5b3cf762020-04-03 16:20:04 -0400234} // namespace psync