diff options
19 files changed, 569 insertions, 193 deletions
diff --git a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml index b34672907..507491446 100644 --- a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml +++ b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml @@ -52,12 +52,14 @@ uplink_0: srcip4: "{{get(flow, 'flow.src_ip_0', '1.1.1.1-1.15.255.255') }}" dstip4: "{{get(flow, 'flow.dst_ip_0', '90.90.1.1-90.105.255.255') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" ttl: 32 dscp: 0 outer_l4: srcport: "{{get(flow, 'flow.src_port_0', '1234') }}" dstport: "{{get(flow, 'flow.dst_port_0', '2001') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" downlink_0: ipv4: id: 2 @@ -83,12 +85,14 @@ downlink_0: dstip4: "{{get(flow, 'flow.public_ip_0', '90.90.1.1-90.105.255.255') }}" {% endif %} count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" ttl: 32 dscp: 0 outer_l4: srcport: "{{get(flow, 'flow.src_port_0', '1234') }}" dstport: "{{get(flow, 'flow.dst_port_0', '2001') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" uplink_1: ipv4: id: 3 @@ -111,12 +115,14 @@ uplink_1: srcip4: "{{get(flow, 'flow.src_ip_1', '1.1.1.1-1.15.255.255') }}" dstip4: "{{get(flow, 'flow.dst_ip_1', '90.90.1.1-90.105.255.255') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" ttl: 32 dscp: 0 outer_l4: srcport: "{{get(flow, 'flow.src_port_1', '1234') }}" dstport: "{{get(flow, 'flow.dst_port_1', '2001') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" downlink_1: ipv4: id: 4 @@ -142,9 +148,11 @@ downlink_1: dstip4: "{{get(flow, 'flow.public_ip_1', '90.90.1.1-90.105.255.255') }}" {% endif %} count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" ttl: 32 dscp: 0 outer_l4: srcport: "{{get(flow, 'flow.dst_port_1', '1234') }}" dstport: "{{get(flow, 'flow.src_port_1', '2001') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" diff --git a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_cgnapt.yaml b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_cgnapt.yaml index 513aefb40..3cbd7cd62 100644 --- a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_cgnapt.yaml +++ b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_cgnapt.yaml @@ -50,12 +50,14 @@ uplink_0: srcip4: "{{get(flow, 'flow.src_ip_0', '1.1.1.1-1.15.255.255') }}" dstip4: "{{get(flow, 'flow.dst_ip_0', '90.90.1.1-90.105.255.255') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" ttl: 32 dscp: 0 outer_l4: srcport: "{{get(flow, 'flow.src_port_0', '1234') }}" dstport: "{{get(flow, 'flow.dst_port_0', '2001') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" downlink_0: ipv4: id: 2 @@ -76,12 +78,14 @@ downlink_0: srcip4: "{{get(flow, 'flow.dst_ip_0', '1.1.1.1-1.15.255.255') }}" dstip4: "{{get(flow, 'flow.public_ip_0', '10.0.2.1-10.0.2.255') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" ttl: 32 dscp: 0 outer_l4: srcport: "{{get(flow, 'flow.src_port_0', '1234') }}" dstport: "{{get(flow, 'flow.dst_port_0', '2001') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" uplink_1: ipv4: id: 3 @@ -102,12 +106,14 @@ uplink_1: srcip4: "{{get(flow, 'flow.src_ip_1', '1.1.1.1-1.15.255.255') }}" dstip4: "{{get(flow, 'flow.dst_ip_1', '90.90.1.1-90.105.255.255') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" ttl: 32 dscp: 0 outer_l4: srcport: "{{get(flow, 'flow.src_port_1', '1234') }}" dstport: "{{get(flow, 'flow.dst_port_1', '2001') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" downlink_1: ipv4: id: 4 @@ -128,9 +134,11 @@ downlink_1: srcip4: "{{get(flow, 'flow.dst_ip_1', '1.1.1.1-1.15.255.255') }}" dstip4: "{{get(flow, 'flow.public_ip_1', '10.0.2.1-10.0.2.255') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" ttl: 32 dscp: 0 outer_l4: srcport: "{{get(flow, 'flow.dst_port_1', '1234') }}" dstport: "{{get(flow, 'flow.src_port_1', '2001') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" diff --git a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vpe.yaml b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vpe.yaml index aad751549..edff3612e 100644 --- a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vpe.yaml +++ b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency_vpe.yaml @@ -72,6 +72,7 @@ uplink_0: srcip4: "{{get(flow, 'flow.src_ip_0', '192.168.0.0-192.168.255.255') }}" dstip4: "{{get(flow, 'flow.dst_ip_0', '192.16.0.0-192.16.0.31') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" ttl: 32 dscp: 32 @@ -79,6 +80,7 @@ uplink_0: srcport: "{{get(flow, 'flow.src_port_0', '0') }}" dstport: "{{get(flow, 'flow.dst_port_0', '0') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" downlink_0: id: 2 ipv4: @@ -97,6 +99,7 @@ downlink_0: srcip4: "{{get(flow, 'flow.dst_ip_0', '192.16.0.0-192.16.0.31') }}" dstip4: "{{get(flow, 'flow.src_ip_0', '192.168.0.0-192.168.255.255') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" ttl: 32 dscp: 32 @@ -104,6 +107,7 @@ downlink_0: srcport: "{{get(flow, 'flow.dst_port_0', '0') }}" dstport: "{{get(flow, 'flow.src_port_0', '0') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" uplink_1: id: 3 ipv4: @@ -131,6 +135,8 @@ uplink_1: proto: "tcp" srcip4: "{{get(flow, 'flow.srcip_1', '192.168.0.0-192.168.255.255') }}" dstip4: "{{get(flow, 'flow.dstip_1', '192.16.0.0-192.16.0.31') }}" + count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" ttl: 32 dscp: 32 @@ -138,6 +144,7 @@ uplink_1: srcport: "{{get(flow, 'flow.src_port_1', '0') }}" dstport: "{{get(flow, 'flow.dst_port_1', '0') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" downlink_1: id: 4 ipv4: @@ -156,6 +163,7 @@ downlink_1: srcip4: "{{get(flow, 'flow.dst_ip_1', '192.16.0.0-192.16.0.31') }}" dstip4: "{{get(flow, 'flow.src_ip_1', '192.168.0.0-192.168.255.255') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" ttl: 32 dscp: 32 @@ -163,3 +171,4 @@ downlink_1: srcport: "{{get(flow, 'flow.dst_port_1', '0') }}" dstport: "{{get(flow, 'flow.src_port_1', '0') }}" count: "{{get(flow, 'flow.count', '1') }}" + seed: "{{get(flow, 'flow.seed', '1') }}" diff --git a/tests/ci/load_images.sh b/tests/ci/load_images.sh index 1e1591ce3..7a86abb4e 100755 --- a/tests/ci/load_images.sh +++ b/tests/ci/load_images.sh @@ -29,11 +29,6 @@ if [ "${INSTALLER_TYPE}" == 'fuel' ]; then fi export YARD_IMG_ARCH -HW_FW_TYPE="" -if [ "${YARD_IMG_ARCH}" == "arm64" ]; then - HW_FW_TYPE=uefi -fi -export HW_FW_TYPE UCA_HOST="cloud-images.ubuntu.com" if [ "${YARD_IMG_ARCH}" == "arm64" ]; then @@ -104,18 +99,12 @@ load_yardstick_image() echo echo "========== Loading yardstick cloud image ==========" EXTRA_PARAMS="" - if [[ "${YARD_IMG_ARCH}" == "arm64" ]]; then - EXTRA_PARAMS="--property hw_video_model=vga" - fi # VPP requires guest memory to be backed by large pages if [[ "$DEPLOY_SCENARIO" == *"-fdio-"* ]]; then EXTRA_PARAMS=$EXTRA_PARAMS" --property hw_mem_page_size=large" fi - if [[ -n "${HW_FW_TYPE}" ]]; then - EXTRA_PARAMS=$EXTRA_PARAMS" --property hw_firmware_type=${HW_FW_TYPE}" - fi if [[ "$DEPLOY_SCENARIO" == *"-lxd-"* ]]; then output=$(eval openstack ${SECURE} image create \ @@ -165,7 +154,7 @@ load_cirros_image() if [[ "${YARD_IMG_ARCH}" == "arm64" ]]; then CIRROS_IMAGE_VERSION="cirros-d161201" CIRROS_IMAGE_PATH="/home/opnfv/images/cirros-d161201-aarch64-disk.img" - EXTRA_PARAMS="--property hw_video_model=vga --property short_id=ubuntu16.04" + EXTRA_PARAMS="--property short_id=ubuntu16.04" else CIRROS_IMAGE_VERSION="cirros-0.3.5" CIRROS_IMAGE_PATH="/home/opnfv/images/cirros-0.3.5-x86_64-disk.img" @@ -184,9 +173,6 @@ load_cirros_image() EXTRA_PARAMS=$EXTRA_PARAMS" --property hw_mem_page_size=large" fi - if [[ -n "${HW_FW_TYPE}" ]]; then - EXTRA_PARAMS=$EXTRA_PARAMS" --property hw_firmware_type=${HW_FW_TYPE}" - fi output=$(openstack ${SECURE} image create \ --disk-format qcow2 \ 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 48f15c059..9fbe19949 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_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) |