From: Ondrej Lichtner <olichtne(a)redhat.com>
Renamed the IcmpPing testmodule as just Ping. Implements the Ping
TestModule class that can be used to test connectivity between hosts.
The module returns statistics on the measured success rate of the Ping.
The PASS/FAIL of the Ping testmodule job indicates whether or not the
measurement was succesfull, actual connectivity status needs to be
evaluated outside of this class.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
v2: fixed missing if not match
---
lnst/Tests/IcmpPing.py | 63 ---------------------------
lnst/Tests/Ping.py | 97 ++++++++++++++++++++++++++++++++++++++++++
lnst/Tests/__init__.py | 2 +-
3 files changed, 98 insertions(+), 64 deletions(-)
delete mode 100644 lnst/Tests/IcmpPing.py
create mode 100644 lnst/Tests/Ping.py
diff --git a/lnst/Tests/IcmpPing.py b/lnst/Tests/IcmpPing.py
deleted file mode 100644
index ea3cd99..0000000
--- a/lnst/Tests/IcmpPing.py
+++ /dev/null
@@ -1,63 +0,0 @@
-import re
-import logging
-from lnst.Common.Parameters import IntParam, FloatParam, IpParam, DeviceParam
-from lnst.Common.TestModule import BaseTestModule, TestModuleError
-from lnst.Common.ExecCmd import exec_cmd
-
-class IcmpPing(BaseTestModule):
- """Port of old IcmpPing test modules"""
- dst = IpParam(mandatory=True)
- count = IntParam(default=10)
- interval = FloatParam(default=1.0)
- iface = DeviceParam()
- size = IntParam()
- limit_rate = IntParam(default=80)
-
- def _compose_cmd(self):
- cmd = "ping %s" % self.params.dst
- cmd += " -c %d" % self.params.count
- cmd += " -i %f" % self.params.interval
- if "iface" in self.params:
- cmd += " -I %s" % self.params.iface.name
-
- if "size" in self.params:
- cmd += " -s %d" % self.params.size
- return cmd
-
- def run(self):
- cmd = self._compose_cmd()
-
- limit_rate = self.params.limit_rate
-
- data_stdout = exec_cmd(cmd, die_on_err=False)[0]
- stat_pttr1 = r'(\d+) packets transmitted, (\d+) received'
- stat_pttr2 = r'rtt min/avg/max/mdev =
(\d+\.\d+)/(\d+\.\d+)/(\d+\.\d+)/(\d+\.\d+) ms'
-
- match = re.search(stat_pttr1, data_stdout)
- if not match:
- self._res_data = {"msg": "expected pattern not found"}
- return False
-
- trans_pkts, recv_pkts = match.groups()
- rate = int(round((float(recv_pkts) / float(trans_pkts)) * 100))
- logging.debug("Transmitted \"%s\", received \"%s\",
"
- "rate \"%d%%\", limit_rate \"%d%%\""
- % (trans_pkts, recv_pkts, rate, limit_rate))
-
- self._res_data = {"rate": rate,
- "limit_rate": limit_rate}
-
- match = re.search(stat_pttr2, data_stdout)
- if match:
- tmin, tavg, tmax, tmdev = [float(x) for x in match.groups()]
- logging.debug("rtt min \"%.3f\", avg \"%.3f\", max
\"%.3f\", "
- "mdev \"%.3f\"" % (tmin, tavg, tmax,
tmdev))
-
- self._res_data["rtt_min"] = tmin
- self._res_data["rtt_max"] = tmax
-
- if rate < limit_rate:
- self._res_data["msg"] = "rate is lower than limit"
- return False
-
- return True
diff --git a/lnst/Tests/Ping.py b/lnst/Tests/Ping.py
new file mode 100644
index 0000000..aacad05
--- /dev/null
+++ b/lnst/Tests/Ping.py
@@ -0,0 +1,97 @@
+import re
+import logging
+import subprocess
+from lnst.Common.Parameters import IntParam, FloatParam, IpParam, DeviceOrIpParam
+from lnst.Common.TestModule import BaseTestModule, TestModuleError
+from lnst.Common.ExecCmd import exec_cmd
+from lnst.Common.Utils import is_installed
+
+class Ping(BaseTestModule):
+ """Port of old IcmpPing test modules"""
+ dst = IpParam(mandatory=True)
+ count = IntParam(default=10)
+ interval = FloatParam(default=1.0)
+ interface = DeviceOrIpParam(mandatory=False)
+ size = IntParam()
+
+ def _compose_cmd(self):
+ cmd = "ping %s" % self.params.dst
+ cmd += " -c %d" % self.params.count
+ cmd += " -i %f" % self.params.interval
+ if "interface" in self.params:
+ from lnst.Devices.Device import Device
+ if isinstance(self.params.interface, Device):
+ cmd += " -I %s" % self.params.interface.name
+ else:
+ cmd += " -I %s" % str(self.params.interface)
+
+ if "size" in self.params:
+ cmd += " -s %d" % self.params.size
+ return cmd
+
+ def run(self):
+ self._res_data = {}
+ if not is_installed("ping"):
+ self._res_data["msg"] = "Ping is not installed on this
machine!"
+ logging.error(self._res_data["msg"])
+ return False
+
+ cmd = self._compose_cmd()
+
+ logging.debug("compiled command: {}".format(cmd))
+
+ ping_process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, close_fds=True)
+
+ try:
+ stdout, stderr = ping_process.communicate()
+ except KeyboardInterrupt:
+ pass
+
+ self._res_data["stderr"] = stderr
+
+ if stderr != "":
+ self._res_data["msg"] = "errors reported by ping"
+ logging.error(self._res_data["msg"])
+ logging.error(self._res_data["stderr"])
+ return False
+
+ if ping_process.returncode > 0:
+ self._res_data["msg"] = "returncode =
{}".format(ping_process.returncode)
+ logging.error(self._res_data["msg"])
+ return False
+
+ stat_pttr1 = r'(\d+) packets transmitted, (\d+) received'
+ stat_pttr2 = r'rtt min/avg/max/mdev =
(\d+\.\d+)/(\d+\.\d+)/(\d+\.\d+)/(\d+\.\d+) ms'
+
+ match = re.search(stat_pttr1, stdout)
+ if not match:
+ self._res_data = {"msg": "expected pattern not found"}
+ logging.error(self._res_data["msg"])
+ return False
+ else:
+ trans_pkts, recv_pkts = match.groups()
+ rate = int(round((float(recv_pkts) / float(trans_pkts)) * 100))
+ logging.debug("Transmitted '{}', received '{}', "
+ "rate '{}%'".format(trans_pkts, recv_pkts,
rate))
+
+ self._res_data = {"trans_pkts": trans_pkts,
+ "recv_pkts": recv_pkts,
+ "rate": rate}
+
+ match = re.search(stat_pttr2, stdout)
+ if not match:
+ self._res_data = {"msg": "expected pattern not found"}
+ logging.error(self._res_data["msg"])
+ return False
+ else:
+ tmin, tavg, tmax, tmdev = [float(x) for x in match.groups()]
+ logging.debug("rtt min \"%.3f\", avg \"%.3f\", max
\"%.3f\", "
+ "mdev \"%.3f\"" % (tmin, tavg, tmax,
tmdev))
+
+ self._res_data["rtt_min"] = tmin
+ self._res_data["rtt_max"] = tmax
+ self._res_data["rtt_avg"] = tavg
+ self._res_data["rtt_mdev"] = tmdev
+
+ return True
diff --git a/lnst/Tests/__init__.py b/lnst/Tests/__init__.py
index bca4893..a65890c 100644
--- a/lnst/Tests/__init__.py
+++ b/lnst/Tests/__init__.py
@@ -12,7 +12,7 @@ __author__ = """
olichtne(a)redhat.com (Ondrej Lichtner)
"""
-from lnst.Tests.IcmpPing import IcmpPing
+from lnst.Tests.Ping import Ping
from lnst.Tests.Iperf import IperfClient, IperfServer
#TODO add support for test classes from lnst-ctl.conf
--
2.17.0