tests: move integrated tests into unit tests

Change-Id: Ifed29e53091ca430582b1c2e7f3514e02d7c8d14
This commit is contained in:
Qiuhan Ding committed 2015-01-30 14:04:55 -08:00
1 parent e246b62b1b
commit fb8c9e0b7e
8 files changed
+525 -415

No files matched your search

+6 -5
View File
@@ -121,14 +121,15 @@ Logic::~Logic()
}
void
Logic::reset()
Logic::reset(bool isOnInterest)
{
m_isInReset = true;
m_state.reset();
m_log.clear();
sendResetInterest();
if (!isOnInterest)
sendResetInterest();
// reset outstanding interest name, so that data for previous interest will be dropped.
if (m_outstandingInterestId != 0) {
@@ -173,7 +174,7 @@ Logic::addUserNode(const Name& userPrefix, const Name& signingId)
sessionName.appendNumber(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count());
m_nodeList[userPrefix].sessionName = sessionName;
m_nodeList[userPrefix].seqNo = 0;
reset();
reset(false);
}
}
@@ -193,7 +194,7 @@ Logic::removeUserNode(const Name& userPrefix)
m_defaultSigningId = DEFAULT_NAME;
}
}
reset();
reset(false);
}
}
@@ -459,7 +460,7 @@ void
Logic::processResetInterest(const Interest& interest)
{
_LOG_DEBUG_ID(">> Logic::processResetInterest");
reset();
reset(true);
}
void
+6 -2
View File
@@ -126,9 +126,13 @@ public:
~Logic();
/// @brief Reset the sync tree (and restart synchronization again)
/**
* @brief Reset the sync tree (and restart synchronization again)
*
* @param isOnInterest a flag that tells whether the reset is called by reset interest.
*/
void
reset();
reset(bool isOnInterest = false);
/**
* @brief Set user prefix
+29 -2
View File
@@ -30,8 +30,8 @@ INIT_LOGGER("Socket");
namespace chronosync {
const ndn::Name Socket::DEFAULT_PREFIX;
const ndn::Name Socket::DEFAULT_NAME;
const ndn::Name Socket::DEFAULT_PREFIX;
const ndn::shared_ptr<ndn::Validator> Socket::DEFAULT_VALIDATOR;
Socket::Socket(const Name& syncPrefix,
@@ -46,12 +46,30 @@ Socket::Socket(const Name& syncPrefix,
, m_signingId(signingId)
, m_validator(validator)
{
if (m_userPrefix != DEFAULT_NAME)
m_registeredPrefixList[m_userPrefix] =
m_face.setInterestFilter(m_userPrefix,
bind(&Socket::onInterest, this, _1, _2),
[] (const Name& prefix, const std::string& msg) {});
}
void
Socket::addSyncNode(const Name& prefix, const Name& signingId)
{
if (prefix == DEFAULT_NAME)
return;
auto itr = m_registeredPrefixList.find(prefix);
if (itr != m_registeredPrefixList.end())
return;
if (m_userPrefix == DEFAULT_NAME)
m_userPrefix = prefix;
m_logic.addUserNode(prefix, signingId);
m_registeredPrefixList[prefix] =
m_face.setInterestFilter(prefix,
bind(&Socket::onInterest, this, _1, _2),
[] (const Name& prefix, const std::string& msg) {});
}
void
@@ -79,7 +97,7 @@ Socket::publishData(const Block& content, const ndn::time::milliseconds& freshne
else
m_keyChain.signByIdentity(*data, m_signingId);
m_face.put(*data);
m_ims.insert(*data);
m_logic.updateSeqNo(newSeq, prefix);
}
@@ -125,6 +143,15 @@ Socket::fetchData(const Name& sessionName, const SeqNo& seqNo,
_LOG_DEBUG("<< Socket::fetchData");
}
void
Socket::onInterest(const Name& prefix, const Interest& interest)
{
shared_ptr<const Data>data = m_ims.find(interest);
if (static_cast<bool>(data)) {
m_face.put(*data);
}
}
void
Socket::onData(const Interest& interest, Data& data,
const ndn::OnDataValidated& onValidated,
+9
View File
@@ -26,6 +26,8 @@
#define CHRONOSYNC_SOCKET_HPP
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/util/in-memory-storage-persistent.hpp>
#include <unordered_map>
#include "logic.hpp"
@@ -139,6 +141,9 @@ public:
}
private:
void
onInterest(const Name& prefix, const Interest& interest);
void
onData(const Interest& interest, Data& data,
const ndn::OnDataValidated& dataCallback,
@@ -159,6 +164,7 @@ public:
static const ndn::shared_ptr<ndn::Validator> DEFAULT_VALIDATOR;
private:
typedef std::unordered_map<ndn::Name, const ndn::RegisteredPrefixId*> RegisteredPrefixList;
Name m_userPrefix;
ndn::Face& m_face;
@@ -168,6 +174,9 @@ private:
ndn::Name m_signingId;
ndn::KeyChain m_keyChain;
ndn::shared_ptr<ndn::Validator> m_validator;
RegisteredPrefixList m_registeredPrefixList;
ndn::util::InMemoryStoragePersistent m_ims;
};
} // namespace chronosync
-301
View File
@@ -1,301 +0,0 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2014 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
*
* ChronoSync is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* ChronoSync 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
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "logic.hpp"
#include "boost-test.hpp"
namespace chronosync {
namespace test {
using std::vector;
class Handler
{
public:
Handler(ndn::Face& face,
const Name& syncPrefix,
const Name& userPrefix)
: logic(face,
syncPrefix,
userPrefix,
bind(&Handler::onUpdate, this, _1))
{
}
void
onUpdate(const vector<MissingDataInfo>& v)
{
for (size_t i = 0; i < v.size(); i++) {
update(v[i].session, v[i].high, v[i].low);
}
}
void
update(const Name& p, const SeqNo& high, const SeqNo& low)
{
map[p] = high;
}
void
updateSeqNo(const SeqNo& seqNo)
{
logic.updateSeqNo(seqNo);
}
Logic logic;
std::map<Name, SeqNo> map;
};
class LogicFixture
{
public:
LogicFixture()
: syncPrefix("/ndn/broadcast/sync")
, scheduler(io)
{
syncPrefix.appendVersion();
userPrefix[0] = Name("/user0");
userPrefix[1] = Name("/user1");
userPrefix[2] = Name("/user2");
faces[0] = make_shared<ndn::Face>(ref(io));
faces[1] = make_shared<ndn::Face>(ref(io));
faces[2] = make_shared<ndn::Face>(ref(io));
}
Name syncPrefix;
Name userPrefix[3];
boost::asio::io_service io;
shared_ptr<ndn::Face> faces[3];
ndn::Scheduler scheduler;
shared_ptr<Handler> handler[3];
};
BOOST_FIXTURE_TEST_SUITE(LogicTests, LogicFixture)
void
onUpdate(const vector<MissingDataInfo>& v)
{
}
BOOST_AUTO_TEST_CASE(Constructor)
{
Name syncPrefix("/ndn/broadcast/sync");
Name userPrefix("/user");
ndn::Face face;
BOOST_REQUIRE_NO_THROW(Logic(face, syncPrefix, userPrefix,
bind(onUpdate, _1)));
}
BOOST_AUTO_TEST_CASE(TwoBasic)
{
scheduler.scheduleEvent(ndn::time::milliseconds(100),
[this] { handler[0] = make_shared<Handler>(ref(*faces[0]), syncPrefix, userPrefix[0]); });
scheduler.scheduleEvent(ndn::time::milliseconds(200),
[this] { handler[1] = make_shared<Handler>(ref(*faces[1]), syncPrefix, userPrefix[1]); });
scheduler.scheduleEvent(ndn::time::milliseconds(300), [this] { handler[0]->updateSeqNo(1); });
scheduler.scheduleEvent(ndn::time::milliseconds(1000),
[this] { BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1); });
scheduler.scheduleEvent(ndn::time::milliseconds(1100), [this] { handler[0]->updateSeqNo(2); });
scheduler.scheduleEvent(ndn::time::milliseconds(1800),
[this] { BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 2); });
scheduler.scheduleEvent(ndn::time::milliseconds(1900), [this] { handler[1]->updateSeqNo(2); });
scheduler.scheduleEvent(ndn::time::milliseconds(2600),
[this] { BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2); });
scheduler.scheduleEvent(ndn::time::milliseconds(2800), [this] { io.stop(); });
io.run();
}
BOOST_AUTO_TEST_CASE(ThreeBasic)
{
scheduler.scheduleEvent(ndn::time::milliseconds(100),
[this] { handler[0] = make_shared<Handler>(ref(*faces[0]), syncPrefix, userPrefix[0]); });
scheduler.scheduleEvent(ndn::time::milliseconds(200),
[this] { handler[1] = make_shared<Handler>(ref(*faces[1]), syncPrefix, userPrefix[1]); });
scheduler.scheduleEvent(ndn::time::milliseconds(300),
[this] { handler[2] = make_shared<Handler>(ref(*faces[2]), syncPrefix, userPrefix[2]); });
scheduler.scheduleEvent(ndn::time::milliseconds(500), [this] { handler[0]->updateSeqNo(1); });
scheduler.scheduleEvent(ndn::time::milliseconds(1400),
[this] { BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1); });
scheduler.scheduleEvent(ndn::time::milliseconds(1450),
[this] { BOOST_CHECK_EQUAL(handler[2]->map[handler[0]->logic.getSessionName()], 1); });
scheduler.scheduleEvent(ndn::time::milliseconds(1500), [this] { handler[1]->updateSeqNo(2); });
scheduler.scheduleEvent(ndn::time::milliseconds(2400),
[this] { BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2); });
scheduler.scheduleEvent(ndn::time::milliseconds(2450),
[this] { BOOST_CHECK_EQUAL(handler[2]->map[handler[1]->logic.getSessionName()], 2); });
scheduler.scheduleEvent(ndn::time::milliseconds(2500), [this] { handler[2]->updateSeqNo(4); });
scheduler.scheduleEvent(ndn::time::milliseconds(4400),
[this] { BOOST_CHECK_EQUAL(handler[0]->map[handler[2]->logic.getSessionName()], 4); });
scheduler.scheduleEvent(ndn::time::milliseconds(4450),
[this] { BOOST_CHECK_EQUAL(handler[1]->map[handler[2]->logic.getSessionName()], 4); });
scheduler.scheduleEvent(ndn::time::milliseconds(4500), [this] { io.stop(); });
io.run();
}
BOOST_AUTO_TEST_CASE(ResetRecover)
{
scheduler.scheduleEvent(ndn::time::milliseconds(100),
[this] { handler[0] = make_shared<Handler>(ref(*faces[0]), syncPrefix, userPrefix[0]); });
scheduler.scheduleEvent(ndn::time::milliseconds(200),
[this] { handler[1] = make_shared<Handler>(ref(*faces[1]), syncPrefix, userPrefix[1]); });
scheduler.scheduleEvent(ndn::time::milliseconds(500), [this] { handler[0]->updateSeqNo(1); });
scheduler.scheduleEvent(ndn::time::milliseconds(1400),
[this] { BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1); });
scheduler.scheduleEvent(ndn::time::milliseconds(1500), [this] { handler[1]->updateSeqNo(2); });
scheduler.scheduleEvent(ndn::time::milliseconds(2400),
[this] { BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2); });
scheduler.scheduleEvent(ndn::time::milliseconds(2500),
[this] { handler[2] = make_shared<Handler>(ref(*faces[2]), syncPrefix, userPrefix[2]); });
scheduler.scheduleEvent(ndn::time::milliseconds(3000),
[this] { BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1); });
scheduler.scheduleEvent(ndn::time::milliseconds(3050),
[this] { BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2); });
scheduler.scheduleEvent(ndn::time::milliseconds(3100), [this] { handler[2]->updateSeqNo(4); });
scheduler.scheduleEvent(ndn::time::milliseconds(4000),
[this] { BOOST_CHECK_EQUAL(handler[1]->map[handler[2]->logic.getSessionName()], 4); });
scheduler.scheduleEvent(ndn::time::milliseconds(4050),
[this] { BOOST_CHECK_EQUAL(handler[0]->map[handler[2]->logic.getSessionName()], 4); });
scheduler.scheduleEvent(ndn::time::milliseconds(4500), [this] { io.stop(); });
io.run();
}
BOOST_AUTO_TEST_CASE(RecoverConflict)
{
scheduler.scheduleEvent(ndn::time::milliseconds(0),
[this] { handler[0] = make_shared<Handler>(ref(*faces[0]), syncPrefix, userPrefix[0]); });
scheduler.scheduleEvent(ndn::time::milliseconds(50),
[this] { handler[1] = make_shared<Handler>(ref(*faces[1]), syncPrefix, userPrefix[1]); });
scheduler.scheduleEvent(ndn::time::milliseconds(100),
[this] { handler[2] = make_shared<Handler>(ref(*faces[2]), syncPrefix, userPrefix[2]); });
scheduler.scheduleEvent(ndn::time::milliseconds(500), [this] { handler[0]->updateSeqNo(1); });
scheduler.scheduleEvent(ndn::time::milliseconds(1400),
[this] { BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1); });
scheduler.scheduleEvent(ndn::time::milliseconds(1400),
[this] { BOOST_CHECK_EQUAL(handler[2]->map[handler[0]->logic.getSessionName()], 1); });
scheduler.scheduleEvent(ndn::time::milliseconds(1500), [this] { handler[1]->updateSeqNo(2); });
scheduler.scheduleEvent(ndn::time::milliseconds(1500), [this] { handler[2]->updateSeqNo(4); });
scheduler.scheduleEvent(ndn::time::milliseconds(2400),
[this] { BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2); });
scheduler.scheduleEvent(ndn::time::milliseconds(2450),
[this] { BOOST_CHECK_EQUAL(handler[0]->map[handler[2]->logic.getSessionName()], 4); });
scheduler.scheduleEvent(ndn::time::milliseconds(2500),
[this] { BOOST_CHECK_EQUAL(handler[1]->map[handler[2]->logic.getSessionName()], 4); });
scheduler.scheduleEvent(ndn::time::milliseconds(2550),
[this] { BOOST_CHECK_EQUAL(handler[2]->map[handler[1]->logic.getSessionName()], 2); });
scheduler.scheduleEvent(ndn::time::milliseconds(4500), [this] { io.stop(); });
io.run();
}
BOOST_AUTO_TEST_CASE(MultipleUserUnderOneLogic)
{
scheduler.scheduleEvent(ndn::time::milliseconds(0),
[this] { handler[0] = make_shared<Handler>(ref(*faces[0]), syncPrefix, userPrefix[0]); });
scheduler.scheduleEvent(ndn::time::milliseconds(50),
[this] { handler[1] = make_shared<Handler>(ref(*faces[1]), syncPrefix, userPrefix[2]); });
scheduler.scheduleEvent(ndn::time::milliseconds(100),
[this] { handler[0]->logic.addUserNode(userPrefix[1]); });
scheduler.scheduleEvent(ndn::time::milliseconds(500), [this] { handler[0]->updateSeqNo(1); });
scheduler.scheduleEvent(ndn::time::milliseconds(1400),
[this] { BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1); });
scheduler.scheduleEvent(ndn::time::milliseconds(1500),
[this] { handler[0]->logic.updateSeqNo(2, userPrefix[1]); });
scheduler.scheduleEvent(ndn::time::milliseconds(2400),
[this] {
Name sessionName = handler[0]->logic.getSessionName(userPrefix[1]);
BOOST_CHECK_EQUAL(handler[1]->map[sessionName], 2);
});
scheduler.scheduleEvent(ndn::time::milliseconds(2500), [this] { handler[1]->updateSeqNo(4); });
scheduler.scheduleEvent(ndn::time::milliseconds(3200),
[this] { BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 4); });
scheduler.scheduleEvent(ndn::time::milliseconds(3300),
[this] { handler[0]->logic.removeUserNode(userPrefix[0]); });
scheduler.scheduleEvent(ndn::time::milliseconds(4500),
[this] { BOOST_CHECK_EQUAL(handler[1]->logic.getSessionNames().size(), 2); });
scheduler.scheduleEvent(ndn::time::milliseconds(5000), [this] { io.stop(); });
io.run();
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace test
} // namespace chronosync
+344
View File
@@ -0,0 +1,344 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2012-2014 University of California, Los Angeles
*
* This file is part of ChronoSync, synchronization library for distributed realtime
* applications for NDN.
*
* ChronoSync is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* ChronoSync 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
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "logic.hpp"
#include "../unit-test-time-fixture.hpp"
#include <ndn-cxx/util/dummy-client-face.hpp>
#include "boost-test.hpp"
namespace chronosync {
namespace test {
using std::vector;
using ndn::util::DummyClientFace;
using ndn::util::makeDummyClientFace;
class Handler
{
public:
Handler(DummyClientFace& face,
const Name& syncPrefix,
const Name& userPrefix)
: logic(face,
syncPrefix,
userPrefix,
bind(&Handler::onUpdate, this, _1))
{
}
void
onUpdate(const vector<MissingDataInfo>& v)
{
for (size_t i = 0; i < v.size(); i++) {
update(v[i].session, v[i].high, v[i].low);
}
}
void
update(const Name& p, const SeqNo& high, const SeqNo& low)
{
map[p] = high;
}
void
updateSeqNo(const SeqNo& seqNo)
{
logic.updateSeqNo(seqNo);
}
Logic logic;
std::map<Name, SeqNo> map;
};
class LogicFixture : public ndn::tests::UnitTestTimeFixture
{
public:
LogicFixture()
: syncPrefix("/ndn/broadcast/sync")
{
syncPrefix.appendVersion();
userPrefix[0] = Name("/user0");
userPrefix[1] = Name("/user1");
userPrefix[2] = Name("/user2");
faces[0] = makeDummyClientFace(ref(io), {true, true});
faces[1] = makeDummyClientFace(ref(io), {true, true});
faces[2] = makeDummyClientFace(ref(io), {true, true});
for (int i = 0; i < 3; i++) {
readInterestOffset[i] = 0;
readDataOffset[i] = 0;
}
}
void
passPacket()
{
for (int i = 0; i < 3; i++)
checkFace(i);
}
void
checkFace(int sender)
{
while (faces[sender]->sentInterests.size() > readInterestOffset[sender]) {
for (int i = 0; i < 3; i++) {
if (sender != i)
faces[i]->receive(faces[sender]->sentInterests[readInterestOffset[sender]]);
}
readInterestOffset[sender]++;
}
while (faces[sender]->sentDatas.size() > readDataOffset[sender]) {
for (int i = 0; i < 3; i++) {
if (sender != i)
faces[i]->receive(faces[sender]->sentDatas[readDataOffset[sender]]);
}
readDataOffset[sender]++;
}
}
Name syncPrefix;
Name userPrefix[3];
shared_ptr<DummyClientFace> faces[3];
shared_ptr<Handler> handler[3];
size_t readInterestOffset[3];
size_t readDataOffset[3];
};
BOOST_FIXTURE_TEST_SUITE(LogicTests, LogicFixture)
void
onUpdate(const vector<MissingDataInfo>& v)
{
}
BOOST_AUTO_TEST_CASE(Constructor)
{
Name syncPrefix("/ndn/broadcast/sync");
Name userPrefix("/user");
shared_ptr<DummyClientFace> face = makeDummyClientFace(ref(io), {true, true});
BOOST_REQUIRE_NO_THROW(Logic(ref(*face), syncPrefix, userPrefix,
bind(onUpdate, _1)));
}
BOOST_AUTO_TEST_CASE(TwoBasic)
{
handler[0] = make_shared<Handler>(ref(*faces[0]), syncPrefix, userPrefix[0]);
advanceClocks(ndn::time::milliseconds(10), 10);
handler[1] = make_shared<Handler>(ref(*faces[1]), syncPrefix, userPrefix[1]);
advanceClocks(ndn::time::milliseconds(10), 10);
handler[0]->updateSeqNo(1);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1);
advanceClocks(ndn::time::milliseconds(10), 10);
handler[0]->updateSeqNo(2);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 2);
advanceClocks(ndn::time::milliseconds(10), 10);
handler[1]->updateSeqNo(2);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2);
}
BOOST_AUTO_TEST_CASE(ThreeBasic)
{
handler[0] = make_shared<Handler>(ref(*faces[0]), syncPrefix, userPrefix[0]);
advanceClocks(ndn::time::milliseconds(10), 10);
handler[1] = make_shared<Handler>(ref(*faces[1]), syncPrefix, userPrefix[1]);
advanceClocks(ndn::time::milliseconds(10), 10);
handler[2] = make_shared<Handler>(ref(*faces[2]), syncPrefix, userPrefix[2]);
advanceClocks(ndn::time::milliseconds(10), 20);
handler[0]->updateSeqNo(1);
for (int i = 0; i < 70; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1);
BOOST_CHECK_EQUAL(handler[2]->map[handler[0]->logic.getSessionName()], 1);
handler[1]->updateSeqNo(2);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2);
BOOST_CHECK_EQUAL(handler[2]->map[handler[1]->logic.getSessionName()], 2);
handler[2]->updateSeqNo(4);
for (int i = 0; i < 100; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[0]->map[handler[2]->logic.getSessionName()], 4);
BOOST_CHECK_EQUAL(handler[1]->map[handler[2]->logic.getSessionName()], 4);
}
BOOST_AUTO_TEST_CASE(ResetRecover)
{
handler[0] = make_shared<Handler>(ref(*faces[0]), syncPrefix, userPrefix[0]);
advanceClocks(ndn::time::milliseconds(10), 10);
handler[1] = make_shared<Handler>(ref(*faces[1]), syncPrefix, userPrefix[1]);
advanceClocks(ndn::time::milliseconds(10), 30);
handler[0]->updateSeqNo(1);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1);
handler[1]->updateSeqNo(2);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2);
advanceClocks(ndn::time::milliseconds(10), 10);
handler[2] = make_shared<Handler>(ref(*faces[2]), syncPrefix, userPrefix[2]);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1);
BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2);
handler[2]->updateSeqNo(4);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[1]->map[handler[2]->logic.getSessionName()], 4);
BOOST_CHECK_EQUAL(handler[0]->map[handler[2]->logic.getSessionName()], 4);
}
BOOST_AUTO_TEST_CASE(RecoverConflict)
{
handler[0] = make_shared<Handler>(ref(*faces[0]), syncPrefix, userPrefix[0]);
advanceClocks(ndn::time::milliseconds(10), 10);
handler[1] = make_shared<Handler>(ref(*faces[1]), syncPrefix, userPrefix[1]);
advanceClocks(ndn::time::milliseconds(10), 10);
handler[2] = make_shared<Handler>(ref(*faces[2]), syncPrefix, userPrefix[2]);
advanceClocks(ndn::time::milliseconds(10), 30);
handler[0]->updateSeqNo(1);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1);
BOOST_CHECK_EQUAL(handler[2]->map[handler[0]->logic.getSessionName()], 1);
handler[1]->updateSeqNo(2);
handler[2]->updateSeqNo(4);
for (int i = 0; i < 75; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 2);
BOOST_CHECK_EQUAL(handler[0]->map[handler[2]->logic.getSessionName()], 4);
BOOST_CHECK_EQUAL(handler[1]->map[handler[2]->logic.getSessionName()], 4);
BOOST_CHECK_EQUAL(handler[2]->map[handler[1]->logic.getSessionName()], 2);
}
BOOST_AUTO_TEST_CASE(MultipleUserUnderOneLogic)
{
handler[0] = make_shared<Handler>(ref(*faces[0]), syncPrefix, userPrefix[0]);
advanceClocks(ndn::time::milliseconds(10), 10);
handler[1] = make_shared<Handler>(ref(*faces[1]), syncPrefix, userPrefix[2]);
advanceClocks(ndn::time::milliseconds(10), 10);
handler[0]->logic.addUserNode(userPrefix[1]);
for (int i = 0; i < 20; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
handler[0]->updateSeqNo(1);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName()], 1);
handler[0]->logic.updateSeqNo(2, userPrefix[1]);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[1]->map[handler[0]->logic.getSessionName(userPrefix[1])], 2);
handler[1]->updateSeqNo(4);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[0]->map[handler[1]->logic.getSessionName()], 4);
handler[0]->logic.removeUserNode(userPrefix[0]);
for (int i = 0; i < 100; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(handler[1]->logic.getSessionNames().size(), 2);
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace test
} // namespace chronosync
+3 -3
View File
@@ -50,11 +50,11 @@ public:
std::map<Name, SeqNo> map;
};
class LogicFixture
class MultiUserFixture
{
public:
LogicFixture()
MultiUserFixture()
: syncPrefix("/ndn/broadcast/sync")
, scheduler(io)
{
@@ -75,7 +75,7 @@ public:
shared_ptr<Handler> handler;
};
BOOST_FIXTURE_TEST_SUITE(LogicTests, LogicFixture)
BOOST_FIXTURE_TEST_SUITE(MultiUserTests, MultiUserFixture)
BOOST_AUTO_TEST_CASE(ThreeUserNode)
{
@@ -18,7 +18,8 @@
*/
#include "socket.hpp"
#include "../unit-test-time-fixture.hpp"
#include <ndn-cxx/util/dummy-client-face.hpp>
#include "boost-test.hpp"
namespace chronosync {
@@ -27,6 +28,9 @@ namespace test {
using std::string;
using std::vector;
using std::map;
using ndn::util::DummyClientFace;
using ndn::util::makeDummyClientFace;
/**
* @brief Emulate an app that use the Socket class
@@ -39,7 +43,7 @@ class SocketTestApp : noncopyable
public:
SocketTestApp(const Name& syncPrefix,
const Name& userPrefix,
ndn::Face& face,
DummyClientFace& face,
bool isNum)
: sum(0)
, socket(syncPrefix,
@@ -137,21 +141,51 @@ public:
Socket socket;
};
class SocketFixture
class SocketFixture : public ndn::tests::UnitTestTimeFixture
{
public:
SocketFixture()
: syncPrefix("/ndn/broadcast/sync")
, scheduler(io)
{
syncPrefix.appendVersion();
userPrefix[0] = Name("/user0");
userPrefix[1] = Name("/user1");
userPrefix[2] = Name("/user2");
faces[0] = make_shared<ndn::Face>(ref(io));
faces[1] = make_shared<ndn::Face>(ref(io));
faces[2] = make_shared<ndn::Face>(ref(io));
faces[0] = makeDummyClientFace(ref(io), {true, true});
faces[1] = makeDummyClientFace(ref(io), {true, true});
faces[2] = makeDummyClientFace(ref(io), {true, true});
for (int i = 0; i < 3; i++) {
readInterestOffset[i] = 0;
readDataOffset[i] = 0;
}
}
void
passPacket()
{
for (int i = 0; i < 3; i++)
checkFace(i);
}
void
checkFace(int sender)
{
while (faces[sender]->sentInterests.size() > readInterestOffset[sender]) {
for (int i = 0; i < 3; i++) {
if (sender != i)
faces[i]->receive(faces[sender]->sentInterests[readInterestOffset[sender]]);
}
readInterestOffset[sender]++;
}
while (faces[sender]->sentDatas.size() > readDataOffset[sender]) {
for (int i = 0; i < 3; i++) {
if (sender != i)
faces[i]->receive(faces[sender]->sentDatas[readDataOffset[sender]]);
}
readDataOffset[sender]++;
}
}
void
@@ -190,34 +224,15 @@ public:
app[idx]->setNum(dataName, buf, size);
}
void
check(int round)
{
BOOST_CHECK_EQUAL(app[0]->toString(), app[1]->toString());
BOOST_CHECK_EQUAL(app[0]->toString(), app[2]->toString());
}
void
check2Num(int num)
{
BOOST_CHECK_EQUAL(app[0]->sum, app[1]->sum);
BOOST_CHECK_EQUAL(app[1]->sum, num);
}
void
terminate()
{
io.stop();
}
Name syncPrefix;
Name userPrefix[3];
Name sessionName[3];
boost::asio::io_service io;
shared_ptr<ndn::Face> faces[3];
ndn::Scheduler scheduler;
shared_ptr<DummyClientFace> faces[3];
shared_ptr<SocketTestApp> app[3];
size_t readInterestOffset[3];
size_t readDataOffset[3];
};
@@ -226,105 +241,116 @@ BOOST_FIXTURE_TEST_SUITE(SocketTests, SocketFixture)
BOOST_AUTO_TEST_CASE(BasicData)
{
scheduler.scheduleEvent(ndn::time::milliseconds(0),
bind(&SocketFixture::createSocket, this, 0, false));
scheduler.scheduleEvent(ndn::time::milliseconds(50),
bind(&SocketFixture::createSocket, this, 1, false));
scheduler.scheduleEvent(ndn::time::milliseconds(100),
bind(&SocketFixture::createSocket, this, 2, false));
createSocket(0, false);
advanceClocks(ndn::time::milliseconds(10), 5);
createSocket(1, false);
advanceClocks(ndn::time::milliseconds(10), 5);
createSocket(2, false);
advanceClocks(ndn::time::milliseconds(10), 5);
string data0 = "Very funny Scotty, now beam down my clothes";
scheduler.scheduleEvent(ndn::time::milliseconds(150),
bind(&SocketFixture::publishAppData, this, 0, data0));
scheduler.scheduleEvent(ndn::time::milliseconds(1150),
bind(&SocketFixture::setAppData, this, 0, 1, data0));
scheduler.scheduleEvent(ndn::time::milliseconds(1160),
bind(&SocketFixture::check, this, 1));
publishAppData(0, data0);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
setAppData(0, 1, data0);
advanceClocks(ndn::time::milliseconds(10), 1);
BOOST_CHECK_EQUAL(app[0]->toString(), app[1]->toString());
BOOST_CHECK_EQUAL(app[0]->toString(), app[2]->toString());
string data1 = "Yes, give me that ketchup";
string data2 = "Don't look conspicuous, it draws fire";
scheduler.scheduleEvent(ndn::time::milliseconds(1170),
bind(&SocketFixture::publishAppData, this, 0, data1));
scheduler.scheduleEvent(ndn::time::milliseconds(1180),
bind(&SocketFixture::publishAppData, this, 0, data2));
scheduler.scheduleEvent(ndn::time::milliseconds(2150),
bind(&SocketFixture::setAppData, this, 0, 2, data1));
scheduler.scheduleEvent(ndn::time::milliseconds(2160),
bind(&SocketFixture::setAppData, this, 0, 3, data2));
scheduler.scheduleEvent(ndn::time::milliseconds(2170),
bind(&SocketFixture::check, this, 2));
publishAppData(0, data1);
advanceClocks(ndn::time::milliseconds(10), 1);
publishAppData(0, data2);
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
setAppData(0, 2, data1);
advanceClocks(ndn::time::milliseconds(10), 1);
setAppData(0, 3, data2);
advanceClocks(ndn::time::milliseconds(10), 1);
BOOST_CHECK_EQUAL(app[0]->toString(), app[1]->toString());
BOOST_CHECK_EQUAL(app[0]->toString(), app[2]->toString());
string data3 = "You surf the Internet, I surf the real world";
string data4 = "I got a fortune cookie once that said 'You like Chinese food'";
string data5 = "Real men wear pink. Why? Because their wives make them";
scheduler.scheduleEvent(ndn::time::milliseconds(3180),
bind(&SocketFixture::publishAppData, this, 2, data3));
scheduler.scheduleEvent(ndn::time::milliseconds(3200),
bind(&SocketFixture::publishAppData, this, 1, data4));
scheduler.scheduleEvent(ndn::time::milliseconds(3210),
bind(&SocketFixture::publishAppData, this, 1, data5));
scheduler.scheduleEvent(ndn::time::milliseconds(4710),
bind(&SocketFixture::setAppData, this, 2, 1, data3));
scheduler.scheduleEvent(ndn::time::milliseconds(4720),
bind(&SocketFixture::setAppData, this, 1, 1, data4));
scheduler.scheduleEvent(ndn::time::milliseconds(4730),
bind(&SocketFixture::setAppData, this, 1, 2, data5));
scheduler.scheduleEvent(ndn::time::milliseconds(4800),
bind(&SocketFixture::check, this, 3));
publishAppData(2, data3);
advanceClocks(ndn::time::milliseconds(10), 2);
publishAppData(1, data4);
advanceClocks(ndn::time::milliseconds(10), 1);
publishAppData(1, data5);
for (int i = 0; i < 100; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
setAppData(2, 1, data3);
advanceClocks(ndn::time::milliseconds(10), 1);
setAppData(1, 1, data4);
advanceClocks(ndn::time::milliseconds(10), 1);
setAppData(1, 2, data5);
advanceClocks(ndn::time::milliseconds(10), 7);
BOOST_CHECK_EQUAL(app[0]->toString(), app[1]->toString());
BOOST_CHECK_EQUAL(app[0]->toString(), app[2]->toString());
// not sure weither this is simultanous data generation from multiple sources
string data6 = "Shakespeare says: 'Prose before hos.'";
string data7 = "Pick good people, talent never wears out";
scheduler.scheduleEvent(ndn::time::milliseconds(5500),
bind(&SocketFixture::publishAppData, this, 0, data6));
scheduler.scheduleEvent(ndn::time::milliseconds(5500),
bind(&SocketFixture::publishAppData, this, 1, data7));
scheduler.scheduleEvent(ndn::time::milliseconds(6800),
bind(&SocketFixture::setAppData, this, 0, 4, data6));
scheduler.scheduleEvent(ndn::time::milliseconds(6800),
bind(&SocketFixture::setAppData, this, 1, 3, data7));
scheduler.scheduleEvent(ndn::time::milliseconds(6900),
bind(&SocketFixture::check, this, 4));
publishAppData(0, data6);
publishAppData(1, data7);
scheduler.scheduleEvent(ndn::time::milliseconds(7000),
bind(&SocketFixture::terminate, this));
for (int i = 0; i < 100; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
setAppData(0, 4, data6);
setAppData(1, 3, data7);
io.run();
BOOST_CHECK_EQUAL(app[0]->toString(), app[1]->toString());
BOOST_CHECK_EQUAL(app[0]->toString(), app[2]->toString());
}
BOOST_AUTO_TEST_CASE(BasicNumber)
{
scheduler.scheduleEvent(ndn::time::milliseconds(0),
bind(&SocketFixture::createSocket, this, 0, true));
scheduler.scheduleEvent(ndn::time::milliseconds(50),
bind(&SocketFixture::createSocket, this, 1, true));
createSocket(0, true);
advanceClocks(ndn::time::milliseconds(10), 5);
createSocket(1, true);
advanceClocks(ndn::time::milliseconds(10), 5);
uint32_t num1[5] = {0, 1, 2, 3, 4};
uint8_t* buf1 = reinterpret_cast<uint8_t*>(num1);
size_t size1 = sizeof(num1);
scheduler.scheduleEvent(ndn::time::milliseconds(100),
bind(&SocketFixture::publishAppNum, this, 0, buf1, size1));
scheduler.scheduleEvent(ndn::time::milliseconds(150),
bind(&SocketFixture::setAppNum, this, 0, 0, buf1, size1));
scheduler.scheduleEvent(ndn::time::milliseconds(1000),
bind(&SocketFixture::check2Num, this, 10));
publishAppNum(0, buf1, size1);
advanceClocks(ndn::time::milliseconds(10), 5);
setAppNum(0, 0, buf1, size1);
for (int i = 0; i < 100; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(app[0]->sum, app[1]->sum);
BOOST_CHECK_EQUAL(app[1]->sum, 10);
uint32_t num2[5] = {9, 7, 2, 1, 1};
uint8_t* buf2 = reinterpret_cast<uint8_t*>(num2);
size_t size2 = sizeof(num2);
scheduler.scheduleEvent(ndn::time::milliseconds(1100),
bind(&SocketFixture::publishAppNum, this, 1, buf2, size2));
scheduler.scheduleEvent(ndn::time::milliseconds(1150),
bind(&SocketFixture::setAppNum, this, 1, 0, buf2, size2));
scheduler.scheduleEvent(ndn::time::milliseconds(2000),
bind(&SocketFixture::check2Num, this, 30));
publishAppNum(1, buf2, size2);
setAppNum(1, 0, buf2, size2);
scheduler.scheduleEvent(ndn::time::milliseconds(7000),
bind(&SocketFixture::terminate, this));
io.run();
for (int i = 0; i < 50; i++) {
advanceClocks(ndn::time::milliseconds(2), 10);
passPacket();
}
BOOST_CHECK_EQUAL(app[0]->sum, app[1]->sum);
BOOST_CHECK_EQUAL(app[1]->sum, 30);
}
BOOST_AUTO_TEST_SUITE_END()