Ido Barkan has uploaded a new change for review. Change subject: net: tests: support iperf3 for performance tests ......................................................................
net: tests: support iperf3 for performance tests Support running iperf3 client server using context managers in an optional network namespace. This is handy for performance testing on a single machine. TC qos tests following patches use it. Change-Id: I15657f8844d131c5444dd680b8de7aa1c4ec2638 Signed-off-by: Ido Barkan <[email protected]> --- M configure.ac M lib/vdsm/constants.py.in M tests/nettestlib.py 3 files changed, 92 insertions(+), 3 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/48/46448/1 diff --git a/configure.ac b/configure.ac index 88817a8..1fee53c 100644 --- a/configure.ac +++ b/configure.ac @@ -285,6 +285,7 @@ AC_PATH_PROG([IFUP_PATH], [ifup], [/sbin/ifup]) AC_PATH_PROG([IONICE_PATH], [ionice], [/usr/bin/ionice]) AC_PATH_PROG([IP_PATH], [ip], [/sbin/ip]) +AC_PATH_PROG([IPERF3_PATH], [iperf3], [/usr/bin/iperf3]) AC_PATH_PROG([ISCSIADM_PATH], [iscsiadm], [/sbin/iscsiadm]) AC_PATH_PROG([KILL_PATH], [kill], [/bin/kill]) AC_PATH_PROG([LVM_PATH], [lvm], [/sbin/lvm]) diff --git a/lib/vdsm/constants.py.in b/lib/vdsm/constants.py.in index c9dff39..d4adac9 100644 --- a/lib/vdsm/constants.py.in +++ b/lib/vdsm/constants.py.in @@ -117,6 +117,7 @@ EXT_IFDOWN = '@IFDOWN_PATH@' EXT_IFUP = '@IFUP_PATH@' EXT_IONICE = '@IONICE_PATH@' +EXT_IPERF3 = '@IPERF3_PATH@' EXT_ISCSIADM = '@ISCSIADM_PATH@' EXT_TC = '@TC_PATH@' diff --git a/tests/nettestlib.py b/tests/nettestlib.py index c923f44..d019778 100644 --- a/tests/nettestlib.py +++ b/tests/nettestlib.py @@ -20,6 +20,7 @@ import errno import fcntl import functools +import json import os import platform import signal @@ -28,13 +29,17 @@ from multiprocessing import Process from nose.plugins.skip import SkipTest +import time -from vdsm.constants import EXT_BRCTL, EXT_TC -from vdsm.ipwrapper import addrAdd, linkSet, linkAdd, linkDel, IPRoute2Error +from vdsm.constants import EXT_BRCTL, EXT_TC, EXT_IPERF3 +from vdsm.ipwrapper import addrAdd, linkSet, linkAdd, linkDel, IPRoute2Error, \ + netns_add, netns_delete from vdsm.netlink import monitor -from vdsm.utils import execCmd, random_iface_name +from vdsm.utils import (execCmd, random_iface_name, pgrep, kill_and_rm_pid, + CommandPath) EXT_IP = "/sbin/ip" +_IPERF3_BINARY = CommandPath('iperf3', EXT_IPERF3) class ExecError(RuntimeError): @@ -237,6 +242,70 @@ raise SkipTest(message) +class _Iperf(object): + @staticmethod + def stop(): + pids = pgrep(_IPERF3_BINARY.name) + for pid in pids: + kill_and_rm_pid(pid, pid_file=None) + + +class IperfServer(_Iperf): + """starts iperf as a daemon""" + def __init__(self, host, network_ns=None): + """host: the IP address for the server to listen on. + network_ns: an optional network namespace for the server to run in. + """ + self._bind_to = host + self._net_ns = network_ns + + def start(self): + cmd = [EXT_IPERF3, '--server', '--bind', self._bind_to, '--daemon'] + if self._net_ns is not None: + cmd = ['ip', 'netns', 'exec', self._net_ns] + cmd + rc, out, err = execCmd(cmd) + return rc + + +class IperfClient(_Iperf): + def __init__(self, server_ip, bind_to, test_time, threads=1): + """the client generate a machine readable json output that is set in + _raw_output upon completion, ANd can be read using the 'out' property. + server_ip: the ip of the corresponding iperf server + bind_to: IP address of the client + test_time: in seconds + """ + self._server_ip = server_ip + self._bind_to = bind_to + self._test_time = test_time + self._threads = threads + self._raw_output = None + + def start(self): + cmd = [EXT_IPERF3, '--client', self._server_ip, + '--version4', # only IPv4 + '--time', str(self._test_time), '--parallel', + str(self._threads), '--bind', self._bind_to, + '--zerocopy', # use less cpu + '--json'] + rc, self._raw_output, err = execCmd(cmd) + if rc == 1 and 'No route to host' in self.error: + time.sleep(3) + rc, self._raw_output, err = execCmd(cmd) + if rc: + raise Exception('iperf3 client failed: cmd=%s, rc=%s, out=%s, ' + 'err=%s' % (' '.join(cmd), rc, self._raw_output, + err)) + + @property + def error(self): + return self.out['error'] + + @property + def out(self): + return json.loads(' '.join(self._raw_output)) + + @contextmanager def dummy_device(prefix='dummy_', max_length=11): dummy_interface = Dummy(prefix, max_length) @@ -304,3 +373,21 @@ check_tc() return f(*a, **kw) return wrapper + + +def check_iperf(): + try: + execCmd([_IPERF3_BINARY.cmd, "--version"]) + except OSError as e: + if e.errno == errno.ENOENT: + raise SkipTest("Cannot run %r: %s\nDo you have iperf3 installed?" + % (_IPERF3_BINARY.cmd, e)) + raise + + +def requires_iperf3(f): + @functools.wraps(f) + def wrapper(*a, **kw): + check_iperf() + return f(*a, **kw) + return wrapper -- To view, visit https://gerrit.ovirt.org/46448 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I15657f8844d131c5444dd680b8de7aa1c4ec2638 Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Ido Barkan <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
