BIND 10 trac1958, updated. 5d2116c14a18c5aa2f41fa75e0f893ad8a645bf3 [1958] Provided access to all basic counters and created corresponding unit tests.

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Jul 19 14:48:43 UTC 2012


The branch, trac1958 has been updated
       via  5d2116c14a18c5aa2f41fa75e0f893ad8a645bf3 (commit)
      from  df4d0be872ff9ff4e120e156b71d0abc25df0319 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 5d2116c14a18c5aa2f41fa75e0f893ad8a645bf3
Author: Marcin Siodelski <marcin at isc.org>
Date:   Thu Jul 19 16:48:19 2012 +0200

    [1958] Provided access to all basic counters and created corresponding unit tests.

-----------------------------------------------------------------------

Summary of changes:
 tests/tools/perfdhcp/stats_mgr.h                 |  254 ++++++++++++++++++----
 tests/tools/perfdhcp/tests/stats_mgr_unittest.cc |  191 +++++++++++++++-
 2 files changed, 394 insertions(+), 51 deletions(-)

-----------------------------------------------------------------------
diff --git a/tests/tools/perfdhcp/stats_mgr.h b/tests/tools/perfdhcp/stats_mgr.h
index b224fa7..0fed0ae 100644
--- a/tests/tools/perfdhcp/stats_mgr.h
+++ b/tests/tools/perfdhcp/stats_mgr.h
@@ -85,7 +85,9 @@ public:
                 boost::multi_index::sequenced<>,
                 boost::multi_index::hashed_non_unique<
                         boost::multi_index::global_fun<
-                            boost::shared_ptr<T>, uint32_t, &ExchangeStats::transid_hash
+                            boost::shared_ptr<T>,
+                            uint32_t,
+                            &ExchangeStats::transid_hash
                         >
                 >
             >
@@ -111,7 +113,9 @@ public:
             square_sum_delay_(0.),
             ordered_lookups_(0),
             unordered_lookup_size_sum_(0),
