/* 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 . */ /** @file capability.cpp * @author Vladislav Gluhovsky * @date May 2015 */ #include #include #include #include #include #include #include #include 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 { VerbosityHolder(): oldLogVerbosity(g_logVerbosity) { g_logVerbosity = 10; } ~VerbosityHolder() { g_logVerbosity = oldLogVerbosity; } int oldLogVerbosity; }; class TestCapability: public Capability { public: TestCapability(Session* _s, HostCapabilityFace* _h, unsigned _idOffset, CapDesc const&): 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; sealAndSend(prep(s, UserPacket, 1) << _i); } protected: virtual bool interpret(unsigned _id, RLP const& _r) override; int m_cntReceivedMessages; int m_testSum; }; bool TestCapability::interpret(unsigned _id, RLP const& _r) { cnote << "Capability::interpret(): custom message received"; ++m_cntReceivedMessages; m_testSum += _r[0].toInt(); BOOST_ASSERT(_id == UserPacket); return (_id == UserPacket); } class TestHostCapability: public HostCapability, 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().get()->sendTestMessage(_x); } std::pair retrieveTestData(NodeId const& _id) { int cnt = 0; int checksum = 0; for (auto i: peerSessions()) if (_id == i.second->id) { cnt += i.first->cap().get()->countReceivedMessages(); checksum += i.first->cap().get()->testSum(); } return std::pair(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 && (!host1.isStarted() || !host2.isStarted()); i += step) 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 && (!host1.peerCount() || !host2.peerCount()); i += step) 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 testData = thc1->retrieveTestData(host2.id()); BOOST_REQUIRE_EQUAL(target, testData.first); BOOST_REQUIRE_EQUAL(checksum, testData.second); } BOOST_AUTO_TEST_SUITE_END()