Browse Source

[1959] Use StatsMgr to track packet exchanges.

Marcin Siodelski 12 years ago
parent
commit
00e8a3ebd6

+ 12 - 8
tests/tools/perfdhcp/stats_mgr.h

@@ -243,20 +243,21 @@ public:
         /// In this mode all packets are stored throughout the test execution.
         ExchangeStats(const ExchangeType xchg_type, const bool archive_enabled)
             : xchg_type_(xchg_type),
+            sent_packets_(),
+            rcvd_packets_(),
+            archived_packets_(),
+            archive_enabled_(archive_enabled),
             min_delay_(std::numeric_limits<double>::max()),
             max_delay_(0.),
             sum_delay_(0.),
-            orphans_(0),
             sum_delay_squared_(0.),
-            ordered_lookups_(0),
+            orphans_(0),
             unordered_lookup_size_sum_(0),
             unordered_lookups_(0),
+            ordered_lookups_(0),
             sent_packets_num_(0),
-            rcvd_packets_num_(0),
-            sent_packets_(),
-            rcvd_packets_(),
-            archived_packets_(),
-            archive_enabled_(archive_enabled) {
+            rcvd_packets_num_(0)
+        {
             next_sent_ = sent_packets_.begin();
         }
 
@@ -555,7 +556,10 @@ public:
         /// number of dropped packets and number of orphans.
         void printMainStats() const {
             using namespace std;
-            uint64_t drops = getRcvdPacketsNum() - getSentPacketsNum();
+            uint64_t drops = 0;
+            if (getRcvdPacketsNum() >= getSentPacketsNum()) {
+                drops = getRcvdPacketsNum() - getSentPacketsNum();
+            }
             cout << "sent packets: " << getSentPacketsNum() << endl
                  << "received packets: " << getRcvdPacketsNum() << endl
                  << "drops: " << drops << endl

+ 94 - 11
tests/tools/perfdhcp/test_control.cc

@@ -268,6 +268,27 @@ TestControl::getNextExchangesNum() const {
     return (0);
 }
 
+void
+TestControl::initializeStatsMgr() {
+    CommandOptions& options = CommandOptions::instance();
+    if (options.getIpVersion() == 4) {
+        stats_mgr4_.reset();
+        stats_mgr4_ = StatsMgr4Ptr(new StatsMgr4());
+        stats_mgr4_->addExchangeStats(StatsMgr4::XCHG_DO);
+        if (options.getExchangeMode() == CommandOptions::DO_SA) {
+            stats_mgr4_->addExchangeStats(StatsMgr4::XCHG_RA);
+        }
+
+    } else if (options.getIpVersion() == 6) {
+        stats_mgr6_.reset();
+        stats_mgr6_ = StatsMgr6Ptr(new StatsMgr6());
+        stats_mgr6_->addExchangeStats(StatsMgr6::XCHG_SA);
+        if (options.getExchangeMode() == CommandOptions::DO_SA) {
+            stats_mgr6_->addExchangeStats(StatsMgr6::XCHG_RR);
+        } 
+    }
+}
+
 int
 TestControl::openSocket(uint16_t port) const {
     CommandOptions& options = CommandOptions::instance();
@@ -278,9 +299,9 @@ TestControl::openSocket(uint16_t port) const {
     IOAddress remoteaddr(servername);
     if (port == 0) {
         if (options.getIpVersion() == 6) {
-            port = 547;
-        } else if (port == 0) {
-            port = 67;
+            port = DHCP6_CLIENT_PORT;
+        } else if (options.getIpVersion() == 4) {
+            port = 67; //  TODO: find out why port 68 is wrong here.
         }
     }
     if (options.getIpVersion() == 6) {
@@ -351,10 +372,60 @@ TestControl::openSocket(uint16_t port) const {
             }
         }
     }
+
     return(sock);
 }
 
 void
+TestControl::printStats() const {
+    CommandOptions& options = CommandOptions::instance();
+    if (options.getIpVersion() == 4) {
+        if (!stats_mgr4_) {
+            isc_throw(InvalidOperation, "Statistics Manager for DHCPv4 "
+                      "hasn't been initialized");
+        }
+        stats_mgr4_->printStats();
+    } else if (options.getIpVersion() == 6) {
+        if (!stats_mgr6_) {
+            isc_throw(InvalidOperation, "Statistics Manager for DHCPv6 "
+                      "hasn't been initialized");
+        }
+        stats_mgr6_->printStats();
+    }
+}
+
+void
+TestControl::receivePacket4(Pkt4Ptr& pkt4) {
+    switch(pkt4->getType()) {
+    case DHCPOFFER :
+        stats_mgr4_->passRcvdPacket(StatsMgr4::XCHG_DO, pkt4);
+        break;
+    case DHCPACK :
+        stats_mgr4_->passRcvdPacket(StatsMgr4::XCHG_RA, pkt4);
+        break;
+    default:
+        isc_throw(BadValue, "unknown type " << pkt4->getType()
+                  << " of received DHCPv4 packet");
+    }
+}
+
+void
+TestControl::receivePacket6(Pkt6Ptr& pkt6) {
+    switch(pkt6->getType()) {
+    case DHCPV6_ADVERTISE :
+        stats_mgr6_->passRcvdPacket(StatsMgr6::XCHG_SA, pkt6);
+        break;
+    case DHCPV6_REPLY :
+        stats_mgr6_->passRcvdPacket(StatsMgr6::XCHG_RR, pkt6);
+        break;
+    default:
+        isc_throw(BadValue, "unknown type " << pkt6->getType()
+                  << " of received DHCPv6 packet");
+    }
+
+}
+
+void
 TestControl::receivePackets() {
     int timeout = 0;
     bool receiving = true;
@@ -364,17 +435,17 @@ TestControl::receivePackets() {
             if (!pkt4) {
                 receiving = false;
             } else {
-                // TODO: replace this with use of StatsMgr to increase
-                // number of received packets. This can be done once
-                // the 1958 ticket is reviewed and checked-in.
-                std::cout << "Received packet" << std::endl;
+                pkt4->unpack();
+                receivePacket4(pkt4);
             }
         } else if (CommandOptions::instance().getIpVersion() == 6) {
             Pkt6Ptr pkt6 = IfaceMgr::instance().receive6(timeout);
             if (!pkt6) {
                 receiving  = false;
             } else {
-                std::cout << "Received DHCPv6 packet" << std::endl;
+                if (pkt6->unpack()) {
+                    receivePacket6(pkt6);
+                }
             }
         }
     }
@@ -453,6 +524,8 @@ TestControl::run() {
     }
     registerOptionFactories();
     TestControlSocket socket(openSocket());
+    
+    initializeStatsMgr();
     uint64_t packets_sent = 0;
     for (;;) {
         updateSendDue();
@@ -470,9 +543,9 @@ TestControl::run() {
                 sendSolicit6(socket);
             }
             ++packets_sent;
-            cout << "Packets sent " << packets_sent << endl;
         }
     }
+    printStats();
 }
 
 void
