From 890bf3cce1352b703be0f10ea4d40a8c7440afed Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Wed, 21 Jan 2015 17:28:49 -0800 Subject: [PATCH] Add PeerFinder Logic backoff unit test --- Builds/VisualStudio2013/RippleD.vcxproj | 3 + .../VisualStudio2013/RippleD.vcxproj.filters | 3 + src/ripple/peerfinder/impl/Logic.h | 9 + .../peerfinder/tests/PeerFinder_test.cpp | 160 ++++++++++++++++++ src/ripple/unity/peerfinder.cpp | 1 + 5 files changed, 176 insertions(+) create mode 100644 src/ripple/peerfinder/tests/PeerFinder_test.cpp diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj index 10a927a592..a08b521585 100755 --- a/Builds/VisualStudio2013/RippleD.vcxproj +++ b/Builds/VisualStudio2013/RippleD.vcxproj @@ -2709,6 +2709,9 @@ True + + True + diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters index eccd596e5f..6726fc089b 100755 --- a/Builds/VisualStudio2013/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters @@ -3849,6 +3849,9 @@ ripple\peerfinder\tests + + ripple\peerfinder\tests + ripple\protocol diff --git a/src/ripple/peerfinder/impl/Logic.h b/src/ripple/peerfinder/impl/Logic.h index a4c90d3b11..f0b3e67bb5 100644 --- a/src/ripple/peerfinder/impl/Logic.h +++ b/src/ripple/peerfinder/impl/Logic.h @@ -179,6 +179,15 @@ public: state->counts.onConfig (state->config); } + void + addFixedPeer (std::string const& name, + beast::IP::Endpoint const& ep) + { + std::vector v; + v.push_back(ep); + addFixedPeer (name, v); + } + void addFixedPeer (std::string const& name, std::vector const& addresses) diff --git a/src/ripple/peerfinder/tests/PeerFinder_test.cpp b/src/ripple/peerfinder/tests/PeerFinder_test.cpp new file mode 100644 index 0000000000..7ef7372a78 --- /dev/null +++ b/src/ripple/peerfinder/tests/PeerFinder_test.cpp @@ -0,0 +1,160 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include +#include +#include + +namespace ripple { +namespace PeerFinder { + +class Logic_test : public beast::unit_test::suite +{ +public: + struct TestStore : Store + { + std::size_t + load (load_callback const& cb) override + { + return 0; + } + + void + save (std::vector const&) override + { + } + }; + + struct TestChecker + { + void + stop() + { + } + + void + wait() + { + } + + template + void + async_connect (beast::IP::Endpoint const& ep, + Handler&& handler) + { + boost::system::error_code ec; + handler (ep, ep, ec); + } + }; + + void + test_backoff1() + { + auto const seconds = 10000; + testcase("backoff 1"); + TestStore store; + TestChecker checker; + beast::manual_clock clock; + Logic logic (clock, store, checker, beast::Journal{}); + logic.addFixedPeer ("test", + beast::IP::Endpoint::from_string("65.0.0.1:5")); + { + Config c; + c.autoConnect = false; + c.listeningPort = 1024; + logic.config(c); + } + std::size_t n = 0; + for (std::size_t i = 0; i < seconds; ++i) + { + auto const list = logic.autoconnect(); + if (! list.empty()) + { + expect (list.size() == 1); + auto const slot = logic.new_outbound_slot(list.front()); + expect (logic.onConnected(slot, + beast::IP::Endpoint::from_string("65.0.0.2:5"))); + logic.on_closed(slot); + ++n; + } + clock.advance(std::chrono::seconds(1)); + logic.once_per_second(); + } + // Less than 20 attempts + expect (n < 20, "backoff"); + } + + // with activate + void + test_backoff2() + { + auto const seconds = 10000; + testcase("backoff 2"); + TestStore store; + TestChecker checker; + beast::manual_clock clock; + Logic logic (clock, store, checker, beast::Journal{}); + logic.addFixedPeer ("test", + beast::IP::Endpoint::from_string("65.0.0.1:5")); + { + Config c; + c.autoConnect = false; + c.listeningPort = 1024; + logic.config(c); + } + std::size_t n = 0; + std::array key; + key.fill(0); + for (std::size_t i = 0; i < seconds; ++i) + { + auto const list = logic.autoconnect(); + if (! list.empty()) + { + expect (list.size() == 1); + auto const slot = logic.new_outbound_slot(list.front()); + if (! expect (logic.onConnected(slot, + beast::IP::Endpoint::from_string("65.0.0.2:5")))) + return; + std::string s = "."; + RipplePublicKey pk (key.begin(), key.end()); + if (! expect (logic.activate(slot, pk, false) == + PeerFinder::Result::success, "activate")) + return; + logic.on_closed(slot); + ++n; + } + clock.advance(std::chrono::seconds(1)); + logic.once_per_second(); + } + // No more often than once per minute + expect (n <= (seconds+59)/60, "backoff"); + } + + void run () + { + test_backoff1(); + test_backoff2(); + } +}; + +BEAST_DEFINE_TESTSUITE(Logic,PeerFinder,ripple); + +} +} diff --git a/src/ripple/unity/peerfinder.cpp b/src/ripple/unity/peerfinder.cpp index 0e9906d2e7..ee5a783dc9 100644 --- a/src/ripple/unity/peerfinder.cpp +++ b/src/ripple/unity/peerfinder.cpp @@ -42,6 +42,7 @@ #include #include +#include #if DOXYGEN #include