ping: remove potential divide-by-zero in StatisticsCollector
refs #3504
Change-Id: I38c1a5079e2884e53a4fff2311c98b553f42c2a3
diff --git a/tests/ping/client/statistics-collector.t.cpp b/tests/ping/client/statistics-collector.t.cpp
index 6bcb9fb..270c576 100644
--- a/tests/ping/client/statistics-collector.t.cpp
+++ b/tests/ping/client/statistics-collector.t.cpp
@@ -120,7 +120,14 @@
BOOST_CHECK_EQUAL(stats.prefix, pingOptions.prefix);
BOOST_CHECK_EQUAL(stats.nSent, 2);
BOOST_CHECK_EQUAL(stats.nReceived, 0);
+ BOOST_CHECK_EQUAL(stats.nNacked, 0);
BOOST_CHECK_CLOSE(stats.packetLossRate, 1.0, 0.001);
+ BOOST_CHECK_CLOSE(stats.packetNackedRate, 0.0, 0.001);
+ BOOST_CHECK_CLOSE(stats.minRtt, std::numeric_limits<double>::max(), 0.001);
+ BOOST_CHECK_CLOSE(stats.maxRtt, 0.0, 0.001);
+ BOOST_CHECK_CLOSE(stats.sumRtt, 0.0, 0.001);
+ BOOST_CHECK(std::isnan(stats.avgRtt));
+ BOOST_CHECK(std::isnan(stats.stdDevRtt));
}
BOOST_AUTO_TEST_CASE(Resp50msLoss)
@@ -185,6 +192,22 @@
BOOST_CHECK_CLOSE(stats.packetLossRate, 0.5, 0.001);
}
+BOOST_AUTO_TEST_CASE(NoneSent)
+{
+ Statistics stats = sc.computeStatistics();
+ BOOST_CHECK_EQUAL(stats.prefix, pingOptions.prefix);
+ BOOST_CHECK_EQUAL(stats.nSent, 0);
+ BOOST_CHECK_EQUAL(stats.nReceived, 0);
+ BOOST_CHECK_EQUAL(stats.nNacked, 0);
+ BOOST_CHECK(std::isnan(stats.packetLossRate));
+ BOOST_CHECK(std::isnan(stats.packetNackedRate));
+ BOOST_CHECK_CLOSE(stats.minRtt, std::numeric_limits<double>::max(), 0.001);
+ BOOST_CHECK_CLOSE(stats.maxRtt, 0.0, 0.001);
+ BOOST_CHECK_CLOSE(stats.sumRtt, 0.0, 0.001);
+ BOOST_CHECK(std::isnan(stats.avgRtt));
+ BOOST_CHECK(std::isnan(stats.stdDevRtt));
+}
+
BOOST_AUTO_TEST_SUITE_END() // TestStatisticsCollector
BOOST_AUTO_TEST_SUITE_END() // Ping
diff --git a/tools/ping/client/statistics-collector.cpp b/tools/ping/client/statistics-collector.cpp
index 0e7ad2a..7954e64 100644
--- a/tools/ping/client/statistics-collector.cpp
+++ b/tools/ping/client/statistics-collector.cpp
@@ -85,11 +85,26 @@
statistics.pingStartTime = m_pingStartTime;
statistics.minRtt = m_minRtt;
statistics.maxRtt = m_maxRtt;
- statistics.packetLossRate = static_cast<double>(m_nSent - m_nReceived - m_nNacked) / static_cast<double>(m_nSent);
- statistics.packetNackedRate = static_cast<double>(m_nNacked) / static_cast<double>(m_nSent);
+
+ if (m_nSent > 0) {
+ statistics.packetLossRate = static_cast<double>(m_nSent - m_nReceived - m_nNacked) / static_cast<double>(m_nSent);
+ statistics.packetNackedRate = static_cast<double>(m_nNacked) / static_cast<double>(m_nSent);
+ }
+ else {
+ statistics.packetLossRate = std::numeric_limits<double>::quiet_NaN();
+ statistics.packetNackedRate = std::numeric_limits<double>::quiet_NaN();
+ }
+
statistics.sumRtt = m_sumRtt;
- statistics.avgRtt = m_sumRtt / m_nReceived;
- statistics.stdDevRtt = std::sqrt((m_sumRttSquared / m_nReceived) - (statistics.avgRtt * statistics.avgRtt));
+
+ if (m_nReceived > 0) {
+ statistics.avgRtt = m_sumRtt / m_nReceived;
+ statistics.stdDevRtt = std::sqrt((m_sumRttSquared / m_nReceived) - (statistics.avgRtt * statistics.avgRtt));
+ }
+ else {
+ statistics.avgRtt = std::numeric_limits<double>::quiet_NaN();
+ statistics.stdDevRtt = std::numeric_limits<double>::quiet_NaN();
+ }
return statistics;
}
@@ -97,24 +112,36 @@
std::ostream&
Statistics::printSummary(std::ostream& os) const
{
- os << nReceived << "/" << nSent << " packets, " << packetLossRate * 100.0
- << "% loss, min/avg/max/mdev = " << minRtt << "/" << avgRtt << "/" << maxRtt << "/"
- << stdDevRtt << " ms" << std::endl;
+ os << nReceived << "/" << nSent << " packets";
- return os;
+ if (nSent > 0) {
+ os << ", " << packetLossRate * 100.0 << "% lost, " << packetNackedRate * 100.0 << "% nacked";
+ }
+
+ if (nReceived > 0) {
+ os << ", min/avg/max/mdev = " << minRtt << "/" << avgRtt << "/" << maxRtt << "/" << stdDevRtt
+ << " ms";
+ }
+
+ return os << std::endl;
}
std::ostream&
operator<<(std::ostream& os, const Statistics& statistics)
{
os << "\n";
- os << "--- " << statistics.prefix <<" ping statistics ---\n";
+ os << "--- " << statistics.prefix << " ping statistics ---\n";
os << statistics.nSent << " packets transmitted";
os << ", " << statistics.nReceived << " received";
os << ", " << statistics.nNacked << " nacked";
- os << ", " << statistics.packetLossRate * 100.0 << "% packet loss";
- os << ", " << statistics.packetNackedRate * 100.0 << "% nacked";
+
+ if (statistics.nSent > 0) {
+ os << ", " << statistics.packetLossRate * 100.0 << "% lost";
+ os << ", " << statistics.packetNackedRate * 100.0 << "% nacked";
+ }
+
os << ", time " << statistics.sumRtt << " ms";
+
if (statistics.nReceived > 0) {
os << "\n";
os << "rtt min/avg/max/mdev = ";