1 ##############################################################################
2 # Copyright (c) 2016 Huawei Technologies Co.,Ltd and other.
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 ##############################################################################
9 from __future__ import absolute_import
13 import yardstick.ssh as ssh
14 from yardstick.benchmark.scenarios import base
15 from six.moves import zip
17 LOG = logging.getLogger(__name__)
20 class NetUtilization(base.Scenario):
21 """Collect network utilization statistics.
23 This scenario reads statistics from the network devices on a Linux host.
24 Network utilization statistics are read using the utility 'sar'.
26 The following values are displayed:
28 IFACE: Name of the network interface for which statistics are reported.
30 rxpck/s: Total number of packets received per second.
32 txpck/s: Total number of packets transmitted per second.
34 rxkB/s: Total number of kilobytes received per second.
36 txkB/s: Total number of kilobytes transmitted per second.
38 rxcmp/s: Number of compressed packets received per second (for cslip etc.).
40 txcmp/s: Number of compressed packets transmitted per second.
42 rxmcst/s: Number of multicast packets received per second.
44 %ifutil: Utilization percentage of the network interface. For half-duplex
45 interfaces, utilization is calculated using the sum of rxkB/s and txkB/s
46 as a percentage of the interface speed. For full-duplex, this is the
47 greater of rxkB/S or txkB/s.
50 interval - Time interval to measure network utilization.
55 count - Number of times to measure network utilization.
61 __scenario_type__ = "NetUtilization"
63 NET_UTILIZATION_FIELD_SIZE = 8
65 def __init__(self, scenario_cfg, context_cfg):
66 """Scenario construction."""
67 self.scenario_cfg = scenario_cfg
68 self.context_cfg = context_cfg
69 self.setup_done = False
73 host = self.context_cfg['host']
75 self.client = ssh.SSH.from_node(host, defaults={"user": "ubuntu"})
76 self.client.wait(timeout=600)
78 self.setup_done = True
80 def _execute_command(self, cmd):
81 """Execute a command on target."""
82 LOG.info("Executing: %s", cmd)
83 status, stdout, stderr = self.client.execute(cmd)
85 raise RuntimeError("Failed executing command: ",
89 def _filtrate_result(self, raw_result):
90 """Filtrate network utilization statistics."""
96 time_marker = re.compile("^([0-9]+):([0-9]+):([0-9]+)$")
98 # Parse network utilization stats
99 for row in raw_result.splitlines():
102 if line and re.match(time_marker, line[0]):
105 index = line.index('IFACE')
108 net_interface = line[0]
111 if values and len(values) == len(fields):
112 temp_dict = dict(zip(fields, values))
113 if net_interface not in maximum:
114 maximum[net_interface] = temp_dict
116 for item in temp_dict:
117 if float(maximum[net_interface][item]) <\
118 float(temp_dict[item]):
119 maximum[net_interface][item] = \
122 if net_interface not in minimum:
123 minimum[net_interface] = temp_dict
125 for item in temp_dict:
126 if float(minimum[net_interface][item]) >\
127 float(temp_dict[item]):
128 minimum[net_interface][item] = \
131 raise RuntimeError("network_utilization: parse error",
136 if len(fields) != NetUtilization.\
137 NET_UTILIZATION_FIELD_SIZE:
138 raise RuntimeError("network_utilization: unexpected\
141 elif line and line[0] == 'Average:':
144 if line[0] == 'IFACE':
147 if len(fields) != NetUtilization.\
148 NET_UTILIZATION_FIELD_SIZE:
149 raise RuntimeError("network_utilization average: \
150 unexpected field size", fields)
153 net_interface = line[0]
155 if values and len(values) == len(fields):
156 average[net_interface] = dict(
159 raise RuntimeError("network_utilization average: \
160 parse error", fields, line)
162 return {'network_utilization_maximun': maximum,
163 'network_utilization_minimum': minimum,
164 'network_utilization_average': average}
166 def _get_network_utilization(self):
167 """Get network utilization statistics using sar."""
168 options = self.scenario_cfg["options"]
169 interval = options.get('interval', 1)
170 count = options.get('count', 1)
172 cmd = "sudo sar -n DEV %d %d" % (interval, count)
174 raw_result = self._execute_command(cmd)
175 result = self._filtrate_result(raw_result)
179 def run(self, result):
180 """Read statistics."""
181 if not self.setup_done:
184 result.update(self._get_network_utilization())