mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-22 09:57:41 +00:00
perfdhcp avalache: improvements after review
- simplified differentiating for IP version and exchange types - added more comments - fixed unittest for receiver by mocking socket - added option for building perfdhcp by hammer - added workaround for compiler bug that cannot handle enum class as a key to std::unordered_map - hidden warnings from boost by changing compiler flag from -I<boost-path> to -isystem <boost-path> - removed unused options_ field from StatsMgr class
This commit is contained in:
parent
a20cf4615a
commit
98e64a69d5
15
hammer.py
15
hammer.py
@ -224,7 +224,9 @@ def execute(cmd, timeout=60, cwd=None, env=None, raise_error=True, dry_run=False
|
||||
# if still running, kill harder
|
||||
if p.poll() is None:
|
||||
execute('sudo kill -s KILL %s' % p.pid)
|
||||
raise ExecutionError('Execution timeout')
|
||||
msg = "Execution timeout, %d > %d seconds elapsed (start: %d, stop %d), cmd: '%s'"
|
||||
msg = msg % (t1 - t0, timeout, t0, t1, cmd)
|
||||
raise ExecutionError(msg)
|
||||
exitcode = p.returncode
|
||||
|
||||
if exitcode == 0:
|
||||
@ -984,6 +986,8 @@ def _build_binaries_and_run_ut(system, revision, features, tarball_path, env, ch
|
||||
cmd += ' --with-freeradius=/usr/local'
|
||||
if 'shell' in features:
|
||||
cmd += ' --enable-shell'
|
||||
if 'perfdhcp' in features:
|
||||
cmd += ' --enable-perfdhcp'
|
||||
|
||||
# do ./configure
|
||||
execute(cmd, cwd=src_path, env=env, timeout=120, check_times=check_times, dry_run=dry_run)
|
||||
@ -1016,7 +1020,7 @@ def _build_binaries_and_run_ut(system, revision, features, tarball_path, env, ch
|
||||
env['KEA_SOCKET_TEST_DIR'] = '/tmp/'
|
||||
# run unit tests
|
||||
execute('make check -k',
|
||||
cwd=src_path, env=env, timeout=60 * 60, raise_error=False,
|
||||
cwd=src_path, env=env, timeout=90 * 60, raise_error=False,
|
||||
check_times=check_times, dry_run=dry_run)
|
||||
|
||||
# parse unit tests results
|
||||
@ -1052,7 +1056,8 @@ def _build_binaries_and_run_ut(system, revision, features, tarball_path, env, ch
|
||||
f.write(json.dumps(results))
|
||||
|
||||
if 'install' in features:
|
||||
execute('sudo make install', cwd=src_path, env=env, check_times=check_times, dry_run=dry_run)
|
||||
execute('sudo make install', timeout=2 * 60,
|
||||
cwd=src_path, env=env, check_times=check_times, dry_run=dry_run)
|
||||
execute('sudo ldconfig', dry_run=dry_run) # TODO: this shouldn't be needed
|
||||
|
||||
if 'forge' in features:
|
||||
@ -1244,9 +1249,9 @@ class CollectCommaSeparatedArgsAction(argparse.Action):
|
||||
setattr(namespace, self.dest, values2)
|
||||
|
||||
|
||||
DEFAULT_FEATURES = ['install', 'unittest', 'docs']
|
||||
DEFAULT_FEATURES = ['install', 'unittest', 'docs', 'perfdhcp']
|
||||
ALL_FEATURES = ['install', 'distcheck', 'unittest', 'docs', 'mysql', 'pgsql', 'cql', 'native-pkg',
|
||||
'radius', 'shell', 'forge']
|
||||
'radius', 'shell', 'forge', 'perfdhcp']
|
||||
|
||||
|
||||
def parse_args():
|
||||
|
@ -71,7 +71,7 @@ fi
|
||||
# Check the path with some specific headers.
|
||||
CPPFLAGS_SAVED="$CPPFLAGS"
|
||||
if test "${boost_include_path}" ; then
|
||||
BOOST_INCLUDES="-I${boost_include_path}"
|
||||
BOOST_INCLUDES="-isystem ${boost_include_path}"
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_INCLUDES"
|
||||
fi
|
||||
AC_CHECK_HEADERS([boost/shared_ptr.hpp boost/foreach.hpp boost/interprocess/sync/interprocess_upgradable_mutex.hpp boost/date_time/posix_time/posix_time_types.hpp boost/bind.hpp boost/function.hpp boost/asio.hpp boost/asio/ip/address.hpp boost/system/error_code.hpp boost/atomic.hpp boost/circular_buffer.hpp],,
|
||||
|
@ -26,7 +26,16 @@ public:
|
||||
/// \param socket reference to a socket.
|
||||
AbstractScen(CommandOptions& options, BasePerfSocket &socket) :
|
||||
options_(options),
|
||||
tc_(options, socket) {};
|
||||
tc_(options, socket)
|
||||
{
|
||||
if (options_.getIpVersion() == 4) {
|
||||
stage1_xchg_ = ExchangeType::DO;
|
||||
stage2_xchg_ = ExchangeType::RA;
|
||||
} else {
|
||||
stage1_xchg_ = ExchangeType::SA;
|
||||
stage2_xchg_ = ExchangeType::RR;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Run performance test.
|
||||
///
|
||||
@ -39,8 +48,13 @@ public:
|
||||
virtual ~AbstractScen() {};
|
||||
|
||||
protected:
|
||||
CommandOptions& options_;
|
||||
CommandOptions& options_; ///< Reference to commandline options.
|
||||
TestControl tc_; ///< Object for controling sending and receiving packets.
|
||||
|
||||
// Helper fields to avoid checking IP version each time an exchange type
|
||||
// is needed.
|
||||
ExchangeType stage1_xchg_;
|
||||
ExchangeType stage2_xchg_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -128,16 +128,9 @@ AvalancheScen::run() {
|
||||
if (now - prev_cycle_time > milliseconds(200)) { // check if 0.2s elapsed
|
||||
prev_cycle_time = now;
|
||||
int still_left_cnt = 0;
|
||||
if (options_.getIpVersion() == 4) {
|
||||
still_left_cnt += resendPackets(ExchangeType::DO);
|
||||
still_left_cnt += resendPackets(stage1_xchg_);
|
||||
if (options_.getExchangeMode() == CommandOptions::DORA_SARR) {
|
||||
still_left_cnt += resendPackets(ExchangeType::RA);
|
||||
}
|
||||
} else {
|
||||
still_left_cnt += resendPackets(ExchangeType::SA);
|
||||
if (options_.getExchangeMode() == CommandOptions::DORA_SARR) {
|
||||
still_left_cnt += resendPackets(ExchangeType::RR);
|
||||
}
|
||||
still_left_cnt += resendPackets(stage2_xchg_);
|
||||
}
|
||||
|
||||
if (still_left_cnt == 0) {
|
||||
@ -173,22 +166,16 @@ AvalancheScen::run() {
|
||||
}
|
||||
|
||||
// Calculate total stats.
|
||||
int total_sent_pkts = total_resent_;
|
||||
int total_rcvd_pkts = 0;
|
||||
if (options_.getIpVersion() == 4) {
|
||||
total_sent_pkts += tc_.getStatsMgr().getSentPacketsNum(ExchangeType::DO);
|
||||
total_rcvd_pkts += tc_.getStatsMgr().getRcvdPacketsNum(ExchangeType::DO);
|
||||
int total_sent_pkts = total_resent_; // This holds sent + resent packets counts.
|
||||
int total_rcvd_pkts = 0; // This holds received packets count.
|
||||
// Get sent and received counts for DO/SA (stage1) exchange from StatsMgr.
|
||||
total_sent_pkts += tc_.getStatsMgr().getSentPacketsNum(stage1_xchg_);
|
||||
total_rcvd_pkts += tc_.getStatsMgr().getRcvdPacketsNum(stage1_xchg_);
|
||||
// Get sent and received counts for RA/RR (stage2) exchange from StatsMgr
|
||||
// if RA/RR was not disabled.
|
||||
if (options_.getExchangeMode() == CommandOptions::DORA_SARR) {
|
||||
total_sent_pkts += tc_.getStatsMgr().getSentPacketsNum(ExchangeType::RA);
|
||||
total_rcvd_pkts += tc_.getStatsMgr().getRcvdPacketsNum(ExchangeType::RA);
|
||||
}
|
||||
} else {
|
||||
total_sent_pkts += tc_.getStatsMgr().getSentPacketsNum(ExchangeType::SA);
|
||||
total_rcvd_pkts += tc_.getStatsMgr().getRcvdPacketsNum(ExchangeType::SA);
|
||||
if (options_.getExchangeMode() == CommandOptions::DORA_SARR) {
|
||||
total_sent_pkts += tc_.getStatsMgr().getSentPacketsNum(ExchangeType::RR);
|
||||
total_rcvd_pkts += tc_.getStatsMgr().getRcvdPacketsNum(ExchangeType::RR);
|
||||
}
|
||||
total_sent_pkts += tc_.getStatsMgr().getSentPacketsNum(stage2_xchg_);
|
||||
total_rcvd_pkts += tc_.getStatsMgr().getRcvdPacketsNum(stage2_xchg_);
|
||||
}
|
||||
|
||||
std::cout << "It took " << duration.length() << " to provision " << clients_num
|
||||
|
@ -15,6 +15,17 @@
|
||||
namespace isc {
|
||||
namespace perfdhcp {
|
||||
|
||||
// This class fixes an issue in older compilers
|
||||
// that cannot handle enum class as key in std::unordered_map.
|
||||
// See: https://stackoverflow.com/questions/18837857/cant-use-enum-class-as-unordered-map-key
|
||||
struct EnumClassHash
|
||||
{
|
||||
template <typename T>
|
||||
std::size_t operator()(T t) const
|
||||
{
|
||||
return static_cast<std::size_t>(t);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Avalanche Scenario class.
|
||||
///
|
||||
@ -46,9 +57,9 @@ protected:
|
||||
BasePerfSocket &socket_;
|
||||
|
||||
/// A map xchg type -> (a map of trans id -> retransmissions count.
|
||||
std::unordered_map<ExchangeType, std::unordered_map<uint32_t, int>> retransmissions_;
|
||||
std::unordered_map<ExchangeType, std::unordered_map<uint32_t, int>, EnumClassHash> retransmissions_;
|
||||
/// A map xchg type -> (a map of trans id -> time of sending first packet.
|
||||
std::unordered_map<ExchangeType, std::unordered_map<uint32_t, boost::posix_time::ptime>> start_times_;
|
||||
std::unordered_map<ExchangeType, std::unordered_map<uint32_t, boost::posix_time::ptime>, EnumClassHash> start_times_;
|
||||
|
||||
/// Total number of resent packets.
|
||||
int total_resent_;
|
||||
|
@ -27,15 +27,10 @@ BasicScen::checkExitConditions() {
|
||||
|
||||
const StatsMgr& stats_mgr(tc_.getStatsMgr());
|
||||
|
||||
bool test_period_reached = false;
|
||||
// Check if test period passed.
|
||||
if (options_.getPeriod() != 0) {
|
||||
time_period period(stats_mgr.getTestPeriod());
|
||||
if (period.length().total_seconds() >= options_.getPeriod()) {
|
||||
test_period_reached = true;
|
||||
}
|
||||
}
|
||||
if (test_period_reached) {
|
||||
if (options_.testDiags('e')) {
|
||||
std::cout << "reached test-period." << std::endl;
|
||||
}
|
||||
@ -43,35 +38,22 @@ BasicScen::checkExitConditions() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool max_requests = false;
|
||||
// Check if we reached maximum number of DISCOVER/SOLICIT sent.
|
||||
if (options_.getNumRequests().size() > 0) {
|
||||
if (options_.getIpVersion() == 4) {
|
||||
if (stats_mgr.getSentPacketsNum(ExchangeType::DO) >=
|
||||
if (stats_mgr.getSentPacketsNum(stage1_xchg_) >=
|
||||
options_.getNumRequests()[0]) {
|
||||
max_requests = true;
|
||||
}
|
||||
} else if (options_.getIpVersion() == 6) {
|
||||
if (stats_mgr.getSentPacketsNum(ExchangeType::SA) >=
|
||||
options_.getNumRequests()[0]) {
|
||||
max_requests = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if we reached maximum number REQUEST packets.
|
||||
if (options_.getNumRequests().size() > 1) {
|
||||
if (options_.getIpVersion() == 4) {
|
||||
if (stats_mgr.getSentPacketsNum(ExchangeType::RA) >=
|
||||
if (stats_mgr.getSentPacketsNum(stage2_xchg_) >=
|
||||
options_.getNumRequests()[1]) {
|
||||
max_requests = true;
|
||||
}
|
||||
} else if (options_.getIpVersion() == 6) {
|
||||
if (stats_mgr.getSentPacketsNum(ExchangeType::RR) >=
|
||||
options_.getNumRequests()[1]) {
|
||||
max_requests = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (max_requests) {
|
||||
if (options_.testDiags('e')) {
|
||||
@ -85,31 +67,17 @@ BasicScen::checkExitConditions() {
|
||||
// Check if we reached maximum number of drops of OFFER/ADVERTISE packets.
|
||||
bool max_drops = false;
|
||||
if (options_.getMaxDrop().size() > 0) {
|
||||
if (options_.getIpVersion() == 4) {
|
||||
if (stats_mgr.getDroppedPacketsNum(ExchangeType::DO) >=
|
||||
if (stats_mgr.getDroppedPacketsNum(stage1_xchg_) >=
|
||||
options_.getMaxDrop()[0]) {
|
||||
max_drops = true;
|
||||
}
|
||||
} else if (options_.getIpVersion() == 6) {
|
||||
if (stats_mgr.getDroppedPacketsNum(ExchangeType::SA) >=
|
||||
options_.getMaxDrop()[0]) {
|
||||
max_drops = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if we reached maximum number of drops of ACK/REPLY packets.
|
||||
if (options_.getMaxDrop().size() > 1) {
|
||||
if (options_.getIpVersion() == 4) {
|
||||
if (stats_mgr.getDroppedPacketsNum(ExchangeType::RA) >=
|
||||
if (stats_mgr.getDroppedPacketsNum(stage2_xchg_) >=
|
||||
options_.getMaxDrop()[1]) {
|
||||
max_drops = true;
|
||||
}
|
||||
} else if (options_.getIpVersion() == 6) {
|
||||
if (stats_mgr.getDroppedPacketsNum(ExchangeType::RR) >=
|
||||
options_.getMaxDrop()[1]) {
|
||||
max_drops = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (max_drops) {
|
||||
if (options_.testDiags('e')) {
|
||||
@ -123,40 +91,23 @@ BasicScen::checkExitConditions() {
|
||||
// Check if we reached maximum drops percentage of OFFER/ADVERTISE packets.
|
||||
bool max_pdrops = false;
|
||||
if (options_.getMaxDropPercentage().size() > 0) {
|
||||
if (options_.getIpVersion() == 4) {
|
||||
if ((stats_mgr.getSentPacketsNum(ExchangeType::DO) > 10) &&
|
||||
((100. * stats_mgr.getDroppedPacketsNum(ExchangeType::DO) /
|
||||
stats_mgr.getSentPacketsNum(ExchangeType::DO)) >=
|
||||
options_.getMaxDropPercentage()[0])) {
|
||||
if ((stats_mgr.getSentPacketsNum(stage1_xchg_) > 10) &&
|
||||
((100. * stats_mgr.getDroppedPacketsNum(stage1_xchg_) /
|
||||
stats_mgr.getSentPacketsNum(stage1_xchg_)) >=
|
||||
options_.getMaxDropPercentage()[0]))
|
||||
{
|
||||
max_pdrops = true;
|
||||
|
||||
}
|
||||
} else if (options_.getIpVersion() == 6) {
|
||||
if ((stats_mgr.getSentPacketsNum(ExchangeType::SA) > 10) &&
|
||||
((100. * stats_mgr.getDroppedPacketsNum(ExchangeType::SA) /
|
||||
stats_mgr.getSentPacketsNum(ExchangeType::SA)) >=
|
||||
options_.getMaxDropPercentage()[0])) {
|
||||
max_pdrops = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if we reached maximum drops percentage of ACK/REPLY packets.
|
||||
if (options_.getMaxDropPercentage().size() > 1) {
|
||||
if (options_.getIpVersion() == 4) {
|
||||
if ((stats_mgr.getSentPacketsNum(ExchangeType::RA) > 10) &&
|
||||
((100. * stats_mgr.getDroppedPacketsNum(ExchangeType::RA) /
|
||||
stats_mgr.getSentPacketsNum(ExchangeType::RA)) >=
|
||||
options_.getMaxDropPercentage()[1])) {
|
||||
if ((stats_mgr.getSentPacketsNum(stage2_xchg_) > 10) &&
|
||||
((100. * stats_mgr.getDroppedPacketsNum(stage2_xchg_) /
|
||||
stats_mgr.getSentPacketsNum(stage2_xchg_)) >=
|
||||
options_.getMaxDropPercentage()[1]))
|
||||
{
|
||||
max_pdrops = true;
|
||||
}
|
||||
} else if (options_.getIpVersion() == 6) {
|
||||
if ((stats_mgr.getSentPacketsNum(ExchangeType::RR) > 10) &&
|
||||
((100. * stats_mgr.getDroppedPacketsNum(ExchangeType::RR) /
|
||||
stats_mgr.getSentPacketsNum(ExchangeType::RR)) >=
|
||||
options_.getMaxDropPercentage()[1])) {
|
||||
max_pdrops = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (max_pdrops) {
|
||||
if (options_.testDiags('e')) {
|
||||
|
@ -404,6 +404,9 @@ private:
|
||||
|
||||
/// \brief Validates initialized options.
|
||||
///
|
||||
/// It checks provided options. If there are issues they are reported
|
||||
/// and exception is raised. If possible some options are corrected
|
||||
/// e.g. overriding drop_time in case of avalanche scenario.
|
||||
/// \throws isc::InvalidParameter if command line validation fails.
|
||||
void validate();
|
||||
|
||||
|
@ -17,11 +17,18 @@
|
||||
namespace isc {
|
||||
namespace perfdhcp {
|
||||
|
||||
/// \brief Socket wrapper structure.
|
||||
///
|
||||
/// This is a base class that is inherited by PerfSocket
|
||||
/// and unit tests derived that. This way it allows mocking
|
||||
/// out socket operations and avoid using real network
|
||||
/// interfaces.
|
||||
class BasePerfSocket : public dhcp::SocketInfo {
|
||||
public:
|
||||
/// Interface index.
|
||||
uint16_t ifindex_;
|
||||
|
||||
/// \brief Default constructor of BasePerfSocket.
|
||||
BasePerfSocket() :
|
||||
SocketInfo(asiolink::IOAddress("127.0.0.1"), 0, 0),
|
||||
ifindex_(0) {}
|
||||
@ -29,10 +36,19 @@ public:
|
||||
/// \brief Destructor of the socket wrapper class.
|
||||
virtual ~BasePerfSocket() = default;
|
||||
|
||||
/// \brief See description of this method in PerfSocket class below.
|
||||
virtual dhcp::Pkt4Ptr receive4(uint32_t timeout_sec, uint32_t timeout_usec) = 0;
|
||||
|
||||
/// \brief See description of this method in PerfSocket class below.
|
||||
virtual dhcp::Pkt6Ptr receive6(uint32_t timeout_sec, uint32_t timeout_usec) = 0;
|
||||
|
||||
/// \brief See description of this method in PerfSocket class below.
|
||||
virtual bool send(const dhcp::Pkt4Ptr& pkt) = 0;
|
||||
|
||||
/// \brief See description of this method in PerfSocket class below.
|
||||
virtual bool send(const dhcp::Pkt6Ptr& pkt) = 0;
|
||||
|
||||
/// \brief See description of this method in PerfSocket class below.
|
||||
virtual dhcp::IfacePtr getIface() = 0;
|
||||
};
|
||||
|
||||
|
@ -316,8 +316,7 @@ ExchangeStats::printTimestamps() {
|
||||
|
||||
StatsMgr::StatsMgr(CommandOptions& options) :
|
||||
exchanges_(),
|
||||
boot_time_(boost::posix_time::microsec_clock::universal_time()),
|
||||
options_(options)
|
||||
boot_time_(boost::posix_time::microsec_clock::universal_time())
|
||||
{
|
||||
// Check if packet archive mode is required. If user
|
||||
// requested diagnostics option -x t we have to enable
|
||||
|
@ -1110,8 +1110,6 @@ private:
|
||||
bool archive_enabled_;
|
||||
|
||||
boost::posix_time::ptime boot_time_; ///< Time when test is started.
|
||||
|
||||
CommandOptions& options_;
|
||||
};
|
||||
|
||||
/// Pointer to Statistics Manager;
|
||||
|
@ -126,7 +126,7 @@ public:
|
||||
class TestControl : public boost::noncopyable {
|
||||
public:
|
||||
/// \brief Default constructor.
|
||||
TestControl(CommandOptions& options, BasePerfSocket &socket);
|
||||
TestControl(CommandOptions& options, BasePerfSocket& socket);
|
||||
|
||||
/// Packet template buffer.
|
||||
typedef std::vector<uint8_t> TemplateBuffer;
|
||||
|
@ -43,7 +43,9 @@ public:
|
||||
};
|
||||
|
||||
|
||||
TEST_F(PerfSocketTest, Basic) {
|
||||
TEST_F(PerfSocketTest, WrongCommandOptions) {
|
||||
// Check if incorrect command options are casing failure during
|
||||
// socket setup.
|
||||
CommandOptions opt;
|
||||
|
||||
// make sure we catch -6 paired with v4 address
|
||||
|
@ -8,25 +8,90 @@
|
||||
|
||||
#include "command_options_helper.h"
|
||||
|
||||
#include <dhcp/iface_mgr.h>
|
||||
|
||||
|
||||
#include <exceptions/exceptions.h>
|
||||
#include "receiver.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
using namespace isc;
|
||||
using namespace isc::dhcp;
|
||||
using namespace isc::perfdhcp;
|
||||
|
||||
|
||||
/// \brief FakeReceiverPerfSocket class that mocks PerfSocket.
|
||||
///
|
||||
/// It stubs send and receive operations and collects statistics.
|
||||
class FakeReceiverPerfSocket: public BasePerfSocket {
|
||||
public:
|
||||
/// \brief Default constructor for FakeReceiverPerfSocket.
|
||||
FakeReceiverPerfSocket() :
|
||||
iface_(boost::make_shared<Iface>("fake", 0)),
|
||||
sent_cnt_(0),
|
||||
recv_cnt_(0) {};
|
||||
|
||||
IfacePtr iface_; ///< Local fake interface.
|
||||
|
||||
int sent_cnt_; ///< Counter of sent packets
|
||||
int recv_cnt_; ///< Counter of received packets.
|
||||
|
||||
/// \brief Simulate receiving DHCPv4 packet.
|
||||
virtual dhcp::Pkt4Ptr receive4(uint32_t timeout_sec, uint32_t timeout_usec) override {
|
||||
(void)timeout_sec; // silence compile 'unused parameter' warning;
|
||||
(void)timeout_usec; // silence compile 'unused parameter' warning;
|
||||
recv_cnt_++;
|
||||
// slow down receiving as receiver calls it in a loop thousands of time
|
||||
// if null is returned
|
||||
usleep(50);
|
||||
return(dhcp::Pkt4Ptr());
|
||||
};
|
||||
|
||||
/// \brief Simulate receiving DHCPv6 packet.
|
||||
virtual dhcp::Pkt6Ptr receive6(uint32_t timeout_sec, uint32_t timeout_usec) override {
|
||||
(void)timeout_sec; // silence compile 'unused parameter' warning;
|
||||
(void)timeout_usec; // silence compile 'unused parameter' warning;
|
||||
recv_cnt_++;
|
||||
return(dhcp::Pkt6Ptr());
|
||||
};
|
||||
|
||||
/// \brief Simulate sending DHCPv4 packet.
|
||||
virtual bool send(const dhcp::Pkt4Ptr& pkt) override {
|
||||
sent_cnt_++;
|
||||
pkt->updateTimestamp();
|
||||
return true;
|
||||
};
|
||||
|
||||
/// \brief Simulate sending DHCPv6 packet.
|
||||
virtual bool send(const dhcp::Pkt6Ptr& pkt) override {
|
||||
sent_cnt_++;
|
||||
pkt->updateTimestamp();
|
||||
return true;
|
||||
};
|
||||
|
||||
/// \brief Override getting interface.
|
||||
virtual IfacePtr getIface() override { return iface_; }
|
||||
|
||||
void reset() {
|
||||
sent_cnt_ = 0;
|
||||
recv_cnt_ = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEST(Receiver, singleThreaded) {
|
||||
CommandOptions opt;
|
||||
CommandOptionsHelper::process(opt, "perfdhcp -g single -l 127.0.0.1 all");
|
||||
ASSERT_TRUE(opt.isSingleThreaded());
|
||||
|
||||
PerfSocket socket(opt);
|
||||
FakeReceiverPerfSocket socket;
|
||||
Receiver receiver(socket, opt.isSingleThreaded(), opt.getIpVersion());
|
||||
|
||||
ASSERT_NO_THROW(receiver.start());
|
||||
|
||||
auto pkt = receiver.getPkt();
|
||||
|
||||
EXPECT_EQ(pkt, nullptr);
|
||||
|
||||
ASSERT_NO_THROW(receiver.stop());
|
||||
@ -38,12 +103,13 @@ TEST(Receiver, multiThreaded) {
|
||||
CommandOptionsHelper::process(opt, "perfdhcp -g multi -l 127.0.0.1 all");
|
||||
ASSERT_FALSE(opt.isSingleThreaded());
|
||||
|
||||
PerfSocket socket(opt);
|
||||
FakeReceiverPerfSocket socket;
|
||||
Receiver receiver(socket, opt.isSingleThreaded(), opt.getIpVersion());
|
||||
|
||||
ASSERT_NO_THROW(receiver.start());
|
||||
|
||||
auto pkt = receiver.getPkt();
|
||||
|
||||
EXPECT_EQ(pkt, nullptr);
|
||||
|
||||
ASSERT_NO_THROW(receiver.stop());
|
||||
|
@ -34,10 +34,10 @@ using namespace isc::perfdhcp;
|
||||
/// \brief FakePerfSocket class that mocks PerfSocket.
|
||||
///
|
||||
/// It stubs send and receive operations and collects statistics.
|
||||
class FakePerfSocket: public BasePerfSocket {
|
||||
class FakeTestControlPerfSocket: public BasePerfSocket {
|
||||
public:
|
||||
/// \brief Default constructor for FakePerfSocket.
|
||||
FakePerfSocket() :
|
||||
FakeTestControlPerfSocket() :
|
||||
iface_(boost::make_shared<Iface>("fake", 0)),
|
||||
sent_cnt_(0),
|
||||
recv_cnt_(0) {};
|
||||
@ -169,7 +169,7 @@ public:
|
||||
using TestControl::options_;
|
||||
using TestControl::stats_mgr_;
|
||||
|
||||
FakePerfSocket fake_sock_;
|
||||
FakeTestControlPerfSocket fake_sock_;
|
||||
|
||||
NakedTestControl(CommandOptions &opt) : TestControl(opt, fake_sock_) {
|
||||
uint32_t clients_num = opt.getClientsNum() == 0 ?
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2014-2019 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
|
Loading…
x
Reference in New Issue
Block a user