@@ -482,7 +555,7 @@ TestControl::sendDiscover4(const TestControlSocket& socket) {
     // Generate the MAC address to be passed in the packet.
     std::vector<uint8_t> mac_address = generateMacAddress();
     // Generate trasnaction id to be set for the new exchange.
-    const uint32_t transid = static_cast<uint32_t>(random());
+    const uint32_t transid = static_cast<uint32_t>(random() % 0x00FFFFFF);
     boost::shared_ptr<Pkt4> pkt4(new Pkt4(DHCPDISCOVER, transid));
     if (!pkt4) {
         isc_throw(Unexpected, "failed to create DISCOVER packet");
@@ -500,6 +573,11 @@ TestControl::sendDiscover4(const TestControlSocket& socket) {
     setDefaults4(socket, pkt4);
     pkt4->pack();
     IfaceMgr::instance().send(pkt4);
+    if (!stats_mgr4_) {
+        isc_throw(InvalidOperation, "Statistics Manager for DHCPv4 "
+                  "hasn't been initialized");
+    }
+    stats_mgr4_->passSentPacket(StatsMgr4::XCHG_DO, pkt4);
 }
 
 void
@@ -511,7 +589,7 @@ TestControl::sendSolicit6(const TestControlSocket& socket) {
     // Generate DUID to be passed to the packet
     std::vector<uint8_t> duid = generateDuid();
     // Generate trasnaction id to be set for the new exchange.
-    const uint32_t transid = static_cast<uint32_t>(random());
+    const uint32_t transid = static_cast<uint32_t>(random() % 0x00FFFFFF);
     boost::shared_ptr<Pkt6> pkt6(new Pkt6(DHCPV6_SOLICIT, transid));
     if (!pkt6) {
         isc_throw(Unexpected, "failed to create SOLICIT packet");
@@ -525,6 +603,11 @@ TestControl::sendSolicit6(const TestControlSocket& socket) {
     setDefaults6(socket, pkt6);
     pkt6->pack();
     IfaceMgr::instance().send(pkt6);
+    if (!stats_mgr6_) {
+        isc_throw(InvalidOperation, "Statistics Manager for DHCPv6 "
+                  "hasn't been initialized");
+    }
+    stats_mgr6_->passSentPacket(StatsMgr6::XCHG_SA, pkt6);
 }
 
 void

+ 32 - 1
tests/tools/perfdhcp/test_control.h

@@ -19,12 +19,15 @@
 #include <vector>
 
 #include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
 #include <boost/date_time/posix_time/posix_time.hpp>
 
 #include <dhcp/dhcp6.h>
 #include <dhcp/pkt4.h>
 #include <dhcp/pkt6.h>
 
+#include "stats_mgr.h"
+
 namespace isc {
 namespace perfdhcp {
 
@@ -44,6 +47,15 @@ namespace perfdhcp {
 class TestControl : public boost::noncopyable {
 public:
 
+    // Statistics Manager for DHCPv4.
+    typedef StatsMgr<dhcp::Pkt4> StatsMgr4;
+    // Pointer to Statistics Manager for DHCPv4;
+    typedef boost::shared_ptr<StatsMgr4> StatsMgr4Ptr;
+    // Statictics Manager for DHCPv6.
+    typedef StatsMgr<dhcp::Pkt6> StatsMgr6;
+    // Pointer to Statistics Manager for DHCPv6.
+    typedef boost::shared_ptr<StatsMgr6> StatsMgr6Ptr;
+
     /// \brief Socket wrapper class.
     ///
     /// This is wrapper class that holds descriptor of the socket
@@ -152,7 +164,6 @@ protected:
     /// \return true if any of the exit conditions is fulfiled.
     bool checkExitConditions() const;
 
-
     /// \brief Factory function to create DHCPv6 ELAPSED_TIME option.
     ///
     /// This factory function creates DHCPv6 ELAPSED_TIME option instance.
@@ -284,6 +295,12 @@ protected:
     /// \return number of exchanges to be started immediatelly.
     uint64_t getNextExchangesNum() const;
 
+    /// \brief Initializes Statistics Manager.
+    ///
+    /// This function initializes Statistics Manager. If there is
+    /// the one initialized already it is released.
+    void initializeStatsMgr();
+
     /// \brief Open socket to communicate with DHCP server.
     ///
     /// Method opens socket and binds it to local address. Function will
@@ -305,6 +322,17 @@ protected:
     /// \return socket descriptor.
     int openSocket(uint16_t port = 0) const;
 
+    /// \brief Print performance statistics.
+    ///
+    /// Method prints performance statistics.
+    /// \throws isc::InvalidOperation if Statistics Manager was
+    /// not initialized.
+    void printStats() const;
+
+    void receivePacket4(dhcp::Pkt4Ptr& pkt4);
+
+    void receivePacket6(dhcp::Pkt6Ptr& pkt4);
+
     /// \brief Receive DHCPv4 or DHCPv6 packets from the server.
     ///
     /// Method receives DHCPv4 or DHCPv6 packets from the server.
@@ -408,6 +436,9 @@ private:
     boost::posix_time::ptime last_sent_;   ///< Indicates when the last exchange
                                            /// was initiated.
 
+    StatsMgr4Ptr stats_mgr4_;  /// Statistics Manager 4.
+    StatsMgr6Ptr stats_mgr6_;  /// Statistics Manager 6.
+
     uint64_t sent_packets_0_;
     uint64_t sent_packets_1_;
 };