blob: 433f8d9597b6aadcf50c192161f02a9d72c9e7bc [file] [log] [blame]
Alexander Afanasyeva5625322012-03-06 00:03:41 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
Alexander Afanasyev8722d872014-07-02 13:00:29 -07003 * Copyright (c) 2012-2014 University of California, Los Angeles
Alexander Afanasyeva5625322012-03-06 00:03:41 -08004 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -07005 * This file is part of ChronoSync, synchronization library for distributed realtime
6 * applications for NDN.
Alexander Afanasyeva5625322012-03-06 00:03:41 -08007 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -07008 * 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.
Alexander Afanasyeva5625322012-03-06 00:03:41 -080011 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -070012 * 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.
Alexander Afanasyeva5625322012-03-06 00:03:41 -080015 *
Alexander Afanasyev8722d872014-07-02 13:00:29 -070016 * 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/>.
Alexander Afanasyeva5625322012-03-06 00:03:41 -080018 */
19
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -080020#define BOOST_TEST_DYN_LINK 1
21#define BOOST_TEST_NO_MAIN 1
22// #define BOOST_TEST_MODULE StateTests
Alexander Afanasyeva5625322012-03-06 00:03:41 -080023#include <boost/test/unit_test.hpp>
Alexander Afanasyev8722d872014-07-02 13:00:29 -070024#include <boost/test/output_test_stream.hpp>
Alexander Afanasyeva5625322012-03-06 00:03:41 -080025using boost::test_tools::output_test_stream;
26
27#include <boost/make_shared.hpp>
28#include <boost/date_time/posix_time/posix_time.hpp>
29
Alexander Afanasyev158ec0d2012-04-05 13:48:55 -070030#include "sync-std-name-info.h"
31#include "sync-full-state.h"
32#include "sync-diff-state.h"
Alexander Afanasyeva5625322012-03-06 00:03:41 -080033
34using namespace Sync;
35using namespace std;
36using namespace boost;
37
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -080038BOOST_AUTO_TEST_SUITE(StateTests)
Alexander Afanasyeva5625322012-03-06 00:03:41 -080039
40BOOST_AUTO_TEST_CASE (FullStateTest)
41{
42 BOOST_CHECK_NO_THROW (FullState ());
43 FullState state;
44 BOOST_CHECK_EQUAL (state.getLeaves ().size (), 0);
45
46 output_test_stream output;
47 output << state.getTimeFromLastUpdate ();
48 BOOST_CHECK (output.is_equal ("not-a-date-time", true));
49
50 NameInfoConstPtr name = StdNameInfo::FindOrCreate ("/test/name");
51 BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
52 BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
53 BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
54 BOOST_CHECK_EQUAL (state.getLeaves ().size (), 1);
55 BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 12);
56
57 BOOST_CHECK_NO_THROW (state.update (name, SeqNo (13)));
58 BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 13);
59
60 BOOST_CHECK_NO_THROW (state.remove (name));
61 BOOST_CHECK_EQUAL (state.getLeaves ().size (), 0);
62
63 BOOST_CHECK_EQUAL (state.getTimeFromLastUpdate ().total_milliseconds (), 0);
64}
65
66BOOST_AUTO_TEST_CASE (DiffStateTest)
67{
68 BOOST_CHECK_NO_THROW (DiffState ());
69 DiffState state;
70 BOOST_CHECK_EQUAL (state.getLeaves ().size (), 0);
71
72 NameInfoConstPtr name = StdNameInfo::FindOrCreate ("/test/name");
73 BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
74 BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
75 BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
76 BOOST_CHECK_EQUAL (state.getLeaves ().size (), 1);
77 BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 12);
78
79 BOOST_CHECK_NO_THROW (state.update (name, SeqNo (13)));
80 BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 13);
81
82 BOOST_CHECK_NO_THROW (state.remove (name));
83 BOOST_CHECK_EQUAL (state.getLeaves ().size (), 1);
84 BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 0);
85}
86
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -080087BOOST_AUTO_TEST_CASE (FullStateDigestTest)
88{
89 FullState state;
90 BOOST_CHECK_EQUAL (state.getLeaves ().size (), 0);
91
92 NameInfoConstPtr name3 = StdNameInfo::FindOrCreate ("3");
93 NameInfoConstPtr name2 = StdNameInfo::FindOrCreate ("2");
94 NameInfoConstPtr name1 = StdNameInfo::FindOrCreate ("1");
95
96 state.update (name1, SeqNo (10));
97 DigestConstPtr digest1 = state.getDigest ();
98
99 state.update (name2, SeqNo (12));
100 DigestConstPtr digest2 = state.getDigest ();
101
102 BOOST_CHECK (digest1.get () != digest2.get ());
103 BOOST_CHECK (!digest1->empty ());
104 BOOST_CHECK (!digest2->empty ());
105
106 state.update (name3, SeqNo (8));
107 DigestConstPtr digest3 = state.getDigest ();
108
109 BOOST_CHECK (digest1.get () != digest2.get ());
110 BOOST_CHECK (digest2.get () != digest3.get ());
111 BOOST_CHECK (digest1.get () != digest3.get ());
112
113 BOOST_CHECK (*digest1 != *digest2);
114 BOOST_CHECK (*digest2 != *digest3);
115 BOOST_CHECK (*digest1 != *digest3);
116
117 // removing elements. Digest should get reverted to digest1
118 state.remove (name2);
119 state.remove (name3);
120 DigestConstPtr digest4 = state.getDigest ();
121 BOOST_CHECK (*digest1 == *digest4);
122
123 name2.reset (); // force destructor
124 name3.reset (); // force destructor
125 name3 = StdNameInfo::FindOrCreate ("3"); // this will enforce different (larger) hashing ID of name
126 name2 = StdNameInfo::FindOrCreate ("2"); // this will enforce different (larger) hashing ID of name
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700127
Alexander Afanasyeva4ce9cf2012-03-06 14:29:58 -0800128 // adding in different order
129 state.update (name3, SeqNo (8));
130 state.update (name2, SeqNo (12));
131 DigestConstPtr digest5 = state.getDigest ();
132 BOOST_CHECK (*digest5 == *digest3);
133}
134
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800135BOOST_AUTO_TEST_CASE (FullStateXml)
136{
137 FullState state;
138
139 NameInfoConstPtr name3 = StdNameInfo::FindOrCreate ("3");
140 NameInfoConstPtr name2 = StdNameInfo::FindOrCreate ("2");
141 NameInfoConstPtr name1 = StdNameInfo::FindOrCreate ("1");
142
143 state.update (name1, SeqNo (10));
144 state.update (name2, SeqNo (12));
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700145 state.update (name3, SeqNo (8));
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800146
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800147 string xml1 = "<state>"
148 "<item><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item>"
149 "<item><name>2</name><seq><session>0</session><seqno>12</seqno></seq></item>"
150 "<item><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item>"
151 "</state>";
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800152 {
153 ostringstream os;
154 os << state;
155 string s = os.str ();
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700156 // cout << s << endl;
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800157 erase_all (s, "\n");
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800158 BOOST_CHECK_EQUAL (s, xml1);
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800159 }
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700160
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800161 state.remove (name2);
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800162 string xml2 = "<state>"
163 "<item><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item>"
164 "<item><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item>"
165 "</state>";
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800166 {
167 ostringstream os;
168 os << state;
169 string s = os.str ();
170 erase_all (s, "\n");
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800171 BOOST_CHECK_EQUAL (s, xml2);
172 }
173
174 FullState state2;
175 istringstream xml1_is (xml1);
176 BOOST_CHECK_NO_THROW (xml1_is >> state2);
177 {
178 ostringstream os;
179 os << state2;
180 string xml1_test = os.str ();
181 erase_all (xml1_test, "\n");
182 BOOST_CHECK_EQUAL (xml1_test, xml1);
183 }
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700184
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800185 istringstream xml2_is ("<state><item action=\"remove\"><name>2</name></item></state>");
186 BOOST_CHECK_NO_THROW (xml2_is >> state2);
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700187
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800188 {
189 ostringstream os;
190 os << state2;
191 string xml2_test = os.str ();
192 erase_all (xml2_test, "\n");
193 BOOST_CHECK_EQUAL (xml2_test, xml2);
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800194 }
195}
196
197BOOST_AUTO_TEST_CASE (DiffStateXml)
198{
199 DiffState state;
200
201 NameInfoConstPtr name3 = StdNameInfo::FindOrCreate ("3");
202 NameInfoConstPtr name2 = StdNameInfo::FindOrCreate ("2");
203 NameInfoConstPtr name1 = StdNameInfo::FindOrCreate ("1");
204
205 state.update (name1, SeqNo (10));
206 state.update (name2, SeqNo (12));
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700207 state.update (name3, SeqNo (8));
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800208
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800209 string xml1 = "<state>"
210 "<item action=\"update\"><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item>"
211 "<item action=\"update\"><name>2</name><seq><session>0</session><seqno>12</seqno></seq></item>"
212 "<item action=\"update\"><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item>"
213 "</state>";
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800214 {
215 ostringstream os;
216 os << state;
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800217 string xml1_test = os.str ();
218 erase_all (xml1_test, "\n");
219 BOOST_CHECK_EQUAL (xml1_test, xml1);
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800220 }
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700221
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800222 state.remove (name2);
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800223 string xml2 = "<state>"
224 "<item action=\"update\"><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item>"
225 "<item action=\"remove\"><name>2</name></item>"
226 "<item action=\"update\"><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item>"
227 "</state>";
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800228 {
229 ostringstream os;
230 os << state;
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800231 string xml2_test = os.str ();
232 erase_all (xml2_test, "\n");
233 BOOST_CHECK_EQUAL (xml2_test, xml2);
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800234 }
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800235
236 //////////// //////////// //////////// //////////// //////////// ////////////
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700237
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800238 DiffState state2;
239 istringstream xml1_is (xml1);
240 BOOST_CHECK_NO_THROW (xml1_is >> state2);
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700241
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800242 {
243 ostringstream os;
244 os << state2;
245 string xml1_test = os.str ();
246 erase_all (xml1_test, "\n");
247 BOOST_CHECK_EQUAL (xml1_test, xml1);
248 }
249
250 istringstream xml2_is ("<state><item action=\"remove\"><name>2</name></item></state>");
251 BOOST_CHECK_NO_THROW (xml2_is >> state2);
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700252
Alexander Afanasyev44a5fbe2012-03-08 14:15:25 -0800253 {
254 ostringstream os;
255 os << state2;
256 string xml2_test = os.str ();
257 erase_all (xml2_test, "\n");
258 BOOST_CHECK_EQUAL (xml2_test, xml2);
259 }
260
Alexander Afanasyev64d50692012-03-07 20:48:35 -0800261}
262
Alexander Afanasyeva36b7512012-03-12 16:03:03 -0700263BOOST_AUTO_TEST_CASE (DiffStateDiffTest)
264{
265 DiffStatePtr root = make_shared<DiffState> ();
266
267 DiffStatePtr head = make_shared<DiffState> ();
268 root->setNext (head);
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700269
Alexander Afanasyeva36b7512012-03-12 16:03:03 -0700270 head->update (StdNameInfo::FindOrCreate ("3"), SeqNo (1));
271 head->remove (StdNameInfo::FindOrCreate ("1"));
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700272
Alexander Afanasyeva36b7512012-03-12 16:03:03 -0700273 DiffStatePtr tail = make_shared<DiffState> ();
274 head->setNext (tail);
275
Alexander Afanasyev8722d872014-07-02 13:00:29 -0700276 tail->update (StdNameInfo::FindOrCreate ("3"), SeqNo (2));
Alexander Afanasyeva36b7512012-03-12 16:03:03 -0700277
278 {
279 ostringstream os;
280 os << *root->diff ();
281 string diffState = os.str ();
282 erase_all (diffState, "\n");
283 BOOST_CHECK_EQUAL (diffState,
284 "<state>"
285 "<item action=\"remove\"><name>1</name></item>"
286 "<item action=\"update\"><name>3</name><seq><session>0</session><seqno>2</seqno></seq></item>"
287 "</state>");
288 }
289}
290
Alexander Afanasyeva5625322012-03-06 00:03:41 -0800291BOOST_AUTO_TEST_SUITE_END()