aboutsummaryrefslogtreecommitdiffstats
path: root/yardstick
diff options
context:
space:
mode:
Diffstat (limited to 'yardstick')
-rw-r--r--yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py30
-rw-r--r--yardstick/benchmark/scenarios/networking/vnf_generic.py1
-rw-r--r--yardstick/common/exceptions.py4
-rw-r--r--yardstick/common/utils.py12
-rw-r--r--yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py66
-rw-r--r--yardstick/network_services/pipeline.py11
-rw-r--r--yardstick/network_services/traffic_profile/ixia_rfc2544.py22
-rw-r--r--yardstick/ssh.py5
-rw-r--r--yardstick/tests/unit/benchmark/runner/test_arithmetic.py220
-rw-r--r--yardstick/tests/unit/benchmark/scenarios/availability/test_attacker_baremetal.py4
-rw-r--r--yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk.py197
-rw-r--r--yardstick/tests/unit/common/test_template_format.py13
-rw-r--r--yardstick/tests/unit/common/test_utils.py45
-rw-r--r--yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py65
-rw-r--r--yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py16
-rw-r--r--yardstick/tests/unit/test_ssh.py23
16 files changed, 552 insertions, 182 deletions
diff --git a/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py b/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py
index 979e3ab14..53abd586b 100644
--- a/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py
+++ b/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py
@@ -23,7 +23,7 @@ def _execute_shell_command(command, stdin=None):
output = []
try:
output = subprocess.check_output(command, stdin=stdin, shell=True)
- except Exception:
+ except Exception: # pylint: disable=broad-except
exitcode = -1
LOG.error("exec command '%s' error:\n ", command, exc_info=True)
@@ -49,8 +49,7 @@ class BaremetalAttacker(BaseAttacker):
LOG.debug("jump_host ip:%s user:%s", jump_host['ip'], jump_host['user'])
self.jump_connection = ssh.SSH.from_node(
jump_host,
- # why do we allow pwd for password?
- defaults={"user": "root", "password": jump_host.get("pwd")}
+ defaults={"user": "root", "password": jump_host.get("password")}
)
self.jump_connection.wait(timeout=600)
LOG.debug("ssh jump host success!")
@@ -59,7 +58,7 @@ class BaremetalAttacker(BaseAttacker):
self.ipmi_ip = host.get("ipmi_ip", None)
self.ipmi_user = host.get("ipmi_user", "root")
- self.ipmi_pwd = host.get("ipmi_pwd", None)
+ self.ipmi_pwd = host.get("ipmi_password", None)
self.fault_cfg = BaseAttacker.attacker_cfgs.get('bare-metal-down')
self.check_script = self.get_script_fullpath(
@@ -107,26 +106,3 @@ class BaremetalAttacker(BaseAttacker):
else:
_execute_shell_command(cmd, stdin=stdin_file)
LOG.info("Recover fault END")
-
-
-def _test(): # pragma: no cover
- host = {
- "ipmi_ip": "10.20.0.5",
- "ipmi_user": "root",
- "ipmi_pwd": "123456",
- "ip": "10.20.0.5",
- "user": "root",
- "key_filename": "/root/.ssh/id_rsa"
- }
- context = {"node1": host}
- attacker_cfg = {
- 'fault_type': 'bear-metal-down',
- 'host': 'node1',
- }
- ins = BaremetalAttacker(attacker_cfg, context)
- ins.setup()
- ins.inject_fault()
-
-
-if __name__ == '__main__': # pragma: no cover
- _test()
diff --git a/yardstick/benchmark/scenarios/networking/vnf_generic.py b/yardstick/benchmark/scenarios/networking/vnf_generic.py
index a7557733b..10f10d4e6 100644
--- a/yardstick/benchmark/scenarios/networking/vnf_generic.py
+++ b/yardstick/benchmark/scenarios/networking/vnf_generic.py
@@ -118,6 +118,7 @@ class NetworkServiceTestCase(scenario_base.Scenario):
flow["dst_port_{}".format(index)] = dst_port
flow["count"] = fflow["count"]
+ flow["seed"] = fflow["seed"]
except KeyError:
flow = {}
return {"flow": flow}
diff --git a/yardstick/common/exceptions.py b/yardstick/common/exceptions.py
index 7e16e39ae..b39a0af9c 100644
--- a/yardstick/common/exceptions.py
+++ b/yardstick/common/exceptions.py
@@ -88,6 +88,10 @@ class YardstickBannedModuleImported(YardstickException):
message = 'Module "%(module)s" cannnot be imported. Reason: "%(reason)s"'
+class IXIAUnsupportedProtocol(YardstickException):
+ message = 'Protocol "%(protocol)" is not supported in IXIA'
+
+
class PayloadMissingAttributes(YardstickException):
message = ('Error instantiating a Payload class, missing attributes: '
'%(missing_attributes)s')
diff --git a/yardstick/common/utils.py b/yardstick/common/utils.py
index 6c5389cd0..c019cd264 100644
--- a/yardstick/common/utils.py
+++ b/yardstick/common/utils.py
@@ -194,20 +194,16 @@ def parse_ini_file(path):
def get_port_mac(sshclient, port):
cmd = "ifconfig |grep HWaddr |grep %s |awk '{print $5}' " % port
- status, stdout, stderr = sshclient.execute(cmd)
+ _, stdout, _ = sshclient.execute(cmd, raise_on_error=True)
- if status:
- raise RuntimeError(stderr)
return stdout.rstrip()
def get_port_ip(sshclient, port):
cmd = "ifconfig %s |grep 'inet addr' |awk '{print $2}' " \
"|cut -d ':' -f2 " % port
- status, stdout, stderr = sshclient.execute(cmd)
+ _, stdout, _ = sshclient.execute(cmd, raise_on_error=True)
- if status:
- raise RuntimeError(stderr)
return stdout.rstrip()
@@ -291,6 +287,10 @@ def mac_address_to_hex_list(mac):
return octets
+def make_ipv4_address(ip_addr):
+ return ipaddress.IPv4Address(six.text_type(ip_addr))
+
+
def safe_ip_address(ip_addr):
""" get ip address version v6 or v4 """
try:
diff --git a/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py b/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py
index ba27d4d05..82f406d08 100644
--- a/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py
+++ b/yardstick/network_services/libs/ixia_libs/ixnet/ixnet_api.py
@@ -40,6 +40,8 @@ IP_VERSION_6_MASK = 64
TRAFFIC_STATUS_STARTED = 'started'
TRAFFIC_STATUS_STOPPED = 'stopped'
+SUPPORTED_PROTO = [PROTO_UDP]
+
# NOTE(ralonsoh): this pragma will be removed in the last patch of this series
class IxNextgen(object): # pragma: no cover
@@ -430,15 +432,75 @@ class IxNextgen(object): # pragma: no cover
count = traffic_param['outer_l3']['count']
srcip = str(traffic_param['outer_l3']['srcip'])
dstip = str(traffic_param['outer_l3']['dstip'])
+ seed = traffic_param['outer_l3']['seed']
srcmask = traffic_param['outer_l3']['srcmask'] or IP_VERSION_4_MASK
dstmask = traffic_param['outer_l3']['dstmask'] or IP_VERSION_4_MASK
self._update_ipv4_address(
self._get_stack_item(fg_id, PROTO_IPV4)[0],
- 'srcIp', srcip, 1, srcmask, count)
+ 'srcIp', srcip, seed, srcmask, count)
self._update_ipv4_address(
self._get_stack_item(fg_id, PROTO_IPV4)[0],
- 'dstIp', dstip, 1, dstmask, count)
+ 'dstIp', dstip, seed, dstmask, count)
+
+ def update_l4(self, traffic):
+ """Update the L4 headers
+
+ NOTE: Only UDP is currently supported
+ :param traffic: list of traffic elements; each traffic element contains
+ the injection parameter for each flow group
+ """
+ for traffic_param in traffic.values():
+ fg_id = str(traffic_param['id'])
+ if not self._get_config_element_by_flow_group_name(fg_id):
+ raise exceptions.IxNetworkFlowNotPresent(flow_group=fg_id)
+
+ proto = traffic_param['outer_l3']['proto']
+ if proto not in SUPPORTED_PROTO:
+ raise exceptions.IXIAUnsupportedProtocol(protocol=proto)
+
+ count = traffic_param['outer_l4']['count']
+ seed = traffic_param['outer_l4']['seed']
+
+ srcport = traffic_param['outer_l4']['srcport']
+ srcmask = traffic_param['outer_l4']['srcportmask']
+
+ dstport = traffic_param['outer_l4']['dstport']
+ dstmask = traffic_param['outer_l4']['dstportmask']
+
+ if proto in SUPPORTED_PROTO:
+ self._update_udp_port(self._get_stack_item(fg_id, proto)[0],
+ 'srcPort', srcport, seed, srcmask, count)
+
+ self._update_udp_port(self._get_stack_item(fg_id, proto)[0],
+ 'dstPort', dstport, seed, dstmask, count)
+
+ def _update_udp_port(self, descriptor, field, value,
+ seed=1, mask=0, count=1):
+ """Set the UDP port in a config element stack UDP field
+
+ :param udp_descriptor: (str) UDP descriptor, e.g.:
+ /traffic/trafficItem:1/configElement:1/stack:"udp-3"
+ :param field: (str) field name, e.g.: scrPort, dstPort
+ :param value: (int) UDP port fixed bits
+ :param seed: (int) seed length
+ :param mask: (int) UDP port mask
+ :param count: (int) number of random ports to generate
+ """
+ field_descriptor = self._get_field_in_stack_item(descriptor, field)
+
+ if mask == 0:
+ seed = count = 1
+
+ self.ixnet.setMultiAttribute(field_descriptor,
+ '-auto', 'false',
+ '-seed', seed,
+ '-fixedBits', value,
+ '-randomMask', mask,
+ '-valueType', 'random',
+ '-countValue', count)
+
+ self.ixnet.commit()
def _build_stats_map(self, view_obj, name_map):
return {data_yardstick: self.ixnet.execute(
diff --git a/yardstick/network_services/pipeline.py b/yardstick/network_services/pipeline.py
index d781ba0cd..7155480d4 100644
--- a/yardstick/network_services/pipeline.py
+++ b/yardstick/network_services/pipeline.py
@@ -18,6 +18,8 @@ import itertools
from six.moves import zip
+from yardstick.common import utils
+
FIREWALL_ADD_DEFAULT = "p {0} firewall add default 1"
FIREWALL_ADD_PRIO = """\
p {0} firewall add priority 1 ipv4 {1} 24 0.0.0.0 0 0 65535 0 65535 6 0xFF port 0"""
@@ -59,8 +61,7 @@ class PipelineRules(object):
self.add_rule(FIREWALL_ADD_PRIO, ip)
def add_firewall_script(self, ip):
- ip_addr = ip.split('.')
- assert len(ip_addr) == 4
+ ip_addr = str(utils.make_ipv4_address(ip)).split('.')
ip_addr[-1] = '0'
for i in range(256):
ip_addr[-2] = str(i)
@@ -87,8 +88,7 @@ class PipelineRules(object):
self.add_rule(ROUTE_ADD_ETHER_MPLS, ip, mac_addr, index)
def add_route_script(self, ip, mac_addr):
- ip_addr = ip.split('.')
- assert len(ip_addr) == 4
+ ip_addr = str(utils.make_ipv4_address(ip)).split('.')
ip_addr[-1] = '0'
for index in range(0, 256, 8):
ip_addr[-2] = str(index)
@@ -101,8 +101,7 @@ class PipelineRules(object):
self.add_rule(ROUTE_ADD_ETHER_QINQ, ip, mask, mac_addr, index)
def add_route_script2(self, ip, mac_addr):
- ip_addr = ip.split('.')
- assert len(ip_addr) == 4
+ ip_addr = str(utils.make_ipv4_address(ip)).split('.')
ip_addr[-1] = '0'
mask = 24
for i in range(0, 256):
diff --git a/yardstick/network_services/traffic_profile/ixia_rfc2544.py b/yardstick/network_services/traffic_profile/ixia_rfc2544.py
index 43455330f..2086273e6 100644
--- a/yardstick/network_services/traffic_profile/ixia_rfc2544.py
+++ b/yardstick/network_services/traffic_profile/ixia_rfc2544.py
@@ -42,6 +42,13 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
mask = utils.get_mask_from_ip_range(_ip_range[0], _ip_range[1])
return _ip_range[0], mask
+ def _get_fixed_and_mask(self, port_range):
+ _port_range = str(port_range).split('-')
+ if len(_port_range) == 1:
+ return int(_port_range[0]), 0
+
+ return int(_port_range[0]), int(_port_range[1])
+
def _get_ixia_traffic_profile(self, profile_data, mac=None):
mac = {} if mac is None else mac
result = {}
@@ -70,6 +77,9 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
srcip, srcmask = self._get_ip_and_mask(ip[src_key])
dstip, dstmask = self._get_ip_and_mask(ip[dst_key])
+ outer_l4 = value.get('outer_l4')
+ src_port, src_port_mask = self._get_fixed_and_mask(outer_l4['srcport'])
+ dst_port, dst_port_mask = self._get_fixed_and_mask(outer_l4['dstport'])
result[traffickey] = {
'bidir': False,
'id': port_id,
@@ -85,6 +95,7 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
'count': ip['count'],
'dscp': ip['dscp'],
'ttl': ip['ttl'],
+ 'seed': ip['seed'],
'srcip': srcip,
'dstip': dstip,
'srcmask': srcmask,
@@ -92,7 +103,15 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
'type': key,
'proto': ip['proto'],
},
- 'outer_l4': value['outer_l4'],
+ 'outer_l4': {
+ 'srcport': src_port,
+ 'dstport': dst_port,
+ 'srcportmask': src_port_mask,
+ 'dstportmask': dst_port_mask,
+ 'count': outer_l4['count'],
+ 'seed': outer_l4['seed'],
+ }
+
}
except KeyError:
continue
@@ -102,6 +121,7 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
def _ixia_traffic_generate(self, traffic, ixia_obj):
ixia_obj.update_frame(traffic, self.config.duration)
ixia_obj.update_ip_packet(traffic)
+ ixia_obj.update_l4(traffic)
ixia_obj.start_traffic()
def update_traffic_profile(self, traffic_generator):
diff --git a/yardstick/ssh.py b/yardstick/ssh.py
index e6a26ab6b..8bdc32c7c 100644
--- a/yardstick/ssh.py
+++ b/yardstick/ssh.py
@@ -499,9 +499,10 @@ class AutoConnectSSH(SSH):
""" Don't close anything, just force creation of a new client """
self._client = False
- def execute(self, cmd, stdin=None, timeout=3600):
+ def execute(self, cmd, stdin=None, timeout=3600, raise_on_error=False):
self._connect()
- return super(AutoConnectSSH, self).execute(cmd, stdin, timeout)
+ return super(AutoConnectSSH, self).execute(cmd, stdin, timeout,
+ raise_on_error)
def run(self, cmd, stdin=None, stdout=None, stderr=None,
raise_on_error=True, timeout=3600,
diff --git a/yardstick/tests/unit/benchmark/runner/test_arithmetic.py b/yardstick/tests/unit/benchmark/runner/test_arithmetic.py
new file mode 100644
index 000000000..7b1e1e976
--- /dev/null
+++ b/yardstick/tests/unit/benchmark/runner/test_arithmetic.py
@@ -0,0 +1,220 @@
+##############################################################################
+# Copyright (c) 2018 Nokia 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
+##############################################################################
+
+import mock
+import unittest
+import multiprocessing
+import os
+import time
+
+from yardstick.benchmark.runners import arithmetic
+
+
+class ArithmeticRunnerTest(unittest.TestCase):
+ class MyMethod(object):
+ def __init__(self):
+ self.count = 101
+
+ def __call__(self, data):
+ self.count += 1
+ data['my_key'] = self.count
+ return self.count
+
+ def setUp(self):
+ self.scenario_cfg = {
+ 'runner': {
+ 'interval': 0,
+ 'iter_type': 'nested_for_loops',
+ 'iterators': [
+ {
+ 'name': 'stride',
+ 'start': 64,
+ 'stop': 128,
+ 'step': 64
+ },
+ {
+ 'name': 'size',
+ 'start': 500,
+ 'stop': 2000,
+ 'step': 500
+ }
+ ]
+ },
+ 'type': 'some_type'
+ }
+
+ self.benchmark = mock.Mock()
+ self.benchmark_cls = mock.Mock(return_value=self.benchmark)
+
+ def _assert_defaults__worker_process_run_setup_and_teardown(self):
+ self.benchmark_cls.assert_called_once_with(self.scenario_cfg, {})
+ self.benchmark.setup.assert_called_once()
+ self.benchmark.teardown.assert_called_once()
+
+ @mock.patch.object(os, 'getpid')
+ @mock.patch.object(multiprocessing, 'Process')
+ def test__run_benchmark_called_with(self, mock_multiprocessing_process,
+ mock_os_getpid):
+ mock_os_getpid.return_value = 101
+
+ runner = arithmetic.ArithmeticRunner({})
+ benchmark_cls = mock.Mock()
+ runner._run_benchmark(benchmark_cls, 'my_method', self.scenario_cfg,
+ {})
+ mock_multiprocessing_process.assert_called_once_with(
+ name='Arithmetic-some_type-101',
+ target=arithmetic._worker_process,
+ args=(runner.result_queue, benchmark_cls, 'my_method',
+ self.scenario_cfg, {}, runner.aborted, runner.output_queue))
+
+ @mock.patch.object(os, 'getpid')
+ def test__worker_process_runner_id(self, mock_os_getpid):
+ mock_os_getpid.return_value = 101
+
+ arithmetic._worker_process(mock.Mock(), self.benchmark_cls,
+ 'my_method', self.scenario_cfg, {},
+ multiprocessing.Event(), mock.Mock())
+
+ self.assertEqual(self.scenario_cfg['runner']['runner_id'], 101)
+
+ @mock.patch.object(time, 'sleep')
+ def test__worker_process_calls_nested_for_loops(self, mock_time_sleep):
+ self.scenario_cfg['runner']['interval'] = 99
+
+ arithmetic._worker_process(mock.Mock(), self.benchmark_cls,
+ 'my_method', self.scenario_cfg, {},
+ multiprocessing.Event(), mock.Mock())
+
+ self._assert_defaults__worker_process_run_setup_and_teardown()
+ self.benchmark.my_method.assert_has_calls([mock.call({})] * 8)
+ self.assertEqual(self.benchmark.my_method.call_count, 8)
+ mock_time_sleep.assert_has_calls([mock.call(99)] * 8)
+ self.assertEqual(mock_time_sleep.call_count, 8)
+
+ @mock.patch.object(time, 'sleep')
+ def test__worker_process_calls_tuple_loops(self, mock_time_sleep):
+ self.scenario_cfg['runner']['interval'] = 99
+ self.scenario_cfg['runner']['iter_type'] = 'tuple_loops'
+
+ arithmetic._worker_process(mock.Mock(), self.benchmark_cls,
+ 'my_method', self.scenario_cfg, {},
+ multiprocessing.Event(), mock.Mock())
+
+ self._assert_defaults__worker_process_run_setup_and_teardown()
+ self.benchmark.my_method.assert_has_calls([mock.call({})] * 2)
+ self.assertEqual(self.benchmark.my_method.call_count, 2)
+ mock_time_sleep.assert_has_calls([mock.call(99)] * 2)
+ self.assertEqual(mock_time_sleep.call_count, 2)
+
+ def test__worker_process_stored_options_nested_for_loops(self):
+ arithmetic._worker_process(mock.Mock(), self.benchmark_cls,
+ 'my_method', self.scenario_cfg, {},
+ multiprocessing.Event(), mock.Mock())
+
+ self.assertDictEqual(self.scenario_cfg['options'],
+ {'stride': 128, 'size': 2000})
+
+ def test__worker_process_stored_options_tuple_loops(self):
+ self.scenario_cfg['runner']['iter_type'] = 'tuple_loops'
+
+ arithmetic._worker_process(mock.Mock(), self.benchmark_cls,
+ 'my_method', self.scenario_cfg, {},
+ multiprocessing.Event(), mock.Mock())
+
+ self.assertDictEqual(self.scenario_cfg['options'],
+ {'stride': 128, 'size': 1000})
+
+ def test__worker_process_aborted_set_early(self):
+ aborted = multiprocessing.Event()
+ aborted.set()
+ arithmetic._worker_process(mock.Mock(), self.benchmark_cls,
+ 'my_method', self.scenario_cfg, {},
+ aborted, mock.Mock())
+
+ self._assert_defaults__worker_process_run_setup_and_teardown()
+ self.assertEqual(self.scenario_cfg['options'], {})
+ self.benchmark.my_method.assert_not_called()
+
+ def test__worker_process_output_queue_nested_for_loops(self):
+ self.benchmark.my_method = self.MyMethod()
+
+ output_queue = multiprocessing.Queue()
+ arithmetic._worker_process(mock.Mock(), self.benchmark_cls,
+ 'my_method', self.scenario_cfg, {},
+ multiprocessing.Event(), output_queue)
+ time.sleep(0.01)
+
+ self._assert_defaults__worker_process_run_setup_and_teardown()
+ self.assertEqual(self.benchmark.my_method.count, 109)
+ result = []
+ while not output_queue.empty():
+ result.append(output_queue.get())
+ self.assertListEqual(result, [102, 103, 104, 105, 106, 107, 108, 109])
+
+ def test__worker_process_output_queue_tuple_loops(self):
+ self.scenario_cfg['runner']['iter_type'] = 'tuple_loops'
+ self.benchmark.my_method = self.MyMethod()
+
+ output_queue = multiprocessing.Queue()
+ arithmetic._worker_process(mock.Mock(), self.benchmark_cls,
+ 'my_method', self.scenario_cfg, {},
+ multiprocessing.Event(), output_queue)
+ time.sleep(0.01)
+
+ self._assert_defaults__worker_process_run_setup_and_teardown()
+ self.assertEqual(self.benchmark.my_method.count, 103)
+ result = []
+ while not output_queue.empty():
+ result.append(output_queue.get())
+ self.assertListEqual(result, [102, 103])
+
+ def test__worker_process_queue_nested_for_loops(self):
+ self.benchmark.my_method = self.MyMethod()
+
+ queue = multiprocessing.Queue()
+ timestamp = time.time()
+ arithmetic._worker_process(queue, self.benchmark_cls, 'my_method',
+ self.scenario_cfg, {},
+ multiprocessing.Event(), mock.Mock())
+ time.sleep(0.01)
+
+ self._assert_defaults__worker_process_run_setup_and_teardown()
+ self.assertEqual(self.benchmark.my_method.count, 109)
+ count = 0
+ while not queue.empty():
+ count += 1
+ result = queue.get()
+ self.assertEqual(result['errors'], '')
+ self.assertEqual(result['data'], {'my_key': count + 101})
+ self.assertEqual(result['sequence'], count)
+ self.assertGreater(result['timestamp'], timestamp)
+ timestamp = result['timestamp']
+
+ def test__worker_process_queue_tuple_loops(self):
+ self.scenario_cfg['runner']['iter_type'] = 'tuple_loops'
+ self.benchmark.my_method = self.MyMethod()
+
+ queue = multiprocessing.Queue()
+ timestamp = time.time()
+ arithmetic._worker_process(queue, self.benchmark_cls, 'my_method',
+ self.scenario_cfg, {},
+ multiprocessing.Event(), mock.Mock())
+ time.sleep(0.01)
+
+ self._assert_defaults__worker_process_run_setup_and_teardown()
+ self.assertEqual(self.benchmark.my_method.count, 103)
+ count = 0
+ while not queue.empty():
+ count += 1
+ result = queue.get()
+ self.assertEqual(result['errors'], '')
+ self.assertEqual(result['data'], {'my_key': count + 101})
+ self.assertEqual(result['sequence'], count)
+ self.assertGreater(result['timestamp'], timestamp)
+ timestamp = result['timestamp']
diff --git a/yardstick/tests/unit/benchmark/scenarios/availability/test_attacker_baremetal.py b/yardstick/tests/unit/benchmark/scenarios/availability/test_attacker_baremetal.py
index d5c95a086..0f68753fd 100644
--- a/yardstick/tests/unit/benchmark/scenarios/availability/test_attacker_baremetal.py
+++ b/yardstick/tests/unit/benchmark/scenarios/availability/test_attacker_baremetal.py
@@ -48,7 +48,7 @@ class AttackerBaremetalTestCase(unittest.TestCase):
host = {
"ipmi_ip": "10.20.0.5",
"ipmi_user": "root",
- "ipmi_pwd": "123456",
+ "ipmi_password": "123456",
"ip": "10.20.0.5",
"user": "root",
"key_filename": "/root/.ssh/id_rsa"
@@ -77,7 +77,7 @@ class AttackerBaremetalTestCase(unittest.TestCase):
def test__attacker_baremetal_recover_successful(self, mock_ssh, mock_subprocess):
self.attacker_cfg["jump_host"] = 'node1'
- self.context["node1"]["pwd"] = "123456"
+ self.context["node1"]["password"] = "123456"
mock_ssh.SSH.from_node().execute.return_value = (0, "running", '')
ins = attacker_baremetal.BaremetalAttacker(self.attacker_cfg,
self.context)
diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk.py
index bcd417830..70cd8ad40 100644
--- a/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk.py
+++ b/yardstick/tests/unit/benchmark/scenarios/networking/test_pktgen_dpdk.py
@@ -9,16 +9,22 @@
import mock
import unittest
+import time
+import logging
import yardstick.common.utils as utils
+from yardstick import ssh
from yardstick.benchmark.scenarios.networking import pktgen_dpdk
from yardstick.common import exceptions as y_exc
+logging.disable(logging.CRITICAL)
+
+
class PktgenDPDKLatencyTestCase(unittest.TestCase):
def setUp(self):
- self.ctx = {
+ self.context_cfg = {
'host': {
'ip': '172.16.0.137',
'user': 'root',
@@ -31,165 +37,100 @@ class PktgenDPDKLatencyTestCase(unittest.TestCase):
'ipaddr': '172.16.0.138'
}
}
-
- self._mock_ssh = mock.patch(
- 'yardstick.benchmark.scenarios.networking.pktgen_dpdk.ssh')
- self.mock_ssh = self._mock_ssh.start()
- self._mock_time = mock.patch(
- 'yardstick.benchmark.scenarios.networking.pktgen_dpdk.time')
- self.mock_time = self._mock_time.start()
-
- self.addCleanup(self._stop_mock)
-
- def _stop_mock(self):
- self._mock_ssh.stop()
- self._mock_time.stop()
-
- def test_pktgen_dpdk_successful_setup(self):
-
- args = {
- 'options': {'packetsize': 60},
- }
- p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx)
- p.setup()
-
- self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
- self.assertIsNotNone(p.server)
- self.assertIsNotNone(p.client)
- self.assertTrue(p.setup_done)
-
- def test_pktgen_dpdk_successful_get_port_ip(self):
-
- args = {
- 'options': {'packetsize': 60},
+ self.scenario_cfg = {
+ 'options': {'packetsize': 60}
}
- p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx)
- p.server = self.mock_ssh.SSH.from_node()
-
- self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
- utils.get_port_ip(p.server, "eth1")
+ self._mock_SSH = mock.patch.object(ssh, 'SSH')
+ self.mock_SSH = self._mock_SSH.start()
- self.mock_ssh.SSH.from_node().execute.assert_called_with(
- "ifconfig eth1 |grep 'inet addr' |awk '{print $2}' |cut -d ':' -f2 ")
-
- def test_pktgen_dpdk_unsuccessful_get_port_ip(self):
-
- args = {
- 'options': {'packetsize': 60},
- }
+ self._mock_time_sleep = mock.patch.object(time, 'sleep')
+ self.mock_time_sleep = self._mock_time_sleep.start()
- p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx)
- p.server = self.mock_ssh.SSH.from_node()
+ self._mock_utils_get_port_ip = mock.patch.object(utils, 'get_port_ip')
+ self.mock_utils_get_port_ip = self._mock_utils_get_port_ip.start()
- self.mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR')
- self.assertRaises(RuntimeError, utils.get_port_ip, p.server, "eth1")
+ self._mock_utils_get_port_mac = mock.patch.object(utils,
+ 'get_port_mac')
+ self.mock_utils_get_port_mac = self._mock_utils_get_port_mac.start()
- def test_pktgen_dpdk_successful_get_port_mac(self):
+ self.mock_SSH.from_node().execute.return_value = (0, '', '')
- args = {
- 'options': {'packetsize': 60},
- }
- p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx)
- p.server = self.mock_ssh.SSH.from_node()
+ self.addCleanup(self._stop_mock)
- self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+ self.scenario = pktgen_dpdk.PktgenDPDKLatency(self.scenario_cfg,
+ self.context_cfg)
+ self.scenario.server = self.mock_SSH.from_node()
+ self.scenario.client = self.mock_SSH.from_node()
- utils.get_port_mac(p.server, "eth1")
+ def _stop_mock(self):
+ self._mock_SSH.stop()
+ self._mock_time_sleep.stop()
+ self._mock_utils_get_port_ip.stop()
+ self._mock_utils_get_port_mac.stop()
- self.mock_ssh.SSH.from_node().execute.assert_called_with(
- "ifconfig |grep HWaddr |grep eth1 |awk '{print $5}' ")
+ def test_setup(self):
+ scenario = pktgen_dpdk.PktgenDPDKLatency(self.scenario_cfg,
+ self.context_cfg)
+ scenario.setup()
- def test_pktgen_dpdk_unsuccessful_get_port_mac(self):
+ self.assertIsNotNone(scenario.server)
+ self.assertIsNotNone(scenario.client)
+ self.assertTrue(scenario.setup_done)
- args = {
- 'options': {'packetsize': 60},
- }
+ def test_run_get_port_ip_command(self):
+ self.scenario.run({})
- p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx)
- p.server = self.mock_ssh.SSH.from_node()
+ self.mock_utils_get_port_ip.assert_has_calls(
+ [mock.call(self.scenario.server, 'ens4'),
+ mock.call(self.scenario.server, 'ens5')])
- self.mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR')
- self.assertRaises(RuntimeError, utils.get_port_mac, p.server, "eth1")
+ def test_get_port_mac_command(self):
+ self.scenario.run({})
- def test_pktgen_dpdk_successful_no_sla(self):
-
- args = {
- 'options': {'packetsize': 60},
- }
-
- result = {}
- p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx)
+ self.mock_utils_get_port_mac.assert_has_calls(
+ [mock.call(self.scenario.server, 'ens5'),
+ mock.call(self.scenario.server, 'ens4'),
+ mock.call(self.scenario.server, 'ens5')])
+ def test_run_no_sla(self):
sample_output = '100\n110\n112\n130\n149\n150\n90\n150\n200\n162\n'
- self.mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '')
+ self.mock_SSH.from_node().execute.return_value = (0, sample_output, '')
- p.run(result)
+ result = {}
+ self.scenario.run(result)
# with python 3 we get float, might be due python division changes
# AssertionError: {'avg_latency': 132.33333333333334} != {
# 'avg_latency': 132}
delta = result['avg_latency'] - 132
self.assertLessEqual(delta, 1)
- def test_pktgen_dpdk_successful_sla(self):
-
- args = {
- 'options': {'packetsize': 60},
- 'sla': {'max_latency': 100}
- }
- result = {}
-
- p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx)
+ def test_run_sla(self):
+ self.scenario_cfg['sla'] = {'max_latency': 100}
+ scenario = pktgen_dpdk.PktgenDPDKLatency(self.scenario_cfg,
+ self.context_cfg)
sample_output = '100\n100\n100\n100\n100\n100\n100\n100\n100\n100\n'
- self.mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '')
-
- p.run(result)
-
- self.assertEqual(result, {"avg_latency": 100})
+ self.mock_SSH.from_node().execute.return_value = (0, sample_output, '')
- def test_pktgen_dpdk_unsuccessful_sla(self):
-
- args = {
- 'options': {'packetsize': 60},
- 'sla': {'max_latency': 100}
- }
result = {}
+ scenario.run(result)
- p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx)
+ self.assertEqual(result, {"avg_latency": 100})
- p.server = self.mock_ssh.SSH.from_node()
- p.client = self.mock_ssh.SSH.from_node()
+ def test_run_sla_error(self):
+ self.scenario_cfg['sla'] = {'max_latency': 100}
+ scenario = pktgen_dpdk.PktgenDPDKLatency(self.scenario_cfg,
+ self.context_cfg)
sample_output = '100\n110\n112\n130\n149\n150\n90\n150\n200\n162\n'
- self.mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '')
- self.assertRaises(y_exc.SLAValidationError, p.run, result)
+ self.mock_SSH.from_node().execute.return_value = (0, sample_output, '')
- def test_pktgen_dpdk_run_unsuccessful_get_port_mac(self):
-
- args = {
- 'options': {'packetsize': 60},
- 'sla': {'max_latency': 100}
- }
- result = {}
-
- p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx)
-
- self.mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR')
- self.assertRaises(RuntimeError, p.run, result)
-
- def test_pktgen_dpdk_run_unsuccessful_script_error(self):
- args = {
- 'options': {'packetsize': 60}
- }
+ with self.assertRaises(y_exc.SLAValidationError):
+ scenario.run({})
- p = pktgen_dpdk.PktgenDPDKLatency(args, self.ctx)
+ def test_run_last_command_raise_on_error(self):
+ self.mock_SSH.from_node().execute.side_effect = y_exc.SSHError
- self.mock_ssh.SSH.from_node().execute.side_effect = ((0, '', ''),
- (0, '', ''),
- (0, '', ''),
- (0, '', ''),
- (0, '', ''),
- y_exc.SSHError)
- self.assertRaises(y_exc.SSHError, p.run, {})
- self.assertEqual(self.mock_ssh.SSH.from_node().execute.call_count, 6)
+ with self.assertRaises(y_exc.SSHError):
+ self.scenario.run({})
diff --git a/yardstick/tests/unit/common/test_template_format.py b/yardstick/tests/unit/common/test_template_format.py
index 56253efbc..6e4827e16 100644
--- a/yardstick/tests/unit/common/test_template_format.py
+++ b/yardstick/tests/unit/common/test_template_format.py
@@ -22,16 +22,21 @@ from yardstick.common import template_format
class TemplateFormatTestCase(unittest.TestCase):
- def test_parse_to_value_exception(self):
+ def test_parse_scanner(self):
- # TODO(elfoley): Don't hide the error that occurs in
- # template_format.parse
- # TODO(elfoley): Separate these tests; one per error type
with mock.patch.object(yaml, 'load') as yaml_loader:
yaml_loader.side_effect = yaml.scanner.ScannerError()
self.assertRaises(ValueError, template_format.parse, 'FOOBAR')
+
+ def test_parse_parser(self):
+
+ with mock.patch.object(yaml, 'load') as yaml_loader:
yaml_loader.side_effect = yaml.parser.ParserError()
self.assertRaises(ValueError, template_format.parse, 'FOOBAR')
+
+ def test_parse_reader(self):
+
+ with mock.patch.object(yaml, 'load') as yaml_loader:
yaml_loader.side_effect = \
yaml.reader.ReaderError('', '', '', '', '')
self.assertRaises(ValueError, template_format.parse, 'FOOBAR')
diff --git a/yardstick/tests/unit/common/test_utils.py b/yardstick/tests/unit/common/test_utils.py
index b634ff4b4..ef4142148 100644
--- a/yardstick/tests/unit/common/test_utils.py
+++ b/yardstick/tests/unit/common/test_utils.py
@@ -1123,6 +1123,19 @@ class TestUtilsIpAddrMethods(ut_base.BaseUnitTestCase):
u'123:4567:89ab:cdef:123:4567:89ab:cdef/129',
]
+ def test_make_ipv4_address(self):
+ for addr in self.GOOD_IP_V4_ADDRESS_STR_LIST:
+ # test with no mask
+ expected = ipaddress.IPv4Address(addr)
+ self.assertEqual(utils.make_ipv4_address(addr), expected, addr)
+
+ def test_make_ipv4_address_error(self):
+ addr_list = self.INVALID_IP_ADDRESS_STR_LIST +\
+ self.GOOD_IP_V6_ADDRESS_STR_LIST
+ for addr in addr_list:
+ self.assertRaises(Exception, utils.make_ipv4_address, addr)
+
+
def test_safe_ip_address(self):
addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST
for addr in addr_list:
@@ -1346,3 +1359,35 @@ class SendSocketCommandTestCase(unittest.TestCase):
mock_socket_obj.connect_ex.assert_called_once_with(('host', 22))
mock_socket_obj.sendall.assert_called_once_with(six.b('command'))
mock_socket_obj.close.assert_called_once()
+
+
+class GetPortMacTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.ssh_client = mock.Mock()
+ self.ssh_client.execute.return_value = (0, 'foo ', '')
+
+ def test_ssh_client_execute_called(self):
+ utils.get_port_mac(self.ssh_client, 99)
+ self.ssh_client.execute.assert_called_once_with(
+ "ifconfig |grep HWaddr |grep 99 |awk '{print $5}' ",
+ raise_on_error=True)
+
+ def test_return_value(self):
+ self.assertEqual('foo', utils.get_port_mac(self.ssh_client, 99))
+
+
+class GetPortIPTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.ssh_client = mock.Mock()
+ self.ssh_client.execute.return_value = (0, 'foo ', '')
+
+ def test_ssh_client_execute_called(self):
+ utils.get_port_ip(self.ssh_client, 99)
+ self.ssh_client.execute.assert_called_once_with(
+ "ifconfig 99 |grep 'inet addr' |awk '{print $2}' |cut -d ':' -f2 ",
+ raise_on_error=True)
+
+ def test_return_value(self):
+ self.assertEqual('foo', utils.get_port_ip(self.ssh_client, 99))
diff --git a/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py b/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py
index 42ca7f769..2416aee61 100644
--- a/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py
+++ b/yardstick/tests/unit/network_services/libs/ixia_libs/test_ixnet_api.py
@@ -35,6 +35,7 @@ TRAFFIC_PARAMETERS = {
},
'outer_l3': {
'count': 512,
+ 'seed': 1,
'dscp': 0,
'proto': 'udp',
'ttl': 32,
@@ -44,8 +45,12 @@ TRAFFIC_PARAMETERS = {
'srcmask': 24
},
'outer_l4': {
- 'dstport': '2001',
- 'srcport': '1234'
+ 'seed': 1,
+ 'count': 1,
+ 'dstport': 2001,
+ 'srcport': 1234,
+ 'srcportmask': 0,
+ 'dstportmask': 0
},
'traffic_type': 'continuous'
},
@@ -60,6 +65,7 @@ TRAFFIC_PARAMETERS = {
},
'outer_l3': {
'count': 1024,
+ 'seed': 1,
'dscp': 0,
'proto': 'udp',
'ttl': 32,
@@ -69,8 +75,12 @@ TRAFFIC_PARAMETERS = {
'srcmask': 64
},
'outer_l4': {
- 'dstport': '1234',
- 'srcport': '2001'
+ 'seed': 1,
+ 'count': 1,
+ 'dstport': 1234,
+ 'srcport': 2001,
+ 'srcportmask': 0,
+ 'dstportmask': 0
},
'traffic_type': 'continuous'
}
@@ -357,6 +367,21 @@ class TestIxNextgen(unittest.TestCase):
'-randomMask', '0.0.0.63', '-valueType', 'random',
'-countValue', 25)
+ def test__update_udp_port(self):
+ with mock.patch.object(self.ixnet_gen, '_get_field_in_stack_item',
+ return_value='field_desc'):
+ self.ixnet_gen._update_udp_port(mock.ANY, mock.ANY, 1234,
+ 2, 0, 2)
+
+ self.ixnet_gen.ixnet.setMultiAttribute.assert_called_once_with(
+ 'field_desc',
+ '-auto', 'false',
+ '-seed', 1,
+ '-fixedBits', 1234,
+ '-randomMask', 0,
+ '-valueType', 'random',
+ '-countValue', 1)
+
def test_update_ip_packet(self):
with mock.patch.object(self.ixnet_gen, '_update_ipv4_address') as \
mock_update_add, \
@@ -374,6 +399,38 @@ class TestIxNextgen(unittest.TestCase):
with self.assertRaises(exceptions.IxNetworkFlowNotPresent):
self.ixnet_gen.update_ip_packet(TRAFFIC_PARAMETERS)
+ def test_update_l4(self):
+ with mock.patch.object(self.ixnet_gen, '_update_udp_port') as \
+ mock_update_udp, \
+ mock.patch.object(self.ixnet_gen, '_get_stack_item'), \
+ mock.patch.object(self.ixnet_gen,
+ '_get_config_element_by_flow_group_name', return_value='celm'):
+ self.ixnet_gen.update_l4(TRAFFIC_PARAMETERS)
+
+ self.assertEqual(4, len(mock_update_udp.mock_calls))
+
+ def test_update_l4_exception_no_config_element(self):
+ with mock.patch.object(self.ixnet_gen,
+ '_get_config_element_by_flow_group_name',
+ return_value=None):
+ with self.assertRaises(exceptions.IxNetworkFlowNotPresent):
+ self.ixnet_gen.update_l4(TRAFFIC_PARAMETERS)
+
+ def test_update_l4_exception_no_supported_proto(self):
+ traffic_parameters = {
+ UPLINK: {
+ 'id': 1,
+ 'outer_l3': {
+ 'proto': 'unsupported',
+ },
+ },
+ }
+ with mock.patch.object(self.ixnet_gen,
+ '_get_config_element_by_flow_group_name',
+ return_value='celm'):
+ with self.assertRaises(exceptions.IXIAUnsupportedProtocol):
+ self.ixnet_gen.update_l4(traffic_parameters)
+
@mock.patch.object(ixnet_api.IxNextgen, '_get_traffic_state')
def test_start_traffic(self, mock_ixnextgen_get_traffic_state):
self.ixnet_gen._ixnet.getList.return_value = [0]
diff --git a/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py b/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py
index 1a33304a5..6f76eb77c 100644
--- a/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py
+++ b/yardstick/tests/unit/network_services/traffic_profile/test_ixia_rfc2544.py
@@ -462,6 +462,22 @@ class TestIXIARFC2544Profile(unittest.TestCase):
self.assertEqual('192.168.1.10', ip)
self.assertIsNone(mask)
+ def test__get_fixed_and_mask_range(self):
+ fixed_mask = '8-48'
+ r_f_c2544_profile = ixia_rfc2544.IXIARFC2544Profile(
+ self.TRAFFIC_PROFILE)
+ fixed, mask = r_f_c2544_profile._get_fixed_and_mask(fixed_mask)
+ self.assertEqual(8, fixed)
+ self.assertEqual(48, mask)
+
+ def test__get_fixed_and_mask_single(self):
+ fixed_mask = 1234
+ r_f_c2544_profile = ixia_rfc2544.IXIARFC2544Profile(
+ self.TRAFFIC_PROFILE)
+ fixed, mask = r_f_c2544_profile._get_fixed_and_mask(fixed_mask)
+ self.assertEqual(1234, fixed)
+ self.assertEqual(0, mask)
+
def test__get_ixia_traffic_profile_default_args(self):
r_f_c2544_profile = ixia_rfc2544.IXIARFC2544Profile(
self.TRAFFIC_PROFILE)
diff --git a/yardstick/tests/unit/test_ssh.py b/yardstick/tests/unit/test_ssh.py
index b727e821d..71929f1a2 100644
--- a/yardstick/tests/unit/test_ssh.py
+++ b/yardstick/tests/unit/test_ssh.py
@@ -617,3 +617,26 @@ class TestAutoConnectSSH(unittest.TestCase):
auto_connect_ssh.put_file('a', 'b')
mock_put_sftp.assert_called_once()
+
+ def test_execute(self):
+ auto_connect_ssh = AutoConnectSSH('user1', 'host1')
+ auto_connect_ssh._client = mock.Mock()
+ auto_connect_ssh.run = mock.Mock(return_value=0)
+ exit_code, _, _ = auto_connect_ssh.execute('')
+ self.assertEqual(exit_code, 0)
+
+ def _mock_run(self, *args, **kwargs):
+ if args[0] == 'ls':
+ if kwargs.get('raise_on_error'):
+ raise exceptions.SSHError(error_msg='Command error')
+ return 1
+ return 0
+
+ def test_execute_command_error(self):
+ auto_connect_ssh = AutoConnectSSH('user1', 'host1')
+ auto_connect_ssh._client = mock.Mock()
+ auto_connect_ssh.run = mock.Mock(side_effect=self._mock_run)
+ self.assertRaises(exceptions.SSHError, auto_connect_ssh.execute, 'ls',
+ raise_on_error=True)
+ exit_code, _, _ = auto_connect_ssh.execute('ls')
+ self.assertNotEqual(exit_code, 0)