Beispiel #1
0
    def find_binary(cls, ip_version, interval, length, host, marking=None, local_bind=None):
        """Find a suitable ping executable, looking first for a compatible
        `fping`, then falling back to the `ping` binary. Binaries are checked
        for the required capabilities."""

        if ip_version == 6:
            suffix = "6"
        else:
            suffix = ""


        fping = util.which('fping'+suffix)
        ping = util.which('ping'+suffix)

        if fping is not None:
            proc = subprocess.Popen([fping, '-h'],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            out,err = proc.communicate()
            # check for presence of timestamp option
            if "print timestamp before each output line" in str(out):
                return "{binary} -D -p {interval:.0f} -c {count:.0f} {marking} {local_bind} {host}".format(
                    binary=fping,
                    interval=interval * 1000, # fping expects interval in milliseconds
                    # since there's no timeout parameter for fping, calculate a total number
                    # of pings to send
                    count=length // interval + 1,
                    marking="-O {0}".format(marking) if marking else "",
                    local_bind="-I {0}".format(local_bind) if local_bind else "",
                    host=host)
            elif "must run as root?" in str(err):
                sys.stderr.write("Found fping but it seems to be missing permissions (no SUID?). Not using.\n")

        if ping is not None:
            # Ping can't handle hostnames for the -I parameter, so do a lookup first.
            if local_bind:
                local_bind=util.lookup_host(local_bind, ip_version)[4][0]

            # Try parsing the output of 'ping' and complain if no data is
            # returned from the parser. This should pick up e.g. the ping on OSX
            # not having a -D option and allow us to supply a better error message.
            proc = subprocess.Popen([ping, '-D', '-n', '-c', '1', 'localhost'],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            out,err = proc.communicate()
            if hasattr(out, 'decode'):
                out = out.decode(ENCODING)
            if not cls._parse(out)[0]:
                raise RuntimeError("Cannot parse output of the system ping binary ({ping}). "
                                   "Please install fping v3.5+.".format(ping=ping))

            return "{binary} -n -D -i {interval:.2f} -w {length:d} {marking} {local_bind} {host}".format(
                binary=ping,
                interval=max(0.2, interval),
                length=length,
                marking="-Q {0}".format(marking) if marking else "",
                local_bind="-I {0}".format(local_bind) if local_bind else "",
                host=host)

        raise RuntimeError("No suitable ping tool found.")
Beispiel #2
0
    def find_binary(cls, ip_version, interval, length, host, marking=None, local_bind=None):
        """Find a suitable ping executable, looking first for a compatible
        `fping`, then falling back to the `ping` binary. Binaries are checked
        for the required capabilities."""

        if ip_version == 6:
            suffix = "6"
        else:
            suffix = ""


        fping = util.which('fping'+suffix)
        ping = util.which('ping'+suffix)

        if fping is not None:
            proc = subprocess.Popen([fping, '-h'],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            out,err = proc.communicate()
            # check for presence of timestamp option
            if "print timestamp before each output line" in str(out):
                return "{binary} -D -p {interval:.0f} -c {count:.0f} {marking} {local_bind} {host}".format(
                    binary=fping,
                    interval=interval * 1000, # fping expects interval in milliseconds
                    # since there's no timeout parameter for fping, calculate a total number
                    # of pings to send
                    count=length // interval + 1,
                    marking="-O {0}".format(marking) if marking else "",
                    local_bind="-I {0}".format(local_bind) if local_bind else "",
                    host=host)
            elif "must run as root?" in str(err):
                sys.stderr.write("Found fping but it seems to be missing permissions (no SUID?). Not using.\n")

        if ping is not None:
            # Ping can't handle hostnames for the -I parameter, so do a lookup first.
            if local_bind:
                local_bind=util.lookup_host(local_bind, ip_version)[4][0]

            # Try parsing the output of 'ping' and complain if no data is
            # returned from the parser. This should pick up e.g. the ping on OSX
            # not having a -D option and allow us to supply a better error message.
            proc = subprocess.Popen([ping, '-D', '-n', '-c', '1', 'localhost'],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            out,err = proc.communicate()
            if hasattr(out, 'decode'):
                out = out.decode(ENCODING)
            if not cls._parse(out)[0]:
                raise RuntimeError("Cannot parse output of the system ping binary ({ping}). "
                                   "Please install fping v3.5+.".format(ping=ping))

            return "{binary} -n -D -i {interval:.2f} -w {length:d} {marking} {local_bind} {host}".format(
                binary=ping,
                interval=max(0.2, interval),
                length=length,
                marking="-Q {0}".format(marking) if marking else "",
                local_bind="-I {0}".format(local_bind) if local_bind else "",
                host=host)

        raise RuntimeError("No suitable ping tool found.")
Beispiel #3
0
    def find_binary(cls, host, interval, length, ip_version, local_bind=None, no_delay=False, udp=False, bw=None):
        iperf = util.which('iperf')

        if iperf is not None:
            proc = subprocess.Popen([iperf, '-h'],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            out,err = proc.communicate()

            if "--enhancedreports" in str(err):
                if udp:
                    udp_args = "--udp --bandwidth {}".format(bw if bw else "100M")
                else:
                    udp_args = ""
                return "{binary} --enhancedreports --reportstyle C --format m --client {host} --time {length} --interval {interval} " \
                    "{local_bind} {no_delay} {udp} {ip6}".format(
                        host=host,
                        binary=iperf,
                        length=length,
                        interval=interval,
                        ip6="--ipv6_domain" if ip_version == 6 else "", # --help output is wrong
                        local_bind="--bind {0}".format(local_bind) if local_bind else "",
                        no_delay="--nodelay" if no_delay else "",
                        udp=udp_args)
            else:
                sys.stderr.write("Found iperf binary, but it does not have an --enhancedreport option. Not using.\n")

        raise RuntimeError("No suitable Iperf binary found.")
    def find_binary(cls,
                    host,
                    interval,
                    length,
                    ip_version,
                    local_bind=None,
                    no_delay=False,
                    udp=False):
        iperf = util.which('iperf')

        if iperf is not None:
            proc = subprocess.Popen([iperf, '-h'],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            out, err = proc.communicate()

            if "--enhancedreports" in str(err):
                return "{binary} --enhancedreports --reportstyle C --format m --client {host} --time {length} --interval {interval} " \
                    "{local_bind} {no_delay} {udp} {ip6}".format(
                        host=host,
                        binary=iperf,
                        length=length,
                        interval=interval,
                        ip6="--ipv6_domain" if ip_version == 6 else "", # --help output is wrong
                        local_bind="--bind {0}".format(local_bind) if local_bind else "",
                        no_delay="--nodelay" if no_delay else "",
                        udp="--udp" if udp else "")
            else:
                sys.stderr.write(
                    "Found iperf binary, but it does not have an --enhancedreport option. Not using.\n"
                )

        raise RuntimeError("No suitable Iperf binary found.")
Beispiel #5
0
    def find_itgsend(self, test_args, length, host):

        if self.itgsend is None:
            self.itgsend = util.which("ITGSend", fail=True)

        # We put placeholders in the command string to be filled out by string
        # format expansion by the runner once it has communicated with the control
        # server and obtained the port values.
        return "{binary} -Sdp {{signal_port}} -t {length} -a {dest_host} -rp {{dest_port}} {args}".format(
            binary=self.itgsend, length=int(length * 1000), dest_host=host, args=test_args
        )
Beispiel #6
0
    def find_itgsend(self, test_args, length, host):

        if self.itgsend is None:
            self.itgsend = util.which("ITGSend", fail=True)

        # We put placeholders in the command string to be filled out by string
        # format expansion by the runner once it has communicated with the control
        # server and obtained the port values.
        return "{binary} -Sdp {{signal_port}} -t {length} -a {dest_host} -rp {{dest_port}} {args}".format(
            binary=self.itgsend,
            length=int(length * 1000),
            dest_host=host,
            args=test_args)
Beispiel #7
0
    def find_http_getter(self,
                         interval,
                         length,
                         workers=None,
                         ip_version=None,
                         dns_servers=None,
                         url_file=None,
                         timeout=None):

        args = "-i %d -l %d" % (int(interval * 1000.0), length)

        if url_file is None:
            url_file = self.env['HTTP_GETTER_URLLIST']

        if dns_servers is None:
            dns_servers = self.env['HTTP_GETTER_DNS']

        if timeout is None:
            timeout = self.env['HTTP_GETTER_TIMEOUT']

        if workers is None:
            workers = self.env['HTTP_GETTER_WORKERS']

        if ip_version is None:
            ip_version = self.env['IP_VERSION']

        if ip_version == 4:
            args += " -4"
        elif ip_version == 6:
            args += " -6"

        if timeout is None:
            args += " -t %d" % int(length * 1000)
        else:
            args += " -t %d" % timeout

        if workers is not None:
            args += " -n %d" % workers

        if dns_servers is not None:
            args += " -d '%s'" % dns_servers

        if url_file is None:
            args += " http://%s/filelist.txt" % self.env['HOST']
        else:
            args += " %s" % url_file

        if self.http_getter is None:
            self.http_getter = util.which('http-getter', fail=True)

        return "%s %s" % (self.http_getter, args)
    def find_binary(cls, interval, length, host='localhost'):
        script = os.path.join(DATA_DIR, 'scripts', 'stat_iterate.sh')
        if not os.path.exists(script):
            raise RuntimeError("Cannot find stat_iterate.sh.")

        bash = util.which('bash')
        if not bash:
            raise RuntimeError("TC stats requires a Bash shell.")

        return "{bash} {script} -I {interval:.2f} -c {count:.0f} -H {host}".format(
            bash=bash,
            script=script,
            interval=interval,
            count=length // interval + 1,
            host=host)
Beispiel #9
0
    def find_binary(cls, interval, length, host='localhost'):
        script = os.path.join(DATA_DIR, 'scripts', 'stat_iterate.sh')
        if not os.path.exists(script):
            raise RuntimeError("Cannot find stat_iterate.sh.")

        bash = util.which('bash')
        if not bash:
            raise RuntimeError("CPU stats requires a Bash shell.")

        return "{bash} {script} -I {interval:.2f} -c {count:.0f} -H {host}".format(
            bash=bash,
            script=script,
            interval=interval,
            count=length // interval + 1,
            host=host)
Beispiel #10
0
    def find_http_getter(
        self, interval, length, workers=None, ip_version=None, dns_servers=None, url_file=None, timeout=None
    ):

        args = "-i %d -l %d" % (int(interval * 1000.0), length)

        if url_file is None:
            url_file = self.env["HTTP_GETTER_URLLIST"]

        if dns_servers is None:
            dns_servers = self.env["HTTP_GETTER_DNS"]

        if timeout is None:
            timeout = self.env["HTTP_GETTER_TIMEOUT"]

        if workers is None:
            workers = self.env["HTTP_GETTER_WORKERS"]

        if ip_version is None:
            ip_version = self.env["IP_VERSION"]

        if ip_version == 4:
            args += " -4"
        elif ip_version == 6:
            args += " -6"

        if timeout is None:
            args += " -t %d" % int(length * 1000)
        else:
            args += " -t %d" % timeout

        if workers is not None:
            args += " -n %d" % workers

        if dns_servers is not None:
            args += " -d '%s'" % dns_servers

        if url_file is None:
            args += " http://%s/filelist.txt" % self.env["HOST"]
        else:
            args += " %s" % url_file

        if self.http_getter is None:
            self.http_getter = util.which("http-getter", fail=True)

        return "%s %s" % (self.http_getter, args)
Beispiel #11
0
    def find_binary(cls, interface, interval, length):
        script = os.path.join(DATA_DIR, 'scripts', 'tc_iterate.sh')
        if not os.path.exists(script):
            raise RuntimeError("Cannot find tc_iterate.sh.")

        bash = util.which('bash')
        if not bash:
            raise RuntimeError("TC stats requires a Bash shell.")

        if interface is None:
            sys.stderr.write("Warning: No interface given for tc runner. Defaulting to 'eth0'.\n")
            interface='eth0'

        return "{bash} {script} -i {interface} -I {interval:.2f} -c {count:.0f}".format(
            bash=bash,
            script=script,
            interface=interface,
            interval=interval,
            count=length // interval + 1)
Beispiel #12
0
    def find_binary(cls, interface, interval, length, host='localhost'):
        script = os.path.join(DATA_DIR, 'scripts', 'tc_iterate.sh')
        if not os.path.exists(script):
            raise RuntimeError("Cannot find tc_iterate.sh.")

        bash = util.which('bash')
        if not bash:
            raise RuntimeError("TC stats requires a Bash shell.")

        if interface is None:
            sys.stderr.write("Warning: No interface given for tc runner. Defaulting to 'eth0'.\n")
            interface='eth0'

        return "{bash} {script} -i {interface} -I {interval:.2f} -c {count:.0f} -H {host}".format(
            bash=bash,
            script=script,
            interface=interface,
            interval=interval,
            count=length // interval + 1,
            host=host)
Beispiel #13
0
    def find_itgsend(self, test_args, length, host, local_bind=None):

        if local_bind is None:
            local_bind = self.env['LOCAL_BIND'][
                0] if self.env['LOCAL_BIND'] else None

        if self.itgsend is None:
            self.itgsend = util.which("ITGSend", fail=True)

        # We put placeholders in the command string to be filled out by string
        # format expansion by the runner once it has communicated with the control
        # server and obtained the port values.
        return "{binary} -Sdp {{signal_port}} -t {length} {local_bind} " \
            "-a {dest_host} -rp {{dest_port}} {args}".format(
                binary=self.itgsend,
                length=int(length * 1000),
                dest_host=host,
                local_bind="-sa {0} -Ssa {0}".format(
                    local_bind) if local_bind else "",
                args=test_args)
Beispiel #14
0
    def find_itgsend(self, test_args, length, host, local_bind=None):

        if local_bind is None:
            local_bind = self.env['LOCAL_BIND'][0] if self.env[
                'LOCAL_BIND'] else None

        if self.itgsend is None:
            self.itgsend = util.which("ITGSend", fail=True)

        # We put placeholders in the command string to be filled out by string
        # format expansion by the runner once it has communicated with the control
        # server and obtained the port values.
        return "{binary} -Sdp {{signal_port}} -t {length} {local_bind} " \
            "-a {dest_host} -rp {{dest_port}} {args}".format(
                binary=self.itgsend,
                length=int(length * 1000),
                dest_host=host,
                local_bind="-sa {0} -Ssa {0}".format(
                    local_bind) if local_bind else "",
                args=test_args)
Beispiel #15
0
    def find_netperf(self, test, length, host, **args):
        """Find a suitable netperf executable, and test for the required capabilities."""

        if self.netperf is None:
            netperf = util.which('netperf', fail=True)

            # Try to figure out whether this version of netperf supports the -e
            # option for socket timeout on UDP_RR tests, and whether it has been
            # compiled with --enable-demo. Unfortunately, the --help message is
            # not very helpful for this, so the only way to find out is try to
            # invoke it and check for an error message. This has the side-effect
            # of having netperf attempt a connection to localhost, which can
            # stall, so we kill the process almost immediately.

            proc = subprocess.Popen(
                [netperf, '-l', '1', '-D', '-0.2', '--', '-e', '1'],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE)
            time.sleep(
                0.1
            )  # should be enough time for netperf to output any error messages
            proc.kill()
            out, err = proc.communicate()
            if "Demo Mode not configured" in str(out):
                raise RuntimeError("%s does not support demo mode." % netperf)

            if "invalid option -- '0'" in str(err):
                raise RuntimeError(
                    "%s does not support accurate intermediate time reporting. You need netperf v2.6.0 or newer."
                    % netperf)

            self.netperf = {'executable': netperf, "-e": False}

            if not "netperf: invalid option -- 'e'" in str(err):
                self.netperf['-e'] = True

        args.setdefault('ip_version', self.env['IP_VERSION'])
        args.setdefault('interval', self.env['STEP_SIZE'])
        args.setdefault('control_host', self.env['CONTROL_HOST'] or host)
        args.setdefault('local_bind', self.env['LOCAL_BIND'] or "")
        args.setdefault('control_local_bind', self.env['CONTROL_LOCAL_BIND']
                        or args['local_bind'])
        args.setdefault('extra_args', "")
        args.setdefault('extra_test_args', "")
        args.setdefault('format', "")
        args.setdefault('marking', "")
        args.setdefault('socket_timeout', "")

        if self.env['SWAP_UPDOWN']:
            if test == 'TCP_STREAM':
                test = 'TCP_MAERTS'
            elif test == 'TCP_MAERTS':
                test = 'TCP_STREAM'

        args.update({
            'binary': self.netperf['executable'],
            'host': host,
            'test': test,
            'length': length
        })

        if args['marking']:
            args['marking'] = "-Y {0}".format(args['marking'])

        for c in 'local_bind', 'control_local_bind':
            if args[c]:
                args[c] = "-L {0}".format(args[c])

        if test == "UDP_RR" and self.netperf["-e"]:
            args['socket_timeout'] = "-e {0:d}".format(
                self.env['SOCKET_TIMEOUT'])
        elif test in ("TCP_STREAM", "TCP_MAERTS", "omni"):
            args['format'] = "-f m"

        return "{binary} -P 0 -v 0 -D -{interval:.2f} -{ip_version} {marking} -H {control_host} -t {test} " \
               "-l {length:d} {format} {control_local_bind} {extra_args} -- {socket_timeout} {local_bind} -H {host} " \
               "{extra_test_args}".format(**args)
Beispiel #16
0
    def find_netperf(self, test, length, host, **args):
        """Find a suitable netperf executable, and test for the required capabilities."""

        if self.netperf is None:
            netperf = util.which("netperf", fail=True)

            # Try to figure out whether this version of netperf supports the -e
            # option for socket timeout on UDP_RR tests, and whether it has been
            # compiled with --enable-demo. Unfortunately, the --help message is
            # not very helpful for this, so the only way to find out is try to
            # invoke it and check for an error message. This has the side-effect
            # of having netperf attempt a connection to localhost, which can
            # stall, so we kill the process almost immediately.

            proc = subprocess.Popen(
                [netperf, "-l", "1", "-D", "-0.2", "--", "-e", "1"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
            )
            time.sleep(0.1)  # should be enough time for netperf to output any error messages
            proc.kill()
            out, err = proc.communicate()
            if "Demo Mode not configured" in str(out):
                raise RuntimeError("%s does not support demo mode." % netperf)

            if "invalid option -- '0'" in str(err):
                raise RuntimeError(
                    "%s does not support accurate intermediate time reporting. You need netperf v2.6.0 or newer."
                    % netperf
                )

            self.netperf = {"executable": netperf, "-e": False}

            if not "netperf: invalid option -- 'e'" in str(err):
                self.netperf["-e"] = True

        args.setdefault("ip_version", self.env["IP_VERSION"])
        args.setdefault("interval", self.env["STEP_SIZE"])
        args.setdefault("control_host", self.env["CONTROL_HOST"] or host)
        args.setdefault("local_bind", self.env["LOCAL_BIND"] or "")
        args.setdefault("control_local_bind", self.env["CONTROL_LOCAL_BIND"] or args["local_bind"])
        args.setdefault("extra_args", "")
        args.setdefault("extra_test_args", "")
        args.setdefault("format", "")
        args.setdefault("marking", "")
        args.setdefault("socket_timeout", "")

        if self.env["SWAP_UPDOWN"]:
            if test == "TCP_STREAM":
                test = "TCP_MAERTS"
            elif test == "TCP_MAERTS":
                test = "TCP_STREAM"

        args.update({"binary": self.netperf["executable"], "host": host, "test": test, "length": length})

        if args["marking"]:
            args["marking"] = "-Y {0}".format(args["marking"])

        for c in "local_bind", "control_local_bind":
            if args[c]:
                args[c] = "-L {0}".format(args[c])

        if test == "UDP_RR" and self.netperf["-e"]:
            args["socket_timeout"] = "-e {0:d}".format(self.env["SOCKET_TIMEOUT"])
        elif test in ("TCP_STREAM", "TCP_MAERTS", "omni"):
            args["format"] = "-f m"

        return (
            "{binary} -P 0 -v 0 -D -{interval:.2f} -{ip_version} {marking} -H {control_host} -t {test} "
            "-l {length:d} {format} {control_local_bind} {extra_args} -- {socket_timeout} {local_bind} -H {host} "
            "{extra_test_args}".format(**args)
        )
Beispiel #17
0
 def setUp(self):
     sysctl = util.which("sysctl")
     if sysctl is None:
         self.skipTest("Could not find sysctl utility")
Beispiel #18
0
    def find_netperf(self, test, length, host, **args):
        """Find a suitable netperf executable, and test for the required capabilities."""

        if self.netperf is None:
            netperf = util.which('netperf', fail=True)

            # Try to figure out whether this version of netperf supports the -e
            # option for socket timeout on UDP_RR tests, and whether it has been
            # compiled with --enable-demo. Unfortunately, the --help message is
            # not very helpful for this, so the only way to find out is try to
            # invoke it and check for an error message. This has the side-effect
            # of having netperf attempt a connection to localhost, which can
            # stall, so we kill the process almost immediately.

            proc = subprocess.Popen([netperf, '-l', '1', '-D', '-0.2', '--', '-e', '1'],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            time.sleep(0.1) # should be enough time for netperf to output any error messages
            proc.kill()
            out,err = proc.communicate()
            if "Demo Mode not configured" in str(out):
                raise RuntimeError("%s does not support demo mode." % netperf)

            if "invalid option -- '0'" in str(err):
                raise RuntimeError("%s does not support accurate intermediate time reporting. You need netperf v2.6.0 or newer." % netperf)

            self.netperf = {'executable': netperf, "-e": False}

            if not "netperf: invalid option -- 'e'" in str(err):
                self.netperf['-e'] = True

        args.setdefault('ip_version', self.env['IP_VERSION'])
        args.setdefault('interval', self.env['STEP_SIZE'])
        args.setdefault('control_host', self.env['CONTROL_HOST'] or host)
        args.setdefault('local_bind', self.env['LOCAL_BIND'] or "")
        args.setdefault('control_local_bind', self.env['CONTROL_LOCAL_BIND'] or args['local_bind'])
        args.setdefault('extra_args', "")
        args.setdefault('extra_test_args', "")
        args.setdefault('format', "")
        args.setdefault('marking', "")
        args.setdefault('socket_timeout', "")

        if self.env['SWAP_UPDOWN']:
            if test == 'TCP_STREAM':
                test = 'TCP_MAERTS'
            elif test == 'TCP_MAERTS':
                test = 'TCP_STREAM'

        args.update({'binary': self.netperf['executable'],
                       'host': host,
                       'test': test,
                       'length': length})


        if args['marking']:
            args['marking'] = "-Y {0}".format(args['marking'])

        for c in 'local_bind', 'control_local_bind':
            if args[c]:
                args[c] = "-L {0}".format(args[c])

        if test == "UDP_RR" and self.netperf["-e"]:
            args['socket_timeout'] = "-e {0:d}".format(self.env['SOCKET_TIMEOUT'])
        elif test in ("TCP_STREAM", "TCP_MAERTS", "omni"):
            args['format'] = "-f m"

        return "{binary} -P 0 -v 0 -D -{interval:.2f} -{ip_version} {marking} -H {control_host} -t {test} " \
               "-l {length:d} {format} {control_local_bind} {extra_args} -- {socket_timeout} {local_bind} -H {host} " \
               "{extra_test_args}".format(**args)