You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
4.3 KiB
158 lines
4.3 KiB
10 years ago
|
/*
|
||
|
This file is part of cpp-ethereum.
|
||
|
|
||
|
cpp-ethereum 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.
|
||
|
|
||
|
cpp-ethereum 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
/** @file capability.cpp
|
||
|
* @author Vladislav Gluhovsky <vlad@ethdev.com>
|
||
|
* @date May 2015
|
||
|
*/
|
||
|
|
||
|
#include <boost/test/unit_test.hpp>
|
||
|
#include <chrono>
|
||
|
#include <thread>
|
||
|
#include <libp2p/Common.h>
|
||
|
#include <libp2p/Host.h>
|
||
|
#include <libp2p/Session.h>
|
||
|
#include <libp2p/Capability.h>
|
||
|
#include <libp2p/HostCapability.h>
|
||
|
|
||
|
using namespace std;
|
||
|
using namespace dev;
|
||
|
using namespace dev::p2p;
|
||
|
|
||
|
struct P2PFixture
|
||
|
{
|
||
|
P2PFixture() { dev::p2p::NodeIPEndpoint::test_allowLocal = true; }
|
||
|
~P2PFixture() { dev::p2p::NodeIPEndpoint::test_allowLocal = false; }
|
||
|
};
|
||
|
|
||
|
struct VerbosityHolder
|
||
|
{
|
||
|
int m_oldLogVerbosity;
|
||
|
VerbosityHolder() : m_oldLogVerbosity(g_logVerbosity) { g_logVerbosity = 10; }
|
||
|
~VerbosityHolder() { g_logVerbosity = m_oldLogVerbosity; }
|
||
|
};
|
||
|
|
||
|
class TestCapability : public Capability
|
||
|
{
|
||
|
int m_cntReceivedMessages;
|
||
|
int m_testSum;
|
||
|
|
||
|
public:
|
||
|
TestCapability(Session* _s, HostCapabilityFace* _h, unsigned _idOffset) : Capability(_s, _h, _idOffset), m_cntReceivedMessages(0), m_testSum(0) {}
|
||
|
virtual ~TestCapability() {}
|
||
|
int countReceivedMessages() { return m_cntReceivedMessages; }
|
||
|
int testSum() { return m_testSum; }
|
||
|
static std::string name() { return "test"; }
|
||
|
static u256 version() { return 2; }
|
||
|
static unsigned messageCount() { return UserPacket + 1; }
|
||
|
|
||
|
void sendTestMessage(int _i)
|
||
|
{
|
||
|
RLPStream s;
|
||
|
prep(s, UserPacket, 1);
|
||
|
s << _i;
|
||
|
sealAndSend(s);
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
virtual bool interpret(unsigned _id, RLP const& _r) override
|
||
|
{
|
||
|
cnote << "Capability::interpret(): custom message received";
|
||
|
BOOST_REQUIRE_EQUAL(_id, UserPacket);
|
||
|
++m_cntReceivedMessages;
|
||
|
int i = _r[0].toInt();
|
||
|
m_testSum += i;
|
||
|
return true;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
class TestHostCapability : public HostCapability<TestCapability>, public Worker
|
||
|
{
|
||
|
public:
|
||
|
TestHostCapability() : Worker("test") {}
|
||
|
virtual ~TestHostCapability() {}
|
||
|
|
||
|
void sendTestMessage(NodeId const& _id, int _x)
|
||
|
{
|
||
|
for (auto i: peerSessions())
|
||
|
if (_id == i.second->id)
|
||
|
i.first->cap<TestCapability>().get()->sendTestMessage(_x);
|
||
|
}
|
||
|
|
||
|
std::pair<int, int> retrieveTestData(NodeId const& _id)
|
||
|
{
|
||
|
int cnt = 0;
|
||
|
int checksum = 0;
|
||
|
for (auto i : peerSessions())
|
||
|
if (_id == i.second->id)
|
||
|
{
|
||
|
cnt += i.first->cap<TestCapability>().get()->countReceivedMessages();
|
||
|
checksum += i.first->cap<TestCapability>().get()->testSum();
|
||
|
}
|
||
|
|
||
|
return std::pair<int, int>(cnt, checksum);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
BOOST_FIXTURE_TEST_SUITE(p2pCapability, P2PFixture)
|
||
|
|
||
|
BOOST_AUTO_TEST_CASE(capability)
|
||
|
{
|
||
|
VerbosityHolder verbosityHolder;
|
||
|
cnote << "Testing Capability...";
|
||
|
|
||
|
const char* const localhost = "127.0.0.1";
|
||
|
NetworkPreferences prefs1(localhost, 30301, false);
|
||
|
NetworkPreferences prefs2(localhost, 30302, false);
|
||
|
|
||
|
Host host1("Test", prefs1);
|
||
|
auto thc1 = host1.registerCapability(new TestHostCapability());
|
||
|
host1.start();
|
||
|
|
||
|
Host host2("Test", prefs2);
|
||
|
auto thc2 = host2.registerCapability(new TestHostCapability());
|
||
|
host2.start();
|
||
|
|
||
|
int const step = 10;
|
||
|
|
||
|
for (int i = 0; i < 3000; i += step)
|
||
|
if (!host1.isStarted() || !host2.isStarted())
|
||
|
this_thread::sleep_for(chrono::milliseconds(step));
|
||
|
|
||
|
BOOST_REQUIRE(host1.isStarted() && host2.isStarted());
|
||
|
host1.requirePeer(host2.id(), NodeIPEndpoint(bi::address::from_string(localhost), prefs2.listenPort, prefs2.listenPort));
|
||
|
|
||
|
for (int i = 0; i < 3000; i += step)
|
||
|
if (!host1.peerCount() || !host2.peerCount())
|
||
|
this_thread::sleep_for(chrono::milliseconds(step));
|
||
|
|
||
|
BOOST_REQUIRE(host1.peerCount() > 0 && host2.peerCount() > 0);
|
||
|
|
||
|
int const target = 7;
|
||
|
int checksum = 0;
|
||
|
for (int i = 0; i < target; checksum += i++)
|
||
|
thc2->sendTestMessage(host1.id(), i);
|
||
|
|
||
|
this_thread::sleep_for(chrono::seconds(1));
|
||
|
std::pair<int, int> testData = thc1->retrieveTestData(host2.id());
|
||
|
BOOST_REQUIRE_EQUAL(target, testData.first);
|
||
|
BOOST_REQUIRE_EQUAL(checksum, testData.second);
|
||
|
}
|
||
|
|
||
|
BOOST_AUTO_TEST_SUITE_END()
|
||
|
|
||
|
|