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 ##############################################################################
12 import yardstick.ssh as ssh
13 from yardstick.benchmark.scenarios import base
15 LOG = logging.getLogger(__name__)
18 class NetUtilization(base.Scenario):
19 """Collect network utilization statistics.
21 This scenario reads statistics from the network devices on a Linux host.
22 Network utilization statistics are read using the utility 'sar'.
24 The following values are displayed:
26 IFACE: Name of the network interface for which statistics are reported.
28 rxpck/s: Total number of packets received per second.
30 txpck/s: Total number of packets transmitted per second.
32 rxkB/s: Total number of kilobytes received per second.
34 txkB/s: Total number of kilobytes transmitted per second.
36 rxcmp/s: Number of compressed packets received per second (for cslip etc.).
38 txcmp/s: Number of compressed packets transmitted per second.
40 rxmcst/s: Number of multicast packets received per second.
42 %ifutil: Utilization percentage of the network interface. For half-duplex
43 interfaces, utilization is calculated using the sum of rxkB/s and txkB/s
44 as a percentage of the interface speed. For full-duplex, this is the
45 greater of rxkB/S or txkB/s.
48 interval - Time interval to measure network utilization.
53 count - Number of times to measure network utilization.
59 __scenario_type__ = "NetUtilization"
61 NET_UTILIZATION_FIELD_SIZE = 8
63 def __init__(self, scenario_cfg, context_cfg):
64 """Scenario construction."""
65 self.scenario_cfg = scenario_cfg
66 self.context_cfg = context_cfg
67 self.setup_done = False
71 host = self.context_cfg['host']
72 user = host.get('user', 'ubuntu')
73 ssh_port = host.get("ssh_port", ssh.DEFAULT_PORT)
74 ip = host.get('ip', None)
75 key_filename = host.get('key_filename', '~/.ssh/id_rsa')
77 LOG.info("user:%s, host:%s", user, ip)
78 self.client = ssh.SSH(user, ip, key_filename=key_filename,
80 self.client.wait(timeout=600)
82 self.setup_done = True
84 def _execute_command(self, cmd):
85 """Execute a command on target."""
86 LOG.info("Executing: %s" % cmd)
87 status, stdout, stderr = self.client.execute(cmd)
89 raise RuntimeError("Failed executing command: ",
93 def _filtrate_result(self, raw_result):
94 """Filtrate network utilization statistics."""
100 time_marker = re.compile("^([0-9]+):([0-9]+):([0-9]+)$")
101 ampm_marker = re.compile("(AM|PM)$")
103 # Parse network utilization stats
104 for row in raw_result.split('\n'):
107 if line and re.match(time_marker, line[0]):
108 if re.match(ampm_marker, line[1]):
111 if line[0] == 'IFACE':
114 if len(fields) != NetUtilization.\
115 NET_UTILIZATION_FIELD_SIZE:
116 raise RuntimeError("network_utilization: unexpected\
120 net_interface = line[0]
123 if values and len(values) == len(fields):
124 temp_dict = dict(zip(fields, values))
125 if net_interface not in maximum:
126 maximum[net_interface] = temp_dict
128 for item in temp_dict:
129 if float(maximum[net_interface][item]) <\
130 float(temp_dict[item]):
131 maximum[net_interface][item] = \
134 if net_interface not in minimum:
135 minimum[net_interface] = temp_dict
137 for item in temp_dict:
138 if float(minimum[net_interface][item]) >\
139 float(temp_dict[item]):
140 minimum[net_interface][item] = \
143 raise RuntimeError("network_utilization: parse error",
146 elif line and line[0] == 'Average:':
149 if line[0] == 'IFACE':
152 if len(fields) != NetUtilization.\
153 NET_UTILIZATION_FIELD_SIZE:
154 raise RuntimeError("network_utilization average: \
155 unexpected field size", fields)
158 net_interface = line[0]
160 if values and len(values) == len(fields):
161 average[net_interface] = dict(zip(fields, values))
163 raise RuntimeError("network_utilization average: \
164 parse error", fields, line)
166 return {'network_utilization_maximun': maximum,
167 'network_utilization_minimum': minimum,
168 'network_utilization_average': average}
170 def _get_network_utilization(self):
171 """Get network utilization statistics using sar."""
172 options = self.scenario_cfg["options"]
173 interval = options.get('interval', 1)
174 count = options.get('count', 1)
176 cmd = "sudo sar -n DEV %d %d" % (interval, count)
178 raw_result = self._execute_command(cmd)
179 result = self._filtrate_result(raw_result)
183 def run(self, result):
184 """Read statistics."""
185 if not self.setup_done:
188 result.update(self._get_network_utilization())