Source code for yardstick.benchmark.scenarios.networking.iperf3

##############################################################################
# Copyright (c) 2015 Ericsson AB and others.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################

# iperf3 scenario
# iperf3 homepage at: http://software.es.net/iperf/

import logging
import json
import pkg_resources

import yardstick.ssh as ssh
from yardstick.benchmark.scenarios import base

LOG = logging.getLogger(__name__)


[docs]class Iperf(base.Scenario): """Execute iperf3 between two hosts By default TCP is used but UDP can also be configured. For more info see http://software.es.net/iperf Parameters bytes - number of bytes to transmit only valid with a non duration runner, mutually exclusive with blockcount type: int unit: bytes default: 56 udp - use UDP rather than TCP type: bool unit: na default: false nodelay - set TCP no delay, disabling Nagle's Algorithm type: bool unit: na default: false blockcount - number of blocks (packets) to transmit, only valid with a non duration runner, mutually exclusive with bytes type: int unit: bytes default: - """ __scenario_type__ = "Iperf3" def __init__(self, scenario_cfg, context_cfg): self.scenario_cfg = scenario_cfg self.context_cfg = context_cfg self.setup_done = False
[docs] def setup(self): host = self.context_cfg['host'] host_user = host.get('user', 'ubuntu') host_ip = host.get('ip', None) host_key_filename = host.get('key_filename', '~/.ssh/id_rsa') target = self.context_cfg['target'] target_user = target.get('user', 'ubuntu') target_ip = target.get('ip', None) target_key_filename = target.get('key_filename', '~/.ssh/id_rsa') LOG.info("user:%s, target:%s", target_user, target_ip) self.target = ssh.SSH(target_user, target_ip, key_filename=target_key_filename) self.target.wait(timeout=600) LOG.info("user:%s, host:%s", host_user, host_ip) self.host = ssh.SSH(host_user, host_ip, key_filename=host_key_filename) self.host.wait(timeout=600) cmd = "iperf3 -s -D" LOG.debug("Starting iperf3 server with command: %s", cmd) status, _, stderr = self.target.execute(cmd) if status: raise RuntimeError(stderr) self.setup_done = True
[docs] def teardown(self): LOG.debug("teardown") self.host.close() status, stdout, stderr = self.target.execute("pkill iperf3") if status: LOG.warn(stderr) self.target.close()
[docs] def run(self, result): """execute the benchmark""" if not self.setup_done: self.setup() # if run by a duration runner, get the duration time and setup as arg time = self.scenario_cfg["runner"].get("duration", None) \ if "runner" in self.scenario_cfg else None options = self.scenario_cfg['options'] cmd = "iperf3 -c %s --json" % (self.context_cfg['target']['ipaddr']) # If there are no options specified if not options: options = "" use_UDP = False if "udp" in options: cmd += " --udp" use_UDP = True if "bandwidth" in options: cmd += " --bandwidth %s" % options["bandwidth"] else: # tcp obviously if "nodelay" in options: cmd += " --nodelay" # these options are mutually exclusive in iperf3 if time: cmd += " %d" % time elif "bytes" in options: # number of bytes to transmit (instead of --time) cmd += " --bytes %d" % options["bytes"] elif "blockcount" in options: cmd += " --blockcount %d" % options["blockcount"] LOG.debug("Executing command: %s", cmd) status, stdout, stderr = self.host.execute(cmd) if status: # error cause in json dict on stdout raise RuntimeError(stdout) # Note: convert all ints to floats in order to avoid # schema conflicts in influxdb. We probably should add # a format func in the future. result.update(json.loads(stdout, parse_int=float)) if "sla" in self.scenario_cfg: sla_iperf = self.scenario_cfg["sla"] if not use_UDP: sla_bytes_per_second = int(sla_iperf["bytes_per_second"]) # convert bits per second to bytes per second bit_per_second = \ int(result["end"]["sum_received"]["bits_per_second"]) bytes_per_second = bit_per_second / 8 assert bytes_per_second >= sla_bytes_per_second, \ "bytes_per_second %d < sla:bytes_per_second (%d); " % \ (bytes_per_second, sla_bytes_per_second) else: sla_jitter = float(sla_iperf["jitter"]) jitter_ms = float(result["end"]["sum"]["jitter_ms"]) assert jitter_ms <= sla_jitter, \ "jitter_ms %f > sla:jitter %f; " % \ (jitter_ms, sla_jitter)
def _test(): '''internal test function''' key_filename = pkg_resources.resource_filename('yardstick.resources', 'files/yardstick_key') ctx = { 'host': { 'ip': '10.229.47.137', 'user': 'root', 'key_filename': key_filename }, 'target': { 'ip': '10.229.47.137', 'user': 'root', 'key_filename': key_filename, 'ipaddr': '10.229.47.137', } } logger = logging.getLogger('yardstick') logger.setLevel(logging.DEBUG) options = {'packetsize': 120} args = {'options': options} result = {} p = Iperf(args, ctx) p.run(result) print result if __name__ == '__main__': _test()