blob: 7c8c300d3b9811138c4ae16a3a51b23850c22026 [file] [log] [blame]
/* -*- 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 <boost/test/unit_test.hpp>
#include "sync-validator.h"
#include <boost/lexical_cast.hpp>
#include <boost/asio.hpp>
#include <ndn-cxx/util/scheduler.hpp>
BOOST_AUTO_TEST_SUITE(TestSyncValidator)
void
onValidated(const ndn::shared_ptr<const ndn::Data>& data)
{
BOOST_CHECK(true);
}
void
onValidationFailed(const ndn::shared_ptr<const ndn::Data>& data,
const std::string& failureInfo)
{
BOOST_CHECK(false);
}
void
onValidated2(const ndn::shared_ptr<const ndn::Data>& data)
{
BOOST_CHECK(false);
}
void
onValidationFailed2(const ndn::shared_ptr<const ndn::Data>& data,
const std::string& failureInfo)
{
BOOST_CHECK(true);
}
void
publishData(const uint8_t* buf, size_t len, int freshness)
{
}
BOOST_AUTO_TEST_CASE (Graph)
{
using namespace Sync;
using namespace ndn;
Name prefix("/Sync/TestSyncValidator/AddEdge");
KeyChain keychain;
Name identity1("/TestSyncValidator/AddEdge-1/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName1 = keychain.createIdentity(identity1);
shared_ptr<IdentityCertificate> anchor = keychain.getCertificate(certName1);
Name identity2("/TestSyncValidator/AddEdge-2/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName2 = keychain.createIdentity(identity2);
shared_ptr<IdentityCertificate> introducer = keychain.getCertificate(certName2);
Name identity3("/TestSyncValidator/AddEdge-3/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName3 = keychain.createIdentity(identity3);
shared_ptr<IdentityCertificate> introducee = keychain.getCertificate(certName3);
Name identity4("/TestSyncValidator/AddEdge-4/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName4 = keychain.createIdentity(identity4);
shared_ptr<IdentityCertificate> introducer2 = keychain.getCertificate(certName4);
Name identity5("/TestSyncValidator/AddEdge-5/" + boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName5 = keychain.createIdentity(identity5);
shared_ptr<IdentityCertificate> introducee2 = keychain.getCertificate(certName5);
shared_ptr<boost::asio::io_service> ioService = make_shared<boost::asio::io_service>();
shared_ptr<Face> face = make_shared<Face>(ref(*ioService));
shared_ptr<SecRuleRelative> rule;
SyncValidator validator(prefix, *anchor, *face,
bind(&publishData, _1, _2, _3),
rule);
validator.addParticipant(*introducer);
BOOST_CHECK(validator.canTrust(certName2));
IntroCertificate introCert(prefix, *introducee, certName2.getPrefix(-1));
keychain.sign(introCert, certName2);
validator.addParticipant(introCert);
BOOST_CHECK(validator.canTrust(certName3));
IntroCertificate introCert1(prefix, *anchor, certName3.getPrefix(-1));
keychain.sign(introCert1, certName3);
validator.addParticipant(introCert1);
validator.setAnchor(*introducer);
BOOST_CHECK(validator.canTrust(certName2));
BOOST_CHECK(validator.canTrust(certName3));
BOOST_CHECK(validator.canTrust(certName1));
IntroCertificate introCert2(prefix, *introducee2, certName4.getPrefix(-1));
keychain.sign(introCert2, certName4);
validator.addParticipant(introCert2);
BOOST_CHECK(validator.canTrust(certName5) == false);
BOOST_CHECK(validator.canTrust(certName4) == false);
IntroCertificate introCert3(prefix, *introducee, certName5.getPrefix(-1));
keychain.sign(introCert3, certName5);
validator.addParticipant(introCert3);
BOOST_CHECK(validator.canTrust(certName5) == false);
BOOST_CHECK(validator.canTrust(certName4) == false);
validator.setAnchor(*introducee2);
BOOST_CHECK(validator.canTrust(certName1));
BOOST_CHECK(validator.canTrust(certName2));
BOOST_CHECK(validator.canTrust(certName3));
BOOST_CHECK(validator.canTrust(certName4) == false);
BOOST_CHECK(validator.canTrust(certName5));
keychain.deleteIdentity(identity1);
keychain.deleteIdentity(identity2);
keychain.deleteIdentity(identity3);
keychain.deleteIdentity(identity4);
keychain.deleteIdentity(identity5);
}
BOOST_AUTO_TEST_CASE (OfflineValidate)
{
using namespace Sync;
using namespace ndn;
Name prefix("/Sync/TestSyncValidator/OfflineValidate");
KeyChain keychain;
Name identity1("/TestSyncValidator/OfflineValidate-1/"
+ boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName1 = keychain.createIdentity(identity1);
shared_ptr<IdentityCertificate> anchor = keychain.getCertificate(certName1);
Name identity2("/TestSyncValidator/OfflineValidate-2/"
+ boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName2 = keychain.createIdentity(identity2);
shared_ptr<IdentityCertificate> introducer = keychain.getCertificate(certName2);
Name identity3("/TestSyncValidator/OfflineValidate-3/"
+ boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName3 = keychain.createIdentity(identity3);
shared_ptr<IdentityCertificate> introducee = keychain.getCertificate(certName3);
Name identity4("/TestSyncValidator/OfflineValidate-4/"
+ boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName4 = keychain.createIdentity(identity4);
shared_ptr<IdentityCertificate> introducer2 = keychain.getCertificate(certName4);
Name identity5("/TestSyncValidator/OfflineValidate-5/"
+ boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName5 = keychain.createIdentity(identity5);
shared_ptr<IdentityCertificate> introducee2 = keychain.getCertificate(certName5);
shared_ptr<boost::asio::io_service> ioService = make_shared<boost::asio::io_service>();
shared_ptr<Face> face = make_shared<Face>(ref(*ioService));
shared_ptr<SecRuleRelative> rule;
SyncValidator validator(prefix, *anchor, *face,
bind(&publishData, _1, _2, _3),
rule);
validator.addParticipant(*introducer);
BOOST_CHECK(validator.canTrust(certName2));
IntroCertificate introCert(prefix, *introducee, certName2.getPrefix(-1));
keychain.sign(introCert, certName2);
validator.addParticipant(introCert);
BOOST_CHECK(validator.canTrust(certName3));
IntroCertificate introCert2(prefix, *introducee2, certName4.getPrefix(-1));
keychain.sign(introCert2, certName4);
validator.addParticipant(introCert2);
BOOST_CHECK(validator.canTrust(certName5) == false);
BOOST_CHECK(validator.canTrust(certName4) == false);
validator.setAnchor(*introducer2);
BOOST_CHECK(validator.canTrust(certName1) == false);
BOOST_CHECK(validator.canTrust(certName2) == false);
BOOST_CHECK(validator.canTrust(certName3) == false);
BOOST_CHECK(validator.canTrust(certName4));
BOOST_CHECK(validator.canTrust(certName5));
Name dataName1 = prefix;
dataName1.append("data-1");
shared_ptr<Data> data1 = make_shared<Data>(dataName1);
keychain.sign(*data1, certName5);
validator.validate(*data1,
bind(&onValidated, _1),
bind(&onValidationFailed, _1, _2));
Name dataName2 = prefix;
dataName2.append("data-2");
shared_ptr<Data> data2 = make_shared<Data>(dataName2);
keychain.sign(*data2, certName1);
validator.validate(*data2,
bind(&onValidated2, _1),
bind(&onValidationFailed2, _1, _2));
// ioService->run();
keychain.deleteIdentity(identity1);
keychain.deleteIdentity(identity2);
keychain.deleteIdentity(identity3);
keychain.deleteIdentity(identity4);
keychain.deleteIdentity(identity5);
}
struct FacesFixture
{
FacesFixture()
: regPrefixId(0)
, regPrefixId2(0)
{}
void
onInterest(ndn::shared_ptr<ndn::Face> face, ndn::shared_ptr<ndn::Data> data)
{
face->put(*data);
face->unsetInterestFilter(regPrefixId);
}
void
onInterest2(ndn::shared_ptr<ndn::Face> face, ndn::shared_ptr<ndn::Data> data)
{
face->put(*data);
face->unsetInterestFilter(regPrefixId2);
}
void
onRegFailed()
{}
void
validate(ndn::shared_ptr<Sync::SyncValidator> validator, ndn::shared_ptr<ndn::Data> data,
const ndn::Name& certName3, const ndn::Name& certName4)
{
validator->validate(*data,
bind(&onValidated, _1),
bind(&onValidationFailed, _1, _2));
BOOST_CHECK(validator->canTrust(certName3));
BOOST_CHECK(validator->canTrust(certName4));
}
void
terminate(ndn::shared_ptr<ndn::Face> face)
{
face->getIoService().stop();
}
const ndn::RegisteredPrefixId* regPrefixId;
const ndn::RegisteredPrefixId* regPrefixId2;
};
BOOST_FIXTURE_TEST_CASE(OnlineValidate, FacesFixture)
{
using namespace Sync;
using namespace ndn;
Name prefix("/Sync/TestSyncValidator/OnlineValidate");
KeyChain keychain;
Name identity1("/TestSyncValidator/OnlineValidate-1/"
+ boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName1 = keychain.createIdentity(identity1);
shared_ptr<IdentityCertificate> anchor = keychain.getCertificate(certName1);
Name identity2("/TestSyncValidator/OnlineValidate-2/"
+ boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName2 = keychain.createIdentity(identity2);
shared_ptr<IdentityCertificate> introducer = keychain.getCertificate(certName2);
Name identity3("/TestSyncValidator/OnlineValidate-3/"
+ boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName3 = keychain.createIdentity(identity3);
shared_ptr<IdentityCertificate> introducee = keychain.getCertificate(certName3);
Name identity4("/TestSyncValidator/OnlineValidate-4/"
+ boost::lexical_cast<std::string>(ndn::time::toUnixTimestamp(ndn::time::system_clock::now()).count()));
Name certName4 = keychain.createIdentity(identity4);
shared_ptr<IdentityCertificate> introducee2 = keychain.getCertificate(certName4);
shared_ptr<boost::asio::io_service> ioService = make_shared<boost::asio::io_service>();
shared_ptr<Face> face = make_shared<Face>(ref(*ioService));
shared_ptr<Face> face2 = make_shared<Face>(ref(*ioService));
shared_ptr<SecRuleRelative> rule;
shared_ptr<SyncValidator> validator = shared_ptr<SyncValidator>
(new SyncValidator(prefix, *anchor, *face2, bind(&publishData, _1, _2, _3), rule));
validator->addParticipant(*introducer);
BOOST_CHECK(validator->canTrust(certName2));
shared_ptr<IntroCertificate> introCert = shared_ptr<IntroCertificate>(new IntroCertificate(prefix, *introducee, certName2.getPrefix(-1)));
keychain.sign(*introCert, certName2);
BOOST_CHECK(validator->canTrust(certName3) == false);
shared_ptr<IntroCertificate> introCert2 = shared_ptr<IntroCertificate>(new IntroCertificate(prefix, *introducee2, certName3.getPrefix(-1)));
keychain.sign(*introCert2, certName3);
BOOST_CHECK(validator->canTrust(certName4) == false);
Name dataName1 = prefix;
dataName1.append("data-1");
shared_ptr<Data> data1 = make_shared<Data>(dataName1);
keychain.sign(*data1, certName4);
ndn::Scheduler scheduler(*ioService);
scheduler.scheduleEvent(time::seconds(1),
bind(&FacesFixture::terminate, this, face));
regPrefixId = face->setInterestFilter(introCert->getName().getPrefix(-1),
bind(&FacesFixture::onInterest, this, face, introCert),
bind(&FacesFixture::onRegFailed, this));
regPrefixId2 = face->setInterestFilter(introCert2->getName().getPrefix(-1),
bind(&FacesFixture::onInterest2, this, face, introCert2),
bind(&FacesFixture::onRegFailed, this));
scheduler.scheduleEvent(time::milliseconds(200),
bind(&FacesFixture::validate, this,
validator, data1, certName3, certName4));
keychain.deleteIdentity(identity1);
keychain.deleteIdentity(identity2);
keychain.deleteIdentity(identity3);
keychain.deleteIdentity(identity4);
}
BOOST_AUTO_TEST_SUITE_END()