blob: 850f8da684429f65f7598d0ca54935df78a15890 [file] [log] [blame]
Yingdi Yud514c172014-08-26 21:49:39 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
Davide Pesaventofae9def2019-01-29 14:34:33 -05003 * Copyright (c) 2012-2019 University of California, Los Angeles
Yingdi Yud514c172014-08-26 21:49:39 -07004 *
5 * This file is part of ChronoSync, synchronization library for distributed realtime
6 * applications for NDN.
7 *
8 * ChronoSync is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation, either
10 * version 3 of the License, or (at your option) any later version.
11 *
12 * ChronoSync 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
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "state.hpp"
Ashlesh Gawande08784d42017-09-06 23:40:21 -050021
Davide Pesaventofae9def2019-01-29 14:34:33 -050022#include "tests/boost-test.hpp"
Yingdi Yud514c172014-08-26 21:49:39 -070023
24namespace chronosync {
25namespace test {
26
Yingdi Yud514c172014-08-26 21:49:39 -070027BOOST_AUTO_TEST_SUITE(StateTests)
28
29BOOST_AUTO_TEST_CASE(Basic)
30{
31 BOOST_CHECK_NO_THROW(State());
32 State state;
33 BOOST_CHECK_EQUAL(state.getLeaves().size(), 0);
34
35 Name info("/test/name");
36 info.appendNumber(0);
37
38 BOOST_CHECK_NO_THROW(state.update(info, 12));
39
40 BOOST_CHECK_NO_THROW(state.reset());
41 BOOST_CHECK_EQUAL(state.getLeaves().size(), 0);
42
Davide Pesaventofae9def2019-01-29 14:34:33 -050043 std::tuple<bool, bool, SeqNo> result;
Yingdi Yud514c172014-08-26 21:49:39 -070044 result = state.update(info, 12);
Ashlesh Gawande08784d42017-09-06 23:40:21 -050045 BOOST_CHECK_EQUAL(std::get<0>(result), true);
46 BOOST_CHECK_EQUAL(std::get<1>(result), false);
47 BOOST_CHECK_EQUAL(std::get<2>(result), 0);
Yingdi Yud514c172014-08-26 21:49:39 -070048
49 BOOST_CHECK_NO_THROW(state.update(info, 12));
50 result = state.update(info, 12);
Ashlesh Gawande08784d42017-09-06 23:40:21 -050051 BOOST_CHECK_EQUAL(std::get<0>(result), false);
52 BOOST_CHECK_EQUAL(std::get<1>(result), false);
53 BOOST_CHECK_EQUAL(std::get<2>(result), 0);
Yingdi Yud514c172014-08-26 21:49:39 -070054
55 BOOST_CHECK_NO_THROW(state.update(info, 11));
56 result = state.update(info, 11);
Ashlesh Gawande08784d42017-09-06 23:40:21 -050057 BOOST_CHECK_EQUAL(std::get<0>(result), false);
58 BOOST_CHECK_EQUAL(std::get<1>(result), false);
59 BOOST_CHECK_EQUAL(std::get<2>(result), 0);
Yingdi Yud514c172014-08-26 21:49:39 -070060
61 BOOST_CHECK_EQUAL(state.getLeaves().size(), 1);
62 BOOST_CHECK_EQUAL((*state.getLeaves().begin())->getSeq(), 12);
63
64 BOOST_CHECK_NO_THROW(state.update(info, 13));
65 BOOST_CHECK_EQUAL(state.getLeaves().size(), 1);
66 BOOST_CHECK_EQUAL((*state.getLeaves().begin())->getSeq(), 13);
67
68 result = state.update(info, 14);
Ashlesh Gawande08784d42017-09-06 23:40:21 -050069 BOOST_CHECK_EQUAL(std::get<0>(result), false);
70 BOOST_CHECK_EQUAL(std::get<1>(result), true);
71 BOOST_CHECK_EQUAL(std::get<2>(result), 13);
Yingdi Yud514c172014-08-26 21:49:39 -070072
73 BOOST_CHECK_EQUAL(state.getLeaves().size(), 1);
74 BOOST_CHECK_EQUAL((*state.getLeaves().begin())->getSeq(), 14);
75
76 Name info2("/test/name");
77 info2.appendNumber(1);
78 BOOST_CHECK_NO_THROW(state.update(info2, 3));
79 BOOST_CHECK_EQUAL(state.getLeaves().size(), 2);
80}
81
82BOOST_AUTO_TEST_CASE(StateDigest)
83{
84 State state;
85 BOOST_CHECK_EQUAL(state.getLeaves().size(), 0);
86
87 Name info1("/test/name");
88 info1.appendNumber(0);
89
90 Name info2("/test/name");
91 info2.appendNumber(1);
92
93 Name info3("/test/mane");
94 info3.appendNumber(0);
95
96 state.update(info1, 10);
97 ndn::ConstBufferPtr digest1 = state.getRootDigest();
98
99 state.update(info2, 12);
100 ndn::ConstBufferPtr digest2 = state.getRootDigest();
101
102 state.update(info3, 8);
103 ndn::ConstBufferPtr digest3 = state.getRootDigest();
104
105 BOOST_CHECK(*digest1 != *digest2);
106 BOOST_CHECK(*digest2 != *digest3);
107 BOOST_CHECK(*digest1 != *digest3);
108
109 state.reset();
110
111 state.update(info1, 10);
112 ndn::ConstBufferPtr digest4 = state.getRootDigest();
113
114 state.update(info3, 8);
115 ndn::ConstBufferPtr digest5 = state.getRootDigest();
116
117 state.update(info2, 12);
118 ndn::ConstBufferPtr digest6 = state.getRootDigest();
119
120 BOOST_CHECK(*digest4 == *digest1);
121 BOOST_CHECK(*digest5 != *digest2);
122 BOOST_CHECK(*digest6 == *digest3);
123}
124
125BOOST_AUTO_TEST_CASE(DecodeEncode)
126{
127 const uint8_t wire[] = {
128 0x80, 0x2c, // SyncReply
129 0x81, 0x14, // StateLeaf
130 0x07, 0x0f, // Name: /test/name/[0]
131 0x08, 0x04,
132 0x74, 0x65, 0x73, 0x74,
133 0x08, 0x04,
134 0x6e, 0x61, 0x6d, 0x65,
135 0x08, 0x01,
136 0x00,
137 0x82, 0x1, // SeqNo: 14
138 0x0e,
139 0x81, 0x14, // StateLeaf
140 0x07, 0x0f, // Name: /test/name/[1]
141 0x08, 0x04,
142 0x74, 0x65, 0x73, 0x74,
143 0x08, 0x04,
144 0x6e, 0x61, 0x6d, 0x65,
145 0x08, 0x01,
146 0x01,
147 0x82, 0x1, // SeqNo: 4
148 0x04
149 };
150
151 Block block(wire, sizeof(wire));
152 State state;
153 BOOST_REQUIRE_NO_THROW(state.wireDecode(block));
154
155 BOOST_CHECK_EQUAL(state.getLeaves().size(), 2);
156 LeafContainer::index<ordered>::type::iterator it = state.getLeaves().get<ordered>().begin();
157 BOOST_CHECK_EQUAL((*it)->getSeq(), 14);
158 it++;
159 BOOST_CHECK_EQUAL((*it)->getSeq(), 4);
160
161
162 State state2;
163
164 Name info1("/test/name");
165 info1.appendNumber(0);
166 state2.update(info1, 14);
167
168 Name info2("/test/name");
169 info2.appendNumber(1);
170 state2.update(info2, 4);
171
172 BOOST_REQUIRE_NO_THROW(state2.wireEncode());
173 Block block2 = state2.wireEncode();
174
175 BOOST_CHECK_EQUAL_COLLECTIONS(block.wire(),
176 block.wire() + block.size(),
177 block2.wire(),
178 block2.wire() + block2.size());
179
180 BOOST_CHECK(*state.getRootDigest() == *state2.getRootDigest());
181}
182
183BOOST_AUTO_TEST_CASE(Combine)
184{
185 State state1;
186 State state2;
187
188 Name info1("/test/name");
189 info1.appendNumber(0);
190
191 Name info2("/test/name");
192 info2.appendNumber(1);
193
194 Name info3("/test/name");
195 info3.appendNumber(2);
196
197 state1.update(info1, 4);
198 state1.update(info2, 14);
199
200 state2.update(info2, 15);
201 state2.update(info3, 25);
202
203 BOOST_CHECK_EQUAL(state1.getLeaves().size(), 2);
204 BOOST_CHECK_EQUAL(state2.getLeaves().size(), 2);
205
206 BOOST_REQUIRE_NO_THROW(state2 += state1);
207
208 BOOST_CHECK_EQUAL(state1.getLeaves().size(), 2);
209 BOOST_CHECK_EQUAL(state2.getLeaves().size(), 3);
210
211 LeafContainer::index<ordered>::type::iterator it = state2.getLeaves().get<ordered>().begin();
212 BOOST_CHECK_EQUAL((*it)->getSeq(), 4);
213 it++;
214 BOOST_CHECK_EQUAL((*it)->getSeq(), 15);
215 it++;
216 BOOST_CHECK_EQUAL((*it)->getSeq(), 25);
217}
218
219BOOST_AUTO_TEST_SUITE_END()
220
221} // namespace test
222} // namespace chronosync