-            unordered_lookups_(0) {
+            unordered_lookups_(0),
+            sent_packets_num_(0),
+            rcvd_packets_num_(0) {
             sent_packets_cache_ = sent_packets_.begin();
         }
 
@@ -121,6 +125,7 @@ public:
         ///
         /// \param packet packet object to be added.
         void appendSent(const boost::shared_ptr<T> packet) {
+            ++sent_packets_num_;
             sent_packets_.template get<0>().push_back(packet);
         }
 
@@ -130,9 +135,55 @@ public:
         ///
         /// \param packet packet object to be added.
         void appendRcvd(const boost::shared_ptr<T> packet) {
+            ++rcvd_packets_num_;
             rcvd_packets_.template get<0>().push_back(packet);
         }
 
+        ///  \brief Update delay counters.
+        ///
+        /// Method updates delay counters based on timestamps of
+        /// sent and received packets.
+        ///
+        /// \param sent_packet sent packet
+        /// \param rcvd_packet received packet
+        /// \throw isc::Unexpected if failed to calculate timestamps
+        void updateDelays(const boost::shared_ptr<T> sent_packet,
+                          const boost::shared_ptr<T> rcvd_packet) {
+            boost::posix_time::ptime sent_time = sent_packet->getTimestamp();
+            boost::posix_time::ptime rcvd_time = rcvd_packet->getTimestamp();
+
+            if (sent_time.is_not_a_date_time() ||
+                rcvd_time.is_not_a_date_time()) {
+                isc_throw(Unexpected,
+                          "Timestamp must be set for sent and "
+                          "received packet to measure RTT");
+            }
+            boost::posix_time::time_period period(sent_time, rcvd_time);
+            // We don't bother calculating deltas in nanoseconds. It is much
+            // more convenient to use seconds instead because we are going to
+            // sum them up.
+            double delta =
+                static_cast<double>(period.length().total_nanoseconds()) / 1e9;
+
+            if (delta < 0) {
+                isc_throw(Unexpected, "Sent packet's timestamp must not be "
+                          "greater than received packet's timestamp");
+            }
+
+            // Record the minimum delay between sent and received packets.
+            if (delta < min_delay_) {
+                min_delay_ = delta;
+            }
+            // Record the maximum delay between sent and received packets.
+            if (delta > max_delay_) {
+                max_delay_ = delta;
+            }
+            // Update delay sum and square sum. That will be used to calculate
+            // mean delays.
+            sum_delay_ += delta;
+            square_sum_delay_ += delta * delta;
+        }
+
         /// \brief Find packet on the list of sent packets.
         ///
         /// Method finds packet with specified transaction id on the list
@@ -149,21 +200,54 @@ public:
         /// not found
         boost::shared_ptr<T> findSent(const uint32_t transid) {
             if (sent_packets_.size() == 0) {
+                // List of sent packets is empty so there is no sense
+                // to continue looking fo the packet. It also means
+                // that the received packet we got has no corresponding
+                // sent packet so orphans counter has to be updated.
                 ++orphans_;
                 return boost::shared_ptr<T>();
             } else if (sent_packets_cache_ == sent_packets_.end()) {
+                // Even if there are still many unmatched packets on the
+                // list we might hit the end of it because of unordered
+                // lookups. The next logical step is to reset cache.
                 sent_packets_cache_ = sent_packets_.begin();
             }
 
+            // With this variable we will be signalling success or failure
+            // to find the packet.
             bool packet_found = false;
+            // Most likely responses are sent from the server in the same
+            // order as client's requests to the server. We are caching
+            // next sent packet and first try to match with it the next
+            // incoming packet. We are successful if there is no
+            // packet drop or out of order packets sent. This is actually
+            // the fastest way to look for packets.
             if ((*sent_packets_cache_)->getTransid() == transid) {
                 ++ordered_lookups_;
                 packet_found = true;
             } else {
+                // If we are here, it means that we were unable to match the
+                // next incoming packet with next sent packet so we need to
+                // take a little more expensive approach to look packets using
+                // alternative index (transaction id & 1023).
                 PktListTransidIndex& idx = sent_packets_.template get<1>();
+                // Packets are grouped using trasaction id masking with value
+                // of 1023. For instance, packets with transaction id equal to
+                // 1, 1024 ... will belong to the same group (a.k.a. bucket).
+                // When using alternative index we don't find the packet but
+                // bucket of packets and need to iterate through the bucket
+                // to find the one that has desired transaction id.
                 std::pair<PktListTransidIterator,PktListTransidIterator> p =
                     idx.equal_range(transid & 1023);
+                // We want to keep statistics of unordered lookups to make
+                // sure that there is a right balance before number of
+                // unordered lookups and ordered lookups. If number of unordered
+                // lookups is high it may mean that many packets are lost or
+                // sent out of order.
                 ++unordered_lookups_;
+                // We also want to keep the mean value of the bucket. The lower
+                // bucket size the better. If bucket sizes appear to big we
+                // might want to increase number of buckets.
                 unordered_lookup_size_sum_ += std::distance(p.first, p.second);
                 for (PktListTransidIterator it = p.first; it != p.second;
                      ++it) {
@@ -177,53 +261,20 @@ public:
             }
 
             if (!packet_found) {
+                // If we are here, it means that both ordered lookup and
+                // unordered lookup failed. Searched packet is not on the list.
                 ++orphans_;
                 return boost::shared_ptr<T>();
             }
 
             boost::shared_ptr<T> sent_packet(*sent_packets_cache_);
-            ++sent_packets_cache_;
+            // If packet was found, we assume it will be never searched
+            // again. We want to delete this packet from the list to
+            // improve performance of future searches.
+            sent_packets_cache_ = eraseSent(sent_packets_cache_);
             return sent_packet;
         }
 
-        ///  \brief Update delay counters.
-        ///
-        /// Method updates delay counters based on timestamps of
-        /// sent and received packets.
-        ///
-        /// \param sent_packet sent packet
-        /// \param rcvd_packet received packet
-        /// \throw isc::Unexpected if failed to calculate timestamps
-        void updateDelays(const boost::shared_ptr<T> sent_packet,
-                          const boost::shared_ptr<T> rcvd_packet) {
-            boost::posix_time::ptime sent_time = sent_packet->getTimestamp();
-            boost::posix_time::ptime rcvd_time = rcvd_packet->getTimestamp();
-
-            if (sent_time.is_not_a_date_time() ||
-                rcvd_time.is_not_a_date_time()) {
-                isc_throw(Unexpected,
-                          "Timestamp must be set for sent and "
-                          "received packet to measure RTT");
-            }
-            boost::posix_time::time_period period(sent_time, rcvd_time);
-            double delta =
-                static_cast<double>(period.length().total_nanoseconds()) / 1e9;
-
-            if (delta < 0) {
-                isc_throw(Unexpected, "Sent packet's timestamp must not be "
-                          "greater than received packet's timestamp");
-            }
-
-            if (delta < min_delay_) {
-                min_delay_ = delta;
-            }
-            if (delta > max_delay_) {
-                max_delay_ = delta;
-            }
-            sum_delay_ += delta;
-            square_sum_delay_ += delta * delta;
-        }
-
         /// \brief Return minumum delay between sent and received packet.
         ///
         /// Method returns minimum delay between sent and received packet.
@@ -271,6 +322,9 @@ public:
         ///
         /// \return average unordered lookup set size.
         double getAvgUnorderedLookupSetSize() const {
+            if (unordered_lookups_ == 0) {
+                return 0.;
+            }
             return static_cast<double>(unordered_lookup_size_sum_) /
                 static_cast<double>(unordered_lookups_);
         }
@@ -285,7 +339,6 @@ public:
         /// \return number of unordered lookups.
         uint64_t getUnorderedLookups() const { return unordered_lookups_; }
 
-
         /// \brief Return number of ordered sent packets lookups
         ///
         /// Method returns number of ordered sent packet lookups.
@@ -296,6 +349,25 @@ public:
         ///
         /// \return number of ordered lookups.
         uint64_t getOrderedLookups() const { return ordered_lookups_; }
+
+        /// \brief Return total number of sent packets
+        ///
+        /// Method returns total number of sent packets.
+        ///
+        /// \return number of sent packets.
+        uint64_t getSentPacketsNum() const {
+            return sent_packets_num_;
+        }
+
+        /// \brief Return total number of received packets
+        ///
+        /// Method returns total number of received packets.
+        ///
+        /// \return number of received packets.
+        uint64_t getRcvdPacketsNum() const {
+            return rcvd_packets_num_;
+        }
+
     private:
 
         /// \brief Private default constructor.
@@ -304,6 +376,18 @@ public:
         /// class to specify exchange type explicitely.
         ExchangeStats();
 
+
+        /// \brief Erase packet from the list of sent packets.
+        ///
+        /// Method erases packet from the list of sent packets.
+        ///
+        /// \param it iterator pointing to packet to be erased.
+        /// \return iterator pointing to packet following erased
+        /// packet or sent_packets_.end() if packet not found.
+         PktListIterator eraseSent(const PktListIterator it) {
+            return sent_packets_.template get<0>().erase(it);
+        }
+
         ExchangeType xchg_type_;             ///< Packet exchange type.
         PktList sent_packets_;               ///< List of sent packets.
 
@@ -337,6 +421,8 @@ public:
         uint64_t ordered_lookups_;     ///< Number of ordered sent packets
                                        ///< lookups.
 
+        uint64_t sent_packets_num_;    ///< Total number of sent packets.
+        uint64_t rcvd_packets_num_;    ///< Total number of received packets.
     };
 
     /// Pointer to ExchangeStats.
@@ -400,6 +486,59 @@ public:
         }
     }
 
