def find_ping(self, 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 = "" if local_bind is None: local_bind = self.env['LOCAL_BIND'] 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] # FIXME: check for support for -D parameter 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.")
def find_ping(self, ip_version, interval, length, host): """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() if "print timestamp before each output line" in str(out): # fping has timestamp option, use it # there's no timeout parameter for fping, calculate a total number # of pings to send count = length // interval + 1 interval = int(interval * 1000) return "%s -D -p %d -c %d %s" % (fping, interval, count, host) if ping is not None: # No checks atm; should check for presence of -D parameter return "%s -D -i %.2f -w %d %s" % (ping, max(0.2, interval), length, host) raise RuntimeError("No suitable ping tool found.")
def find_netperf(self, test, length, host, ip_version=None, marking=None, interval=None, extra_args=None): """Find a suitable netperf executable, and test for the required capabilities.""" if ip_version is None: ip_version = self.env['IP_VERSION'] if interval is None: interval = self.env['STEP_SIZE'] args = "-P 0 -v 0 -D -%.2f" % interval if ip_version == 4: args += " -4" elif ip_version == 6: args += " -6" if marking is not None: args += " -Y %s" % marking args += " -H %s -t %s -l %d" % (host, test, length) 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 if extra_args is not None: args += " " + extra_args if test == "UDP_RR" and self.netperf["-e"]: # -- might have been passed as extra_args if not "--" in args: args += " --" args += " -e %d" % self.env['SOCKET_TIMEOUT'] elif test in ("TCP_STREAM", "TCP_MAERTS", "omni"): args += " -f m" return "%s %s" % (self.netperf['executable'], args)
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)
def find_ping(self, ip_version, interval, length, host, marking=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() if "print timestamp before each output line" in str(out): # fping has timestamp option, use it # there's no timeout parameter for fping, calculate a total number # of pings to send count = length // interval + 1 interval = int(interval * 1000) if marking is not None: return "%s -D -p %d -c %d -O %s %s" % (fping, interval, count, marking, host) else: return "%s -D -p %d -c %d %s" % (fping, interval, count, 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: # No checks atm; should check for presence of -D parameter if marking is not None: return "%s -n -D -i %.2f -w %d -Q %s %s" % (ping, max(0.2, interval), length, marking, host) else: return "%s -n -D -i %.2f -w %d %s" % (ping, max(0.2, interval), length, host) raise RuntimeError("No suitable ping tool found.")
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_ping(self, ip_version, interval, length, host): """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.""" # This can take a while, so skip if the tests are only loaded for informational # purposes (e.g. for --list-tests) if self.informational: return "" 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() if "print timestamp before each output line" in str(out): # fping has timestamp option, use it # there's no timeout parameter for fping, calculate a total number # of pings to send count = length // interval + 1 interval = int(interval * 1000) return "%s -D -p %d -c %d %s" % (fping, interval, count, host) if ping is not None: # No checks atm; should check for presence of -D parameter return "%s -n -D -i %.2f -w %d %s" % (ping, max(0.2, interval), length, host) raise RuntimeError("No suitable ping tool found.")
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_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)