blob: ed604f3cc60eb8ce52e9a522d4a846bf30b76593 [file] [log] [blame]
Alexander Afanasyev21a166e2013-01-20 16:04:41 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 * Zhenkai Zhu <zhenkai@cs.ucla.edu>
20 */
21
22#include "fetch-manager.h"
23#include "fetcher.h"
24#include "ccnx-wrapper.h"
25#include <boost/test/unit_test.hpp>
26#include <boost/make_shared.hpp>
Yingdi Yuf0b3de32013-07-11 12:59:00 -070027#include <boost/thread/thread.hpp>
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080028#include "logging.h"
29
Yingdi Yuf0b3de32013-07-11 12:59:00 -070030
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080031INIT_LOGGER ("Test.FetchManager");
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080032
33using namespace Ccnx;
34using namespace std;
35using namespace boost;
36
37BOOST_AUTO_TEST_SUITE(TestFetchManager)
38
39struct FetcherTestData
40{
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -080041 set<uint64_t> recvData;
42 set<uint64_t> recvContent;
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080043
44 set<Name> differentNames;
45 set<Name> segmentNames;
46
47 bool m_done;
48 bool m_failed;
49
50 FetcherTestData ()
51 : m_done (false)
52 , m_failed (false)
53 {
54 }
55
56 void
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -080057 onData (const Ccnx::Name &deviceName, const Ccnx::Name &basename, uint64_t seqno, Ccnx::PcoPtr pco)
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080058 {
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080059 _LOG_TRACE ("onData: " << seqno);
60
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080061 recvData.insert (seqno);
62 differentNames.insert (basename);
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -080063 Name name = basename;
64 name.appendComp(seqno);
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080065 segmentNames.insert (name);
66
Alexander Afanasyevf278db32013-01-21 14:41:01 -080067 BytesPtr data = pco->contentPtr ();
68
69 if (data->size () == sizeof(int))
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080070 {
Alexander Afanasyevf278db32013-01-21 14:41:01 -080071 recvContent.insert (*reinterpret_cast<const int*> (head(*data)));
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080072 }
73
Alexander Afanasyev650ba282013-01-20 20:14:06 -080074 // cout << "<<< " << basename << ", " << name << ", " << seqno << endl;
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080075 }
76
77 void
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -080078 finish(const Ccnx::Name &deviceName, const Ccnx::Name &baseName)
79 {
80 }
81
82 void
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080083 onComplete (Fetcher &fetcher)
84 {
85 m_done = true;
86 // cout << "Done" << endl;
87 }
88
89 void
90 onFail (Fetcher &fetcher)
91 {
92 m_failed = true;
93 // cout << "Failed" << endl;
94 }
95};
96
Yingdi Yuf0b3de32013-07-11 12:59:00 -070097void run()
98{
99 CcnxWrapperPtr ccnx = make_shared<CcnxWrapper> ();
100
101 Name baseName ("/base");
102 Name deviceName ("/device");
103
104 for (int i = 0; i < 10; i++)
105 {
106 usleep(100000);
107 ccnx->publishData (Name (baseName)(i), reinterpret_cast<const unsigned char*> (&i), sizeof(int), 30);
108 }
109
110 for (int i = 11; i < 50; i++)
111 {
112 usleep(100000);
113 ccnx->publishData (Name (baseName)(i), reinterpret_cast<const unsigned char*> (&i), sizeof(int), 30);
114 }
115
116}
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800117
118BOOST_AUTO_TEST_CASE (TestFetcher)
119{
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800120 INIT_LOGGERS ();
121
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800122 CcnxWrapperPtr ccnx = make_shared<CcnxWrapper> ();
123
124 Name baseName ("/base");
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -0800125 Name deviceName ("/device");
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800126 /* publish seqnos: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, <gap 5>, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, <gap 1>, 26 */
127 // this will allow us to test our pipeline of 6
128 for (int i = 0; i < 10; i++)
129 {
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800130 ccnx->publishData (Name (baseName)(i), reinterpret_cast<const unsigned char*> (&i), sizeof(int), 30);
131 }
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800132
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800133 for (int i = 15; i < 25; i++)
134 {
135 ccnx->publishData (Name (baseName)(i), reinterpret_cast<const unsigned char*> (&i), sizeof(int), 30);
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800136 }
137
138 int oneMore = 26;
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800139 ccnx->publishData (Name (baseName)(oneMore), reinterpret_cast<const unsigned char*> (&oneMore), sizeof(int), 30);
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800140
141 FetcherTestData data;
Zhenkai Zhuab9215c2013-01-28 23:42:28 -0800142 ExecutorPtr executor = make_shared<Executor>(1);
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800143 executor->start ();
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800144
145 Fetcher fetcher (ccnx,
Zhenkai Zhuab9215c2013-01-28 23:42:28 -0800146 executor,
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -0800147 bind (&FetcherTestData::onData, &data, _1, _2, _3, _4),
148 bind (&FetcherTestData::finish, &data, _1, _2),
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800149 bind (&FetcherTestData::onComplete, &data, _1),
150 bind (&FetcherTestData::onFail, &data, _1),
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -0800151 deviceName, Name ("/base"), 0, 26,
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800152 boost::posix_time::seconds (5)); // this time is not precise
153
154 BOOST_CHECK_EQUAL (fetcher.IsActive (), false);
155 fetcher.RestartPipeline ();
156 BOOST_CHECK_EQUAL (fetcher.IsActive (), true);
157
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800158 usleep(7000000);
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800159 BOOST_CHECK_EQUAL (data.m_failed, true);
160 BOOST_CHECK_EQUAL (data.differentNames.size (), 1);
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800161 BOOST_CHECK_EQUAL (data.segmentNames.size (), 20);
162 BOOST_CHECK_EQUAL (data.recvData.size (), 20);
163 BOOST_CHECK_EQUAL (data.recvContent.size (), 20);
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800164
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800165 {
166 ostringstream recvData;
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -0800167 for (set<uint64_t>::iterator i = data.recvData.begin (); i != data.recvData.end (); i++)
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800168 recvData << *i << ", ";
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800169
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800170 ostringstream recvContent;
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -0800171 for (set<uint64_t>::iterator i = data.recvContent.begin (); i != data.recvContent.end (); i++)
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800172 recvContent << *i << ", ";
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800173
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800174 BOOST_CHECK_EQUAL (recvData.str (), "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, ");
175 BOOST_CHECK_EQUAL (recvData.str (), recvContent.str ());
176 }
177
178 BOOST_CHECK_EQUAL (fetcher.IsActive (), false);
179 fetcher.RestartPipeline ();
180 BOOST_CHECK_EQUAL (fetcher.IsActive (), true);
181
182 usleep(7000000);
183 BOOST_CHECK_EQUAL (data.m_failed, true);
184
185 // publishing missing pieces
186 for (int i = 0; i < 27; i++)
187 {
188 ccnx->publishData (Name (baseName)(i), reinterpret_cast<const unsigned char*> (&i), sizeof(int), 1);
189 }
190 BOOST_CHECK_EQUAL (fetcher.IsActive (), false);
191 fetcher.RestartPipeline ();
192 BOOST_CHECK_EQUAL (fetcher.IsActive (), true);
193
194 usleep(1000000);
195 BOOST_CHECK_EQUAL (data.m_done, true);
196
197 {
198 ostringstream recvData;
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -0800199 for (set<uint64_t>::iterator i = data.recvData.begin (); i != data.recvData.end (); i++)
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800200 recvData << *i << ", ";
201
202 ostringstream recvContent;
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -0800203 for (set<uint64_t>::iterator i = data.recvContent.begin (); i != data.recvContent.end (); i++)
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800204 recvContent << *i << ", ";
205
206 BOOST_CHECK_EQUAL (recvData.str (), "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, ");
207 BOOST_CHECK_EQUAL (recvData.str (), recvContent.str ());
208 }
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -0800209
210 executor->shutdown ();
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800211}
212
Yingdi Yu57f667b2013-07-11 10:37:59 -0700213
214BOOST_AUTO_TEST_CASE (TestFetcher2)
215{
216 INIT_LOGGERS ();
217
218 CcnxWrapperPtr ccnx = make_shared<CcnxWrapper> ();
219
220 Name baseName ("/base");
221 Name deviceName ("/device");
Yingdi Yu57f667b2013-07-11 10:37:59 -0700222
Yingdi Yuf0b3de32013-07-11 12:59:00 -0700223 thread publishThread(run);
Yingdi Yu57f667b2013-07-11 10:37:59 -0700224
225 FetcherTestData data;
226 ExecutorPtr executor = make_shared<Executor>(1);
227 executor->start ();
228
229 Fetcher fetcher (ccnx,
230 executor,
231 bind (&FetcherTestData::onData, &data, _1, _2, _3, _4),
232 bind (&FetcherTestData::finish, &data, _1, _2),
233 bind (&FetcherTestData::onComplete, &data, _1),
234 bind (&FetcherTestData::onFail, &data, _1),
Yingdi Yuf0b3de32013-07-11 12:59:00 -0700235 deviceName, baseName, 0, 49,
Yingdi Yu57f667b2013-07-11 10:37:59 -0700236 boost::posix_time::seconds (5)); // this time is not precise
237
238 BOOST_CHECK_EQUAL (fetcher.IsActive (), false);
239 fetcher.RestartPipeline ();
240 BOOST_CHECK_EQUAL (fetcher.IsActive (), true);
241
Yingdi Yuf0b3de32013-07-11 12:59:00 -0700242 usleep(20000000);
Yingdi Yu57f667b2013-07-11 10:37:59 -0700243 BOOST_CHECK_EQUAL (data.m_failed, true);
244
245 executor->shutdown ();
246}
247
248
249
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800250// BOOST_AUTO_TEST_CASE (CcnxWrapperSelector)
251// {
252
253// Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1));
254
255// Selectors selectors;
256// selectors.interestLifetime(1);
257
258// string n1 = "/random/01";
259// c1->sendInterest(Name(n1), closure, selectors);
260// sleep(2);
261// c2->publishData(Name(n1), (const unsigned char *)n1.c_str(), n1.size(), 4);
262// usleep(100000);
263// BOOST_CHECK_EQUAL(g_timeout_counter, 1);
264// BOOST_CHECK_EQUAL(g_dataCallback_counter, 0);
265
266// string n2 = "/random/02";
267// selectors.interestLifetime(2);
268// c1->sendInterest(Name(n2), closure, selectors);
269// sleep(1);
270// c2->publishData(Name(n2), (const unsigned char *)n2.c_str(), n2.size(), 4);
271// usleep(100000);
272// BOOST_CHECK_EQUAL(g_timeout_counter, 1);
273// BOOST_CHECK_EQUAL(g_dataCallback_counter, 1);
274
275// // reset
276// g_dataCallback_counter = 0;
277// g_timeout_counter = 0;
278// }
279
280BOOST_AUTO_TEST_SUITE_END()