blob: 06535fc009883e5faf17de0d2281c99e4bb6e9bd [file] [log] [blame]
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
* Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#include "ccnx-wrapper.h"
#include "ccnx-closure.h"
#include "ccnx-name.h"
#include "ccnx-selectors.h"
#include "ccnx-pco.h"
#include <unistd.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/make_shared.hpp>
using namespace Ccnx;
using namespace std;
using namespace boost;
BOOST_AUTO_TEST_SUITE(TestCcnxWrapper)
CcnxWrapperPtr c1;
CcnxWrapperPtr c2;
int g_timeout_counter = 0;
int g_dataCallback_counter = 0;
void publish1(const Name &name)
{
string content = name.toString();
c1->publishData(name, (const unsigned char*)content.c_str(), content.size(), 5);
}
void publish2(const Name &name)
{
string content = name.toString();
c2->publishData(name, (const unsigned char*)content.c_str(), content.size(), 5);
}
void dataCallback(const Name &name, Ccnx::PcoPtr pco)
{
cout << " in data callback" << endl;
BytesPtr content = pco->contentPtr ();
string msg(reinterpret_cast<const char *> (head (*content)), content->size());
g_dataCallback_counter ++;
BOOST_CHECK_EQUAL(name, msg);
}
void encapCallback(const Name &name, Ccnx::PcoPtr pco)
{
cout << " in encap data callback" << endl;
PcoPtr npco = make_shared<ParsedContentObject> (*(pco->contentPtr()));
g_dataCallback_counter ++;
BOOST_CHECK(npco);
BOOST_CHECK(c1->verifyPco(npco));
}
void
timeout(const Name &name, const Closure &closure, Selectors selectors)
{
g_timeout_counter ++;
}
void
setup()
{
if (!c1)
{
c1 = make_shared<CcnxWrapper> ();
}
if (!c2)
{
c2 = make_shared<CcnxWrapper> ();
}
}
void
teardown()
{
if (c1)
{
c1.reset();
}
if (c2)
{
c2.reset();
}
}
BOOST_AUTO_TEST_CASE (BlaCcnxWrapperTest)
{
setup();
Name prefix1("/c1");
Name prefix2("/c2");
c1->setInterestFilter(prefix1, bind(publish1, _1));
usleep(100000);
c2->setInterestFilter(prefix2, bind(publish2, _1));
Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1, _2, _3));
c1->sendInterest(Name("/c2/hi"), closure);
usleep(100000);
c2->sendInterest(Name("/c1/hi"), closure);
sleep(1);
BOOST_CHECK_EQUAL(g_dataCallback_counter, 2);
// reset
g_dataCallback_counter = 0;
g_timeout_counter = 0;
teardown();
}
BOOST_AUTO_TEST_CASE (CcnxWrapperSelector)
{
setup();
Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1, _2, _3));
Selectors selectors;
selectors.interestLifetime(1);
string n1 = "/random/01";
c1->sendInterest(Name(n1), closure, selectors);
sleep(2);
c2->publishData(Name(n1), (const unsigned char *)n1.c_str(), n1.size(), 1);
usleep(100000);
BOOST_CHECK_EQUAL(g_timeout_counter, 1);
BOOST_CHECK_EQUAL(g_dataCallback_counter, 0);
string n2 = "/random/02";
selectors.interestLifetime(2);
c1->sendInterest(Name(n2), closure, selectors);
sleep(1);
c2->publishData(Name(n2), (const unsigned char *)n2.c_str(), n2.size(), 1);
usleep(100000);
BOOST_CHECK_EQUAL(g_timeout_counter, 1);
BOOST_CHECK_EQUAL(g_dataCallback_counter, 1);
// reset
g_dataCallback_counter = 0;
g_timeout_counter = 0;
teardown();
}
void
reexpress(const Name &name, const Closure &closure, Selectors selectors)
{
g_timeout_counter ++;
c1->sendInterest(name, closure, selectors);
}
BOOST_AUTO_TEST_CASE (TestTimeout)
{
setup();
g_dataCallback_counter = 0;
g_timeout_counter = 0;
Closure closure (bind(dataCallback, _1, _2), bind(reexpress, _1, _2, _3));
Selectors selectors;
selectors.interestLifetime(1);
string n1 = "/random/04";
c1->sendInterest(Name(n1), closure, selectors);
usleep(3500000);
c2->publishData(Name(n1), (const unsigned char *)n1.c_str(), n1.size(), 1);
usleep(1000);
BOOST_CHECK_EQUAL(g_dataCallback_counter, 1);
BOOST_CHECK_EQUAL(g_timeout_counter, 3);
teardown();
}
BOOST_AUTO_TEST_CASE (TestUnsigned)
{
setup();
string n1 = "/xxxxxx/unsigned/01";
Closure closure (bind(dataCallback, _1, _2), bind(timeout, _1, _2, _3));
g_dataCallback_counter = 0;
c1->sendInterest(Name(n1), closure);
usleep(1000);
c2->publishUnsignedData(Name(n1), (const unsigned char *)n1.c_str(), n1.size(), 1);
usleep(1000);
BOOST_CHECK_EQUAL(g_dataCallback_counter, 1);
string n2 = "/xxxxxx/signed/01";
Bytes content = c1->createContentObject(Name(n1), (const unsigned char *)n2.c_str(), n2.size(), 1);
c1->publishUnsignedData(Name(n2), head(content), content.size(), 1);
Closure encapClosure(bind(encapCallback, _1, _2), bind(timeout, _1, _2, _3));
c2->sendInterest(Name(n2), encapClosure);
usleep(2000);
BOOST_CHECK_EQUAL(g_dataCallback_counter, 2);
teardown();
}
BOOST_AUTO_TEST_CASE (CcnxWrapperUnsigningTest)
{
setup();
Bytes data;
data.resize(1024);
for (int i = 0; i < 1024; i++)
{
data[i] = 'm';
}
Name name("/unsigningtest");
posix_time::ptime start = posix_time::second_clock::local_time();
for (uint64_t i = 0; i < 100000; i++)
{
Name n = name;
n.appendComp(i);
c1->publishUnsignedData(n, data, 10);
}
posix_time::ptime end = posix_time::second_clock::local_time();
posix_time::time_duration duration = end - start;
cout << "Publishing 100000 1K size content objects costs " <<duration.total_milliseconds() << " milliseconds" << endl;
cout << "Average time to publish one content object is " << (double) duration.total_milliseconds() / 100000.0 << " milliseconds" << endl;
teardown();
}
BOOST_AUTO_TEST_SUITE_END()