+    /// \brief Return minumum delay between sent and received packet.
+    ///
+    /// Method returns minimum delay between sent and received packet
+    /// for specified exchange type.
+    ///
+    /// \param xchg_type exchange type.
+    /// \throw isc::BadValue if invalid exchange type specified.
+    /// \return minimum delay between packets.
+    double getMinDelay(const ExchangeType xchg_type) const {
+        ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
+        return xchg_stats->getMinDelay();
+    }
+
+    /// \brief Return maxmimum delay between sent and received packet.
+    ///
+    /// Method returns maximum delay between sent and received packet
+    /// for specified exchange type.
+    ///
+    /// \param xchg_type exchange type.
+    /// \throw isc::BadValue if invalid exchange type specified.
+    /// \return maximum delay between packets.
+    double getMaxDelay(const ExchangeType xchg_type) const {
+        ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
+        return xchg_stats->getMaxDelay();
+    }
+
+    /// \brief Return sum of delays between sent and received packets.
+    ///
+    /// Method returns sum of delays between sent and received packets
+    /// for specified exchange type.
+    ///
+    /// \param xchg_type exchange type.
+    /// \throw isc::BadValue if invalid exchange type specified.
+    /// \return sum of delays between sent and received packets.
+    double getSumDelay(const ExchangeType xchg_type) const {
+        ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
+        return xchg_stats->getSumDelay();
+    }
+
+    /// \brief Return square sum of delays between sent and received
+    /// packets.
+    ///
+    /// Method returns square sum of delays between sent and received
+    /// packets for specified exchange type.
+    ///
+    /// \param xchg_type exchange type.
+    /// \throw isc::BadValue if invalid exchange type specified.
+    /// \return square sum of delays between sent and received packets.
+    double getSquareSumDelay(const ExchangeType xchg_type) const {
+        ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
+        return xchg_stats->getSquareSumDelay();
+    }
+
     /// \brief Return number of orphant packets.
     ///
     /// Method returns number of orphant packets for specified
