]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
perfdhcp with late-exit-delay + documentation fix
authorAndrei Pavel <andrei.pavel@qualitance.com>
Fri, 18 Aug 2017 08:13:10 +0000 (11:13 +0300)
committerAndrei Pavel <andrei.pavel@qualitance.com>
Fri, 18 Aug 2017 08:13:10 +0000 (11:13 +0300)
    * perfdhcp -m <delay> waits for <delay> 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.

src/bin/perfdhcp/command_options.cc
src/bin/perfdhcp/command_options.h
src/bin/perfdhcp/perfdhcp.xml
src/bin/perfdhcp/test_control.cc
src/bin/perfdhcp/test_control.h

index 3f110625fe9162d61e2714150bc4a452e86cbaae..1cf3c43f5fc1c39c6fec25520c37bc9b0da3ef41 100644 (file)
@@ -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<char>(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<value> must be a positive integer");
+                                            " -D<value> 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<value> must not be a "
+                                                  "negative integer");
+            break;
+
         case 'n':
             num_req = positiveInteger("value of num-request:"
                                       " -n<value> must be a positive integer");
@@ -981,6 +989,7 @@ CommandOptions::usage() const {
         "         [-n<num-request>] [-p<test-period>] [-d<drop-time>]\n"
         "         [-D<max-drop>] [-l<local-addr|interface>] [-P<preload>]\n"
         "         [-a<aggressivity>] [-L<local-port>] [-s<seed>] [-i] [-B]\n"
+        "         [-m<late-exit-delay>]\n"
         "         [-c] [-1] [-M<mac-list-file>] [-T<template-file>]\n"
         "         [-X<xid-offset>] [-O<random-offset] [-E<time-offset>]\n"
         "         [-S<srvid-offset>] [-I<ip-offset>] [-x<diagnostic-selector>]\n"
@@ -1098,12 +1107,12 @@ CommandOptions::usage() const {
         "\n"
         "The remaining options are used only in conjunction with -r:\n"
         "\n"
-        "-D<max-drop>: Abort the test if more than <max-drop> requests have\n"
-        "    been dropped.  Use -D0 to abort if even a single request has been\n"
-        "    dropped.  If <max-drop> 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<max-drop>: 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<num-request>: Initiate <num-request> 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
index 8b957d3d8280212deca51624169f096d43671786..f67d0e9e472474be86f901bd717bea7c771a4d11 100644 (file)
@@ -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<value>
     /// options. Supported "bases" are mac=<mac> and duid=<duid>
     std::vector<std::string> 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<int> 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
index a400b3c59b1bea03ab4d11cb033aa61a68daa424..cba199ebc04b18af916bb37bf6a7fe0f5445a8ac 100644 (file)
                     <term><option>-D <replaceable class="parameter">max-drop</replaceable></option></term>
                     <listitem>
                         <para>
-                            Abort the test if more than <replaceable
-                            class="parameter">max-drop</replaceable>
-                            requests have been dropped.  Use <option>-D
-                            0</option> to abort if even a single
-                            request has been dropped.  If <replaceable
+                            Abort the test immediately if <replaceable
+                            class="parameter">max-drop</replaceable> requests
+                            have been dropped. <replaceable
+                            class="parameter">max-drop</replaceable> must be a
+                            positive integer. If <replaceable
                             class="parameter">max-drop</replaceable> 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.
                         </para>
                     </listitem>
                 </varlistentry>
index c4c665b4116e31b647038c6ee2a41330351ff399..20b11c1fe020e1f56bf85c38af8e82a5bbcb50d8 100644 (file)
@@ -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<int>& 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<renew-rate> 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
index f50dcc702207334e0a9fd1206ffcc67c9823e861..b7ddb3f9b79735f1bd40efe1457407a8b46d415f 100644 (file)
@@ -136,6 +136,18 @@ public:
     /// Packet template buffers list.
     typedef std::vector<TemplateBuffer> 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