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/
13 from __future__ import absolute_import
14 from __future__ import print_function
19 from oslo_serialization import jsonutils
21 import yardstick.ssh as ssh
22 from yardstick.common import utils
23 from yardstick.benchmark.scenarios import base
25 LOG = logging.getLogger(__name__)
28 class Iperf(base.Scenario):
29 """Execute iperf3 between two hosts
31 By default TCP is used but UDP can also be configured.
32 For more info see http://software.es.net/iperf
35 bytes - number of bytes to transmit
36 only valid with a non duration runner, mutually exclusive with blockcount
40 udp - use UDP rather than TCP
44 nodelay - set TCP no delay, disabling Nagle's Algorithm
48 blockcount - number of blocks (packets) to transmit,
49 only valid with a non duration runner, mutually exclusive with bytes
53 length - length of buffer to read or write,
54 (default 128 KB for TCP, 8 KB for UDP)
58 window - set window size / socket buffer size
59 set TCP windows size. for UDP way to test, this will set to accept UDP
60 packet buffer size, limit the max size of acceptable data packet.
65 __scenario_type__ = "Iperf3"
67 def __init__(self, scenario_cfg, context_cfg):
68 self.scenario_cfg = scenario_cfg
69 self.context_cfg = context_cfg
70 self.setup_done = False
73 host = self.context_cfg['host']
74 target = self.context_cfg['target']
76 LOG.info("user:%s, target:%s", target['user'], target['ip'])
77 self.target = ssh.SSH.from_node(target, defaults={"user": "ubuntu"})
78 self.target.wait(timeout=600)
80 LOG.info("user:%s, host:%s", host['user'], host['ip'])
81 self.host = ssh.SSH.from_node(host, defaults={"user": "ubuntu"})
82 self.host.wait(timeout=600)
85 LOG.debug("Starting iperf3 server with command: %s", cmd)
86 status, _, stderr = self.target.execute(cmd)
88 raise RuntimeError(stderr)
90 self.setup_done = True
95 status, stdout, stderr = self.target.execute("pkill iperf3")
100 def run(self, result):
101 """execute the benchmark"""
102 if not self.setup_done:
105 # if run by a duration runner, get the duration time and setup as arg
106 time = self.scenario_cfg["runner"].get("duration", None) \
107 if "runner" in self.scenario_cfg else None
108 options = self.scenario_cfg['options']
110 cmd = "iperf3 -c %s --json" % (self.context_cfg['target']['ipaddr'])
112 # If there are no options specified
120 if "bandwidth" in options:
121 cmd += " --bandwidth %s" % options["bandwidth"]
124 if "nodelay" in options:
127 # these options are mutually exclusive in iperf3
130 elif "bytes" in options:
131 # number of bytes to transmit (instead of --time)
132 cmd += " --bytes %d" % options["bytes"]
133 elif "blockcount" in options:
134 cmd += " --blockcount %d" % options["blockcount"]
136 if "length" in options:
137 cmd += " --length %s" % options["length"]
139 if "window" in options:
140 cmd += " --window %s" % options["window"]
142 LOG.debug("Executing command: %s", cmd)
144 status, stdout, stderr = self.host.execute(cmd)
146 # error cause in json dict on stdout
147 raise RuntimeError(stdout)
149 # Note: convert all ints to floats in order to avoid
150 # schema conflicts in influxdb. We probably should add
151 # a format func in the future.
152 iperf_result = jsonutils.loads(stdout, parse_int=float)
153 result.update(utils.flatten_dict_key(iperf_result))
155 if "sla" in self.scenario_cfg:
156 sla_iperf = self.scenario_cfg["sla"]
158 sla_bytes_per_second = int(sla_iperf["bytes_per_second"])
160 # convert bits per second to bytes per second
162 int(iperf_result["end"]["sum_received"]["bits_per_second"])
163 bytes_per_second = bit_per_second / 8
164 assert bytes_per_second >= sla_bytes_per_second, \
165 "bytes_per_second %d < sla:bytes_per_second (%d); " % \
166 (bytes_per_second, sla_bytes_per_second)
168 sla_jitter = float(sla_iperf["jitter"])
170 jitter_ms = float(iperf_result["end"]["sum"]["jitter_ms"])
171 assert jitter_ms <= sla_jitter, \
172 "jitter_ms %f > sla:jitter %f; " % \
173 (jitter_ms, sla_jitter)
177 """internal test function"""
178 key_filename = pkg_resources.resource_filename('yardstick.resources',
179 'files/yardstick_key')
182 'ip': '10.229.47.137',
184 'key_filename': key_filename
187 'ip': '10.229.47.137',
189 'key_filename': key_filename,
190 'ipaddr': '10.229.47.137',
194 logger = logging.getLogger('yardstick')
195 logger.setLevel(logging.DEBUG)
197 options = {'packetsize': 120}
198 args = {'options': options}
206 if __name__ == '__main__':