From: Andrei Pavel Date: Fri, 18 Aug 2017 08:13:10 +0000 (+0300) Subject: perfdhcp with late-exit-delay + documentation fix X-Git-Tag: trac5502_base~5^2~5^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b70c9642fc9a2ff03b0b483bff0690c677453ed7;p=thirdparty%2Fkea.git perfdhcp with late-exit-delay + documentation fix * perfdhcp -m waits for ms after an exit condition has been met to receive all packets without sending any new packets. * documentation: "Use -D0 to abort if even a single request has been dropped.". -D0 is not allowed, -D1 achieves that. --- diff --git a/src/bin/perfdhcp/command_options.cc b/src/bin/perfdhcp/command_options.cc index 3f110625fe..1cf3c43f5f 100644 --- a/src/bin/perfdhcp/command_options.cc +++ b/src/bin/perfdhcp/command_options.cc @@ -124,6 +124,7 @@ CommandOptions::reset() { mac_list_file_.clear(); mac_list_.clear(); num_request_.clear(); + late_exit_delay_ = 0; period_ = 0; drop_time_set_ = 0; drop_time_.assign(dt, dt + 2); @@ -216,7 +217,7 @@ CommandOptions::initialize(int argc, char** argv, bool print_cmd_line) { // In this section we collect argument values from command line // they will be tuned and validated elsewhere - while((opt = getopt(argc, argv, "hv46A:r:t:R:b:n:p:d:D:l:P:a:L:M:" + while((opt = getopt(argc, argv, "hv46A:r:t:R:b:n:p:d:D:l:P:a:L:M:m:" "s:iBc1T:X:O:E:S:I:x:w:e:f:F:")) != -1) { stream << " -" << static_cast(opt); if (optarg) { @@ -307,7 +308,7 @@ CommandOptions::initialize(int argc, char** argv, bool print_cmd_line) { max_pdrop_.push_back(drop_percent); } else { num_drops = positiveInteger("value of max drops number:" - " -d must be a positive integer"); + " -D must be a positive integer"); max_drop_.push_back(num_drops); } break; @@ -368,6 +369,13 @@ CommandOptions::initialize(int argc, char** argv, bool print_cmd_line) { loadMacs(); break; + case 'm': + // 'm' for moratorium + late_exit_delay_ = nonNegativeInteger("value of late exit delay: " + "-m must not be a " + "negative integer"); + break; + case 'n': num_req = positiveInteger("value of num-request:" " -n must be a positive integer"); @@ -981,6 +989,7 @@ CommandOptions::usage() const { " [-n] [-p] [-d]\n" " [-D] [-l] [-P]\n" " [-a] [-L] [-s] [-i] [-B]\n" + " [-m]\n" " [-c] [-1] [-M] [-T]\n" " [-X] [-O]\n" " [-S] [-I] [-x]\n" @@ -1098,12 +1107,12 @@ CommandOptions::usage() const { "\n" "The remaining options are used only in conjunction with -r:\n" "\n" - "-D: Abort the test if more than requests have\n" - " been dropped. Use -D0 to abort if even a single request has been\n" - " dropped. If includes the suffix '%', it specifies a\n" - " maximum percentage of requests that may be dropped before abort.\n" - " In this case, testing of the threshold begins after 10 requests\n" - " have been expected to be received.\n" + "-D: Abort the test immediately if max-drop requests have\n" + " been dropped. max-drop must be a positive integer. If max-drop\n" + " includes the suffix '%', it specifies a maximum percentage of\n" + " requests that may be dropped before abort. In this case, testing\n" + " of the threshold begins after 10 requests have been expected to\n" + " be received.\n" "-n: Initiate transactions. No report is\n" " generated until all transactions have been initiated/waited-for,\n" " after which a report is generated and the program terminates.\n" @@ -1133,6 +1142,5 @@ CommandOptions::version() const { std::cout << "VERSION: " << VERSION << std::endl; } - -} // namespace perfdhcp -} // namespace isc +} // namespace perfdhcp +} // namespace isc diff --git a/src/bin/perfdhcp/command_options.h b/src/bin/perfdhcp/command_options.h index 8b957d3d82..f67d0e9e47 100644 --- a/src/bin/perfdhcp/command_options.h +++ b/src/bin/perfdhcp/command_options.h @@ -247,6 +247,11 @@ public: /// \return local port number. int getLocalPort() const { return local_port_; } + /// @brief Returns the time in microseconds to delay the program by. + /// + /// @return the time in microseconds to delay the program by. + int getLateExitDelay() const { return late_exit_delay_; } + /// \brief Checks if seed provided. /// /// \return true if seed was provided. @@ -512,6 +517,8 @@ private: /// Collection of base values specified with -b /// options. Supported "bases" are mac= and duid= std::vector base_; + /// Number of microseconds by which you should delay the exit + int late_exit_delay_; /// Number of 2 or 4-way exchanges to perform. std::vector num_request_; /// Test period in seconds @@ -594,7 +601,7 @@ private: uint8_t v6_relay_encapsulation_level_; }; -} // namespace perfdhcp -} // namespace isc +} // namespace perfdhcp +} // namespace isc #endif // COMMAND_OPTIONS_H diff --git a/src/bin/perfdhcp/perfdhcp.xml b/src/bin/perfdhcp/perfdhcp.xml index a400b3c59b..cba199ebc0 100644 --- a/src/bin/perfdhcp/perfdhcp.xml +++ b/src/bin/perfdhcp/perfdhcp.xml @@ -727,16 +727,16 @@ - Abort the test if more than max-drop - requests have been dropped. Use to abort if even a single - request has been dropped. If max-drop requests + have been dropped. max-drop must be a + positive integer. If max-drop includes - the suffix '%', it specifies a maximum percentage - of requests that may be dropped before abort. - In this case, testing of the threshold begins after - 10 requests have been expected to be received. + the suffix '%', it specifies a maximum percentage of + requests that may be dropped before abort. In this + case, testing of the threshold begins after 10 + requests have been expected to be received. diff --git a/src/bin/perfdhcp/test_control.cc b/src/bin/perfdhcp/test_control.cc index c4c665b411..20b11c1fe0 100644 --- a/src/bin/perfdhcp/test_control.cc +++ b/src/bin/perfdhcp/test_control.cc @@ -42,6 +42,68 @@ namespace perfdhcp { bool TestControl::interrupted_ = false; +ptime late_exit_target_time_ = ptime(not_a_date_time); + +bool +TestControl::hasLateExitCommenced() const { + return !late_exit_target_time_.is_not_a_date_time(); +} + +bool +TestControl::lateExit() const { + if (haveAllPacketsBeenReceived()) { + return true; + } + const ptime now = microsec_clock::universal_time(); + if (late_exit_target_time_.is_not_a_date_time()) { + CommandOptions& options = CommandOptions::instance(); + late_exit_target_time_ = + now + time_duration(microseconds(options.getLateExitDelay())); + } + if (late_exit_target_time_ <= now) { + return true; + } + return false; +} + +bool +TestControl::haveAllPacketsBeenReceived() const { + const CommandOptions& options = CommandOptions::instance(); + const uint8_t& ipversion = options.getIpVersion(); + const std::vector& num_request = options.getNumRequests(); + const size_t& num_request_size = num_request.size(); + + if (num_request_size == 0) { + return false; + } + + const uint32_t& request_count_DO_SA = num_request[0]; + uint32_t request_count_RA_RR; + if (num_request_size >= 2) { + request_count_RA_RR = num_request[1]; + } else { + request_count_RA_RR = num_request[0]; + } + + if (ipversion == 4) { + if (stats_mgr4_->getRcvdPacketsNum(StatsMgr4::XCHG_DO) != + request_count_DO_SA || + stats_mgr4_->getRcvdPacketsNum(StatsMgr4::XCHG_RA) != + request_count_RA_RR) { + return false; + } + } else if (ipversion == 6) { + if (stats_mgr6_->getRcvdPacketsNum(StatsMgr6::XCHG_SA) != + request_count_DO_SA || + stats_mgr6_->getRcvdPacketsNum(StatsMgr6::XCHG_RR) != + request_count_RA_RR) { + return false; + } + } + + return true; +} + TestControl::TestControlSocket::TestControlSocket(const int socket) : SocketInfo(asiolink::IOAddress("127.0.0.1"), 0, socket), ifindex_(0), valid_(true) { @@ -196,7 +258,9 @@ TestControl::checkExitConditions() const { if (testDiags('e')) { std::cout << "reached test-period." << std::endl; } - return (true); + if (lateExit()) { + return true; + } } bool max_requests = false; @@ -232,7 +296,9 @@ TestControl::checkExitConditions() const { if (testDiags('e')) { std::cout << "Reached max requests limit." << std::endl; } - return (true); + if (lateExit()) { + return true; + } } // Check if we reached maximum number of drops of OFFER/ADVERTISE packets. @@ -268,7 +334,9 @@ TestControl::checkExitConditions() const { if (testDiags('e')) { std::cout << "Reached maximum drops number." << std::endl; } - return (true); + if (lateExit()) { + return true; + } } // Check if we reached maximum drops percentage of OFFER/ADVERTISE packets. @@ -313,7 +381,9 @@ TestControl::checkExitConditions() const { if (testDiags('e')) { std::cout << "Reached maximum percentage of drops." << std::endl; } - return (true); + if (lateExit()) { + return true; + } } return (false); } @@ -1485,8 +1555,10 @@ TestControl::run() { break; } - // Initiate new DHCP packet exchanges. - sendPackets(socket, packets_due); + if (!hasLateExitCommenced()) { + // Initiate new DHCP packet exchanges. + sendPackets(socket, packets_due); + } // If -f option was specified we have to check how many // Renew packets should be sent to catch up with a desired rate. @@ -2265,5 +2337,5 @@ TestControl::testDiags(const char diag) const { return (false); } -} // namespace perfdhcp -} // namespace isc +} // namespace perfdhcp +} // namespace isc diff --git a/src/bin/perfdhcp/test_control.h b/src/bin/perfdhcp/test_control.h index f50dcc7022..b7ddb3f9b7 100644 --- a/src/bin/perfdhcp/test_control.h +++ b/src/bin/perfdhcp/test_control.h @@ -136,6 +136,18 @@ public: /// Packet template buffers list. typedef std::vector TemplateBufferCollection; + /// @brief Delay the exit by a fixed given time to catch up to all exchanges + /// that were already started. + bool lateExit() const; + + /// @brief Check if the program is in that period where the program was + /// bound to exit, but was delayed by lateExit(). + bool hasLateExitCommenced() const; + + /// @brief Delay the exit by a fixed given time to catch up to all exchanges + /// that were already started. + bool haveAllPacketsBeenReceived() const; + /// \brief Socket wrapper structure. /// /// This is the wrapper that holds descriptor of the socket @@ -1136,7 +1148,7 @@ protected: static bool interrupted_; ///< Is program interrupted. }; -} // namespace perfdhcp -} // namespace isc +} // namespace perfdhcp +} // namespace isc #endif // TEST_CONTROL_H