From caf81bafc6132d79674f4c31bbd22d97f4aee961 Mon Sep 17 00:00:00 2001 From: JingLu5 Date: Fri, 13 Jan 2017 14:48:25 +0000 Subject: New reliability/availability testcase - IP datagram error rate and etc. JIRA: YARDSTICK-534 This test case uses nstat to monitor network metrics provided by the kernel in a host and calculate IP datagram error rate, ICMP message error rate, TCP segment error rate and UDP datagram error rate. Change-Id: I2fe6457bb5c95d0446c1463991ae31cc664b09f8 Signed-off-by: JingLu5 --- yardstick/benchmark/scenarios/networking/nstat.py | 130 ++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 yardstick/benchmark/scenarios/networking/nstat.py (limited to 'yardstick/benchmark/scenarios') diff --git a/yardstick/benchmark/scenarios/networking/nstat.py b/yardstick/benchmark/scenarios/networking/nstat.py new file mode 100644 index 000000000..df96dbda7 --- /dev/null +++ b/yardstick/benchmark/scenarios/networking/nstat.py @@ -0,0 +1,130 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd 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 +############################################################################## +from __future__ import print_function +from __future__ import absolute_import + +import time +import logging + +import yardstick.ssh as ssh +from yardstick.benchmark.scenarios import base + +LOG = logging.getLogger(__name__) + +PRECISION = 3 + + +class Nstat(base.Scenario): + """Use nstat to monitor network metrics and measure IP datagram error rate + and etc. + """ + + __scenario_type__ = "Nstat" + + def __init__(self, scenario_cfg, context_cfg): + """Scenario construction""" + self.scenario_cfg = scenario_cfg + self.context_cfg = context_cfg + self.setup_done = False + + def setup(self): + """scenario setup""" + host = self.context_cfg["host"] + user = host.get("user", "ubuntu") + ssh_port = host.get("ssh_port", ssh.DEFAULT_PORT) + ip = host.get("ip", None) + key_filename = host.get('key_filename', "~/.ssh/id_rsa") + + LOG.info("user:%s, host:%s", user, ip) + self.client = ssh.SSH(user, ip, key_filename=key_filename, + port=ssh_port) + self.client.wait(timeout=600) + + self.setup_done = True + + def match(self, key, field, line, results): + """match data in the output""" + if key in line: + results[key] = int(line.split()[field]) + + def calculate_error_rate(self, x, y): + """calculate error rate""" + try: + return round(float(x) / float(y), PRECISION) + except ZeroDivisionError: + # If incoming Errors is non-zero, but incoming data is zero + # consider it as 100% error rate + if x: + return 1 + else: + return 0 + + def process_output(self, out): + """process output""" + results = {} + for line in out.splitlines(): + self.match('IpInReceives', 1, line, results) + self.match('IpInHdrErrors', 1, line, results) + self.match('IpInAddrErrors', 1, line, results) + self.match('IcmpInMsgs', 1, line, results) + self.match('IcmpInErrors', 1, line, results) + self.match('TcpInSegs', 1, line, results) + self.match('TcpInErrs', 1, line, results) + self.match('UdpInDatagrams', 1, line, results) + self.match('UdpInErrors', 1, line, results) + results['IpErrors'] = \ + results['IpInHdrErrors'] + results['IpInAddrErrors'] + results['IP_datagram_error_rate'] = \ + self.calculate_error_rate(results['IpErrors'], + results['IpInReceives']) + results['Icmp_message_error_rate'] = \ + self.calculate_error_rate(results['IcmpInErrors'], + results['IcmpInMsgs']) + results['Tcp_segment_error_rate'] = \ + self.calculate_error_rate(results['TcpInErrs'], + results['TcpInSegs']) + results['Udp_datagram_error_rate'] = \ + self.calculate_error_rate(results['UdpInErrors'], + results['UdpInDatagrams']) + return results + + def run(self, result): + """execute the benchmark""" + + if not self.setup_done: + self.setup() + + options = self.scenario_cfg['options'] + duration = options.get('duration', 60) + + time.sleep(duration) + + cmd = "nstat -z" + + LOG.debug("Executing command: %s", cmd) + status, stdout, stderr = self.client.execute(cmd) + + if status: + raise RuntimeError(stderr) + + results = self.process_output(stdout) + + result.update(results) + + if "sla" in self.scenario_cfg: + sla_error = "" + for i, rate in result.items(): + if i not in self.scenario_cfg['sla']: + continue + sla_rate = float(self.scenario_cfg['sla'][i]) + rate = float(rate) + if rate > sla_rate: + sla_error += "%s rate %f > sla:%s_rate(%f); " % \ + (i, rate, i, sla_rate) + assert sla_error == "", sla_error -- cgit 1.2.3-korg