1 ##############################################################################
2 # Copyright (c) 2015 Ericsson AB and others.
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
11 # iperf3 homepage at: http://software.es.net/iperf/
17 import yardstick.ssh as ssh
18 from yardstick.benchmark.scenarios import base
20 LOG = logging.getLogger(__name__)
23 class Iperf(base.Scenario):
24 """Execute iperf3 between two hosts
26 By default TCP is used but UDP can also be configured.
27 For more info see http://software.es.net/iperf
30 bytes - number of bytes to transmit
31 only valid with a non duration runner, mutually exclusive with blockcount
35 udp - use UDP rather than TCP
39 nodelay - set TCP no delay, disabling Nagle's Algorithm
43 blockcount - number of blocks (packets) to transmit,
44 only valid with a non duration runner, mutually exclusive with bytes
49 __scenario_type__ = "Iperf3"
51 def __init__(self, scenario_cfg, context_cfg):
52 self.scenario_cfg = scenario_cfg
53 self.context_cfg = context_cfg
54 self.setup_done = False
57 host = self.context_cfg['host']
58 host_user = host.get('user', 'ubuntu')
59 host_ssh_port = host.get('ssh_port', ssh.DEFAULT_PORT)
60 host_ip = host.get('ip', None)
61 host_key_filename = host.get('key_filename', '~/.ssh/id_rsa')
62 target = self.context_cfg['target']
63 target_user = target.get('user', 'ubuntu')
64 target_ssh_port = target.get('ssh_port', ssh.DEFAULT_PORT)
65 target_ip = target.get('ip', None)
66 target_key_filename = target.get('key_filename', '~/.ssh/id_rsa')
68 LOG.info("user:%s, target:%s", target_user, target_ip)
69 self.target = ssh.SSH(target_user, target_ip,
70 key_filename=target_key_filename,
72 self.target.wait(timeout=600)
74 LOG.info("user:%s, host:%s", host_user, host_ip)
75 self.host = ssh.SSH(host_user, host_ip,
76 key_filename=host_key_filename, port=host_ssh_port)
77 self.host.wait(timeout=600)
80 LOG.debug("Starting iperf3 server with command: %s", cmd)
81 status, _, stderr = self.target.execute(cmd)
83 raise RuntimeError(stderr)
85 self.setup_done = True
90 status, stdout, stderr = self.target.execute("pkill iperf3")
95 def run(self, result):
96 """execute the benchmark"""
97 if not self.setup_done:
100 # if run by a duration runner, get the duration time and setup as arg
101 time = self.scenario_cfg["runner"].get("duration", None) \
102 if "runner" in self.scenario_cfg else None
103 options = self.scenario_cfg['options']
105 cmd = "iperf3 -c %s --json" % (self.context_cfg['target']['ipaddr'])
107 # If there are no options specified
115 if "bandwidth" in options:
116 cmd += " --bandwidth %s" % options["bandwidth"]
119 if "nodelay" in options:
122 # these options are mutually exclusive in iperf3
125 elif "bytes" in options:
126 # number of bytes to transmit (instead of --time)
127 cmd += " --bytes %d" % options["bytes"]
128 elif "blockcount" in options:
129 cmd += " --blockcount %d" % options["blockcount"]
131 LOG.debug("Executing command: %s", cmd)
133 status, stdout, stderr = self.host.execute(cmd)
135 # error cause in json dict on stdout
136 raise RuntimeError(stdout)
138 # Note: convert all ints to floats in order to avoid
139 # schema conflicts in influxdb. We probably should add
140 # a format func in the future.
141 result.update(json.loads(stdout, parse_int=float))
143 if "sla" in self.scenario_cfg:
144 sla_iperf = self.scenario_cfg["sla"]
146 sla_bytes_per_second = int(sla_iperf["bytes_per_second"])
148 # convert bits per second to bytes per second
150 int(result["end"]["sum_received"]["bits_per_second"])
151 bytes_per_second = bit_per_second / 8
152 assert bytes_per_second >= sla_bytes_per_second, \
153 "bytes_per_second %d < sla:bytes_per_second (%d); " % \
154 (bytes_per_second, sla_bytes_per_second)
156 sla_jitter = float(sla_iperf["jitter"])
158 jitter_ms = float(result["end"]["sum"]["jitter_ms"])
159 assert jitter_ms <= sla_jitter, \
160 "jitter_ms %f > sla:jitter %f; " % \
161 (jitter_ms, sla_jitter)
165 '''internal test function'''
166 key_filename = pkg_resources.resource_filename('yardstick.resources',
167 'files/yardstick_key')
170 'ip': '10.229.47.137',
172 'key_filename': key_filename
175 'ip': '10.229.47.137',
177 'key_filename': key_filename,
178 'ipaddr': '10.229.47.137',
182 logger = logging.getLogger('yardstick')
183 logger.setLevel(logging.DEBUG)
185 options = {'packetsize': 120}
186 args = {'options': options}
193 if __name__ == '__main__':