blob: a2bb449e30ca2e000643fcffb3d336c2edb181c1 [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
23#include <boost/test/unit_test.hpp>
24#include <ndn-cxx/name.hpp>
25#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{
74 int size = 10;
75
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -080076 IBLT iblt(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050077 std::string prefix = Name("/test/memphis").appendNumber(1).toUri();
78 uint32_t newHash = murmurHash3(11, prefix);
79 iblt.insert(newHash);
80
81 Name ibltName("sync");
82 iblt.appendToName(ibltName);
83
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -080084 IBLT rcvd(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -050085 rcvd.initialize(ibltName.get(-1));
86
87 BOOST_CHECK_EQUAL(iblt, rcvd);
88
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -080089 IBLT rcvdDiffSize(20, CompressionScheme::DEFAULT);
Ashlesh Gawande79c5baf2020-02-16 12:29:52 -080090 BOOST_CHECK_THROW(rcvdDiffSize.initialize(ibltName.get(-1)), IBLT::Error);
91
92 Name malformedName("test");
93 auto compressed = compress(CompressionScheme::DEFAULT,
94 malformedName.wireEncode().value(),
95 malformedName.wireEncode().value_size());
96 IBLT rcvdDiffSize1(size, CompressionScheme::DEFAULT);
97 malformedName.append(compressed->data(), compressed->size());
98 BOOST_CHECK_THROW(rcvdDiffSize1.initialize(malformedName.get(-1)), IBLT::Error);
99
100 IBLT iblt2(size, CompressionScheme::NONE);
101 iblt2.insert(newHash);
102 Name ibltName2("sync");
103 iblt2.appendToName(ibltName2);
104
105 BOOST_CHECK_EQUAL_COLLECTIONS(IBF, IBF + sizeof(IBF),
106 ibltName2.get(-1).wireEncode().begin(),
107 ibltName2.get(-1).wireEncode().end());
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500108}
109
110BOOST_AUTO_TEST_CASE(CopyInsertErase)
111{
112 int size = 10;
113
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800114 IBLT iblt1(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500115
116 std::string prefix = Name("/test/memphis").appendNumber(1).toUri();
117 uint32_t hash1 = murmurHash3(11, prefix);
118 iblt1.insert(hash1);
119
120 IBLT iblt2(iblt1);
121 iblt2.erase(hash1);
122 prefix = Name("/test/memphis").appendNumber(2).toUri();
123 uint32_t hash3 = murmurHash3(11, prefix);
124 iblt2.insert(hash3);
125
126 iblt1.erase(hash1);
127 prefix = Name("/test/memphis").appendNumber(5).toUri();
128 uint32_t hash5 = murmurHash3(11, prefix);
129 iblt1.insert(hash5);
130
131 iblt2.erase(hash3);
132 iblt2.insert(hash5);
133
134 BOOST_CHECK_EQUAL(iblt1, iblt2);
135}
136
137BOOST_AUTO_TEST_CASE(HigherSeqTest)
138{
139 // The case where we can't recognize if the rcvd IBF has higher sequence number
140 // Relevant to full sync case
141 int size = 10;
142
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800143 IBLT ownIBF(size, CompressionScheme::DEFAULT);
144 IBLT rcvdIBF(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500145
146 std::string prefix = Name("/test/memphis").appendNumber(3).toUri();
147 uint32_t hash1 = murmurHash3(11, prefix);
148 ownIBF.insert(hash1);
149
150 std::string prefix2 = Name("/test/memphis").appendNumber(4).toUri();
151 uint32_t hash2 = murmurHash3(11, prefix2);
152 rcvdIBF.insert(hash2);
153
154 IBLT diff = ownIBF - rcvdIBF;
155 std::set<uint32_t> positive;
156 std::set<uint32_t> negative;
157
158 BOOST_CHECK(diff.listEntries(positive, negative));
159 BOOST_CHECK(*positive.begin() == hash1);
160 BOOST_CHECK(*negative.begin() == hash2);
161}
162
163BOOST_AUTO_TEST_CASE(Difference)
164{
165 int size = 10;
166
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800167 IBLT ownIBF(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500168
169 IBLT rcvdIBF = ownIBF;
170
171 IBLT diff = ownIBF - rcvdIBF;
172
173 std::set<uint32_t> positive; // non-empty Positive means we have some elements that the others don't
174 std::set<uint32_t> negative;
175
176 BOOST_CHECK(diff.listEntries(positive, negative));
177 BOOST_CHECK_EQUAL(positive.size(), 0);
178 BOOST_CHECK_EQUAL(negative.size(), 0);
179
180 std::string prefix = Name("/test/memphis").appendNumber(1).toUri();
181 uint32_t newHash = murmurHash3(11, prefix);
182 ownIBF.insert(newHash);
183
184 diff = ownIBF - rcvdIBF;
185 BOOST_CHECK(diff.listEntries(positive, negative));
186 BOOST_CHECK_EQUAL(positive.size(), 1);
187 BOOST_CHECK_EQUAL(negative.size(), 0);
188
189 prefix = Name("/test/csu").appendNumber(1).toUri();
190 newHash = murmurHash3(11, prefix);
191 rcvdIBF.insert(newHash);
192
193 diff = ownIBF - rcvdIBF;
194 BOOST_CHECK(diff.listEntries(positive, negative));
195 BOOST_CHECK_EQUAL(positive.size(), 1);
196 BOOST_CHECK_EQUAL(negative.size(), 1);
197}
198
199BOOST_AUTO_TEST_CASE(DifferenceBwOversizedIBFs)
200{
201 // Insert 50 elements into IBF of size 10
202 // Check that we can still list the difference
203 // even though we can't list the IBFs itself
204
205 int size = 10;
206
Ashlesh Gawandee23b53b2020-02-16 13:47:38 -0800207 IBLT ownIBF(size, CompressionScheme::DEFAULT);
Ashlesh Gawande0b2897e2018-06-20 14:40:47 -0500208
209 for (int i = 0; i < 50; i++) {
210 std::string prefix = Name("/test/memphis" + std::to_string(i)).appendNumber(1).toUri();
211 uint32_t newHash = murmurHash3(11, prefix);
212 ownIBF.insert(newHash);
213 }
214
215 IBLT rcvdIBF = ownIBF;
216
217 std::string prefix = Name("/test/ucla").appendNumber(1).toUri();
218 uint32_t newHash = murmurHash3(11, prefix);
219 ownIBF.insert(newHash);
220
221 IBLT diff = ownIBF - rcvdIBF;
222
223 std::set<uint32_t> positive;
224 std::set<uint32_t> negative;
225 BOOST_CHECK(diff.listEntries(positive, negative));
226 BOOST_CHECK_EQUAL(positive.size(), 1);
227 BOOST_CHECK_EQUAL(*positive.begin(), newHash);
228 BOOST_CHECK_EQUAL(negative.size(), 0);
229
230 BOOST_CHECK(!ownIBF.listEntries(positive, negative));
231 BOOST_CHECK(!rcvdIBF.listEntries(positive, negative));
232}
233
234BOOST_AUTO_TEST_SUITE_END()
235
236} // namespace psync