@@ -420,6 +559,7 @@ public:
     /// unordered packet lookup using transaction id.
     ///
     /// \param xchg_type exchange type.
+    /// \throw isc::BadValue if invalid exchange type specified.
     /// \return average unordered lookup set size.
     double getAvgUnorderedLookupSetSize(const ExchangeType xchg_type) const {
         ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
@@ -433,6 +573,8 @@ public:
     /// out of order by server - transaction id of received
     /// packet does not match transaction id of next sent packet.
     ///
+    /// \param xchg_type exchange type.
+    /// \throw isc::BadValue if invalid exchange type specified.
     /// \return number of unordered lookups.
     uint64_t getUnorderedLookups(const ExchangeType xchg_type) const {
         ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
@@ -447,14 +589,40 @@ public:
     /// If packets are skipped or received out of order, lookup
     /// function will use unordered lookup (with hash table).
     ///
+    /// \param xchg_type exchange type.
+    /// \throw isc::BadValue if invalid exchange type specified.
     /// \return number of ordered lookups.
     uint64_t getOrderedLookups(const ExchangeType xchg_type) const {
         ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
         return xchg_stats->getOrderedLookups();
     }
 
-private:
+    /// \brief Return total number of sent packets
+    ///
+    /// Method returns total number of sent packets for specified
+    /// exchange type.
+    ///
+    /// \param xchg_type exchange type.
+    /// \throw isc::BadValue if invalid exchange type specified.
+    /// \return number of sent packets.
+    uint64_t getSentPacketsNum(const ExchangeType xchg_type) const {
+        ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
+        return xchg_stats->getSentPacketsNum();
+    }
 
+    /// \brief Return total number of received packets
+    ///
+    /// Method returns total number of received packets for specified
+    /// exchange type.
+    ///
+    /// \param xchg_type exchange type.
+    /// \throw isc::BadValue if invalid exchange type specified.
+    /// \return number of received packets.
+    uint64_t getRcvdPacketsNum(const ExchangeType xchg_type) const {
+        ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
+        return xchg_stats->getRcvdPacketsNum();
+    }
+private:
     /// \brief Return exchange stats object for given exchange type
     ///
     /// Method returns exchange stats object for given exchange type.
diff --git a/tests/tools/perfdhcp/tests/stats_mgr_unittest.cc b/tests/tools/perfdhcp/tests/stats_mgr_unittest.cc
index 2d6ab14..38cd1c2 100644
--- a/tests/tools/perfdhcp/tests/stats_mgr_unittest.cc
+++ b/tests/tools/perfdhcp/tests/stats_mgr_unittest.cc
@@ -16,6 +16,7 @@
 
 #include <exceptions/exceptions.h>
 #include <dhcp/dhcp4.h>
+#include <dhcp/dhcp6.h>
 #include <dhcp/pkt4.h>
 #include <dhcp/pkt6.h>
 
@@ -43,21 +44,79 @@ public:
     Pkt4* createPacket4(const uint8_t msg_type,
                         const uint32_t transid) {
         Pkt4* pkt = new Pkt4(msg_type, transid);
+        // Packet timestamp is normally updated by interface
+        // manager on packets reception or send. Unit tests
+        // do not use interface manager so we need to do it
+        // ourselfs.
         pkt->updateTimestamp();
         return pkt;
     }
+
+    Pkt6* createPacket6(const uint8_t msg_type,
+                        const uint32_t transid) {
+        Pkt6* pkt = new Pkt6(msg_type, transid);
+        // Packet timestamp is normally updated by interface
+        // manager on packets reception or send. Unit tests
+        // do not use interface manager so we need to do it
+        // ourselfs.
+        pkt->updateTimestamp();
+        return pkt;
+    }
+
+    void passMultiplePackets6(const boost::shared_ptr<StatsMgr6> stats_mgr,
+                              const StatsMgr6::ExchangeType xchg_type,
+                              const uint8_t packet_type,
+                              const int num_packets,
+                              const bool receive = false) {
+        for (int i = 0; i < num_packets; ++i) {
+            boost::shared_ptr<Pkt6>
+                packet(createPacket6(packet_type, i));
+
+            if (receive) {
+                ASSERT_NO_THROW(
+                    stats_mgr->passRcvdPacket(xchg_type, packet);
+                );
+            } else {
+                ASSERT_NO_THROW(
+                    stats_mgr->passSentPacket(xchg_type, packet)
+                );
+            }
+        }
+    }
+
 };
 
 TEST_F(StatsMgrTest, Constructor) {
     boost::scoped_ptr<StatsMgr4> stats_mgr(new StatsMgr4());
+    stats_mgr->addExchangeStats(StatsMgr4::XCHG_DO);
+    EXPECT_EQ(
+        std::numeric_limits<double>::max(),
+        stats_mgr->getMinDelay(StatsMgr4::XCHG_DO)
+    );
+    EXPECT_EQ(0, stats_mgr->getMaxDelay(StatsMgr4::XCHG_DO));
+    EXPECT_EQ(0, stats_mgr->getSumDelay(StatsMgr4::XCHG_DO));
+    EXPECT_EQ(0, stats_mgr->getOrphans(StatsMgr4::XCHG_DO));
+    EXPECT_EQ(0, stats_mgr->getSquareSumDelay(StatsMgr4::XCHG_DO));
+    EXPECT_EQ(0, stats_mgr->getOrderedLookups(StatsMgr4::XCHG_DO));
+    EXPECT_EQ(0, stats_mgr->getUnorderedLookups(StatsMgr4::XCHG_DO));
+    EXPECT_EQ(0, stats_mgr->getSentPacketsNum(StatsMgr4::XCHG_DO));
+    EXPECT_EQ(0, stats_mgr->getRcvdPacketsNum(StatsMgr4::XCHG_DO));
+
+    double avg_size = 0.;
+    ASSERT_NO_THROW(
+        avg_size = stats_mgr->getAvgUnorderedLookupSetSize(StatsMgr4::XCHG_DO);
+    );
+    EXPECT_EQ(0., avg_size);
 }
 
-TEST_F(StatsMgrTest, Exchanges) {
+TEST_F(StatsMgrTest, Exchange) {
     boost::scoped_ptr<StatsMgr4> stats_mgr(new StatsMgr4());
     boost::shared_ptr<Pkt4> sent_packet(createPacket4(DHCPDISCOVER,
                                                       common_transid));
     boost::shared_ptr<Pkt4> rcvd_packet(createPacket4(DHCPOFFER,
                                                       common_transid));
+    // This is expected to throw because XCHG_DO was not yet
+    // added to Stats Manager for tracking.
     EXPECT_THROW(
         stats_mgr->passSentPacket(StatsMgr4::XCHG_DO, sent_packet),
         BadValue
@@ -67,7 +126,10 @@ TEST_F(StatsMgrTest, Exchanges) {
         BadValue
     );
 
+    // Adding DISCOVER-OFFER exchanges to be tracked by Stats Manager.
     stats_mgr->addExchangeStats(StatsMgr4::XCHG_DO);
+    // The following two attempts are expected to throw because
+    // invalid exchange types are passed (XCHG_RA instead of XCHG_DO)
     EXPECT_THROW(
         stats_mgr->passSentPacket(StatsMgr4::XCHG_RA, sent_packet),
         BadValue
@@ -77,6 +139,8 @@ TEST_F(StatsMgrTest, Exchanges) {
         BadValue
     );
 
+    // The following two attempts are expected to run fine because
+    // right exchange type is specified.
     EXPECT_NO_THROW(
         stats_mgr->passSentPacket(StatsMgr4::XCHG_DO, sent_packet)
     );
@@ -85,6 +149,46 @@ TEST_F(StatsMgrTest, Exchanges) {
     );
 }
 
+TEST_F(StatsMgrTest, MultipleExchanges) {
+    boost::shared_ptr<StatsMgr6> stats_mgr(new StatsMgr6());
+    stats_mgr->addExchangeStats(StatsMgr6::XCHG_SA);
+    stats_mgr->addExchangeStats(StatsMgr6::XCHG_RR);
+
+    // Simulate sending number of solicit packets.
+    const int solicit_packets_num = 10;
+    passMultiplePackets6(stats_mgr, StatsMgr6::XCHG_SA, DHCPV6_SOLICIT,
+                         solicit_packets_num);
+
+    // Simulate sending number of request packets. It is important that
+    // number of request packets is different then number of solicit
+    // packets. We can now check if right number packets went to
+    // the right exchange type group.
+    const int request_packets_num = 5;
+    passMultiplePackets6(stats_mgr, StatsMgr6::XCHG_RR, DHCPV6_REQUEST,
+                         request_packets_num);
+
+    // Check if all packets are successfuly passed to packet lists.
+    EXPECT_EQ(solicit_packets_num,
+              stats_mgr->getSentPacketsNum(StatsMgr6::XCHG_SA));
+    EXPECT_EQ(request_packets_num,
+              stats_mgr->getSentPacketsNum(StatsMgr6::XCHG_RR));
+
+    // Simulate reception of multiple packets for both SOLICIT-ADVERTISE
+    // and REQUEST-REPLY exchanges. Assume no packet drops.
+    const bool receive_packets = true;
+    passMultiplePackets6(stats_mgr, StatsMgr6::XCHG_SA, DHCPV6_ADVERTISE,
+                         solicit_packets_num, receive_packets);
+
+    passMultiplePackets6(stats_mgr, StatsMgr6::XCHG_RR, DHCPV6_REPLY,
+                         request_packets_num, receive_packets);
+
+    // Verify that all received packets are counted.
+    EXPECT_EQ(solicit_packets_num,
+              stats_mgr->getRcvdPacketsNum(StatsMgr6::XCHG_SA));
+    EXPECT_EQ(request_packets_num,
+              stats_mgr->getRcvdPacketsNum(StatsMgr6::XCHG_RR));
+}
+
 TEST_F(StatsMgrTest, SendReceiveSimple) {
     boost::scoped_ptr<StatsMgr4> stats_mgr(new StatsMgr4());
     boost::shared_ptr<Pkt4> sent_packet(createPacket4(DHCPDISCOVER,
@@ -92,15 +196,22 @@ TEST_F(StatsMgrTest, SendReceiveSimple) {
     boost::shared_ptr<Pkt4> rcvd_packet(createPacket4(DHCPOFFER,
                                                       common_transid));
     stats_mgr->addExchangeStats(StatsMgr4::XCHG_DO);
+    // The following attempt is expected to pass becase the right
+    // exchange type is used.
     ASSERT_NO_THROW(
         stats_mgr->passSentPacket(StatsMgr4::XCHG_DO, sent_packet)
     );
-    EXPECT_NO_THROW(
+    // It is ok, to pass to received packets here. First one will
+    // be matched with sent packet. The latter one will not be
+    // matched with sent packet but orphans counter will simply
+    // increase.
+    ASSERT_NO_THROW(
         stats_mgr->passRcvdPacket(StatsMgr4::XCHG_DO, rcvd_packet)
     );
-    EXPECT_NO_THROW(
+    ASSERT_NO_THROW(
         stats_mgr->passRcvdPacket(StatsMgr4::XCHG_DO, rcvd_packet)
     );
+    EXPECT_EQ(1, stats_mgr->getOrphans(StatsMgr4::XCHG_DO));
 }
 
 TEST_F(StatsMgrTest, SendReceiveUnordered) {
@@ -108,7 +219,9 @@ TEST_F(StatsMgrTest, SendReceiveUnordered) {
     boost::scoped_ptr<StatsMgr4> stats_mgr(new StatsMgr4());
     stats_mgr->addExchangeStats(StatsMgr4::XCHG_DO);
 
-    uint32_t transid[packets_num] = { 1, 1024, 2, 1025, 3, 1026, 4, 1027, 5, 1028 };
+    // Transaction ids of 10 packets to be sent and received.
+    uint32_t transid[packets_num] =
+        { 1, 1024, 2, 1025, 3, 1026, 4, 1027, 5, 1028 };
     for (int i = 0; i < packets_num; ++i) {
         boost::shared_ptr<Pkt4> sent_packet(createPacket4(DHCPDISCOVER,
                                                           transid[i]));
@@ -117,16 +230,24 @@ TEST_F(StatsMgrTest, SendReceiveUnordered) {
         );
     }
 
+    // We are simulating that received packets are coming in reverse order:
+    // 1028, 5, 1027 ....
     for (int i = 0; i < packets_num; ++i) {
-        boost::shared_ptr<Pkt4> rcvd_packet(createPacket4(DHCPDISCOVER,
-                                                          transid[packets_num - 1 - i]));
+        boost::shared_ptr<Pkt4>
+            rcvd_packet(createPacket4(DHCPDISCOVER,
+                                      transid[packets_num - 1 - i]));
         ASSERT_NO_THROW(
             stats_mgr->passRcvdPacket(StatsMgr4::XCHG_DO, rcvd_packet);
         );
     }
+    // All packets are expected to match (we did not drop any)
     EXPECT_EQ(0, stats_mgr->getOrphans(StatsMgr4::XCHG_DO));
-    EXPECT_EQ(10, stats_mgr->getUnorderedLookups(StatsMgr4::XCHG_DO));
-    std::cout << stats_mgr->getAvgUnorderedLookupSetSize(StatsMgr4::XCHG_DO) << std::endl;
+    // Most of the time we have to do unordered lookups except for the last
+    // one. Packets are removed from the sent list every time we have a match
+    // so eventually we come up with the single packet that caching iterator
+    // is pointing to. This is counted as ordered lookup.
+    EXPECT_EQ(1, stats_mgr->getOrderedLookups(StatsMgr4::XCHG_DO));
+    EXPECT_EQ(9, stats_mgr->getUnorderedLookups(StatsMgr4::XCHG_DO));
 }
 
 TEST_F(StatsMgrTest, Orphans) {
@@ -134,19 +255,73 @@ TEST_F(StatsMgrTest, Orphans) {
     boost::scoped_ptr<StatsMgr4> stats_mgr(new StatsMgr4());
     stats_mgr->addExchangeStats(StatsMgr4::XCHG_DO);
 
+    // We skip every second packet to simulate drops.
     for (int i = 0; i < packets_num; i += 2) {
         boost::shared_ptr<Pkt4> sent_packet(createPacket4(DHCPDISCOVER, i));
         ASSERT_NO_THROW(
             stats_mgr->passSentPacket(StatsMgr4::XCHG_DO, sent_packet)
         );
     }
+    // We pass all received packets.
     for (int i = 0; i < packets_num; ++i) {
         boost::shared_ptr<Pkt4> rcvd_packet(createPacket4(DHCPOFFER, i));
         ASSERT_NO_THROW(
             stats_mgr->passRcvdPacket(StatsMgr4::XCHG_DO, rcvd_packet);
         );
     }
+    // The half of received packets are expected not to have matching
+    // sent packet.
     EXPECT_EQ(packets_num / 2, stats_mgr->getOrphans(StatsMgr4::XCHG_DO));
 }
 
+TEST_F(StatsMgrTest, Delays) {
+    boost::scoped_ptr<StatsMgr4> stats_mgr(new StatsMgr4());
+    stats_mgr->addExchangeStats(StatsMgr4::XCHG_DO);
+
+    boost::shared_ptr<Pkt4> sent_packet(createPacket4(DHCPDISCOVER,
+                                                      common_transid));
+    ASSERT_NO_THROW(
+        stats_mgr->passSentPacket(StatsMgr4::XCHG_DO, sent_packet)
+    );
+
+    // There is way to differentiate timstamps of two packets other than
+    // sleep for before we create another packet. Packet is using current
+    // time to update its timestamp.
+    // Sleeping for two seconds will guarantee that delay between packets
+    // will be greater than 1 second. Note that posix time value is
+    // transformed to double value and it makes it hard to determine
+    // actual value to expect.
+    std::cout << "Sleeping for 2 seconds to test packet delays" << std::endl;
+    sleep(2);
+
+    boost::shared_ptr<Pkt4> rcvd_packet(createPacket4(DHCPOFFER,
+                                                      common_transid));
+    ASSERT_NO_THROW(
+        stats_mgr->passRcvdPacket(StatsMgr4::XCHG_DO, rcvd_packet);
+    );
+
+    // Calculate period between packets.
+    boost::posix_time::ptime sent_time = sent_packet->getTimestamp();
+    boost::posix_time::ptime rcvd_time = rcvd_packet->getTimestamp();
+
+    ASSERT_FALSE(sent_time.is_not_a_date_time());
+    ASSERT_FALSE(rcvd_time.is_not_a_date_time());
+
+    boost::posix_time::time_period period(sent_time, rcvd_time);
+
+    // Initially min delay is equal to MAX_DOUBLE. After first packets
+    // are passed, it is expected to set to actual value.
+    EXPECT_LT(stats_mgr->getMinDelay(StatsMgr4::XCHG_DO),
+              std::numeric_limits<double>::max());
+    EXPECT_GT(stats_mgr->getMinDelay(StatsMgr4::XCHG_DO), 1);
+
+    // Max delay is supposed to the same value as mininimum
+    // or maximum delay.
+    EXPECT_GT(stats_mgr->getMaxDelay(StatsMgr4::XCHG_DO), 1);
+
+    // Delay sums are now the same as minimum or maximum delay.
+    EXPECT_GT(stats_mgr->getSumDelay(StatsMgr4::XCHG_DO), 1);
+    EXPECT_GT(stats_mgr->getSquareSumDelay(StatsMgr4::XCHG_DO), 1);
+}
+
 }



More information about the bind10-changes mailing list