class LPM(Test):
    '''
    Performs LPM from source server to remote server, and back.
    '''
    @skipUnless("ppc" in distro.detect().arch,
                "supported only on Power platform")
    @skipIf(IS_POWER_NV or IS_KVM_GUEST,
            "This test is not supported on KVM guest or PowerNV platform")
    def setUp(self):
        '''
        set up required packages and gather necessary test inputs
        '''
        self.install_packages()
        self.rsct_service_start()

        self.hmc_ip = self.get_mcp_component("HMCIPAddr")
        if not self.hmc_ip:
            self.cancel("HMC IP not got from lsrsrc command")
        self.hmc_user = self.params.get("hmc_username", default='hscroot')
        self.hmc_pwd = self.params.get("hmc_pwd", '*', default='********')
        self.options = self.params.get("options", default='')
        self.net_device_type = self.params.get("net_device_type", default='')
        self.lpar = self.get_partition_name("Partition Name")
        if not self.lpar:
            self.cancel("LPAR Name not got from lparstat command")
        self.lpar_ip = self.get_mcp_component("MNName")
        if not self.lpar_ip:
            self.cancel("LPAR IP not got from lsrsrc command")
        self.session = Session(self.hmc_ip,
                               user=self.hmc_user,
                               password=self.hmc_pwd)
        if not self.session.connect():
            self.cancel("failed connecting to HMC")
        cmd = 'lssyscfg -r sys -F name'
        output = self.session.cmd(cmd)
        self.server = ''
        for line in output.stdout_text.splitlines():
            if line in self.lpar:
                self.server = line
                break
        if not self.server:
            self.cancel("Managed System not got")

        self.remote_server = self.params.get("remote_server", default=None)
        if not self.remote_server:
            self.cancel("No Remote Server specified for LPM")

        if 'back' in str(self.name.name):
            current_server = self.remote_server
        else:
            current_server = self.server

        if not self.is_lpar_in_server(current_server, self.lpar):
            self.cancel("%s not in %s" % (self.lpar, current_server))

        if 'vnic' in self.net_device_type:
            self.slot_num = str(self.params.get("slot_num", '*', default=3))
            if int(self.slot_num) < 3 or int(self.slot_num) > 2999:
                self.cancel("Slot invalid. Valid range: 3 - 2999")

            self.bandwidth = str(self.params.get("bandwidth", default=2))

            self.vios_name = self.params.get("vios_names", '*',
                                             default=None).split(' ')
            self.vios_id = []
            for vios_name in self.vios_name:
                self.vios_id.append(self.get_lpar_id(self.server, vios_name))
            self.remote_vios_name = self.params.get("remote_vios_names",
                                                    '*',
                                                    default=None).split(' ')
            self.remote_vios_id = []
            for vios_name in self.remote_vios_name:
                self.remote_vios_id.append(
                    self.get_lpar_id(self.remote_server, vios_name))

            for vios in self.vios_id:
                self.set_msp(self.server, vios)
            for vios in self.remote_vios_id:
                self.set_msp(self.remote_server, vios)

            self.adapters = self.params.get("sriov_adapters",
                                            default='').split(' ')
            self.remote_adapters = self.params.get("remote_sriov_adapters",
                                                   default='').split(' ')
            self.ports = self.params.get("sriov_ports", default='').split(' ')
            self.remote_ports = self.params.get("remote_sriov_ports",
                                                default='').split(' ')

            self.adapter_id = []
            for adapter in self.adapters:
                self.adapter_id.append(
                    self.get_adapter_id(self.server, adapter))
            self.remote_adapter_id = []
            for adapter in self.remote_adapters:
                self.remote_adapter_id.append(
                    self.get_adapter_id(self.remote_server, adapter))
        dmesg.clear_dmesg()

    @staticmethod
    def get_mcp_component(component):
        '''
        probes IBM.MCP class for mentioned component and returns it.
        '''
        for line in process.system_output('lsrsrc IBM.MCP %s' % component,
                                          ignore_status=True, shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split()[-1].strip('{}\"')
        return ''

    @staticmethod
    def get_partition_name(component):
        '''
        get partition name from lparstat -i
        '''

        for line in process.system_output('lparstat -i', ignore_status=True,
                                          shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split(':')[-1].strip()
        return ''

    def rsct_service_start(self):
        '''
        Running rsct services which is necessary for Network
        virtualization tests
        '''
        try:
            for svc in ["rsct", "rsct_rm"]:
                process.run('startsrc -g %s' % svc, shell=True, sudo=True)
        except CmdError as details:
            self.log.debug(str(details))
            self.fail("Starting service %s failed", svc)

        output = process.system_output("lssrc -a",
                                       ignore_status=True,
                                       shell=True,
                                       sudo=True).decode("utf-8")
        if "inoperative" in output:
            self.fail("Failed to start the rsct and rsct_rm services")

    def is_RMC_active(self, server):
        '''
        Get the state of the RMC connection for the given parition
        '''
        cmd = "diagrmc -m %s --ip %s -p %s --autocorrect" % (
            server, self.lpar_ip, self.lpar)
        output = self.session.cmd(cmd)
        for line in output.stdout_text.splitlines():
            if "%s has RMC connection." % self.lpar_ip in line:
                return True
        return False

    def rmc_service_start(self, server):
        '''
        Start RMC services which is needed for LPM migration
        '''
        for svc in ["-z", "-A", "-p"]:
            process.run('/opt/rsct/bin/rmcctrl %s' % svc,
                        shell=True,
                        sudo=True)
        if not wait.wait_for(self.is_RMC_active(server), timeout=60):
            process.run('/usr/sbin/rsct/install/bin/recfgct',
                        shell=True,
                        sudo=True)
            process.run('/opt/rsct/bin/rmcctrl -p', shell=True, sudo=True)
            if not wait.wait_for(self.is_RMC_active(server), timeout=300):
                self.fail("ERROR : RMC connection is down !!")

    def install_packages(self):
        '''
        Install required packages
        '''
        smm = SoftwareManager()
        detected_distro = distro.detect()
        self.log.info("Test is running on: %s", detected_distro.name)
        for pkg in [
                'ksh', 'src', 'rsct.basic', 'rsct.core.utils', 'rsct.core',
                'DynamicRM'
        ]:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel('%s is needed for the test to be run' % pkg)

    def set_msp(self, server, vios_id):
        '''
        Sets the msp for the specified VIOS
        '''
        cmd = "chsyscfg -m %s -r lpar -i lpar_id=%s,msp=1" % (server, vios_id)
        self.session.cmd(cmd)

    def do_migrate(self, server, remote_server, lpar, params):
        '''
        Migrate the LPAR from server to remote server, with additional
        params specified.
        '''
        if not self.is_RMC_active(server):
            self.warn("RMC service is inactive..!")
            self.rmc_service_start(server)
        cmd = "migrlpar -o m -m %s -t %s -p %s %s" % (server, remote_server,
                                                      lpar, params)
        if self.options:
            cmd = "%s %s" % (cmd, self.options)
        self.log.debug(self.session.cmd(cmd).stdout_text)
        time.sleep(10)
        if not self.is_lpar_in_server(remote_server, lpar):
            self.fail("%s not in %s" % (lpar, remote_server))
        # TODO: find a way to ensure migrated lpar is stable
        time.sleep(300)

    def is_lpar_in_server(self, server, lpar):
        '''
        Check if the LPAR is found in the server.
        Returns True, if found.
        Returns False, otherwise.
        '''
        cmd = "lssyscfg -r lpar -m %s -F name,state" % server
        output = self.session.cmd(cmd).stdout_text
        if "%s," % lpar in output:
            return True
        return False

    def get_adapter_id(self, server, loc_code):
        '''
        Gets the adapter id of given location code on the server.
        '''
        cmd = 'lshwres -m %s -r sriov --rsubtype adapter -F \
              phys_loc:adapter_id' % server
        adapter_id_output = self.session.cmd(cmd)
        for line in adapter_id_output.stdout_text.splitlines():
            if str(loc_code) in line:
                return line.split(':')[1]
        return ''

    def get_lpar_id(self, server, lpar_name):
        '''
        Gets the lpar id of given lpar on the server.
        '''
        cmd = "lssyscfg -m %s -r lpar --filter lpar_names=%s \
              -F lpar_id" % (server, lpar_name)
        return self.session.cmd(cmd).stdout_text

    def form_virt_net_options(self, remote=''):
        '''
        Form the vnic_mappings param based on the adapters' details
        provided.
        '''
        if remote:
            cmd = []
            for index in range(0, len(self.adapters)):
                l_cmd = []
                for param in [
                        self.slot_num, 'ded', self.vios_name[index],
                        self.vios_id[index], self.adapter_id[index],
                        self.ports[index], self.bandwidth,
                        self.remote_adapter_id[index], self.remote_ports[index]
                ]:
                    l_cmd.append(param)
                cmd.append("/".join(l_cmd))
        else:
            cmd = []
            for index in range(0, len(self.adapters)):
                l_cmd = []
                for param in [
                        self.slot_num, 'ded', self.remote_vios_name[index],
                        self.remote_vios_id[index],
                        self.remote_adapter_id[index],
                        self.remote_ports[index], self.bandwidth,
                        self.adapter_id[index], self.ports[index]
                ]:
                    l_cmd.append(param)
                cmd.append("/".join(l_cmd))

        return " -i \"vnic_mappings=\\\"%s\\\"\" " % ",".join(cmd)

    def check_dmesg_error(self):
        """
        check for dmesg error
        """
        error = [
            'uevent: failed to send synthetic uevent', 'failed to send uevent',
            'registration failed'
        ]
        self.log.info("Gathering kernel errors if any")
        try:
            dmesg.collect_errors_by_level(skip_errors=error)
        except Exception as exc:
            self.log.info(exc)
            self.fail("test failed,check dmesg log in debug log")

    def test_migrate(self):
        '''
        Migrate the LPAR from given server to remote server.
        '''
        cmd = ''
        if 'vnic' in self.net_device_type:
            cmd = self.form_virt_net_options()
        self.do_migrate(self.server, self.remote_server, self.lpar, cmd)
        self.check_dmesg_error()

    def test_migrate_back(self):
        '''
        Migrate the LPAR from given remote server back to server.
        '''
        cmd = ''
        if 'vnic' in self.net_device_type:
            cmd = self.form_virt_net_options('remote')
        self.do_migrate(self.remote_server, self.server, self.lpar, cmd)
        self.check_dmesg_error()

    def tearDown(self):
        self.session.quit()
class NetworkVirtualization(Test):
    '''
    Adding and deleting Network Virtualized devices from the vios
    Performs adding and deleting of Backing devices
    Performs HMC failover for Network Virtualized device
    Performs driver unbind and bind for Network virtualized device
    Performs Client initiated failover for Network Virtualized device
    '''
    @skipUnless("ppc" in distro.detect().arch,
                "supported only on Power platform")
    @skipIf(IS_POWER_NV or IS_KVM_GUEST,
            "This test is not supported on KVM guest or PowerNV platform")
    def setUp(self):
        '''
        set up required packages and gather necessary test inputs
        '''
        self.install_packages()
        self.hmc_ip = self.get_mcp_component("HMCIPAddr")
        if not self.hmc_ip:
            self.cancel("HMC IP not got")
        self.hmc_pwd = self.params.get("hmc_pwd", '*', default=None)
        self.hmc_username = self.params.get("hmc_username", '*', default=None)
        self.lpar = self.get_partition_name("Partition Name")
        if not self.lpar:
            self.cancel("LPAR Name not got from lparstat command")
        for root, dirct, files in os.walk("/root/.ssh"):
            for file in files:
                if file.startswith("avocado-master-root"):
                    path = os.path.join(root, file)
                    os.remove(path)
        self.session_hmc = Session(self.hmc_ip,
                                   user=self.hmc_username,
                                   password=self.hmc_pwd)
        if not self.session_hmc.connect():
            self.cancel("failed connecting to HMC")
        cmd = 'lssyscfg -r sys  -F name'
        output = self.session_hmc.cmd(cmd)
        self.server = ''
        for line in output.stdout_text.splitlines():
            if line in self.lpar:
                self.server = line
                break
        if not self.server:
            self.cancel("Managed System not got")
        self.slot_num = self.params.get("slot_num", '*', default=None)
        self.slot_num = self.slot_num.split(' ')
        for slot in self.slot_num:
            if int(slot) < 3 or int(slot) > 2999:
                self.cancel("Slot invalid. Valid range: 3 - 2999")
        self.vios_name = self.params.get("vios_names", '*',
                                         default=None).split(' ')
        self.sriov_port = self.params.get("sriov_ports", '*',
                                          default=None).split(' ')
        self.backing_adapter = self.params.get("sriov_adapters",
                                               '*',
                                               default=None).split(' ')
        if len(self.sriov_port) != len(self.backing_adapter):
            self.cancel('Backing Device counts and port counts differ')
        if len(self.vios_name) != len(self.backing_adapter):
            self.cancel('Backing Device counts and vios name counts differ')
        self.backingdev_count = len(self.backing_adapter)
        self.bandwidth = self.params.get("bandwidth", '*', default=None)
        self.vnic_priority = self.params.get("priority", '*', default=None)
        if not self.vnic_priority:
            self.vnic_priority = [50] * len(self.backing_adapter)
        else:
            self.vnic_priority = self.vnic_priority.split(' ')
        if len(self.vnic_priority) != len(self.backing_adapter):
            self.cancel('Backing Device counts and priority counts differ')
        self.auto_failover = self.params.get("auto_failover",
                                             '*',
                                             default=None)
        if self.auto_failover not in ['0', '1']:
            self.auto_failover = '1'
        self.vios_ip = self.params.get('vios_ip', '*', default=None)
        self.vios_user = self.params.get('vios_username', '*', default=None)
        self.vios_pwd = self.params.get('vios_pwd', '*', default=None)
        self.count = int(self.params.get('vnic_test_count', default="1"))
        self.num_of_dlpar = int(self.params.get("num_of_dlpar", default='1'))
        self.device_ip = self.params.get('device_ip', '*',
                                         default=None).split(' ')
        self.mac_id = self.params.get('mac_id',
                                      default="02:03:03:03:03:01").split(' ')
        self.mac_id = [mac.replace(':', '') for mac in self.mac_id]
        self.netmask = self.params.get('netmasks', '*',
                                       default=None).split(' ')
        self.peer_ip = self.params.get('peer_ip', default=None).split(' ')
        dmesg.clear_dmesg()
        self.session_hmc.cmd("uname -a")
        cmd = 'lssyscfg -m ' + self.server + \
              ' -r lpar --filter lpar_names=' + self.lpar + \
              ' -F lpar_id'
        self.lpar_id = self.session_hmc.cmd(cmd).stdout_text.split()[0]
        self.vios_id = []
        for vios_name in self.vios_name:
            cmd = 'lssyscfg -m ' + self.server + \
                  ' -r lpar --filter lpar_names=' + vios_name + \
                  ' -F lpar_id'
            self.vios_id.append(
                self.session_hmc.cmd(cmd).stdout_text.split()[0])
        cmd = 'lshwres -m %s -r sriov --rsubtype adapter -F \
              phys_loc:adapter_id' % self.server
        adapter_id_output = self.session_hmc.cmd(cmd).stdout_text
        self.backing_adapter_id = []
        for backing_adapter in self.backing_adapter:
            for line in adapter_id_output.splitlines():
                if str(backing_adapter) in line:
                    self.backing_adapter_id.append(line.split(':')[1])
        if not self.backing_adapter_id:
            self.cancel("SRIOV adapter provided was not found.")
        self.rsct_service_start()
        if len(self.slot_num) > 1:
            if 'backing' in str(self.name.name) or \
               'failover' in str(self.name.name):
                self.cancel("this test is not needed")
        self.local = LocalHost()
        cmd = "echo 'module ibmvnic +p; func send_subcrq -p' > /sys/kernel/debug/dynamic_debug/control"
        result = process.run(cmd, shell=True, ignore_status=True)
        if result.exit_status:
            self.fail("failed to enable debug mode")

    @staticmethod
    def get_mcp_component(component):
        '''
        probes IBM.MCP class for mentioned component and returns it.
        '''
        for line in process.system_output('lsrsrc IBM.MCP %s' % component,
                                          ignore_status=True, shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split()[-1].strip('{}\"')
        return ''

    @staticmethod
    def get_partition_name(component):
        '''
        get partition name from lparstat -i
        '''

        for line in process.system_output('lparstat -i', ignore_status=True,
                                          shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split(':')[-1].strip()
        return ''

    def check_slot_availability(self, slot_num):
        '''
        Checks if given slot is available(free) to be used.
        :return: True if slot available, False otherwise.
        '''
        cmd = 'lshwres -r virtualio -m %s --rsubtype vnic --filter \
           "lpar_names=%s" -F slot_num' % (self.server, self.lpar)
        for slot in self.session_hmc.cmd(cmd).stdout_text:
            if 'No results were found' in slot:
                return True
            if slot_num == slot:
                self.log.debug("Slot %s already exists" % slot_num)
                return False
        return True

    def rsct_service_start(self):
        '''
        Running rsct services which is necessary for Network
        virtualization tests
        '''
        try:
            for svc in ["rsct", "rsct_rm"]:
                process.run('startsrc -g %s' % svc, shell=True, sudo=True)
        except CmdError as details:
            self.log.debug(str(details))
            self.fail("Starting service %s failed", svc)

        output = process.system_output("lssrc -a",
                                       ignore_status=True,
                                       shell=True,
                                       sudo=True)
        if "inoperative" in output.decode("utf-8"):
            self.cancel("Failed to start the rsct and rsct_rm services")

    def install_packages(self):
        '''
        Install necessary packages
        '''
        smm = SoftwareManager()
        packages = [
            'ksh', 'src', 'rsct.basic', 'rsct.core.utils', 'rsct.core',
            'DynamicRM', 'powerpc-utils'
        ]
        detected_distro = distro.detect()
        if detected_distro.name == "Ubuntu":
            packages.extend(['python-paramiko'])
        self.log.info("Test is running on: %s", detected_distro.name)
        for pkg in packages:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel('%s is needed for the test to be run' % pkg)
        if detected_distro.name == "Ubuntu":
            ubuntu_url = self.params.get('ubuntu_url', default=None)
            debs = self.params.get('debs', default=None)
            for deb in debs:
                deb_url = os.path.join(ubuntu_url, deb)
                deb_install = self.fetch_asset(deb_url, expire='7d')
                shutil.copy(deb_install, self.workdir)
                process.system("dpkg -i %s/%s" % (self.workdir, deb),
                               ignore_status=True,
                               sudo=True)

    def test_add(self):
        '''
        Network virtualized device add operation
        '''
        for slot, mac, sriov_port, adapter_id, device_ip, netmask in zip(
                self.slot_num, self.mac_id, self.sriov_port,
                self.backing_adapter_id, self.device_ip, self.netmask):
            if not self.check_slot_availability(slot):
                self.fail("Slot does not exist")
            self.device_add_remove(slot, mac, sriov_port, adapter_id, 'add')
            self.interface_naming(mac, slot)
            output = self.list_device(slot)
            if 'slot_num=%s' % slot not in str(output):
                self.log.debug(output)
                self.fail("lshwres fails to list Network virtualized device \
                           after add operation")
            if mac not in str(output):
                self.log.debug(output)
                self.fail("MAC address in HMC differs")
            if not self.find_device(mac):
                self.fail("MAC address differs in linux")
            device = self.find_device(mac)
            networkinterface = NetworkInterface(device, self.local)
            try:
                networkinterface.add_ipaddr(device_ip, netmask)
                networkinterface.save(device_ip, netmask)
            except Exception:
                networkinterface.save(device_ip, netmask)
            networkinterface.bring_up()
            if not wait.wait_for(networkinterface.is_link_up, timeout=120):
                self.fail("Unable to bring up the link on the Network \
                       virtualized device")
        self.check_dmesg_error()

    def test_backingdevadd(self):
        '''
        Adding Backing device for Network virtualized device
        '''
        for slot in self.slot_num:
            if self.check_slot_availability(slot):
                self.fail("Slot does not exist")
        pre_add = self.backing_dev_count()
        for count in range(1, self.backingdev_count):
            self.backing_dev_add_remove('add', count)
        post_add = self.backing_dev_count()
        post_add_count = post_add - pre_add + 1
        if post_add_count != self.backingdev_count:
            self.log.debug("Actual backing dev count: %d", post_add_count)
            self.log.debug("Expected backing dev count: %d",
                           self.backingdev_count)
            self.fail("Failed to add backing device")
        self.check_dmesg_error()

    def test_hmcfailover(self):
        '''
        Triggers Failover for the Network virtualized
        device
        '''
        original = self.get_active_device_logport(self.slot_num[0])
        for _ in range(self.count):
            before = self.get_active_device_logport(self.slot_num[0])
            self.trigger_failover(
                self.get_backing_device_logport(self.slot_num[0]))
            time.sleep(10)
            after = self.get_active_device_logport(self.slot_num[0])
            self.log.debug("Active backing device: %s", after)
            if before == after:
                self.fail("No failover happened")
            device = self.find_device(self.mac_id[0])
            networkinterface = NetworkInterface(device, self.local)
            if networkinterface.ping_check(self.peer_ip[0],
                                           count=5) is not None:
                self.fail("Failover has affected Network connectivity")
        if original != self.get_active_device_logport(self.slot_num[0]):
            self.trigger_failover(original)
        if original != self.get_active_device_logport(self.slot_num[0]):
            self.log.warn("Fail: Activating Initial backing dev %s" % original)
        self.check_dmesg_error()

    def test_clientfailover(self):
        '''
        Performs Client initiated failover for Network virtualized
        device
        '''
        device_id = self.find_device_id(self.mac_id[0])
        try:
            for _ in range(self.count):
                for val in range(int(self.backing_dev_count())):
                    self.log.info(
                        "Performing Client initiated\
                                  failover - Attempt %s", int(val + 1))
                    genio.write_file_or_fail(
                        "/sys/devices/vio/%s/failover" % device_id, "1")
                    time.sleep(10)
                    self.log.info("Running a ping test to check if failover \
                                    affected Network connectivity")
                    device = self.find_device(self.mac_id[0])
                    networkinterface = NetworkInterface(device, self.local)
                    if networkinterface.ping_check(self.peer_ip[0],
                                                   count=5,
                                                   options="-w50") is not None:
                        self.fail("Ping test failed. Network virtualized \
                                   failover has affected Network connectivity")
        except CmdError as details:
            self.log.debug(str(details))
            self.fail("Client initiated Failover for Network virtualized \
                      device has failed")
        self.check_dmesg_error()

    def test_vnic_auto_failover(self):
        '''
        Set the priority for vNIC active and backing devices and check if autofailover works
        '''
        if len(self.backing_adapter) >= 2:
            for _ in range(self.count):
                self.update_backing_devices(self.slot_num[0])
                backing_logport = self.get_backing_device_logport(
                    self.slot_num[0])
                active_logport = self.get_active_device_logport(
                    self.slot_num[0])
                if self.enable_auto_failover():
                    if not self.change_failover_priority(backing_logport, '1'):
                        self.fail(
                            "Fail to change the priority for backing device %s",
                            backing_logport)
                    if not self.change_failover_priority(
                            active_logport, '100'):
                        self.fail(
                            "Fail to change the priority for active device %s",
                            active_logport)
                    time.sleep(10)
                    if backing_logport != self.get_active_device_logport(
                            self.slot_num[0]):
                        self.fail("Auto failover of backing device failed")
                    device = self.find_device(self.mac_id[0])
                    networkinterface = NetworkInterface(device, self.local)
                    if networkinterface.ping_check(self.peer_ip[0],
                                                   count=5) is not None:
                        self.fail("Auto failover has effected connectivity")
                else:
                    self.fail("Could not enable auto failover")
        else:
            self.cancel("Provide more backing device, only 1 given")
        self.check_dmesg_error()

    def test_rmdev_viosfailover(self):
        '''
        using mrdev and mkdev command to check vios failover works
        '''

        self.session = Session(self.vios_ip,
                               user=self.vios_user,
                               password=self.vios_pwd)
        if not self.session.connect():
            self.fail("Failed connecting to VIOS")

        cmd = "ioscli lsmap -all -vnic -cpid %s" % self.lpar_id
        vnic_server = self.session.cmd(
            cmd).stdout_text.splitlines()[2].split()[0]

        cmd = "ioscli lsmap -vnic -vadapter %s" % vnic_server
        output = self.session.cmd(cmd)

        vnic_backing_device = None
        for line in output.stdout_text.splitlines():
            if 'Backing device' in line:
                vnic_backing_device = line.split(':')[-1]

        before = self.get_active_device_logport(self.slot_num[0])
        self.log.debug("Active backing device before : %s", before)

        self.validate_vios_command('rmdev -l %s' % vnic_server, 'Defined')
        if vnic_backing_device:
            self.validate_vios_command('rmdev -l %s' % vnic_backing_device,
                                       'Defined')

        after = self.get_active_device_logport(self.slot_num[0])
        self.log.debug("Active backing device after: %s", after)

        if before == after:
            self.fail("failover not occour")
        time.sleep(20)

        if vnic_backing_device:
            self.validate_vios_command('mkdev -l %s' % vnic_backing_device,
                                       'Available')
        self.validate_vios_command('mkdev -l %s' % vnic_server, 'Available')

        device = self.find_device(self.mac_id[0])
        networkinterface = NetworkInterface(device, self.local)
        if networkinterface.ping_check(self.peer_ip[0], count=5) is not None:
            self.fail("Ping test failed. Network virtualized \
                      vios failover has affected Network connectivity")
        self.check_dmesg_error()

    def test_vnic_dlpar(self):
        '''
        Perform vNIC device hot add and hot remove using drmgr command
        '''
        for slot_no, device_ip, netmask, mac, peer_ip in zip(
                self.slot_num, self.device_ip, self.netmask, self.mac_id,
                self.peer_ip):
            self.update_backing_devices(slot_no)
            dev_id = self.find_device_id(mac)
            device_name = self.find_device(mac)
            slot = self.find_virtual_slot(dev_id)
            if slot:
                try:
                    for _ in range(self.num_of_dlpar):
                        self.drmgr_vnic_dlpar('-r', slot)
                        self.drmgr_vnic_dlpar('-a', slot)
                        self.wait_intrerface(device_name)
                except CmdError as details:
                    self.log.debug(str(details))
                    self.fail("dlpar operation did not complete")
                device = self.find_device(mac)
                networkinterface = NetworkInterface(device, self.local)
                try:
                    networkinterface.add_ipaddr(device_ip, netmask)
                except Exception:
                    networkinterface.save(device_ip, netmask)
                if not wait.wait_for(networkinterface.is_link_up, timeout=120):
                    self.fail("Unable to bring up the link on the Network \
                              virtualized device")
                if networkinterface.ping_check(peer_ip, count=5) is not None:
                    self.fail("dlpar has affected Network connectivity")
            else:
                self.fail("slot not found")
        self.check_dmesg_error()

    def test_backingdevremove(self):
        '''
        Removing Backing device for Network virtualized device
        '''
        for slot in self.slot_num:
            if self.check_slot_availability(slot):
                self.fail("Slot does not exist")
            self.update_backing_devices(slot)
            pre_remove = self.backing_dev_count()
            for count in range(1, self.backingdev_count):
                self.backing_dev_add_remove('remove', count)
            post_remove = self.backing_dev_count()
            post_remove_count = pre_remove - post_remove + 1
            if post_remove_count != self.backingdev_count:
                self.log.debug("Actual backing dev count: %d",
                               post_remove_count)
                self.log.debug("Expected backing dev count: %d",
                               self.backingdev_count)
                self.fail("Failed to remove backing device")
        self.check_dmesg_error()

    def test_remove(self):
        '''
        Network virtualized device remove operation
        '''
        for slot in self.slot_num:
            if self.check_slot_availability(slot):
                self.fail("Slot does not exist")
            self.update_backing_devices(slot)
            self.device_add_remove(slot, '', '', '', 'remove')
            output = self.list_device(slot)
            if 'slot_num=%s' % slot in str(output):
                self.log.debug(output)
                self.fail("lshwres still lists the Network virtualized device \
                           after remove operation")
        self.check_dmesg_error()

    def validate_vios_command(self, cmd, validate_string):
        '''
        checking for vnicserver and backing device
        '''
        l_cmd = "echo \"%s\" | ioscli oem_setup_env" % cmd
        output = self.session.cmd(l_cmd)
        if validate_string not in output.stdout_text:
            self.fail("command fail in vios")

    def device_add_remove(self, slot, mac, sriov_port, adapter_id, operation):
        '''
        Adds and removes a Network virtualized device based
        on the operation
        '''
        backing_device = "backing_devices=sriov/%s/%s/%s/%s/%s/%s"\
                         % (self.vios_name[0], self.vios_id[0],
                            adapter_id, sriov_port,
                            self.bandwidth, self.vnic_priority[0])
        if operation == 'add':
            cmd = 'chhwres -m %s --id %s -r virtualio --rsubtype vnic \
                   -o a -s %s -a \"auto_priority_failover=%s,mac_addr=%s,%s\" '\
                   % (self.server, self.lpar_id, slot,
                      self.auto_failover, mac, backing_device)
        else:
            cmd = 'chhwres -m %s --id %s -r virtualio --rsubtype vnic \
                   -o r -s %s'\
                   % (self.server, self.lpar_id, slot)
        output = self.session_hmc.cmd(cmd)
        if output.exit_status != 0:
            self.log.debug(output.stderr)
            self.fail("Network virtualization %s device operation \
                       failed" % operation)

    def list_device(self, slot):
        '''
        Lists the Network vritualized devices
        '''
        cmd = 'lshwres -r virtualio -m %s --rsubtype vnic --filter \
              \"lpar_names=%s,slots=%s\"' % (self.server, self.lpar, slot)
        try:
            output = self.session_hmc.cmd(cmd)
        except CmdError as details:
            self.log.debug(str(details))
            self.fail("lshwres operation failed ")
        return output.stdout_text

    def backing_dev_add_remove(self, operation, i):
        '''
        Adds and removes a backing device based on the operation
        '''
        add_backing_device = "sriov/%s/%s/%s/%s/%s/%s" \
                             % (self.vios_name[i], self.vios_id[i],
                                self.backing_adapter_id[i],
                                self.sriov_port[i],
                                self.bandwidth,
                                self.vnic_priority[i])
        if operation == 'add':
            cmd = 'chhwres -r virtualio --rsubtype vnic -o s -m %s -s %s \
                   --id %s -a \"auto_priority_failover=%s,backing_devices+=%s\"' % (
                self.server, self.slot_num[0], self.lpar_id,
                self.auto_failover, add_backing_device)
        else:
            cmd = 'chhwres -r virtualio --rsubtype vnic -o s -m %s -s %s \
                   --id %s -a backing_devices-=%s' % (
                self.server, self.slot_num[0], self.lpar_id,
                add_backing_device)
        output = self.session_hmc.cmd(cmd)
        if output.exit_status != 0:
            self.log.debug(output.stderr)
            self.fail("Network virtualization Backing device %s \
                       operation failed" % operation)

    def backing_dev_list(self):
        '''
        Lists the Backing devices for a Network virtualized
        device
        '''
        cmd = 'lshwres -r virtualio -m %s --rsubtype vnic --level lpar \
               --filter lpar_names=%s -F slot_num,backing_device_states' \
               % (self.server, self.lpar)
        try:
            output = self.session_hmc.cmd(cmd)
        except CmdError as details:
            self.log.debug(str(details))
            self.fail("lshwres operation failed ")
        return output.stdout_text

    def get_backing_devices(self):
        '''
        Lists the Backing devices for a Network virtualized
        device
        '''
        cmd = 'lshwres -r virtualio -m %s --rsubtype vnic --level lpar \
               --filter lpar_names=%s -F backing_devices' \
               % (self.server, self.lpar)
        try:
            output = self.session_hmc.cmd(cmd)
        except CmdError as details:
            self.log.debug(str(details))
            self.fail("lshwres operation failed ")
        return output.stdout_text

    def update_backing_devices(self, slot):
        '''
        Updates the lists of backing devices, ports, vioses.
        Makes sure the active device's details are on index 0.
        '''
        logport = self.get_active_device_logport(slot)
        adapter_id = ''
        for entry in self.get_backing_devices()[-1].split(','):
            if logport in entry:
                adapter_id = entry.split('/')[3]
                port = entry.split('/')[4]
        if not adapter_id:
            return
        for i in range(0, len(self.backing_adapter_id)):
            if adapter_id == self.backing_adapter_id[i]:
                if port == self.sriov_port[i]:
                    index = i
        vios_id = self.vios_id.pop(index)
        self.vios_id.insert(0, vios_id)
        self.sriov_port.pop(index)
        self.sriov_port.insert(0, port)
        self.backing_adapter_id.pop(index)
        self.backing_adapter_id.insert(0, adapter_id)

    def backing_dev_count(self):
        '''
        Lists the count of backing devices
        '''
        for slot in self.slot_num:
            output = self.backing_dev_list()
            for i in output.splitlines():
                if i.startswith('%s,' % slot):
                    count = len(i.split(',')[1:])
            return count

    @staticmethod
    def find_device(mac_addrs):
        """
        Finds out the latest added network virtualized device
        """
        mac = ':'.join(mac_addrs[i:i + 2] for i in range(0, 12, 2))
        devices = netifaces.interfaces()
        for device in devices:
            if mac in netifaces.ifaddresses(device)[17][0]['addr']:
                return device
        return ''

    def drmgr_vnic_dlpar(self, operation, slot):
        """
        Perform add / remove operation
        """
        cmd = 'drmgr %s -c slot -s %s -w 5 -d 1' % (operation, slot)
        if process.system(cmd, shell=True, sudo=True, ignore_status=True):
            self.fail("drmgr operation %s fails for vNIC device %s" %
                      (operation, slot))

    def is_auto_failover_enabled(self):
        """
        Check if auto failover is enabled for the vNIC device
        """
        cmd = 'lshwres -r virtualio -m %s --rsubtype vnic \
               --filter lpar_names=%s,slots=%s' \
               % (self.server, self.lpar, self.slot_num[0])
        output = self.session_hmc.cmd(cmd)
        if output.exit_status != 0:
            self.log.debug(output.stderr)
        if 'auto_priority_failover=1' in output.stdout_text:
            return True
        return False

    def enable_auto_failover(self):
        """
        Function to enable auto failover option
        """
        cmd = 'chhwres -r virtualio -m %s --rsubtype vnic \
               -o s --id %s -s %s -a auto_priority_failover=1' \
               % (self.server, self.lpar_id, self.slot_num[0])
        output = self.session_hmc.cmd(cmd)
        if output.exit_status != 0:
            self.log.debug(output.stderr)
        if not self.is_auto_failover_enabled():
            return False
        return True

    def get_failover_priority(self, logport):
        """
        get the priority value for the given backing device
        """
        priority = None
        cmd = 'lshwres -r virtualio -m %s --rsubtype vnic --level lpar \
               --filter lpar_names=%s -F slot_num,backing_devices' \
               % (self.server, self.lpar)
        output = self.session_hmc.cmd(cmd)
        if output.exit_status != 0:
            self.log.debug(output.stderr)
        if output.stdout_text.startswith('%s,' % self.slot_num[0]):
            backing_dev = output.stdout_text.strip('%s,"' % self.slot_num[0])
            for entry in backing_dev.split(','):
                entry = entry.split('/')
                if logport in entry:
                    priority = entry[8]
                    break
        return priority

    def change_failover_priority(self, logport, priority):
        """
        Change the fail over priroity for given backing device
        """
        cmd = 'chhwres -r virtualio --rsubtype vnicbkdev -o s -m %s \
               -s %s --id %s --logport %s -a failover_priority=%s' \
               % (self.server, self.slot_num[0], self.lpar_id, logport, priority)
        output = self.session_hmc.cmd(cmd)
        if output.exit_status != 0:
            self.log.debug(output.stderr)
        if priority != self.get_failover_priority(logport):
            return False
        return True

    def find_device_id(self, mac):
        """
        Finds the device id needed to trigger failover
        """
        device = self.find_device(mac)
        device_id = process.system_output("ls -l /sys/class/net/ | \
                                           grep %s | cut -d '/' -f \
                                           5" % device,
                                          shell=True).decode("utf-8").strip()
        return device_id

    def find_virtual_slot(self, dev_id):
        """
        finds the virtual slot for the given virtual ID
        """
        output = process.system_output("lsslot",
                                       ignore_status=True,
                                       shell=True,
                                       sudo=True)
        for slot in output.decode("utf-8").split('\n'):
            if dev_id in slot:
                return slot.split(' ')[0]
        return False

    def trigger_failover(self, logport):
        '''
        Triggers failover from HMC
        '''
        cmd = 'chhwres -r virtualio --rsubtype vnicbkdev -o act -m %s \
               -s %s --id %s \
               --logport %s' % (self.server, self.slot_num[0], self.lpar_id,
                                logport)
        output = self.session_hmc.cmd(cmd)
        if output.exit_status != 0:
            self.log.debug(output.stderr)
            self.fail("Command to set %s as Active has failed" % logport)

    def get_backing_device_logport(self, slot):
        '''
        Get the logical port id of the
        backing device
        '''
        for backing_dev in self.backing_dev_list().splitlines():
            if backing_dev.startswith('%s,' % slot):
                backing_dev = backing_dev.strip('%s,"' % slot)
                for entry in backing_dev.split(','):
                    entry = entry.split('/')
                    if '0' in entry[2] and 'Operational' in entry[3]:
                        logport = entry[1]
                        break
        return logport

    def get_active_device_logport(self, slot):
        '''
        Get the logical port id of the Network
        virtualized device
        '''
        for backing_dev in self.backing_dev_list().splitlines():
            if backing_dev.startswith('%s,' % slot):
                backing_dev = backing_dev.strip('%s,"' % slot)
                for entry in backing_dev.split(','):
                    entry = entry.split('/')
                    if '1' in entry[2]:
                        logport = entry[1]
                        break
        return logport

    def is_backing_device_active(self, slot):
        '''
        TO check the status of the backing device
        after failover
        '''
        for backing_dev in self.backing_dev_list().splitlines():
            if backing_dev.startswith('%s,' % slot):
                val = int(backing_dev.split(',')[1:][1].split('/')[2])
        if val:
            return True
        return False

    def interface_naming(self, mac, slot):
        '''
        naming to vnic interface
        '''
        mac_addrs = ':'.join(mac[i:i + 2] for i in range(0, 12, 2))
        file = "/etc/udev/rules.d/70-persistent-net.rules-%s" % slot
        with open(file, "w") as interface_conf:
            interface_conf.write("SUBSYSTEM==net \n")
            interface_conf.write("ACTION==add \n")
            interface_conf.write("DRIVERS==? \n")
            interface_conf.write("ATTR{address}==%s \n" % mac_addrs)
            interface_conf.write("ATTR{dev_id}==0x0 \n")
            interface_conf.write("ATTR{type}==1 \n")
            interface_conf.write("KERNEL==vnic \n")
            interface_conf.write("NAME=vnic%s \n" % slot)

    def wait_intrerface(self, device_name):
        """
        Wait till interface come up
        """
        for _ in range(0, 120, 10):
            for interface in netifaces.interfaces():
                if device_name == interface:
                    self.log.info("Network virtualized device %s is up",
                                  device_name)
                    return True
                time.sleep(2)
        return False

    def check_dmesg_error(self):
        """
        check for dmesg error
        """
        self.log.info("Gathering kernel errors if any")
        try:
            dmesg.collect_errors_by_level()
        except Exception as exc:
            self.log.info(exc)
            self.fail("test failed,check dmesg log in debug log")

    def tearDown(self):
        self.session_hmc.quit()
        if 'vios' in str(self.name.name):
            self.session.quit()
        cmd = "echo 'module ibmvnic -p; func send_subcrq -p' > /sys/kernel/debug/dynamic_debug/control"
        result = process.run(cmd, shell=True, ignore_status=True)
        if result.exit_status:
            self.log.debug("failed to disable debug mode")
class NetworkSriovDevice(Test):
    '''
    adding and deleting logical sriov device through
    HMC.
    '''
    def setUp(self):
        '''
        set up required packages and gather necessary test inputs
        '''
        smm = SoftwareManager()
        packages = [
            'src', 'rsct.basic', 'rsct.core.utils', 'rsct.core', 'DynamicRM',
            'powerpc-utils'
        ]
        for pkg in packages:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel('%s is needed for the test to be run' % pkg)
        self.hmc_ip = self.get_mcp_component("HMCIPAddr")
        if not self.hmc_ip:
            self.cancel("HMC IP not got")
        self.hmc_pwd = self.params.get("hmc_pwd", '*', default=None)
        self.hmc_username = self.params.get("hmc_username", '*', default=None)
        self.lpar = self.get_partition_name("Partition Name")
        if not self.lpar:
            self.cancel("LPAR Name not got from lparstat command")
        self.session = Session(self.hmc_ip,
                               user=self.hmc_username,
                               password=self.hmc_pwd)
        if not self.session.connect():
            self.cancel("failed connetion to HMC")
        cmd = 'lssyscfg -r sys  -F name'
        output = self.session.cmd(cmd)
        self.server = ''
        for line in output.stdout_text.splitlines():
            if line in self.lpar:
                self.server = line
                break
        if not self.server:
            self.cancel("Managed System not got")
        self.sriov_adapter = self.params.get('sriov_adapter',
                                             '*',
                                             default=None).split(' ')
        self.sriov_port = self.params.get('sriov_port', '*',
                                          default=None).split(' ')
        self.ipaddr = self.params.get('ipaddr', '*', default="").split(' ')
        self.netmask = self.params.get('netmasks', '*', default="").split(' ')
        self.peer_ip = self.params.get('peer_ip', '*', default="").split(' ')
        self.mac_id = self.params.get('mac_id',
                                      default="02:03:03:03:03:01").split(' ')
        self.mac_id = [mac.replace(':', '') for mac in self.mac_id]
        self.local = LocalHost()

    @staticmethod
    def get_mcp_component(component):
        '''
        probes IBM.MCP class for mentioned component and returns it.
        '''
        for line in process.system_output('lsrsrc IBM.MCP %s' % component,
                                          ignore_status=True, shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split()[-1].strip('{}\"')
        return ''

    @staticmethod
    def get_partition_name(component):
        '''
        get partition name from lparstat -i
        '''

        for line in process.system_output('lparstat -i', ignore_status=True,
                                          shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split(':')[-1].strip()
        return ''

    def test_add_logical_device(self):
        '''
        test to create logical sriov device
        '''
        for slot, port, mac, ipaddr, netmask, peer_ip in zip(
                self.sriov_adapter, self.sriov_port, self.mac_id, self.ipaddr,
                self.netmask, self.peer_ip):
            self.device_add_remove(slot, port, mac, '', 'add')
            if not self.list_device(mac):
                self.fail("failed to list logical device after add operation")
            device = self.find_device(mac)
            networkinterface = NetworkInterface(device, self.local)
            networkinterface.add_ipaddr(ipaddr, netmask)
            networkinterface.bring_up()
            if networkinterface.ping_check(peer_ip, count=5) is not None:
                self.fail("ping check failed")

    def test_remove_logical_device(self):
        """
        test to remove logical device
        """
        for mac, slot in zip(self.mac_id, self.sriov_adapter):
            logical_port_id = self.get_logical_port_id(mac)
            self.device_add_remove(slot, '', '', logical_port_id, 'remove')
            if self.list_device(mac):
                self.fail("still list logical device after remove operation")

    def device_add_remove(self, slot, port, mac, logical_id, operation):
        """
        add and remove operation of logical devices
        """
        cmd = "lshwres -m %s -r sriov --rsubtype adapter -F phys_loc:adapter_id" \
              % (self.server)
        output = self.session.cmd(cmd)
        for line in output.stdout_text.splitlines():
            if slot in line:
                adapter_id = line.split(':')[-1]

        if operation == 'add':
            cmd = 'chhwres -r sriov -m %s --rsubtype logport \
                  -o a -p %s -a \"adapter_id=%s,phys_port_id=%s, \
                  logical_port_type=eth,mac_addr=%s\" ' \
                  % (self.server, self.lpar, adapter_id,
                     port, mac)
        else:
            cmd = 'chhwres -r sriov -m %s --rsubtype logport \
                  -o r -p %s -a \"adapter_id=%s,logical_port_id=%s\" ' \
                  % (self.server, self.lpar, adapter_id, logical_id)
        cmd = self.session.cmd(cmd)
        if cmd.exit_status != 0:
            self.log.debug(cmd.stderr)
            self.fail("sriov logical device %s operation \
                       failed" % operation)

    def get_logical_port_id(self, mac):
        """
        findout logical device port id
        """
        cmd = "lshwres -r sriov --rsubtype logport -m  %s \
               --level eth | grep %s | grep %s" \
               % (self.server, self.lpar, mac)
        output = self.session.cmd(cmd)
        logical_port_id = output.stdout_text.split(',')[6].split('=')[-1]
        return logical_port_id

    @staticmethod
    def find_device(mac_addrs):
        """
        Finds out the latest added sriov logical device
        """
        mac = ':'.join(mac_addrs[i:i + 2] for i in range(0, 12, 2))
        devices = netifaces.interfaces()
        for device in devices:
            if mac in netifaces.ifaddresses(device)[17][0]['addr']:
                return device
        return ''

    def list_device(self, mac):
        """
        list the sriov logical device
        """
        cmd = 'lshwres -r sriov --rsubtype logport -m  ltcfleet2 \
              --level eth --filter \"lpar_names=%s\" ' % self.lpar
        output = self.session.cmd(cmd)
        if mac in output.stdout_text:
            return True
        return False

    def tearDown(self):
        self.session.quit()
Beispiel #4
0
class NVMfTest(Test):
    """
    NVM-Express over Fabrics using nvme-cli.
    """
    def setUp(self):
        """
        Sets up NVMf configuration
        """
        self.nss = self.params.get('namespaces', default='')
        self.peer_ips = self.params.get('peer_ips', default='')
        if not self.nss or not self.peer_ips:
            self.cancel("No inputs provided")
        self.peer_user = self.params.get("peer_user", default="root")
        self.peer_password = self.params.get("peer_password", default=None)
        self.nss = self.nss.split(' ')
        self.peer_ips = self.peer_ips.split(' ')
        self.ids = range(1, len(self.peer_ips) + 1)
        if len(self.nss) != len(self.peer_ips):
            self.cancel("Count of namespace and peer ips mismatch")
        smm = SoftwareManager()
        if not smm.check_installed("nvme-cli") and not \
                smm.install("nvme-cli"):
            self.cancel('nvme-cli is needed for the test to be run')
        try:
            if not linux_modules.module_is_loaded("nvme-rdma"):
                linux_modules.load_module("nvme-rdma")
        except CmdError:
            self.cancel("nvme-rdma module not loadable")
        self.cfg_tmpl = self.get_data("nvmf_template.cfg")
        dirname = os.path.dirname(os.path.abspath(self.cfg_tmpl))
        self.cfg_file = os.path.join(dirname, "nvmf.cfg")
        self.nvmf_discovery_file = "/etc/nvme/discovery.conf"

    def create_cfg_file(self):
        """
        Creates the config file for nvmetcli to use in the target
        """
        with open(self.cfg_tmpl, "r") as cfg_fp:
            cfg = yaml.safe_load(cfg_fp)

        subsys_template = list(cfg["subsystems"])
        ports_template = list(cfg["ports"])
        del cfg["subsystems"][0]
        del cfg["ports"][0]
        for i in range(len(self.ids)):
            cfg["subsystems"].append(copy.deepcopy(subsys_template[0]))
            cfg["ports"].append(copy.deepcopy(ports_template[0]))

            cfg_namespace = cfg["subsystems"][i]["namespaces"][0]
            cfg_namespace["device"]["nguid"] = str(i + 1).zfill(32)
            cfg_namespace["device"]["path"] = self.nss[i]
            cfg_namespace["nsid"] = str(i + 1)

            cfg["subsystems"][i]["nqn"] = "mysubsys%s" % str(i + 1)
            cfg["ports"][i]["addr"]["traddr"] = self.peer_ips[i]
            cfg["ports"][i]["subsystems"][0] = "mysubsys%s" % str(i + 1)
            cfg["ports"][i]["portid"] = str(i + 1)

        with open(self.cfg_file, "w") as cfg_fp:
            json.dump(cfg, cfg_fp, indent=2)

    @staticmethod
    def nvme_devs_count():
        """
        Returns count of nvme devices in the system
        """
        cmd = "nvme list"
        output = process.system_output(cmd, shell=True, ignore_status=True)
        count = max(len(output.splitlines()) - 2, 0)
        return count

    def test_targetconfig(self):
        """
        Configures the peer NVMf.
        """
        self.session = Session(self.peer_ips[0],
                               user=self.peer_user,
                               password=self.peer_password)
        if not self.session.connect():
            self.fail("failed connecting to peer")
        self.create_cfg_file()
        destination = "%s:/tmp/" % self.peer_ips[0]
        output = self.session.copy_files(self.cfg_file, destination)
        if not output:
            self.cancel("unable to copy the NVMf cfg file into peer machine")
        for mdl in ["nvmet", "nvmet-rdma"]:
            cmd = "modprobe %s" % mdl
            output = self.session.cmd(cmd)
            if output.exit_status:
                self.cancel("%s is not loadable on the peer" % mdl)
        msg = "which nvmetcli"
        output = self.session.cmd(msg)
        if output.exit_status:
            self.cancel("nvmetcli is not installed on the peer")
        msg = "nvmetcli restore /tmp/nvmf.cfg"
        output = self.session.cmd(msg)
        if output.exit_status:
            self.fail("nvmetcli setup config fails on peer")

    def test_nvmfdiscover(self):
        """
        Discovers NVMf subsystems on the initiator
        """
        for i in range(len(self.ids)):
            cmd = "nvme discover -t rdma -a %s -s 4420 -q mysubsys%s" % (
                self.peer_ips[i], str(i + 1))
            if process.system(cmd, shell=True, ignore_status=True) != 0:
                self.fail("Discover of mysubsys%s fails" % str(i + 1))

    def test_nvmfconnect(self):
        """
        Connects to NVMf subsystems on the initiator
        """
        pre_count = self.nvme_devs_count()
        for i in range(len(self.ids)):
            cmd = "nvme connect -t rdma -n mysubsys%s -a %s -s 4420" % (
                str(i + 1), self.peer_ips[i])
            if process.system(cmd, shell=True, ignore_status=True) != 0:
                self.fail("Connect to mysubsys%s fails" % str(i + 1))
            # Time needed to populate the device in nvme list command
            time.sleep(1)
        if (self.nvme_devs_count() - pre_count) != len(self.ids):
            self.fail("%d new nvme devices not added" % len(self.ids))

    def test_nvmfdisconnect(self):
        """
        Disconnects to NVMf subsystems on the initiator
        """
        pre_count = self.nvme_devs_count()
        for i in range(len(self.ids)):
            cmd = "nvme disconnect -n mysubsys%s" % str(i + 1)
            if process.system(cmd, shell=True, ignore_status=True) != 0:
                self.fail("Disconnect to mysubsys%s fails" % str(i + 1))
        if (pre_count - self.nvme_devs_count()) != len(self.ids):
            self.fail("%d new nvme devices not removed" % len(self.ids))

    def test_nvmfconnectcfg(self):
        """
        Connects to allNVMf subsystems in /etc/nvme/discovery.conf
        """
        if not os.path.exists(os.path.dirname(self.nvmf_discovery_file)):
            os.makedirs(os.path.dirname(self.nvmf_discovery_file))
        msg = []
        for i in range(len(self.ids)):
            msg.append("-t rdma -a %s -s 4420 -q mysubsys%s" %
                       (self.peer_ips[i], str(i + 1)))
        genio.write_file(self.nvmf_discovery_file, "\n".join(msg))
        process.system("cat %s" % self.nvmf_discovery_file)
        pre_count = self.nvme_devs_count()
        cmd = "nvme connect-all"
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            self.fail("connect-all fails")
        if (self.nvme_devs_count() - pre_count) != len(self.ids):
            self.fail("%d new nvme devices not added" % len(self.ids))

    def test_nvmfdisconnectcfg(self):
        """
        Disconnects to NVMf subsystems on the initiator
        """
        pre_count = self.nvme_devs_count()
        for i in range(len(self.ids)):
            cmd = "nvme disconnect -n mysubsys%s" % str(i + 1)
            if process.system(cmd, shell=True, ignore_status=True) != 0:
                self.fail("Disconnect to mysubsys%s fails" % str(i + 1))
        genio.write_file(self.nvmf_discovery_file, "")
        if (pre_count - self.nvme_devs_count()) != len(self.ids):
            self.fail("%d new nvme devices not removed" % len(self.ids))

    def test_cleartargetconfig(self):
        """
        Clears the peer NVMf
        """
        self.session = Session(self.peer_ips[0],
                               user=self.peer_user,
                               password=self.peer_password)
        if not self.session.connect():
            self.fail("failed connecting to peer")
        msg = "nvmetcli clear"
        output = self.session.cmd(msg)
        if output.exit_status:
            self.fail("nvmetcli clear config remove on peer")
        msg = "rm -rf /tmp/nvmf.cfg"
        output = self.session.cmd(msg)
        if output.exit_status:
            self.log.warn("removing config file on peer failed")
class Bonding(Test):
    '''
    Channel bonding enables two or more network interfaces to act as one,
    simultaneously increasing the bandwidth and providing redundancy.
    '''
    def setUp(self):
        '''
        To check and install dependencies for the test
        '''
        detected_distro = distro.detect()
        smm = SoftwareManager()
        depends = []
        # FIXME: "redhat" as the distro name for RHEL is deprecated
        # on Avocado versions >= 50.0.  This is a temporary compatibility
        # enabler for older runners, but should be removed soon
        if detected_distro.name == "Ubuntu":
            depends.extend(["openssh-client", "iputils-ping"])
        elif detected_distro.name in ["rhel", "fedora", "centos", "redhat"]:
            depends.extend(["openssh-clients", "iputils"])
        else:
            depends.extend(["openssh", "iputils"])
        for pkg in depends:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("%s package is need to test" % pkg)
        self.mode = self.params.get("bonding_mode", default="")
        if 'setup' in str(self.name) or 'run' in str(self.name):
            if not self.mode:
                self.cancel("test skipped because mode not specified")
        interfaces = netifaces.interfaces()
        self.peer_public_ip = self.params.get("peer_public_ip", default="")
        self.user = self.params.get("user_name", default="root")
        self.password = self.params.get("peer_password", '*', default="None")
        self.host_interfaces = self.params.get("bond_interfaces",
                                               default="").split(" ")
        if not self.host_interfaces:
            self.cancel("user should specify host interfaces")
        self.peer_interfaces = self.params.get("peer_interfaces",
                                               default="").split(" ")
        for self.host_interface in self.host_interfaces:
            if self.host_interface not in interfaces:
                self.cancel("interface is not available")
        self.peer_first_ipinterface = self.params.get("peer_ip", default="")
        if not self.peer_interfaces or self.peer_first_ipinterface == "":
            self.cancel("peer machine should available")
        self.ipaddr = self.params.get("host_ips", default="").split(" ")
        self.netmask = self.params.get("netmask", default="")
        self.localhost = LocalHost()
        if 'setup' in str(self.name.name):
            for ipaddr, interface in zip(self.ipaddr, self.host_interfaces):
                networkinterface = NetworkInterface(interface, self.localhost)
                try:
                    networkinterface.add_ipaddr(ipaddr, self.netmask)
                    networkinterface.save(ipaddr, self.netmask)
                except Exception:
                    networkinterface.save(ipaddr, self.netmask)
                networkinterface.bring_up()
        self.miimon = self.params.get("miimon", default="100")
        self.fail_over_mac = self.params.get("fail_over_mac", default="2")
        self.downdelay = self.params.get("downdelay", default="0")
        self.bond_name = self.params.get("bond_name", default="tempbond")
        self.net_path = "/sys/class/net/"
        self.bond_status = "/proc/net/bonding/%s" % self.bond_name
        self.bond_dir = os.path.join(self.net_path, self.bond_name)
        self.bonding_slave_file = "%s/bonding/slaves" % self.bond_dir
        self.bonding_masters_file = "%s/bonding_masters" % self.net_path
        self.peer_bond_needed = self.params.get("peer_bond_needed",
                                                default=False)
        self.peer_wait_time = self.params.get("peer_wait_time", default=5)
        self.sleep_time = int(self.params.get("sleep_time", default=5))
        self.mtu = self.params.get("mtu", default=1500)
        self.ib = False
        if self.host_interface[0:2] == 'ib':
            self.ib = True
        self.log.info("Bond Test on IB Interface? = %s", self.ib)
        self.session = Session(self.peer_first_ipinterface,
                               user=self.user,
                               password=self.password)
        if not self.session.connect():
            self.cancel("failed connecting to peer")
        self.setup_ip()
        self.err = []
        self.remotehost = RemoteHost(self.peer_first_ipinterface,
                                     self.user,
                                     password=self.password)
        self.remotehost_public = RemoteHost(self.peer_public_ip,
                                            self.user,
                                            password=self.password)
        if 'setup' in str(self.name.name):
            for interface in self.peer_interfaces:
                peer_networkinterface = NetworkInterface(
                    interface, self.remotehost)
                if peer_networkinterface.set_mtu(self.mtu) is not None:
                    self.cancel("Failed to set mtu in peer")
            for host_interface in self.host_interfaces:
                self.networkinterface = NetworkInterface(
                    host_interface, self.localhost)
                if self.networkinterface.set_mtu(self.mtu) is not None:
                    self.cancel("Failed to set mtu in host")

    def bond_ib_conf(self, bond_name, arg1, arg2):
        '''
        configure slaves for IB cards
        '''
        cmd = 'ip link set %s up;' % (bond_name)
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            self.fail("unable to bring Bond interface %s up" % bond_name)
        if arg2 == "ATTACH":
            cmd = 'ifenslave %s %s -f;' % (bond_name, arg1)
        else:
            cmd = 'ifenslave %s -d %s ;' % (bond_name, arg1)
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            self.fail("unable to %s IB interface " % arg2)

    def setup_ip(self):
        '''
        set up the IP config
        '''
        if 'setup' in str(self.name):
            interface = self.host_interfaces[0]
        else:
            interface = self.bond_name
        cmd = "ip addr show  | grep %s" % self.peer_first_ipinterface
        output = self.session.cmd(cmd)
        result = ""
        result = result.join(output.stdout.decode("utf-8"))
        self.peer_first_interface = result.split()[-1]
        if self.peer_first_interface == "":
            self.fail("test failed because peer interface can not retrieved")
        self.peer_ips = [self.peer_first_ipinterface]
        self.local_ip = netifaces.ifaddresses(interface)[2][0]['addr']
        self.net_mask = []
        stf = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        for val1, val2 in zip([interface], [self.local_ip]):
            mask = ""
            if val2:
                tmp = fcntl.ioctl(stf.fileno(), 0x891b,
                                  struct.pack('256s', val1.encode()))
                mask = socket.inet_ntoa(tmp[20:24]).strip('\n')
            self.net_mask.append(mask)
        cmd = "route -n | grep %s | grep -w UG | awk "\
              "'{ print $2 }'" % interface
        self.gateway = process.system_output('%s' % cmd, shell=True)

    def bond_remove(self, arg1):
        '''
        bond_remove
        '''
        if arg1 == "local":
            self.log.info("Removing Bonding configuration on local machine")
            self.log.info("------------------------------------------------")
            for ifs in self.host_interfaces:
                cmd = "ip link set %s down" % ifs
                if process.system(cmd, shell=True, ignore_status=True) != 0:
                    self.log.info("unable to bring down the interface")
                if self.ib:
                    self.bond_ib_conf(self.bond_name, ifs, "REMOVE")
                else:
                    genio.write_file(self.bonding_slave_file, "-%s" % ifs)
            genio.write_file(self.bonding_masters_file, "-%s" % self.bond_name)
            self.log.info("Removing bonding module")
            linux_modules.unload_module("bonding")
            time.sleep(self.sleep_time)
        else:
            self.log.info("Removing Bonding configuration on Peer machine")
            self.log.info("------------------------------------------------")
            cmd = ''
            cmd += 'ip link set %s down;' % self.bond_name
            for val in self.peer_interfaces:
                cmd += 'ip link set %s down;' % val
            for val in self.peer_interfaces:
                cmd += 'ip addr flush dev %s;' % val
            for val in self.peer_interfaces:
                if self.ib:
                    self.bond_ib_conf(self.bond_name, val, "REMOVE")
                else:
                    cmd += 'echo "-%s" > %s;' % (val, self.bonding_slave_file)
            cmd += 'echo "-%s" > %s;' % (self.bond_name,
                                         self.bonding_masters_file)
            cmd += 'rmmod bonding;'
            cmd += 'ip addr add %s/%s dev %s;ip link set %s up;sleep 5;'\
                   % (self.peer_first_ipinterface, self.net_mask[0],
                      self.peer_interfaces[0], self.peer_interfaces[0])
            output = self.session.cmd(cmd)
            if not output.exit_status == 0:
                self.log.info("bond removing command failed in peer machine")

    def ping_check(self):
        '''
        ping check
        '''
        # need some time for specific interface before ping
        time.sleep(10)
        cmd = "ping -I %s %s -c 5"\
              % (self.bond_name, self.peer_first_ipinterface)
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            return False
        return True

    def is_vnic(self):
        '''
        check if slave interface is vnic
        '''
        for interface in self.host_interfaces:
            cmd = "lsdevinfo -q name=%s" % interface
            if 'type="IBM,vnic"' in process.system_output(
                    cmd, shell=True).decode("utf-8"):
                return True
        return False

    def bond_fail(self, arg1):
        '''
        bond fail
        '''
        if len(self.host_interfaces) > 1:
            for interface in self.host_interfaces:
                self.log.info("Failing interface %s for mode %s", interface,
                              arg1)
                cmd = "ip link set %s down" % interface
                if process.system(cmd, shell=True, ignore_status=True) != 0:
                    self.fail("bonding not working when trying to down the\
                               interface %s " % interface)
                time.sleep(self.sleep_time)
                if self.ping_check():
                    self.log.info("Ping passed for Mode %s", arg1)
                else:
                    error_str = "Ping fail in Mode %s when interface %s down"\
                        % (arg1, interface)
                    self.log.debug(error_str)
                    self.err.append(error_str)
                self.log.info(genio.read_file(self.bond_status))
                cmd = "ip link set %s up" % interface
                time.sleep(self.sleep_time)
                if process.system(cmd, shell=True, ignore_status=True) != 0:
                    self.fail("Not able to bring up the slave\
                                    interface %s" % interface)
                time.sleep(self.sleep_time)
        else:
            self.log.debug("Need a min of 2 host interfaces to test\
                         slave failover in Bonding")

        self.log.info("\n----------------------------------------")
        self.log.info("Failing all interfaces for mode %s", arg1)
        self.log.info("----------------------------------------")
        for interface in self.host_interfaces:
            cmd = "ip link set %s down" % interface
            if process.system(cmd, shell=True, ignore_status=True) != 0:
                self.fail("Could not bring down the interface %s " % interface)
            time.sleep(self.sleep_time)
        if not self.ping_check():
            self.log.info("Ping to Bond interface failed. This is expected")
        self.log.info(genio.read_file(self.bond_status))
        for interface in self.host_interfaces:
            cmd = "ip link set %s up" % interface
            time.sleep(self.sleep_time)
            if process.system(cmd, shell=True, ignore_status=True) != 0:
                self.fail("Not able to bring up the slave\
                                interface %s" % interface)
            time.sleep(self.sleep_time)
        bond_mtu = [
            '2000', '3000', '4000', '5000', '6000', '7000', '8000', '9000'
        ]
        if self.is_vnic():
            bond_mtu = ['9000']
        for mtu in bond_mtu:
            self.bond_networkinterface = NetworkInterface(
                self.bond_name, self.localhost)
            if self.bond_networkinterface.set_mtu(mtu) is not None:
                self.cancel("Failed to set mtu in host")
            for interface in self.peer_interfaces:
                peer_networkinterface = NetworkInterface(
                    interface, self.remotehost)
                if peer_networkinterface.set_mtu(mtu) is not None:
                    self.cancel("Failed to set mtu in peer")
            if self.ping_check():
                self.log.info("Ping passed for Mode %s", self.mode, mtu)
            else:
                error_str = "Ping fail in Mode %s after MTU change to %s"\
                    % (arg1, mtu)
            if self.bond_networkinterface.set_mtu('1500'):
                self.cancel("Failed to set mtu back to 1500 in host")
            for interface in self.peer_interfaces:
                peer_networkinterface = NetworkInterface(
                    interface, self.remotehost)
                if peer_networkinterface.set_mtu('1500') is not None:
                    self.cancel("Failed to set mtu back to 1500 in peer")

    def bond_setup(self, arg1, arg2):
        '''
        bond setup
        '''
        if arg1 == "local":
            self.log.info("Configuring Bonding on Local machine")
            self.log.info("--------------------------------------")
            for ifs in self.host_interfaces:
                cmd = "ip addr flush dev %s" % ifs
                process.system(cmd, shell=True, ignore_status=True)
            for ifs in self.host_interfaces:
                cmd = "ip link set %s down" % ifs
                process.system(cmd, shell=True, ignore_status=True)
            linux_modules.load_module("bonding")
            genio.write_file(self.bonding_masters_file, "+%s" % self.bond_name)
            genio.write_file("%s/bonding/mode" % self.bond_dir, arg2)
            genio.write_file("%s/bonding/miimon" % self.bond_dir, self.miimon)
            genio.write_file("%s/bonding/fail_over_mac" % self.bond_dir,
                             self.fail_over_mac)
            genio.write_file("%s/bonding/downdelay" % self.bond_dir,
                             self.downdelay)
            dict = {
                '0': ['packets_per_slave', 'resend_igmp'],
                '1':
                ['num_unsol_na', 'primary', 'primary_reselect', 'resend_igmp'],
                '2': ['xmit_hash_policy'],
                '4': ['lacp_rate', 'xmit_hash_policy'],
                '5': [
                    'tlb_dynamic_lb', 'primary', 'primary_reselect',
                    'resend_igmp', 'xmit_hash_policy', 'lp_interval'
                ],
                '6':
                ['primary', 'primary_reselect', 'resend_igmp', 'lp_interval']
            }
            if self.mode in dict.keys():
                for param in dict[self.mode]:
                    param_value = self.params.get(param, default='')
                    if param_value:
                        genio.write_file(
                            "%s/bonding/%s" % (self.bond_dir, param),
                            param_value)
            for val in self.host_interfaces:
                if self.ib:
                    self.bond_ib_conf(self.bond_name, val, "ATTACH")
                else:
                    genio.write_file(self.bonding_slave_file, "+%s" % val)
                time.sleep(2)
            bond_name_val = ''
            for line in genio.read_file(self.bond_status).splitlines():
                if 'Bonding Mode' in line:
                    bond_name_val = line.split(':')[1]
            self.log.info("Trying bond mode %s [ %s ]", arg2, bond_name_val)
            for ifs in self.host_interfaces:
                cmd = "ip link set %s up" % ifs
                if process.system(cmd, shell=True, ignore_status=True) != 0:
                    self.fail("unable to interface up")
            cmd = "ip addr add %s/%s dev %s;ip link set %s up"\
                  % (self.local_ip, self.net_mask[0],
                     self.bond_name, self.bond_name)
            process.system(cmd, shell=True, ignore_status=True)
            for _ in range(0, 600, 60):
                if 'state UP' in process.system_output(
                        "ip link \
                     show %s" % self.bond_name,
                        shell=True).decode("utf-8"):
                    self.log.info("Bonding setup is successful on\
                                  local machine")
                    break
                time.sleep(60)
            else:
                self.fail("Bonding setup on local machine has failed")
            if self.gateway:
                cmd = 'ip route add default via %s dev %s' % \
                    (self.gateway, self.bond_name)
                process.system(cmd, shell=True, ignore_status=True)

        else:
            self.log.info("Configuring Bonding on Peer machine")
            self.log.info("------------------------------------------")
            cmd = ''
            for val in self.peer_interfaces:
                cmd += 'ip addr flush dev %s;' % val
            for val in self.peer_interfaces:
                cmd += 'ip link set %s down;' % val
            cmd += 'modprobe bonding;'
            cmd += 'echo +%s > %s;'\
                   % (self.bond_name, self.bonding_masters_file)
            cmd += 'echo 0 > %s/bonding/mode;'\
                   % self.bond_dir
            cmd += 'echo 100 > %s/bonding/miimon;'\
                   % self.bond_dir
            cmd += 'echo 2 > %s/bonding/fail_over_mac;'\
                   % self.bond_dir
            for val in self.peer_interfaces:
                if self.ib:
                    self.bond_ib_conf(self.bond_name, val, "ATTACH")
                else:
                    cmd += 'echo "+%s" > %s;' % (val, self.bonding_slave_file)
            for val in self.peer_interfaces:
                cmd += 'ip link set %s up;' % val
            cmd += 'ip addr add %s/%s dev %s;ip link set %s up;sleep 5;'\
                   % (self.peer_first_ipinterface, self.net_mask[0],
                      self.bond_name, self.bond_name)
            output = self.session.cmd(cmd)
            if not output.exit_status == 0:
                self.fail("bond setup command failed in peer machine")

    def test_setup(self):
        '''
        bonding the interfaces
        work for multiple interfaces on both host and peer
        '''
        cmd = "[ -d %s ]" % self.bond_dir
        output = self.session.cmd(cmd)
        if output.exit_status == 0:
            self.fail("bond name already exists on peer machine")
        if os.path.isdir(self.bond_dir):
            self.fail("bond name already exists on local machine")
        if self.peer_bond_needed:
            self.bond_setup("peer", "")
        self.bond_setup("local", self.mode)
        self.log.info(genio.read_file(self.bond_status))
        self.ping_check()
        self.error_check()

    def test_run(self):
        self.bond_fail(self.mode)
        self.log.info("Mode %s OK", self.mode)
        self.error_check()
        # need few sec for interface to not lost the connection to peer
        time.sleep(5)

    def test_cleanup(self):
        '''
        clean up the interface config
        '''
        self.bond_remove("local")

        if self.gateway:
            cmd = 'ip route add default via %s' % \
                (self.gateway)
            process.system(cmd, shell=True, ignore_status=True)

        if self.peer_bond_needed:
            self.bond_remove("peer")
            for val in self.peer_interfaces:
                cmd = "ifdown %s; ifup %s; sleep %s"\
                      % (val, val, self.peer_wait_time)
                output = self.session.cmd(cmd)
                if not output.exit_status == 0:
                    self.log.warn("unable to bring to original state in peer")
                time.sleep(self.sleep_time)
        self.error_check()

        for ipaddr, host_interface in zip(self.ipaddr, self.host_interfaces):
            networkinterface = NetworkInterface(host_interface, self.localhost)
            try:
                networkinterface.add_ipaddr(ipaddr, self.netmask)
                networkinterface.bring_up()
            except Exception:
                self.fail("Interface is taking long time to link up")
            if networkinterface.set_mtu("1500") is not None:
                self.cancel("Failed to set mtu in host")
            try:
                networkinterface.restore_from_backup()
            except Exception:
                self.log.info(
                    "backup file not availbale, could not restore file.")
        try:
            for interface in self.peer_interfaces:
                peer_networkinterface = NetworkInterface(
                    interface, self.remotehost)
                peer_networkinterface.set_mtu("1500")
        except Exception:
            for interface in self.peer_interfaces:
                peer_public_networkinterface = NetworkInterface(
                    interface, self.remotehost_public)
                peer_public_networkinterface.set_mtu("1500")
        self.remotehost.remote_session.quit()
        self.remotehost_public.remote_session.quit()

    def error_check(self):
        if self.err:
            self.fail("Tests failed. Details:\n%s" % "\n".join(self.err))

    def tearDown(self):
        self.session.quit()
Beispiel #6
0
class NetworkSriovDevice(Test):
    '''
    adding and deleting logical sriov device through
    HMC.
    '''
    def setUp(self):
        '''
        set up required packages and gather necessary test inputs
        '''
        smm = SoftwareManager()
        packages = [
            'src', 'rsct.basic', 'rsct.core.utils', 'NetworkManager',
            'rsct.core', 'DynamicRM', 'powerpc-utils'
        ]
        for pkg in packages:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel('%s is needed for the test to be run' % pkg)
        self.hmc_ip = self.get_mcp_component("HMCIPAddr")
        if not self.hmc_ip:
            self.cancel("HMC IP not got")
        self.hmc_pwd = self.params.get("hmc_pwd", '*', default=None)
        self.hmc_username = self.params.get("hmc_username", '*', default=None)
        self.lpar = self.get_partition_name("Partition Name")
        if not self.lpar:
            self.cancel("LPAR Name not got from lparstat command")
        self.session = Session(self.hmc_ip,
                               user=self.hmc_username,
                               password=self.hmc_pwd)
        if not self.session.connect():
            self.cancel("failed connetion to HMC")
        cmd = 'lssyscfg -r sys  -F name'
        output = self.session.cmd(cmd)
        self.server = ''
        for line in output.stdout_text.splitlines():
            if line in self.lpar:
                self.server = line
                break
        if not self.server:
            self.cancel("Managed System not got")
        self.sriov_adapter = self.params.get('sriov_adapter',
                                             '*',
                                             default=None).split(' ')
        self.sriov_port = self.params.get('sriov_port', '*',
                                          default=None).split(' ')
        self.ipaddr = self.params.get('ipaddr', '*', default="").split(' ')
        self.netmask = self.params.get('netmasks', '*', default="").split(' ')
        self.prefix = self.netmask_to_cidr(self.netmask[0])
        self.peer_ip = self.params.get('peer_ip', '*', default="").split(' ')
        self.mac_id = self.params.get('mac_id',
                                      default="02:03:03:03:03:01").split(' ')
        self.mac_id = [mac.replace(':', '') for mac in self.mac_id]
        self.migratable = self.params.get('migratable', '*', default=0)
        self.backup_device_type = self.params.get('backup_device_type',
                                                  '*',
                                                  default='')
        self.backup_device_slot_num = self.params.get('backup_device_slot_num',
                                                      '*',
                                                      default=None)
        self.backup_veth_vnetwork = self.params.get('backup_veth_vnetwork',
                                                    '*',
                                                    default=None)
        if 'vnic' in self.backup_device_type:
            self.vnic_sriov_adapter = self.params.get('vnic_sriov_adapter',
                                                      '*',
                                                      default=None)
            self.vnic_port_id = self.params.get('vnic_port_id',
                                                '*',
                                                default=None)
            self.vnic_adapter_id = self.get_adapter_id(self.vnic_sriov_adapter)
            self.priority = self.params.get('failover_priority',
                                            '*',
                                            default='50')
            self.max_capacity = self.params.get('max_capacity',
                                                '*',
                                                default='10')
            self.capacity = self.params.get('capacity', '*', default='2')
            self.vios_name = self.params.get('vios_name', '*', default=None)
            cmd = 'lssyscfg -m %s -r lpar --filter lpar_names=%s -F lpar_id' % (
                self.server, self.vios_name)
            self.vios_id = self.session.cmd(cmd).stdout_text.split()[0]
            self.backup_vnic_backing_device = 'sriov/%s/%s/%s/%s/%s/%s/%s' % \
                (self.vios_name, self.vios_id, self.vnic_adapter_id, self.vnic_port_id,
                 self.capacity, self.priority, self.max_capacity)
        self.local = LocalHost()

    @staticmethod
    def netmask_to_cidr(netmask):
        return (sum([bin(int(bits)).count("1")
                     for bits in netmask.split(".")]))

    def get_adapter_id(self, slot):
        cmd = "lshwres -m %s -r sriov --rsubtype adapter -F phys_loc:adapter_id" \
              % (self.server)
        output = self.session.cmd(cmd)
        for line in output.stdout_text.splitlines():
            if slot in line:
                return line.split(':')[-1]
        self.cancel("adapter not found at slot %s", slot)

    @staticmethod
    def get_mcp_component(component):
        '''
        probes IBM.MCP class for mentioned component and returns it.
        '''
        for line in process.system_output('lsrsrc IBM.MCP %s' % component,
                                          ignore_status=True, shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split()[-1].strip('{}\"')
        return ''

    @staticmethod
    def get_partition_name(component):
        '''
        get partition name from lparstat -i
        '''

        for line in process.system_output('lparstat -i', ignore_status=True,
                                          shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split(':')[-1].strip()
        return ''

    def test_add_logical_device(self):
        '''
        test to create logical sriov device
        '''
        if self.migratable:
            self.cancel("Test unsupported")
        for slot, port, mac, ipaddr, netmask, peer_ip in zip(
                self.sriov_adapter, self.sriov_port, self.mac_id, self.ipaddr,
                self.netmask, self.peer_ip):
            self.device_add_remove(slot, port, mac, '', 'add')
            if not self.list_device(mac):
                self.fail("failed to list logical device after add operation")
            device = self.find_device(mac)
            networkinterface = NetworkInterface(device, self.local)
            networkinterface.add_ipaddr(ipaddr, netmask)
            networkinterface.bring_up()
            if networkinterface.ping_check(peer_ip, count=5) is not None:
                self.fail("ping check failed")

    def test_add_migratable_sriov(self):
        '''
        test to create Migratable sriov device
        '''
        if not self.migratable:
            self.cancel("Test unsupported")

        for slot, port, mac, ipaddr, netmask, peer_ip in zip(
                self.sriov_adapter, self.sriov_port, self.mac_id, self.ipaddr,
                self.netmask, self.peer_ip):

            self.device_add_remove(slot, port, mac, '', 'add')
            if not self.list_device(mac):
                self.fail(
                    "failed to list Migratable logical device after add operation"
                )
            bond_device = self.get_hnv_bond(mac)
            if bond_device:
                ret = process.run(
                    'nmcli c mod id %s ipv4.method manual ipv4.addres %s/%s' %
                    (bond_device, ipaddr, self.prefix),
                    ignore_status=True)
                if ret.exit_status:
                    self.fail(
                        "nmcli ip configuration for hnv bond fail with %s" %
                        (ret.exit_status))
                ret = process.run('nmcli c up %s' % bond_device,
                                  ignore_status=True)
                if ret.exit_status:
                    self.fail("hnv bond ip bring up fail with %s" %
                              (ret.exit_status))
                networkinterface = NetworkInterface(bond_device, self.local)
                if networkinterface.ping_check(peer_ip, count=5) is not None:
                    self.fail("ping check failed for hnv bond device")
            else:
                self.fail("failed to create hnv bond device")

    def test_remove_migratable_sriov(self):
        '''
        test to remove Migratable sriov device
        '''
        if not self.migratable:
            self.cancel("Test unsupported")
        for mac, slot in zip(self.mac_id, self.sriov_adapter):
            bond_device = self.get_hnv_bond(mac)
            if bond_device:
                ret = process.run('nmcli c down %s' % bond_device,
                                  ignore_status=True)
                if ret.exit_status:
                    self.fail("hnv bond ip bring down fail with %s" %
                              (ret.exit_status))
                ret = process.run('nmcli c del %s' % bond_device,
                                  ignore_status=True)
                if ret.exit_status:
                    self.fail("hnv bond delete fail with %s" %
                              (ret.exit_status))
                logical_port_id = self.get_logical_port_id(mac)
                self.device_add_remove(slot, '', '', logical_port_id, 'remove')
                if self.list_device(mac):
                    self.fail("fail to remove migratable logical device")

    def test_remove_logical_device(self):
        """
        test to remove logical device
        """
        if self.migratable:
            self.cancel("Test unsupported")
        for mac, slot in zip(self.mac_id, self.sriov_adapter):
            logical_port_id = self.get_logical_port_id(mac)
            self.device_add_remove(slot, '', '', logical_port_id, 'remove')
            if self.list_device(mac):
                self.fail("still list logical device after remove operation")

    def device_add_remove(self, slot, port, mac, logical_id, operation):
        """
        add and remove operation of logical devices
        """
        adapter_id = self.get_adapter_id(slot)
        backup_device = ''
        if self.backup_device_type:
            if 'veth' in self.backup_device_type:
                backup_device = ',backup_device_type=%s,backup_veth_vnetwork=%s' % (
                    self.backup_device_type, self.backup_veth_vnetwork)
            else:
                backup_device = ',backup_device_type=%s,backup_vnic_backing_device=%s' % (
                    self.backup_device_type, self.backup_vnic_backing_device)

        if operation == 'add':
            cmd = 'chhwres -r sriov -m %s --rsubtype logport \
                  -o a -p %s -a \"adapter_id=%s,phys_port_id=%s, \
                  logical_port_type=eth,mac_addr=%s,migratable=%s%s\" ' \
                  % (self.server, self.lpar, adapter_id,
                     port, mac, self.migratable, backup_device)
        else:
            cmd = 'chhwres -r sriov -m %s --rsubtype logport \
                  -o r -p %s -a \"adapter_id=%s,logical_port_id=%s\" ' \
                  % (self.server, self.lpar, adapter_id, logical_id)
        cmd = self.session.cmd(cmd)
        if cmd.exit_status != 0:
            self.log.debug(cmd.stderr)
            self.fail("sriov logical device %s operation \
                       failed" % operation)

    def get_logical_port_id(self, mac):
        """
        findout logical device port id
        """
        cmd = "lshwres -r sriov --rsubtype logport -m  %s \
               --level eth | grep %s | grep %s" \
               % (self.server, self.lpar, mac)
        output = self.session.cmd(cmd)
        logical_port_id = output.stdout_text.split(',')[6].split('=')[-1]
        return logical_port_id

    def get_hnv_bond(self, mac):
        """
        Get the newly created hnv bond interface name
        """
        output = genio.read_one_line("/sys/class/net/bonding_masters").split()
        for bond in output:
            if mac in netifaces.ifaddresses(bond)[17][0]['addr'].replace(
                    ':', ''):
                return bond
        self.fail("Test fail due to mac address mismatch")

    @staticmethod
    def find_device(mac_addrs):
        """
        Finds out the latest added sriov logical device
        """
        mac = ':'.join(mac_addrs[i:i + 2] for i in range(0, 12, 2))
        devices = netifaces.interfaces()
        for device in devices:
            if mac in netifaces.ifaddresses(device)[17][0]['addr']:
                return device
        return ''

    def list_device(self, mac):
        """
        list the sriov logical device
        """
        cmd = 'lshwres -r sriov --rsubtype logport -m  ltcfleet2 \
              --level eth --filter \"lpar_names=%s\" ' % self.lpar
        output = self.session.cmd(cmd)
        if mac in output.stdout_text:
            return True
        return False

    def tearDown(self):
        self.session.quit()
Beispiel #7
0
class DlparPci(Test):
    '''
    DLPAR PCI script does pci add,remove and also move operation from one
    lpar to another lpar. Update the details in yaml file.
    For move operation, please configure another lpar and update in yaml file.
    And also make sure both rsct and rsct_rm services up and running
    '''

    def setUp(self):
        '''
        Gather necessary test inputs.
        Test all services.
        '''
        self.session = None
        self.install_packages()
        self.rsct_service_start()
        self.hmc_ip = self.get_mcp_component("HMCIPAddr")
        if not self.hmc_ip:
            self.cancel("HMC IP not got")
        self.hmc_user = self.params.get("hmc_username", default='hscroot')
        self.hmc_pwd = self.params.get("hmc_pwd", '*', default='********')
        self.sriov = self.params.get("sriov", default="no")
        self.lpar_1 = self.get_partition_name("Partition Name")
        if not self.lpar_1:
            self.cancel("LPAR Name not got from lparstat command")
        self.session = Session(self.hmc_ip, user=self.hmc_user,
                               password=self.hmc_pwd)
        if not self.session.connect():
            self.cancel("failed connecting to HMC")
        cmd = 'lssyscfg -r sys  -F name'
        output = self.session.cmd(cmd)
        self.server = ''
        for line in output.stdout_text.splitlines():
            if line in self.lpar_1:
                self.server = line
                break
        if not self.server:
            self.cancel("Managed System not got")
        self.lpar_2 = self.params.get("lpar_2", '*', default=None)
        if self.lpar_2 is not None:
            cmd = 'lshwres -r io -m %s --rsubtype slot --filter \
                   lpar_names=%s -F lpar_id' % (self.server, self.lpar_2)
            output = self.session.cmd(cmd)
            self.lpar2_id = output.stdout_text[0]
        self.pci_device = self.params.get("pci_device", '*', default=None)
        self.loc_code = pci.get_slot_from_sysfs(self.pci_device)
        self.num_of_dlpar = int(self.params.get("num_of_dlpar", default='1'))
        if self.loc_code is None:
            self.cancel("Failed to get the location code for the pci device")
        self.session.cmd("uname -a")
        if self.sriov == "yes":
            cmd = "lshwres -r sriov --rsubtype logport -m %s \
            --level eth --filter lpar_names=%s -F \
            'adapter_id,logical_port_id,phys_port_id,lpar_id,location_code,drc_name'" \
                   % (self.server, self.lpar_1)
            output = self.session.cmd(cmd)
            for line in output.stdout_text.splitlines():
                if self.loc_code in line:
                    self.adapter_id = line.split(',')[0]
                    self.logical_port_id = line.split(',')[1]
                    self.phys_port_id = line.split(',')[2]
                    self.lpar_id = line.split(',')[3]
                    self.location_code = line.split(',')[4]
                    self.phb = line.split(',')[5].split(' ')[1]
                    break
            self.log.info("lpar_id : %s, loc_code: %s",
                          self.lpar_id, self.loc_code)
        else:
            cmd = 'lshwres -r io -m %s --rsubtype slot \
                   --filter lpar_names=%s -F drc_index,lpar_id,drc_name,bus_id' \
                   % (self.server, self.lpar_1)
            output = self.session.cmd(cmd)
            for line in output.stdout_text.splitlines():
                if self.loc_code in line:
                    self.drc_index = line.split(',')[0]
                    self.lpar_id = line.split(',')[1]
                    self.phb = line.split(',')[3]
                    break

            self.log.info("lpar_id : %s, loc_code: %s, drc_index: %s, phb: %s",
                          self.lpar_id, self.loc_code, self.drc_index,
                          self.phb)

    @staticmethod
    def get_mcp_component(component):
        '''
        probes IBM.MCP class for mentioned component and returns it.
        '''
        for line in process.system_output('lsrsrc IBM.MCP %s' % component,
                                          ignore_status=True, shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split()[-1].strip('{}\"')
        return ''

    @staticmethod
    def get_partition_name(component):
        '''
        get partition name from lparstat -i
        '''

        for line in process.system_output('lparstat -i',
                                          ignore_status=True, shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split(':')[-1].strip()
        return ''

    def install_packages(self):
        '''
        Install required packages
        '''
        smm = SoftwareManager()
        packages = ['ksh', 'src', 'rsct.basic', 'rsct.core.utils',
                    'rsct.core', 'DynamicRM', 'pciutils']
        detected_distro = distro.detect()
        if detected_distro.name == "Ubuntu":
            packages.extend(['python-paramiko'])
        self.log.info("Test is running on: %s", detected_distro.name)
        for pkg in packages:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel('%s is needed for the test to be run' % pkg)
        if detected_distro.name == "Ubuntu":
            ubuntu_url = self.params.get('ubuntu_url', default=None)
            debs = self.params.get('debs', default=None)
            for deb in debs:
                deb_url = os.path.join(ubuntu_url, deb)
                deb_install = self.fetch_asset(deb_url, expire='7d')
                shutil.copy(deb_install, self.workdir)
                process.system("dpkg -i %s/%s" % (self.workdir, deb),
                               ignore_status=True, sudo=True)

    def rsct_service_start(self):
        '''
        Start required services
        '''
        try:
            process.run("startsrc -g rsct", shell=True, sudo=True)
        except CmdError as details:
            self.log.debug(str(details))
            self.cancel("Command startsrc -g rsct failed")

        try:
            process.run("startsrc -g rsct_rm", shell=True, sudo=True)
        except CmdError as details:
            self.log.debug(str(details))
            self.cancel("Command startsrc -g rsct_rm failed")

        output = process.system_output("lssrc -a", ignore_status=True,
                                       shell=True, sudo=True).decode("utf-8")

        if "inoperative" in output:
            self.cancel("Failed to start the rsct and rsct_rm services")

    def test_dlpar(self):
        '''
        DLPAR remove, add and move operations from lpar_1 to lpar_2
        '''
        for _ in range(self.num_of_dlpar):
            self.dlpar_remove()
            self.dlpar_add()
            self.dlpar_move()

    def test_drmgr_pci(self):
        '''
        drmgr remove, add and replace operations
        '''
        for _ in range(self.num_of_dlpar):
            self.do_drmgr_pci('r')
            self.do_drmgr_pci('a')
        for _ in range(self.num_of_dlpar):
            self.do_drmgr_pci('R')

    def test_drmgr_phb(self):
        '''
        drmgr remove, add and replace operations
        '''
        for _ in range(self.num_of_dlpar):
            self.do_drmgr_phb('r')
            self.do_drmgr_phb('a')

    def do_drmgr_pci(self, operation):
        '''
        drmgr operation for pci
        '''
        cmd = "echo -e \"\n\" | drmgr -c pci -s %s -%s" % (self.loc_code,
                                                           operation)
        if process.system(cmd, shell=True, sudo=True, ignore_status=True):
            self.fail("drmgr operation %s fails for PCI" % operation)

    def do_drmgr_phb(self, operation):
        '''
        drmgr operation for phb
        '''
        cmd = "drmgr -c phb -s \"PHB %s\" -%s" % (self.phb, operation)
        if process.system(cmd, shell=True, sudo=True, ignore_status=True):
            self.fail("drmgr operation %s fails for PHB" % operation)

    def dlpar_remove(self):
        '''
        dlpar remove operation
        '''
        if self.sriov == "yes":
            self.changehwres_sriov(self.server, 'r', self.lpar_id,
                                   self.adapter_id, self.logical_port_id,
                                   self.phys_port_id, 'remove')
            output = self.listhwres_sriov(self.server, self.lpar_1,
                                          self.logical_port_id)
            if output:
                self.log.debug(output)
                self.fail("lshwres still lists the drc after dlpar remove")
        else:
            self.changehwres(self.server, 'r', self.lpar_id, self.lpar_1,
                             self.drc_index, 'remove')
            output = self.listhwres(self.server, self.lpar_1, self.drc_index)
            if output:
                self.log.debug(output)
                self.fail("lshwres still lists the drc after dlpar remove")

    def dlpar_add(self):
        '''
        dlpar add operation
        '''
        if self.sriov == "yes":
            self.changehwres_sriov(self.server, 'a', self.lpar_id,
                                   self.adapter_id, self.logical_port_id,
                                   self.phys_port_id, 'add')
            output = self.listhwres_sriov(self.server, self.lpar_1,
                                          self.logical_port_id)
            if self.logical_port_id not in output:
                self.log.debug(output)
                self.fail("lshwres fails to list the drc after dlpar add")
        else:
            self.changehwres(self.server, 'a', self.lpar_id, self.lpar_1,
                             self.drc_index, 'add')
            output = self.listhwres(self.server, self.lpar_1, self.drc_index)
            if self.drc_index not in output:
                self.log.debug(output)
                self.fail("lshwres fails to list the drc after dlpar add")

    def dlpar_move(self):
        '''
        dlpar move operation from lpar_1 to lpar2 and back from
        lpar_2 to lpar_1
        '''
        if self.lpar_2 is None:
            return

        self.changehwres(self.server, 'm', self.lpar_id, self.lpar_2,
                         self.drc_index, 'move')
        output = self.listhwres(self.server, self.lpar_1, self.drc_index)
        if self.drc_index in output:
            self.log.debug(output)
            self.fail("lshwres still lists the drc in lpar_1 after \
                      dlpar move to lpar_2")

        output = self.listhwres(self.server, self.lpar_2, self.drc_index)
        if self.drc_index not in output:
            self.log.debug(output)
            self.fail("lshwres fails to list the drc in lpar_2 after \
                       dlpar move")

        # dlpar move operation from lpar2 to lpar1
        self.changehwres(self.server, 'm', self.lpar2_id, self.lpar_1,
                         self.drc_index, 'move')

        output = self.listhwres(self.server, self.lpar_1, self.drc_index)
        if self.drc_index not in output:
            self.log.debug(output)
            self.fail("lshwres fails to list the drc in lpar_1 after \
                       dlpar move")

        output = self.listhwres(self.server, self.lpar_2, self.drc_index)
        if self.drc_index in output:
            self.log.debug(output)
            self.fail("lshwres still lists the drc in lpar_2 after \
                      dlpar move to lpar_1")

    def listhwres(self, server, lpar, drc_index):
        '''
        lists the drc index resources
        '''
        cmd = 'lshwres -r io -m %s \
               --rsubtype slot --filter lpar_names= %s \
               | grep -i %s' % (server, lpar, drc_index)
        try:
            cmd = self.session.cmd(cmd).stdout_text
        except CmdError as details:
            self.log.debug(str(details))
            self.fail("lshwres operation failed ")
        return cmd

    def listhwres_sriov(self, server, lpar, logical_port_id):
        cmd = 'lshwres -r sriov -m %s \
              --rsubtype logport --filter lpar_names= %s --level eth \
              | grep -i %s' % (server, lpar, logical_port_id)
        try:
            cmd = self.session.cmd(cmd).stdout_text
        except CmdError as details:
            self.log.debug(str(details))
            self.fail("lshwres operation failed ")
        return cmd

    def changehwres(self, server, operation, lpar_id, lpar, drc_index, msg):
        '''
        changes the drc index resource: add / remove / move
        '''
        if operation == 'm':
            cmd = 'chhwres -r io --rsubtype slot -m %s \
               -o %s --id %s -t %s -l %s ' % (server, operation, lpar_id,
                                              lpar, drc_index)
        else:
            cmd = 'chhwres -r io --rsubtype slot -m %s \
                   -o %s --id %s -l %s ' % (server, operation, lpar_id,
                                            drc_index)
        cmd = self.session.cmd(cmd)
        if cmd.exit_status != 0:
            self.log.debug(cmd.stderr)
            self.fail("dlpar %s operation failed" % msg)

    def changehwres_sriov(self, server, operation, lpar_id, adapter_id,
                          logical_port_id, phys_port_id, msg):
        '''
        operation add / remove for sriov ports
        '''
        if operation == 'r':
            cmd = 'chhwres -r sriov -m %s --rsubtype logport -o r --id %s -a \
                  adapter_id=%s,logical_port_id=%s' \
                  % (server, lpar_id, adapter_id, logical_port_id)
        elif operation == 'a':
            cmd = 'chhwres -r sriov -m %s --rsubtype logport -o a --id %s -a \
                  phys_port_id=%s,adapter_id=%s,logical_port_id=%s, \
                  logical_port_type=eth' % (server, lpar_id, phys_port_id,
                                            adapter_id, logical_port_id)
        cmd = self.session.cmd(cmd)
        if cmd.exit_status != 0:
            self.log.debug(cmd.stderr)
            self.fail("dlpar %s operation failed" % msg)

    def tearDown(self):
        if self.session:
            self.session.quit()
class DlparTest(Test):
    '''
    DLPAR disk script does vscsi device add,remove.
    Update the details in yaml file.
    '''
    def setUp(self):
        '''
        Gather necessary test inputs.
        '''
        self.disk = self.params.get('disk', default=None)
        self.num_of_dlpar = int(self.params.get("num_of_dlpar", default='1'))
        self.vios_ip = self.params.get('vios_ip', '*', default=None)
        self.vios_user = self.params.get('vios_username', '*', default=None)
        self.vios_pwd = self.params.get('vios_pwd', '*', default=None)
        self.session = Session(self.vios_ip,
                               user=self.vios_user,
                               password=self.vios_pwd)
        self.session.connect()
        cmd = "lscfg -l %s" % self.disk
        for line in process.system_output(cmd, shell=True).decode("utf-8") \
                                                          .splitlines():
            if self.disk in line:
                self.slot = line.split()[-1].split('-')[-2]
        cmd = "ioscli lsdev -slots"
        output = self.session.cmd(cmd)
        for line in output.stdout_text.splitlines():
            if self.slot in line:
                self.host = line.split()[-1]
        self.log.info(self.host)
        cmd = "lsscsi -vl"
        output = process.system_output(cmd, shell=True)
        for line in output.decode("utf-8").splitlines():
            if self.disk in line:
                value = line.split()[0].replace('[', '').replace(']', '')
        for line in output.decode("utf-8").splitlines():
            if value in line:
                if "dir" in line:
                    self.disk_dir = line.split()[-1].replace('[', '') \
                                                    .replace(']', '')
        cmd = r"cat %s/inquiry" % self.disk_dir
        output = process.system_output(cmd, shell=True)
        self.hdisk_name = output.split()[2].strip(b'0001').decode("utf-8")
        self.log.info(self.hdisk_name)
        cmd = "ioscli lsmap -all|grep -p %s" % self.hdisk_name
        output = self.session.cmd(cmd)
        for line in output.stdout_text.splitlines():
            if "VTD" in line:
                self.vscsi = line.split()[-1]
        if not self.vscsi:
            self.cancel("failed to get vscsi")
        self.log.info(self.vscsi)

    def dlpar_remove(self):
        '''
        dlpar remove operation
        '''
        cmd = "ioscli rmvdev -vdev %s" % self.hdisk_name
        output = self.session.cmd(cmd)
        self.log.info(output.stdout_text)
        if output.exit_status != 0:
            self.fail("failed dlpar remove operation")

    def dlpar_add(self):
        '''
        dlpar add operation
        '''
        cmd = "ioscli mkvdev -vdev %s -vadapter %s -dev %s" % (
            self.hdisk_name, self.host, self.vscsi)
        output = self.session.cmd(cmd)
        self.log.info(output.stdout_text)
        if output.exit_status != 0:
            self.fail("Failed dlpar add operation")

    def test_dlpar(self):
        '''
        vscsi dlpar remove and add operation
        '''
        for _ in range(self.num_of_dlpar):
            self.dlpar_remove()
            self.dlpar_add()

    def tearDown(self):
        self.session.quit()
class VirtualFC(Test):
    '''
    Removing and Adding and Fibre Chanel Virtualized devices from the HMC
    '''
    @skipUnless("ppc" in distro.detect().arch,
                "supported only on Power platform")
    @skipIf(IS_POWER_NV or IS_KVM_GUEST,
            "This test is not supported on KVM guest or PowerNV platform")
    def setUp(self):
        '''
        set up required packages and gather necessary test inputs
        '''
        self.install_packages()
        self.rsct_service_start()
        self.hmc_ip = self.get_mcp_component("HMCIPAddr")
        if not self.hmc_ip:
            self.cancel("HMC IP not got")
        self.vioses = self.params.get("vioses", default=None)
        self.hmc_pwd = self.params.get("hmc_pwd", '*', default=None)
        self.hmc_username = self.params.get("hmc_username", '*', default=None)
        self.count = self.params.get("count", default=1)
        # TO_DO: self.skip_host parameter can be remove
        # if script is self reliable to find bootable disk
        self.skip_host = self.params.get("skip_host", default=None)
        self.vfc_id = self.params.get("vfchost_id", default=None)
        self.vfchost_count = int(self.params.get("vfc_count", default=1))
        # Since the command in each layer doesn't take same time to complete
        # there is delay observed in status reflect (like host and multipath).
        # even though we have used the wait.wait_for funtion, this is not
        # enough to handle the case. since the operation flow reflect in 3
        # stages (lpar, HMC, vios), giving a short sleep time helps the flow
        # to happen smoother. Hence adding the sleep time after each major
        # operation like unamp, map, define, undefine, create, delete.
        # we can remove this sleep time in future if the flow happens smoother
        self.opp_sleep_time = 20
        self.lpar = self.get_partition_name("Partition Name")
        if not self.lpar:
            self.cancel("LPAR Name not got from lparstat command")
        self.session = Session(self.hmc_ip,
                               user=self.hmc_username,
                               password=self.hmc_pwd)
        if not self.session.connect():
            self.cancel("failed connecting to HMC")
        cmd = 'lssyscfg -r sys  -F name'
        output = self.session.cmd(cmd).stdout_text
        self.server = ''
        for line in output.splitlines():
            if line in self.lpar:
                self.server = line
        if not self.server:
            self.cancel("Managed System not got")
        self.dic_list = []
        self.err_mesg = []
        for vios in self.vioses.split(" "):
            for vfchost in self.get_vfchost(vios):
                vfc_dic = {}
                vfc_dic["vios"] = vios
                vfc_dic["vfchost"] = vfchost
                vfc_dic["fcs"] = self.get_fcs_name(vfchost, vios)
                vfc_dic["vfc_client"] = self.get_vfc_client(vfchost, vios)
                vfc_dic["paths"] = self.get_paths(vfc_dic["vfc_client"])
                if vfc_dic["vfc_client"] != self.skip_host:
                    self.dic_list.append(vfc_dic)

        self.log.info("complete list : %s" % self.dic_list)

    @staticmethod
    def get_mcp_component(component):
        '''
        probes IBM.MCP class for mentioned component and returns it.
        '''
        for line in process.system_output('lsrsrc IBM.MCP %s' % component,
                                          ignore_status=True, shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split()[-1].strip('{}\"')
        return ''

    @staticmethod
    def get_partition_name(component):
        '''
        get partition name from lparstat -i
        '''

        for line in process.system_output('lparstat -i', ignore_status=True,
                                          shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split(':')[-1].strip()
        return ''

    def rsct_service_start(self):
        '''
        Running rsct services which is necessary for Network
        virtualization tests
        '''
        try:
            for svc in ["rsct", "rsct_rm"]:
                process.run('startsrc -g %s' % svc, shell=True, sudo=True)
        except CmdError as details:
            self.log.debug(str(details))
            self.fail("Starting service %s failed", svc)

        output = process.system_output("lssrc -a",
                                       ignore_status=True,
                                       shell=True,
                                       sudo=True).decode("utf-8")
        if "inoperative" in output:
            self.fail("Failed to start the rsct and rsct_rm services")

    def install_packages(self):
        '''
        Install required packages
        '''
        smm = SoftwareManager()
        detected_distro = distro.detect()
        self.log.info("Test is running on: %s", detected_distro.name)
        for pkg in [
                'ksh', 'src', 'rsct.basic', 'rsct.core.utils', 'rsct.core',
                'DynamicRM'
        ]:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel('%s is needed for the test to be run' % pkg)

    def test_unmap_map(self):
        '''
        Remove and add vfc interfaces Dynamically from HMC
        '''
        for _ in range(self.count):
            for vfc_dic in self.dic_list:
                self.vfchost_map_unmap("unmap", vfc_dic)
                time.sleep(self.opp_sleep_time)
                self.vfchost_map_unmap("map", vfc_dic)
                # sleeping between the operation. can be enhanced in future.
                time.sleep(self.opp_sleep_time)
        if self.err_mesg:
            self.fail("test failed due to folowing reasons:%s" % self.err_mesg)

    def get_vfchost(self, vios_name):
        '''
        Returns the drc_name i,e vfc slot name mapped to lpar
        '''
        vfchost = []
        cmd = 'viosvrcmd -m %s -p %s -c "lsmap -all -npiv -field  Name \
               ClntName -fmt :"' % (self.server, vios_name)
        output = self.session.cmd(cmd).stdout_text
        for line in output.splitlines():
            if self.lpar in line:
                vfchost.append(line.split(":")[0])
        return vfchost

    def get_fcs_name(self, vfchost, vios_name):
        '''
        returns the linux_name of corresponding drc_name
        '''
        cmd = 'viosvrcmd -m %s -p %s -c "lsmap -all -npiv -field Name \
               fc -fmt :"' % (self.server, vios_name)
        output = self.session.cmd(cmd).stdout_text
        self.log.info("output value : %s" % output)
        for line in output.splitlines():
            if vfchost in line:
                return line.split(":")[-1]
        return ''

    def get_vfc_client(self, vfchost, vios_name):
        '''
        returns the linux_name of corresponding drc_name
        '''
        cmd = 'viosvrcmd -m %s -p %s -c "lsmap -all -npiv -field  name\
               vfcclient -fmt :"' % (self.server, vios_name)
        output = self.session.cmd(cmd).stdout_text
        self.log.info("output value : %s" % output)
        for line in output.splitlines():
            if vfchost in line:
                return line.split(":")[-1]
        return ''

    def get_vfchost_status(self, vfchost, vios_name):
        '''
        returns the linux_name of corresponding drc_name
        '''
        cmd = 'viosvrcmd -m %s -p %s -c "lsmap -all -npiv -field  name\
               Status -fmt :"' % (self.server, vios_name)
        output = self.session.cmd(cmd).stdout_text
        self.log.info("output value : %s" % output)
        for line in output.splitlines():
            if vfchost in line:
                return line.split(":")[-1]
        return ''

    def get_paths(self, vfc_client):
        '''
        returns the mpaths corresponding to linux name
        '''
        paths = []
        cmd = "ls -l /sys/block/"
        output = process.system_output(cmd).decode('utf-8').splitlines()
        for line in output:
            if "/%s/" % vfc_client in line:
                paths.append(line.split("/")[-1])
        return paths

    def vfchost_map_unmap(self, operation, vfc_dic):
        '''
        Adds and removes a Network virtualized device based
        on the operation
        '''
        self.log.info("%sing %s" % (operation, vfc_dic["vfchost"]))
        if operation == 'map':
            cmd = 'viosvrcmd -m %s -p %s -c "vfcmap -vadapter %s -fcp %s"' \
                % (self.server, vfc_dic["vios"],
                   vfc_dic["vfchost"], vfc_dic["fcs"])
        else:
            cmd = 'viosvrcmd -m %s -p %s -c "vfcmap -vadapter %s -fcp"' \
                % (self.server, vfc_dic["vios"], vfc_dic["vfchost"])

        output = self.session.cmd(cmd)
        if output.exit_status != 0:
            self.log.debug(output.stderr)
            self.fail("vfchost %s operation failed" % operation)
        time.sleep(5)
        self.vfchost_status_verify(operation, vfc_dic["vfchost"],
                                   vfc_dic["vios"])
        time.sleep(5)
        self.vfc_client_status_verify(operation, vfc_dic["vfc_client"])
        self.mpath_verification(operation, vfc_dic["paths"])

    def vfc_client_status_verify(self, operation, vfc_client):
        '''
        Verifies client host status after running given operation
        '''
        self.log.info("verifying %s status after %s its \
                       vfchost" % (vfc_client, operation))

        def is_host_online():
            file_name = '/sys/class/fc_host/%s/port_state' % vfc_client
            status = genio.read_file(file_name).strip("\n")
            if operation in ('map', 'add'):
                if status == 'Online':
                    self.log.info("operation:%s host:%s status=%s return:True \
                                   " % (operation, vfc_client, status))
                    return True
                else:
                    self.log.info("operation:%s host:%s status=%s return:True \
                                   " % (operation, vfc_client, status))
                    return False
            elif operation in ('unmap', 'remove'):
                if status in ('Linkdown', 'Offline'):
                    self.log.info("operation:%s host:%s status=%s return:True \
                                   " % (operation, vfc_client, status))
                    return True
                else:
                    self.log.info("opertion:%s host:%s status=%s return:False \
                                   " % (operation, vfc_client, status))
                    return False

        if not wait.wait_for(is_host_online, timeout=10):
            self.err_mesg.append("operation:%s client_host:%s verify failed \
                                  " % (operation, vfc_client))
        else:
            self.log.info("operation:%s client_host:%s verify success \
                           " % (operation, vfc_client))

    def vfchost_status_verify(self, operation, vfchost, vios_name):
        '''
        verify the vfc slot/rdc_name exists in HMC
        '''
        self.log.info("verifying % status after its %s" % (vfchost, operation))

        def status_check():
            vfchost_status = self.get_vfchost_status(vfchost, vios_name)
            if operation == "map":
                if vfchost_status == 'LOGGED_IN':
                    return True
                return False
            elif operation == "unmap":
                if vfchost_status == 'NOT_LOGGED_IN':
                    return True
                return False

        if not wait.wait_for(status_check, timeout=10):
            self.err_mesg.append("after %s %s staus change failed \
                                  " % (operation, vfchost))
        else:
            self.log.info("%s status change success \
                           after %s" % (operation, vfchost))

    def mpath_verification(self, operation, paths):
        '''
        verify the paths status on add or remove operations of vfc
        '''
        self.path = ''
        self.log.info("mpath verification for %s operation for \
                       paths: %s" % (operation, paths))

        def is_path_online():
            path_stat = []
            process.system("multipathd -k'show paths'", ignore_status=True)
            path_stat = multipath.get_path_status(self.path)
            self.log.info("operation:%s path=%s path_stat=%s \
                           " % (operation, self.path, path_stat))
            if operation in ('map', 'add'):
                if path_stat[0] != "active" or path_stat[2] != "ready":
                    self.log.info("operation:%s path=%s stat=%s return=False \
                                   " % (operation, self.path, path_stat))
                    return False
                else:
                    self.log.info("operation:%s path=%s stat=%s return=True \
                                   " % (operation, self.path, path_stat))
                    return True
            elif operation in ('unmap', 'remove'):
                if path_stat[0] != "failed" or path_stat[2] != "faulty":
                    self.log.info("operation:%s path=%s stat=%s return=False \
                                   " % (operation, self.path, path_stat))
                    return False
                else:
                    self.log.info("operation:%s path=%s stat=%s return=True \
                                   " % (operation, self.path, path_stat))
                    return True
            else:
                self.log.info("Operation unknown, provide correct opertion")

        for path in paths:
            self.path = path
            if not wait.wait_for(is_path_online, timeout=10):
                self.err_mesg.append("operation:%s path:%s verify failed \
                                      " % (operation, path))
            else:
                self.log.info("operation:%s path:%s verify success \
                               " % (operation, path))

    def test_remove_add(self):
        '''
        remove and add back the vfchost from vios
        '''
        self.err_mesg = []
        self.log.info("\nvfchost remove_add operations\n")
        for _ in range(self.count):
            for vfc_dic in self.dic_list:
                self.log.info("%s/%s remove operation on \
                               dic :%s" % (_, self.count, vfc_dic))
                self.vfchost_remove_add("remove", vfc_dic)
                time.sleep(self.opp_sleep_time)
                self.log.info("%s/%s add operation on \
                               dic : %s" % (_, vfc_dic, self.count))
                self.vfchost_remove_add("add", vfc_dic)
                # sleep time between operations, can be enhanced in future.
                time.sleep(self.opp_sleep_time)
        if self.err_mesg:
            self.fail("test failed due to folowing reasons:%s" % self.err_mesg)

    def vfchost_remove_add(self, operation, vfc_dic):
        '''
        removes and adds back the vfchost from vios as a root user.
        '''
        if operation == 'remove':
            cmd = 'viosvrcmd -m %s -p %s -c "rmdev -dev %s -ucfg"' \
                % (self.server, vfc_dic["vios"], vfc_dic["vfchost"])
        else:
            cmd = 'viosvrcmd -m %s -p %s -c "cfgdev -dev %s"' \
                % (self.server, vfc_dic["vios"], vfc_dic["vfchost"])
        output = self.session.cmd(cmd)
        if output.exit_status != 0:
            self.log.debug(output.stderr)
            self.fail("vfchost %s operation failed" % operation)
        else:
            self.log.info("%s of %s succes" % (operation, vfc_dic["vfchost"]))
        time.sleep(5)
        self.log.info("verifying %s status after %s operation.... \
                       " % (vfc_dic["vfchost"], operation))
        self.vfchost_config_status_verify(operation, vfc_dic["vfchost"],
                                          vfc_dic["vios"])
        self.log.info("verifying %s status after %s operation.... \
                       " % (vfc_dic["vfc_client"], operation))
        self.vfc_client_status_verify(operation, vfc_dic["vfc_client"])
        time.sleep(8)
        self.log.info("verifying mpath status after %s operation, paths=%s \
                        " % (operation, vfc_dic["paths"]))
        self.mpath_verification(operation, vfc_dic["paths"])

    def get_vfchost_config_status(self, vios, vfchost):
        '''
        Returns vfchost status as defined or available for vfchost add_remove
        '''
        cmd = 'viosvrcmd -m %s -p %s -c "lsdev -dev %s -field  name status \
               -fmt :"' % (self.server, vios, vfchost)
        output = self.session.cmd(cmd).stdout_text
        self.log.info("output value : %s" % output)
        for line in output.splitlines():
            if vfchost in line:
                return line.split(":")[-1]
        return ''

    def vfchost_config_status_verify(self, operation, vfchost, vios):
        '''
        check the vfchost config status and returns True or False
        '''
        def is_removed():
            status = self.get_vfchost_config_status(vios, vfchost)
            if operation == 'add':
                if status == 'Available':
                    return True
                return False
            elif operation == 'remove':
                if status == 'Defined':
                    return True
                return False

        if not wait.wait_for(is_removed, timeout=30):
            self.err_mesg.append("after %s %s staus change \
                                  failed" % (operation, vfchost))
        else:
            self.log.info("%s status change success \
                           after %s" % (operation, vfchost))

    def test_create_delete_vfchost(self):
        '''
        start of create delete vfchost here
        '''
        self.err_mesg = []
        vfc_id = {}
        vfc_start_id = int(self.vfc_id.split("-")[0])
        vfc_end_id = int(self.vfc_id.split("-")[-1])
        for vios in self.vioses.split(","):
            for _ in range(self.vfchost_count):
                if vfc_start_id < vfc_end_id:
                    if self.create_vfchost(vios, vfc_start_id,
                                           "server") is True:
                        vfc_id[vfc_start_id] = []
                        self.log.info("server vfchost created with \
                                       id=%s" % vfc_start_id)
                        vfc_id[vfc_start_id].append(vios)
                        if self.create_vfchost(vios, vfc_start_id,
                                               "client") is True:
                            self.log.info("client vfchost created success \
                                           with id=%s" % vfc_start_id)
                            vfc_id[vfc_start_id].append(self.lpar)
                    vfc_start_id = vfc_start_id + 1
                else:
                    self.err_mesg.append("start host id is not in range")

        for v_id in vfc_id:
            for lpar in vfc_id[v_id]:
                self.log.info("deleting vfchost ID=%s lpar=%s" % (v_id, lpar))
                if self.delete_vfchost(v_id, lpar) is True:
                    self.log.info("vfchost deleted sucesfully: %s" % v_id)
                else:
                    self.err_mesg.append("vfc_id=%s delete failed:" % v_id)
        if self.err_mesg:
            self.fail("failed for following IDs:%s" % self.err_mesg)
        else:
            self.log.info("test passed successfully")

    def create_vfchost(self, vios, vfchost_id, vfc_type):
        '''
        creates the number of vfchost with the give adapter ID range
        '''
        if vfc_type == "client":
            cmd = 'chhwres -m %s -r virtualio --rsubtype fc -o a \
                    -p %s -a "adapter_type=%s,remote_lpar_name=%s, \
                   remote_slot_num=%s" -s %s' % (
                self.server,
                self.lpar,
                vfc_type,
                vios,
                vfchost_id,
                vfchost_id,
            )
        else:
            cmd = 'chhwres -m %s -r virtualio --rsubtype fc -o a \
                   -p %s -s %s -a "adapter_type=%s,remote_lpar_name=%s, \
                   remote_slot_num=%s"' % (self.server, vios, vfchost_id,
                                           vfc_type, self.lpar, vfchost_id)
        self.log.info("create-command=%s" % cmd)
        output = self.session.cmd(cmd)
        if self.vfchost_exists("create", vfchost_id, vfc_type) is True:
            return True
        else:
            self.err_mesg.append("%s=%scommand success but not \
                                  deleted" % (vfc_type, vfchost_id))
            return False
        if output.exit_status != 0:
            self.log.debug(output.stderr)
            self.err_mesg.append("failed to create %s vfchost%s on \
                                  %s" % (vfc_type, vfchost_id, vios))

    def delete_vfchost(self, vfchost_id, lpar):
        '''
        delete the given vfchost using vfchost slot number and vfchost type
        '''
        cmd = 'chhwres -r virtualio -m %s -o r -p %s -s %s' % (
            self.server, lpar, vfchost_id)
        self.log.info("delete-command=%s" % cmd)
        output = self.session.cmd(cmd)
        if self.vfchost_exists("delete", vfchost_id, lpar) is True:
            self.log.info("%s vfchost with ID: %s deleted \
                           successfully" % (lpar, vfchost_id))
            return True
        else:
            self.err_mesg.append("%s=%scommand success but not \
                                  deleted" % (lpar, vfchost_id))
            return False
        if output.exit_status != 0:
            self.log.debug(output.stderr)
            self.err_mesg.append("failed to delete %s vfchost%s \
                                  on" % (lpar, vfchost_id))

    def vfchost_exists(self, operation, vfc_slot, lpar):
        '''
        checks whether vfchost is exists or not
        '''
        cmd = 'lshwres -r virtualio --rsubtype fc --level lpar -m %s -F \
               slot_num,adapter_type | grep -i %s' % (self.server, lpar)

        def is_vfc_exist():
            output = self.session.cmd(cmd).stdout_text
            if operation == "create":
                for line in output.splitlines():
                    if str(vfc_slot) == line.split(",")[0]:
                        return True
                return False
            else:
                for line in output.splitlines():
                    if str(vfc_slot) == line.split(",")[0]:
                        return False
                return True

        return wait.wait_for(is_vfc_exist, timeout=30) or False

    def tearDown(self):
        '''
        close ssh session gracefully
        '''
        self.session.quit()
class Netperf(Test):
    """
    Netperf Test
    """
    def setUp(self):
        """
        To check and install dependencies for the test
        """
        self.peer_user = self.params.get("peer_user_name", default="root")
        self.peer_ip = self.params.get("peer_ip", default="")
        self.peer_password = self.params.get("peer_password",
                                             '*',
                                             default="None")
        interfaces = netifaces.interfaces()
        self.iface = self.params.get("interface", default="")
        if self.iface not in interfaces:
            self.cancel("%s interface is not available" % self.iface)
        self.ipaddr = self.params.get("host_ip", default="")
        self.netmask = self.params.get("netmask", default="")
        local = LocalHost()
        self.networkinterface = NetworkInterface(self.iface, local)
        try:
            self.networkinterface.add_ipaddr(self.ipaddr, self.netmask)
            self.networkinterface.save(self.ipaddr, self.netmask)
        except Exception:
            self.networkinterface.save(self.ipaddr, self.netmask)
        self.networkinterface.bring_up()
        self.session = Session(self.peer_ip,
                               user=self.peer_user,
                               password=self.peer_password)
        smm = SoftwareManager()
        detected_distro = distro.detect()
        pkgs = ['gcc']
        if detected_distro.name == "Ubuntu":
            pkgs.append('openssh-client')
        elif detected_distro.name == "SuSE":
            pkgs.append('openssh')
        else:
            pkgs.append('openssh-clients')
        for pkg in pkgs:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("%s package is need to test" % pkg)
            cmd = "%s install %s" % (smm.backend.base_command, pkg)
            output = self.session.cmd(cmd)
            if not output.exit_status == 0:
                self.cancel(
                    "unable to install the package %s on peer machine " % pkg)
        if self.peer_ip == "":
            self.cancel("%s peer machine is not available" % self.peer_ip)
        self.timeout = self.params.get("TIMEOUT", default="600")
        self.mtu = self.params.get("mtu", default=1500)
        remotehost = RemoteHost(self.peer_ip,
                                username=self.peer_user,
                                password=self.peer_password)
        self.peer_interface = remotehost.get_interface_by_ipaddr(
            self.peer_ip).name
        self.peer_networkinterface = NetworkInterface(self.peer_interface,
                                                      remotehost)
        if self.peer_networkinterface.set_mtu(self.mtu) is not None:
            self.cancel("Failed to set mtu in peer")
        if self.networkinterface.set_mtu(self.mtu) is not None:
            self.cancel("Failed to set mtu in host")
        self.netperf_run = str(self.params.get("NETSERVER_RUN", default=0))
        self.netperf = os.path.join(self.teststmpdir, 'netperf')
        netperf_download = self.params.get("netperf_download",
                                           default="https:"
                                           "//github.com/HewlettPackard/"
                                           "netperf/archive/netperf-2.7.0.zip")
        tarball = self.fetch_asset(netperf_download, expire='7d')
        archive.extract(tarball, self.netperf)
        self.version = "%s-%s" % ("netperf",
                                  os.path.basename(tarball.split('.zip')[0]))
        self.neperf = os.path.join(self.netperf, self.version)
        cmd = "scp -r %s %s@%s:/tmp/" % (self.neperf, self.peer_user,
                                         self.peer_ip)
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            self.cancel("unable to copy the netperf into peer machine")
        cmd = "cd /tmp/%s;./configure ppc64le;make" % self.version
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("test failed because command failed in peer machine")
        os.chdir(self.neperf)
        process.system('./configure ppc64le', shell=True)
        build.make(self.neperf)
        self.perf = os.path.join(self.neperf, 'src', 'netperf')
        self.expected_tp = self.params.get("EXPECTED_THROUGHPUT", default="90")
        self.duration = self.params.get("duration", default="300")
        self.min = self.params.get("minimum_iterations", default="1")
        self.max = self.params.get("maximum_iterations", default="15")
        self.option = self.params.get("option", default='')

    def test(self):
        """
        netperf test
        """
        if self.netperf_run == '1':
            cmd = "chmod 777 /tmp/%s/src" % self.version
            output = self.session.cmd(cmd)
            if not output.exit_status == 0:
                self.fail("test failed because netserver not available")
            cmd = "/tmp/%s/src/netserver" % self.version
            output = self.session.cmd(cmd)
            if not output.exit_status == 0:
                self.fail("test failed because netserver not available")
        speed = int(read_file("/sys/class/net/%s/speed" % self.iface))
        cmd = "timeout %s %s -H %s" % (self.timeout, self.perf, self.peer_ip)
        if self.option != "":
            cmd = "%s -t %s" % (cmd, self.option)
        cmd = "%s -l %s -i %s,%s" % (cmd, self.duration, self.max, self.min)
        result = process.run(cmd, shell=True, ignore_status=True)
        if result.exit_status != 0:
            self.fail("FAIL: Run failed")
        for line in result.stdout.decode("utf-8").splitlines():
            if line and 'Throughput' in line.split()[-1]:
                tput = int(
                    result.stdout.decode("utf-8").split()[-1].split('.')[0])
                if tput < (int(self.expected_tp) * speed) / 100:
                    self.fail("FAIL: Throughput Actual - %s%%, Expected - %s%%"
                              ", Throughput Actual value - %s " %
                              ((tput * 100) / speed, self.expected_tp,
                               str(tput) + 'Mb/sec'))

        if 'WARNING' in result.stdout.decode("utf-8"):
            self.log.warn('Test completed with warning')

    def tearDown(self):
        """
        removing the data in peer machine
        """
        cmd = "pkill netserver; rm -rf /tmp/%s" % self.version
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("test failed because peer sys not connected")
        if self.networkinterface.set_mtu('1500') is not None:
            self.cancel("Failed to set mtu in host")
        if self.peer_networkinterface.set_mtu('1500') is not None:
            self.cancel("Failed to set mtu in peer")
        self.networkinterface.remove_ipaddr(self.ipaddr, self.netmask)
Beispiel #11
0
class VlanTest(Test):
    """
    :param switch_name: Switch name or IP
    :param userid: userid of the switch to login into
    :param password: password of the switch for user userid
    :param vlan_num: vlan number where the port port_id will be added
    :param host_port: host port id where the VLAN test will run
    :param peer_port: peer port id where the VLAN test will run
    :param interface: Host test N/W Interface
    :param peer_interface: Peer test N/W Interface
    :param peer_ip: IP address of peer
    :param peer_user: Userid of the peer
    :param peer_password: Password of the peer to ssh into
    :param netmask: netmask of the test N/W Interfaces
    """
    def setUp(self):
        """
        test parameters
        """
        self.parameters()
        self.switch_login(self.switch_name, self.userid, self.password)
        self.session = Session(self.peer_ip,
                               user=self.peer_user,
                               password=self.peer_password)
        if not self.session.connect():
            self.cancel("failed connecting to peer")
        self.get_ips()

    def parameters(self):
        self.switch_name = self.params.get("switch_name", '*', default=None)
        self.userid = self.params.get("userid", '*', default=None)
        self.password = self.params.get("password", '*', default=None)
        self.vlan_num = self.params.get("vlan_num", '*', default=None)
        self.host_port = self.params.get("host_port", '*', default=None)
        self.peer_port = self.params.get("peer_port", '*', default=None)
        self.host_intf = self.params.get("interface", '*', default=None)
        if self.host_intf[0:2] == 'ib':
            self.cancel("vlan is not supported for IB")
        self.peer_intf = self.params.get("peer_interface", '*', default=None)
        self.peer_ip = self.params.get("peer_public_ip", '*', default=None)
        self.peer_user = self.params.get("peer_user", '*', default=None)
        self.peer_password = self.params.get("peer_password",
                                             '*',
                                             default=None)
        self.cidr_value = self.params.get("cidr_value", '*', default=None)
        self.prompt = ">"

    def switch_login(self, ip, username, password):
        '''
        Login method for remote fc switch
        '''
        self.tnc = paramiko.SSHClient()
        self.tnc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.tnc.connect(ip,
                         username=username,
                         password=password,
                         look_for_keys=False,
                         allow_agent=False)
        self.log.info("SSH connection established to " + ip)
        self.remote_conn = self.tnc.invoke_shell()
        self.log.info("Interactive SSH session established")
        assert self.remote_conn
        self.remote_conn.send("iscli" + '\n')

    def _send_only_result(self, command, response):
        output = response.decode("utf-8").splitlines()
        if command in output[0]:
            output.pop(0)
        output.pop()
        output = [element.lstrip() + '\n' for element in output]
        response = ''.join(output)
        response = response.strip()
        self.log.info(''.join(response))
        return ''.join(response)

    def run_switch_command(self, command, timeout=300):
        '''
        Run command method for running commands on fc switch
        '''
        self.prompt = "#"
        self.log.info("Running the %s command on fc/nic switch", command)
        if not hasattr(self, 'tnc'):
            self.fail("telnet connection to the fc/nic switch not yet done")
        self.remote_conn.send(command + '\n')
        response = self.remote_conn.recv(1000)
        return self._send_only_result(command, response)

    def peer_logout(self):
        '''
        SSH Logout method for remote peer server
        '''
        self.session.quit()
        return

    def run_host_command(self, cmd):
        """
        Run command and fail the test if any command fails
        """
        try:
            process.run(cmd, shell=True, sudo=True)
        except CmdError as details:
            self.fail("Command %s failed %s" % (cmd, details))

    @staticmethod
    def run_cmd_output(cmd):
        """
        Execute the command and return output
        """
        return process.system_output(cmd,
                                     ignore_status=True,
                                     shell=True,
                                     sudo=True).decode("utf-8")

    @staticmethod
    def ping_check_host(intf, ip):
        '''
        ping check for peer in host
        '''
        cmd = "ping -I %s %s -c 5" % (intf, ip)
        if process.system(cmd, sudo=True, shell=True, ignore_status=True) != 0:
            return False
        return True

    def ping_check_peer(self, intf, ip):
        '''
        ping check for host in peer
        '''
        cmd = "ping -I %s %s -c 5" % (intf, ip)
        output = self.session.cmd(cmd)
        if output.exit_status == 0:
            return True
        return False

    def test_default_vlan1(self):
        """
        Scenario 1:  keep both host & peer in default VLAN id, VLAN 1.
                     Now ping each other. it should PASS
        """
        # PVID tagging should be disabled for this test
        self.vlan_port_conf("1", "1")
        if not self.ping_check_host(self.host_intf,
                                    self.ip_dic[self.peer_intf]):
            self.fail("Ping test failed for default vlan 1 in host")
        self.log.info("Ping test passed for default vlan 1 in host")
        if not self.ping_check_peer(self.peer_intf,
                                    self.ip_dic[self.host_intf]):
            self.fail("Ping test failed for default vlan 1 in peer")
        self.log.info("Ping test passed for default vlan 1 in peer")

    def test_vlan_1_2230(self):
        """
        Scenario 2: Keep host in vlan 1 and Peer in vlan 2230.
                    Now ping. it should FAIL
        """
        self.vlan_port_conf("1", "2230")
        # before ping need few sec for interface to set vlan
        time.sleep(5)
        if self.ping_check_host(self.host_intf, self.ip_dic[self.peer_intf]):
            self.fail("Ping test failed for vlan 1 & 2230 in host")
        self.log.info("Ping test passed for vlan 1 % 2230 in host")
        if self.ping_check_peer(self.peer_intf, self.ip_dic[self.host_intf]):
            self.fail("Ping test failed for vlan 1 & 2230 in peer")
        self.log.info("Ping test passed for vlan 1 % 2230 in peer")

    def test_vlan_id(self):
        """
        Scenario 3: Keep both in the vlan id (taken from yaml file), and
                    create vlan interfaces and then ping. It should PASS.
        """
        # PVID tagging should be enabled for this test
        self.test_type = "full"
        self.vlan_port_conf(self.vlan_num, self.vlan_num)
        self.conf_host_vlan_intf(self.vlan_num)
        self.conf_peer_vlan_intf(self.vlan_num)
        time.sleep(5)
        if not self.ping_check_host("%s.%s" % (self.host_intf, self.vlan_num),
                                    self.ip_dic[self.peer_intf]):
            self.fail("Ping test failed for vlan %s in host" % self.vlan_num)
        self.log.info("Ping test passed for vlan %s in host" % self.vlan_num)
        if not self.ping_check_peer("%s.%s" % (self.peer_intf, self.vlan_num),
                                    self.ip_dic[self.host_intf]):
            self.fail("Ping test failed for vlan %s in peer" % self.vlan_num)
        self.log.info("Ping test passed for vlan %s in peer" % self.vlan_num)

    def vlan_port_conf(self, host_vlan, peer_vlan):
        """
        Set both host & peer interface ports with corresponding
        vlan's (host_vlan, peer_vlan)
        """
        self.log.info("Enabling the privilege mode")
        self.run_switch_command("enable")
        self.log.info("Entering configuration mode")
        self.run_switch_command("conf t")
        self.set_vlan_port(host_vlan, self.host_port)
        self.set_vlan_port(peer_vlan, self.peer_port)

    def set_vlan_port(self, vlan_num, port_id):
        """
        Sets the interface port to a vlan num
        """
        cmd = "show mac-address-table interface port %s" % port_id
        self.run_switch_command(cmd)
        self.log.info("Going to port %s", port_id)
        self.run_switch_command("interface port %s" % port_id)
        self.log.info("Changing the VLAN to %s of port %s", vlan_num, port_id)
        self.run_switch_command("switchport mode trunk")
        self.run_switch_command("switchport trunk native vlan %s" % vlan_num)
        # Enable PVID tagging only for test test_vlan_id
        if hasattr(self, 'test_type') and self.test_type == "full":
            self.run_switch_command("vlan dot1q tag native")
        # Disable PVID tagging for other tests
        else:
            self.run_switch_command("no vlan dot1q tag native")
        self.log.info("Saving the configuration")
        self.run_switch_command("write memory")
        self.run_switch_command("exit")
        self.run_switch_command(cmd)

    def get_ips(self):
        """
        save current interface ips before test starts
        """
        self.ip_dic = {}
        cmd = "ip addr list %s |grep 'inet ' |cut -d' ' -f6| \
              cut -d/ -f1" % self.host_intf
        self.ip_dic[self.host_intf] = self.run_cmd_output(cmd)
        cmd = "ip addr list %s |grep \'inet \'" % self.peer_intf
        output = self.session.cmd(cmd)
        self.ip_dic[self.peer_intf] = output.stdout_text.splitlines()[0] \
                                                        .split()[1].split('/')[0]
        self.log.info("test interface & ips: %s", self.ip_dic)

    def conf_host_vlan_intf(self, vlan_num):
        """
        Vlan configuration on Host
        """
        ip = self.ip_dic[self.host_intf]
        self.run_host_command("ip addr flush dev %s" % self.host_intf)
        cmd = "ip link add link %s name %s.%s type vlan id %s" \
              % (self.host_intf, self.host_intf, vlan_num, vlan_num)
        self.run_host_command(cmd)
        cmd = "ip addr add %s/%s dev %s.%s" \
              % (ip, self.cidr_value, self.host_intf, vlan_num)
        self.run_host_command(cmd)
        self.run_host_command("ip link set %s.%s up" %
                              (self.host_intf, vlan_num))
        cmd = "ip addr show %s.%s" % (self.host_intf, vlan_num)
        self.run_host_command(cmd)

    def conf_peer_vlan_intf(self, vlan_num):
        """
        Vlan configuration on Peer
        """
        ip = self.ip_dic[self.peer_intf]
        cmd = "ip addr flush dev %s" % self.peer_intf
        self.session.cmd(cmd)
        cmd = "ip link add link %s name %s.%s type vlan id %s" \
              % (self.peer_intf, self.peer_intf, vlan_num, vlan_num)
        self.session.cmd(cmd)
        cmd = "ip addr add %s/%s dev %s.%s" \
              % (ip, self.cidr_value, self.peer_intf, vlan_num)
        self.session.cmd(cmd)
        cmd = "ip link set %s.%s up" % (self.peer_intf, vlan_num)
        self.session.cmd(cmd)
        cmd = "ip addr show %s.%s" % (self.peer_intf, vlan_num)
        self.session.cmd(cmd)

    def restore_host_intf(self):
        """
        Restore host interfaces
        """
        cmd = "ip link delete %s.%s" % (self.host_intf, self.vlan_num)
        self.run_host_command(cmd)
        self.run_host_command("ifdown %s" % self.host_intf)
        self.run_host_command("ifup %s" % self.host_intf)

    def restore_peer_intf(self):
        """
        Restore peer interfaces
        """
        cmd = "ip link delete %s.%s" % (self.peer_intf, self.vlan_num)
        self.session.cmd(cmd)
        cmd = "ifdown %s" % self.peer_intf
        self.session.cmd(cmd)
        cmd = "ifup %s" % self.peer_intf
        self.session.cmd(cmd)

    def tearDown(self):
        """
        Restore back the default VLAN ID 1
        and also restore interfaces back when full test is run
        """
        self.vlan_port_conf("1", "1")
        if hasattr(self, 'test_type') and self.test_type == "full":
            # Disable PVID tagging as other tests need it to be in disabled.
            self.run_switch_command("no vlan dot1q tag native")
            self.restore_host_intf()
            self.restore_peer_intf()
        self.peer_logout()
Beispiel #12
0
class VethdlparTest(Test):
    '''
    DLPAR veth script does veth device add,remove.
    Update the details in yaml file.
    '''
    def setUp(self):
        '''
        Gather necessary test inputs.
        '''
        self.interface = self.params.get('interface', default=None)
        self.ipaddr = self.params.get("host_ip", default="")
        self.netmask = self.params.get("netmask", default="")
        self.peer_ip = self.params.get('peer_ip', default=None)
        self.num_of_dlpar = int(self.params.get("num_of_dlpar", default='1'))
        self.vios_ip = self.params.get('vios_ip', '*', default=None)
        self.vios_user = self.params.get('vios_username', '*', default=None)
        self.vios_pwd = self.params.get('vios_pwd', '*', default=None)
        self.session = Session(self.vios_ip,
                               user=self.vios_user,
                               password=self.vios_pwd)
        self.session.connect()
        local = LocalHost()
        self.networkinterface = NetworkInterface(self.interface, local)
        try:
            self.networkinterface.add_ipaddr(self.ipaddr, self.netmask)
            self.networkinterface.save(self.ipaddr, self.netmask)
        except Exception:
            self.networkinterface.save(self.ipaddr, self.netmask)
        self.networkinterface.bring_up()
        cmd = "lscfg -l %s" % self.interface
        for line in process.system_output(cmd, shell=True).decode("utf-8") \
                                                          .splitlines():
            if self.interface in line:
                self.slot = line.split()[-1].split('-')[-2]
        cmd = "ioscli lsmap -all -net"
        output = self.session.cmd(cmd)
        for line in output.stdout_text.splitlines():
            if self.slot in line:
                self.iface = line.split()[0]
        cmd = "ioscli lsmap -vadapter %s -net" % self.iface
        output = self.session.cmd(cmd)
        for line in output.stdout_text.splitlines():
            if "SEA" in line:
                self.sea = line.split()[-1]
        if not self.sea:
            self.cancel("failed to get SEA")
        self.log.info(self.sea)
        if self.networkinterface.ping_check(self.peer_ip, count=5) is not None:
            self.cancel("peer connection is failed")

    def veth_dlpar_remove(self):
        '''
        veth dlpar remove operation
        '''
        cmd = "rmdev -l %s" % self.sea
        cmd_l = "echo \"%s\" | ioscli oem_setup_env" % cmd
        output = self.session.cmd(cmd_l)
        self.log.info(output.stdout_text)
        if output.exit_status != 0:
            self.fail("failed dlpar remove operation")

    def veth_dlpar_add(self):
        '''
        veth dlpar add operation
        '''
        cmd = "mkdev -l %s" % self.sea
        cmd_l = "echo \"%s\" | ioscli oem_setup_env" % cmd
        output = self.session.cmd(cmd_l)
        self.log.info(output.stdout_text)
        if output.exit_status != 0:
            self.fail("Failed dlpar add operation")

    def test_dlpar(self):
        '''
        veth dlapr remove and add operation
        '''
        for _ in range(self.num_of_dlpar):
            self.veth_dlpar_remove()
            time.sleep(30)
            self.veth_dlpar_add()
            if self.networkinterface.ping_check(self.peer_ip,
                                                count=5) is not None:
                self.fail("ping failed after add operation")

    def tearDown(self):
        self.networkinterface.remove_ipaddr(self.ipaddr, self.netmask)
        self.networkinterface.restore_from_backup()
        self.session.quit()
Beispiel #13
0
class Bonding(Test):
    '''
    Channel bonding enables two or more network interfaces to act as one,
    simultaneously increasing the bandwidth and providing redundancy.
    '''
    def setUp(self):
        '''
        To check and install dependencies for the test
        '''
        detected_distro = distro.detect()
        smm = SoftwareManager()
        depends = []
        # FIXME: "redhat" as the distro name for RHEL is deprecated
        # on Avocado versions >= 50.0.  This is a temporary compatibility
        # enabler for older runners, but should be removed soon
        if detected_distro.name == "Ubuntu":
            depends.extend(["openssh-client", "iputils-ping"])
        elif detected_distro.name in ["rhel", "fedora", "centos", "redhat"]:
            depends.extend(["openssh-clients", "iputils"])
        else:
            depends.extend(["openssh", "iputils"])
        for pkg in depends:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("%s package is need to test" % pkg)
        self.mode = self.params.get("bonding_mode", default="")
        if 'setup' in str(self.name) or 'run' in str(self.name):
            if not self.mode:
                self.cancel("test skipped because mode not specified")
        interfaces = netifaces.interfaces()
        self.user = self.params.get("user_name", default="root")
        self.password = self.params.get("peer_password", '*', default="None")
        self.host_interfaces = self.params.get("bond_interfaces",
                                               default="").split(",")
        if not self.host_interfaces:
            self.cancel("user should specify host interfaces")
        self.peer_interfaces = self.params.get("peer_interfaces",
                                               default="").split(",")
        for self.host_interface in self.host_interfaces:
            if self.host_interface not in interfaces:
                self.cancel("interface is not available")
        self.peer_first_ipinterface = self.params.get("peer_ip", default="")
        if not self.peer_interfaces or self.peer_first_ipinterface == "":
            self.cancel("peer machine should available")
        self.bond_name = self.params.get("bond_name", default="tempbond")
        self.net_path = "/sys/class/net/"
        self.bond_status = "/proc/net/bonding/%s" % self.bond_name
        self.bond_dir = os.path.join(self.net_path, self.bond_name)
        self.bonding_slave_file = "%s/bonding/slaves" % self.bond_dir
        self.bonding_masters_file = "%s/bonding_masters" % self.net_path
        self.peer_bond_needed = self.params.get("peer_bond_needed",
                                                default=False)
        self.peer_wait_time = self.params.get("peer_wait_time", default=5)
        self.sleep_time = int(self.params.get("sleep_time", default=5))
        self.ib = False
        if self.host_interface[0:2] == 'ib':
            self.ib = True
        self.log.info("Bond Test on IB Interface? = %s", self.ib)
        self.session = Session(self.peer_first_ipinterface,
                               user=self.user,
                               password=self.password)
        self.setup_ip()
        self.err = []

    def bond_ib_conf(self, bond_name, arg1, arg2):
        '''
        configure slaves for IB cards
        '''
        cmd = 'ip link set %s up;' % (bond_name)
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            self.fail("unable to bring Bond interface %s up" % bond_name)
        if arg2 == "ATTACH":
            cmd = 'ifenslave %s %s -f;' % (bond_name, arg1)
        else:
            cmd = 'ifenslave %s -d %s ;' % (bond_name, arg1)
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            self.fail("unable to %s IB interface " % arg2)

    def setup_ip(self):
        '''
        set up the IP config
        '''
        if 'setup' in str(self.name):
            interface = self.host_interfaces[0]
        else:
            interface = self.bond_name
        cmd = "ip addr show  | grep %s" % self.peer_first_ipinterface
        output = self.session.cmd(cmd)
        result = ""
        result = result.join(output.stdout.decode("utf-8"))
        self.peer_first_interface = result.split()[0]
        if self.peer_first_interface == "":
            self.fail("test failed because peer interface can not retrieved")
        self.peer_ips = [self.peer_first_ipinterface]
        self.local_ip = netifaces.ifaddresses(interface)[2][0]['addr']
        self.peer_interfaces.insert(0, self.peer_first_interface)
        self.net_mask = []
        stf = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        for val1, val2 in zip([interface], [self.local_ip]):
            mask = ""
            if val2:
                tmp = fcntl.ioctl(stf.fileno(), 0x891b,
                                  struct.pack('256s', val1.encode()))
                mask = socket.inet_ntoa(tmp[20:24]).strip('\n')
            self.net_mask.append(mask)
        cmd = "route -n | grep %s | grep -w UG | awk "\
              "'{ print $2 }'" % interface
        self.gateway = process.system_output('%s' % cmd, shell=True)

    def bond_remove(self, arg1):
        '''
        bond_remove
        '''
        if arg1 == "local":
            self.log.info("Removing Bonding configuration on local machine")
            self.log.info("------------------------------------------------")
            for ifs in self.host_interfaces:
                cmd = "ip link set %s down" % ifs
                if process.system(cmd, shell=True, ignore_status=True) != 0:
                    self.log.info("unable to bring down the interface")
                if self.ib:
                    self.bond_ib_conf(self.bond_name, ifs, "REMOVE")
                else:
                    genio.write_file(self.bonding_slave_file, "-%s" % ifs)
            genio.write_file(self.bonding_masters_file, "-%s" % self.bond_name)
            self.log.info("Removing bonding module")
            linux_modules.unload_module("bonding")
            time.sleep(self.sleep_time)
        else:
            self.log.info("Removing Bonding configuration on Peer machine")
            self.log.info("------------------------------------------------")
            cmd = ''
            cmd += 'ip link set %s down;' % self.bond_name
            for val in self.peer_interfaces:
                cmd += 'ip link set %s down;' % val
            for val in self.peer_interfaces:
                cmd += 'ip addr flush dev %s;' % val
            for val in self.peer_interfaces:
                if self.ib:
                    self.bond_ib_conf(self.bond_name, val, "REMOVE")
                else:
                    cmd += 'echo "-%s" > %s;' % (val, self.bonding_slave_file)
            cmd += 'echo "-%s" > %s;' % (self.bond_name,
                                         self.bonding_masters_file)
            cmd += 'rmmod bonding;'
            cmd += 'ip addr add %s/%s dev %s;ip link set %s up;sleep 5;'\
                   % (self.peer_first_ipinterface, self.net_mask[0],
                      self.peer_first_interface, self.peer_first_interface)
            output = self.session.cmd(cmd)
            if not output.exit_status == 0:
                self.log.info("bond removing command failed in peer machine")

    def ping_check(self):
        '''
        ping check
        '''
        cmd = "ping -I %s %s -c 5"\
              % (self.bond_name, self.peer_first_ipinterface)
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            return False
        return True

    def bond_fail(self, arg1):
        '''
        bond fail
        '''
        if len(self.host_interfaces) > 1:
            for interface in self.host_interfaces:
                self.log.info("Failing interface %s for mode %s", interface,
                              arg1)
                cmd = "ip link set %s down" % interface
                if process.system(cmd, shell=True, ignore_status=True) != 0:
                    self.fail("bonding not working when trying to down the\
                               interface %s " % interface)
                time.sleep(self.sleep_time)
                if self.ping_check():
                    self.log.info("Ping passed for Mode %s", arg1)
                else:
                    error_str = "Ping fail in Mode %s when interface %s down"\
                        % (arg1, interface)
                    self.log.debug(error_str)
                    self.err.append(error_str)
                self.log.info(genio.read_file(self.bond_status))
                cmd = "ip link set %s up" % interface
                time.sleep(self.sleep_time)
                if process.system(cmd, shell=True, ignore_status=True) != 0:
                    self.fail("Not able to bring up the slave\
                                    interface %s" % interface)
                time.sleep(self.sleep_time)
        else:
            self.log.debug("Need a min of 2 host interfaces to test\
                         slave failover in Bonding")

        self.log.info("\n----------------------------------------")
        self.log.info("Failing all interfaces for mode %s", arg1)
        self.log.info("----------------------------------------")
        for interface in self.host_interfaces:
            cmd = "ip link set %s down" % interface
            if process.system(cmd, shell=True, ignore_status=True) != 0:
                self.fail("Could not bring down the interface %s " % interface)
            time.sleep(self.sleep_time)
        if not self.ping_check():
            self.log.info("Ping to Bond interface failed. This is expected")
        self.log.info(genio.read_file(self.bond_status))
        for interface in self.host_interfaces:
            cmd = "ip link set %s up" % interface
            time.sleep(self.sleep_time)
            if process.system(cmd, shell=True, ignore_status=True) != 0:
                self.fail("Not able to bring up the slave\
                                interface %s" % interface)
            time.sleep(self.sleep_time)

    def bond_setup(self, arg1, arg2):
        '''
        bond setup
        '''
        if arg1 == "local":
            self.log.info("Configuring Bonding on Local machine")
            self.log.info("--------------------------------------")
            for ifs in self.host_interfaces:
                cmd = "ip addr flush dev %s" % ifs
                process.system(cmd, shell=True, ignore_status=True)
            for ifs in self.host_interfaces:
                cmd = "ip link set %s down" % ifs
                process.system(cmd, shell=True, ignore_status=True)
            linux_modules.load_module("bonding")
            genio.write_file(self.bonding_masters_file, "+%s" % self.bond_name)
            genio.write_file("%s/bonding/mode" % self.bond_dir, arg2)
            genio.write_file("%s/bonding/miimon" % self.bond_dir, "100")
            genio.write_file("%s/bonding/fail_over_mac" % self.bond_dir, "2")
            for val in self.host_interfaces:
                if self.ib:
                    self.bond_ib_conf(self.bond_name, val, "ATTACH")
                else:
                    genio.write_file(self.bonding_slave_file, "+%s" % val)
                time.sleep(2)
            bond_name_val = ''
            for line in genio.read_file(self.bond_status).splitlines():
                if 'Bonding Mode' in line:
                    bond_name_val = line.split(':')[1]
            self.log.info("Trying bond mode %s [ %s ]", arg2, bond_name_val)
            for ifs in self.host_interfaces:
                cmd = "ip link set %s up" % ifs
                if process.system(cmd, shell=True, ignore_status=True) != 0:
                    self.fail("unable to interface up")
            cmd = "ip addr add %s/%s dev %s;ip link set %s up"\
                  % (self.local_ip, self.net_mask[0],
                     self.bond_name, self.bond_name)
            process.system(cmd, shell=True, ignore_status=True)
            for _ in range(0, 600, 60):
                if 'state UP' in process.system_output(
                        "ip link \
                     show %s" % self.bond_name,
                        shell=True).decode("utf-8"):
                    self.log.info("Bonding setup is successful on\
                                  local machine")
                    break
                time.sleep(60)
            else:
                self.fail("Bonding setup on local machine has failed")
            if self.gateway:
                cmd = 'ip route add default via %s dev %s' % \
                    (self.gateway, self.bond_name)
                process.system(cmd, shell=True, ignore_status=True)

        else:
            self.log.info("Configuring Bonding on Peer machine")
            self.log.info("------------------------------------------")
            cmd = ''
            for val in self.peer_interfaces:
                cmd += 'ip addr flush dev %s;' % val
            for val in self.peer_interfaces:
                cmd += 'ip link set %s down;' % val
            cmd += 'modprobe bonding;'
            cmd += 'echo +%s > %s;'\
                   % (self.bond_name, self.bonding_masters_file)
            cmd += 'echo 0 > %s/bonding/mode;'\
                   % self.bond_dir
            cmd += 'echo 100 > %s/bonding/miimon;'\
                   % self.bond_dir
            cmd += 'echo 2 > %s/bonding/fail_over_mac;'\
                   % self.bond_dir
            for val in self.peer_interfaces:
                if self.ib:
                    self.bond_ib_conf(self.bond_name, val, "ATTACH")
                else:
                    cmd += 'echo "+%s" > %s;' % (val, self.bonding_slave_file)
            for val in self.peer_interfaces:
                cmd += 'ip link set %s up;' % val
            cmd += 'ip addr add %s/%s dev %s;ip link set %s up;sleep 5;'\
                   % (self.peer_first_ipinterface, self.net_mask[0],
                      self.bond_name, self.bond_name)
            output = self.session.cmd(cmd)
            if not output.exit_status == 0:
                self.fail("bond setup command failed in peer machine")

    def test_setup(self):
        '''
        bonding the interfaces
        work for multiple interfaces on both host and peer
        '''
        cmd = "[ -d %s ]" % self.bond_dir
        output = self.session.cmd(cmd)
        if output.exit_status == 0:
            self.fail("bond name already exists on peer machine")
        if os.path.isdir(self.bond_dir):
            self.fail("bond name already exists on local machine")
        if self.peer_bond_needed:
            self.bond_setup("peer", "")
        self.bond_setup("local", self.mode)
        self.log.info(genio.read_file(self.bond_status))
        self.ping_check()
        self.error_check()

    def test_run(self):
        self.bond_fail(self.mode)
        self.log.info("Mode %s OK", self.mode)
        self.error_check()

    def test_cleanup(self):
        '''
        clean up the interface config
        '''
        self.bond_remove("local")
        for val in self.host_interfaces:
            cmd = "ip link set %s up" % val
            process.system(cmd, shell=True, ignore_status=True)
            cmd = "ifup %s" % val
            process.system(cmd, shell=True, ignore_status=True)
            for _ in range(0, 600, 60):
                if 'state UP' in process.system_output(
                        "ip link \
                     show %s" % val, shell=True).decode("utf-8"):
                    self.log.info("Interface %s is up", val)
                    break
                time.sleep(60)
            else:
                self.log.warn(
                    "Interface %s in not up\
                                   in the host machine", val)
        if self.gateway:
            cmd = 'ip route add default via %s' % \
                (self.gateway)
            process.system(cmd, shell=True, ignore_status=True)

        if self.peer_bond_needed:
            self.bond_remove("peer")
            for val in self.peer_interfaces:
                cmd = "ip link set %s up; ifup %s; sleep %s"\
                      % (val, val, self.peer_wait_time)
                output = self.session.cmd(cmd)
                if not output.exit_status == 0:
                    self.log.warn("unable to bring to original state in peer")
                time.sleep(self.sleep_time)
        self.error_check()

    def error_check(self):
        if self.err:
            self.fail("Tests failed. Details:\n%s" % "\n".join(self.err))
Beispiel #14
0
class RDMA(Test):
    '''
    RDMA test for infiniband adaptors
    '''
    def setUp(self):
        '''
        check the availability of perftest package installed
        perftest package should be installed
        '''
        smm = SoftwareManager()
        detected_distro = distro.detect()
        pkgs = ["perftest"]
        if detected_distro.name == "Ubuntu":
            pkgs.append('openssh-client')
        elif detected_distro.name == "SuSE":
            pkgs.append('openssh')
        else:
            pkgs.append('openssh-clients')
        for pkg in pkgs:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("%s package is need to test" % pkg)
        interfaces = netifaces.interfaces()
        self.iface = self.params.get("interface", default="")
        self.peer_ip = self.params.get("peer_ip", default="")
        self.peer_user = self.params.get("peer_user_name", default="root")
        self.peer_password = self.params.get("peer_password",
                                             '*',
                                             default="None")
        self.ipaddr = self.params.get("host_ip", default="")
        self.netmask = self.params.get("netmask", default="")
        if self.iface[0:2] == 'ib':
            configure_network.set_ip(self.ipaddr,
                                     self.netmask,
                                     self.iface,
                                     interface_type='Infiniband')
        else:
            configure_network.set_ip(self.ipaddr,
                                     self.netmask,
                                     self.iface,
                                     interface_type='Ethernet')
        self.session = Session(self.peer_ip,
                               user=self.peer_user,
                               password=self.peer_password)
        if self.iface not in interfaces:
            self.cancel("%s interface is not available" % self.iface)
        if self.peer_ip == "":
            self.cancel("%s peer machine is not available" % self.peer_ip)
        self.ca_name = self.params.get("CA_NAME", default="mlx4_0")
        self.port = self.params.get("PORT_NUM", default="1")
        self.peer_ca = self.params.get("PEERCA", default="mlx4_0")
        self.peer_port = self.params.get("PEERPORT", default="1")
        self.tmo = self.params.get("TIMEOUT", default="600")
        self.tool_name = self.params.get("tool")
        if self.tool_name == "":
            self.cancel("should specify tool name")
        self.log.info("test with %s", self.tool_name)
        self.test_op = self.params.get("test_opt", default="")
        self.mtu = self.params.get("mtu", default=1500)
        self.peerinfo = PeerInfo(self.peer_ip,
                                 peer_user=self.peer_user,
                                 peer_password=self.peer_password)
        self.peer_interface = self.peerinfo.get_peer_interface(self.peer_ip)

        if detected_distro.name == "Ubuntu":
            cmd = "service ufw stop"
        # FIXME: "redhat" as the distro name for RHEL is deprecated
        # on Avocado versions >= 50.0.  This is a temporary compatibility
        # enabler for older runners, but should be removed soon
        elif detected_distro.name in ['rhel', 'fedora', 'redhat']:
            cmd = "systemctl stop firewalld"
        elif detected_distro.name == "SuSE":
            if detected_distro.version == 15:
                cmd = "systemctl stop firewalld"
            else:
                cmd = "rcSuSEfirewall2 stop"
        elif detected_distro.name == "centos":
            cmd = "service iptables stop"
        else:
            self.cancel("Distro not supported")
        if process.system(cmd, ignore_status=True, shell=True) != 0:
            self.cancel("Unable to disable firewall")
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.cancel("Unable to disable firewall on peer")

    def rdma_exec(self, arg1, arg2, arg3):
        '''
        bandwidth performance exec function
        '''
        flag = 0
        logs = "> /tmp/ib_log 2>&1 &"
        cmd = "timeout %s %s -d %s -i %s %s %s %s" \
            % (self.tmo, arg1, self.peer_ca, self.peer_port, arg2, arg3, logs)
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("ssh failed to remote machine\
                      or  faing data from remote machine failed")
        time.sleep(2)
        self.log.info("client data for %s(%s)", arg1, arg2)
        cmd = "timeout %s %s -d %s -i %s %s %s %s" \
            % (self.tmo, arg1, self.ca_name, self.port, self.peer_ip,
               arg2, arg3)
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            flag = 1
        self.log.info("server data for %s(%s)", arg1, arg2)
        cmd = "timeout %s cat /tmp/ib_log && rm -rf /tmp/ib_log" % (self.tmo)
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("ssh failed to remote machine\
                      or fetching data from remote machine failed")
        return flag

    def test(self):
        '''
        test options are mandatory
        '''
        if not self.peerinfo.set_mtu_peer(self.peer_interface, self.mtu):
            self.fail("Failed to set mtu in peer")
        if not configure_network.set_mtu_host(self.iface, self.mtu):
            self.fail("Failed to set mtu in host")
        if self.rdma_exec(self.tool_name, self.test_op, "") != 0:
            self.fail("Client cmd: %s %s" % (self.tool_name, self.test_op))

    def tearDown(self):
        """
        unset ip
        """
        if not configure_network.set_mtu_host(self.iface, '1500'):
            self.fail("Failed to set mtu in host")
        if not self.peerinfo.set_mtu_peer(self.peer_interface, '1500'):
            self.fail("Failed to set mtu in peer")
        configure_network.unset_ip(self.iface)
class Iperf(Test):
    """
    Iperf Test
    """
    def setUp(self):
        """
        To check and install dependencies for the test
        """
        self.peer_user = self.params.get("peer_user_name", default="root")
        self.peer_ip = self.params.get("peer_ip", default="")
        self.peer_password = self.params.get("peer_password",
                                             '*',
                                             default=None)
        interfaces = netifaces.interfaces()
        self.iface = self.params.get("interface", default="")
        if self.iface not in interfaces:
            self.cancel("%s interface is not available" % self.iface)
        self.ipaddr = self.params.get("host_ip", default="")
        self.netmask = self.params.get("netmask", default="")
        localhost = LocalHost()
        self.networkinterface = NetworkInterface(self.iface, localhost)
        try:
            self.networkinterface.add_ipaddr(self.ipaddr, self.netmask)
            self.networkinterface.save(self.ipaddr, self.netmask)
        except Exception:
            self.networkinterface.save(self.ipaddr, self.netmask)
        self.networkinterface.bring_up()
        self.session = Session(self.peer_ip,
                               user=self.peer_user,
                               password=self.peer_password)
        smm = SoftwareManager()
        for pkg in ["gcc", "autoconf", "perl", "m4", "libtool"]:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("%s package is need to test" % pkg)
            cmd = "%s install %s" % (smm.backend.base_command, pkg)
            output = self.session.cmd(cmd)
            if not output.exit_status == 0:
                self.cancel(
                    "unable to install the package %s on peer machine " % pkg)
        if self.peer_ip == "":
            self.cancel("%s peer machine is not available" % self.peer_ip)
        self.mtu = self.params.get("mtu", default=1500)
        remotehost = RemoteHost(self.peer_ip,
                                self.peer_user,
                                password=self.peer_password)
        self.peer_interface = remotehost.get_interface_by_ipaddr(
            self.peer_ip).name
        self.peer_networkinterface = NetworkInterface(self.peer_interface,
                                                      remotehost)
        if self.peer_networkinterface.set_mtu(self.mtu) is not None:
            self.cancel("Failed to set mtu in peer")
        if self.networkinterface.set_mtu(self.mtu) is not None:
            self.cancel("Failed to set mtu in host")
        self.iperf = os.path.join(self.teststmpdir, 'iperf')
        iperf_download = self.params.get("iperf_download",
                                         default="https:"
                                         "//excellmedia.dl.sourceforge.net/"
                                         "project/iperf2/iperf-2.0.13.tar.gz")
        tarball = self.fetch_asset(iperf_download, expire='7d')
        archive.extract(tarball, self.iperf)
        self.version = os.path.basename(tarball.split('.tar')[0])
        self.iperf_dir = os.path.join(self.iperf, self.version)
        cmd = "scp -r %s %s@%s:/tmp" % (self.iperf_dir, self.peer_user,
                                        self.peer_ip)
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            self.cancel("unable to copy the iperf into peer machine")
        cmd = "cd /tmp/%s;./configure ppc64le;make" % self.version
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.cancel("Unable to compile Iperf into peer machine")
        self.iperf_run = str(self.params.get("IPERF_SERVER_RUN", default=0))
        if self.iperf_run == '1':
            cmd = "/tmp/%s/src/iperf -s" % self.version
            cmd = self.session.get_raw_ssh_command(cmd)
            self.obj = SubProcess(cmd)
            self.obj.start()
        os.chdir(self.iperf_dir)
        process.system('./configure', shell=True)
        build.make(self.iperf_dir)
        self.iperf = os.path.join(self.iperf_dir, 'src')
        self.expected_tp = self.params.get("EXPECTED_THROUGHPUT", default="85")

    def test(self):
        """
        Test run is a One way throughput test. In this test, we have one host
        transmitting (or receiving) data from a client. This transmit large
        messages using multiple threads or processes.
        """
        speed = int(read_file("/sys/class/net/%s/speed" % self.iface))
        os.chdir(self.iperf)
        cmd = "./iperf -c %s" % self.peer_ip
        result = process.run(cmd, shell=True, ignore_status=True)
        if result.exit_status:
            self.fail("FAIL: Iperf Run failed")
        for line in result.stdout.decode("utf-8").splitlines():
            if 'sender' in line:
                tput = int(line.split()[6].split('.')[0])
                if tput < (int(self.expected_tp) * speed) / 100:
                    self.fail("FAIL: Throughput Actual - %s%%, Expected - %s%%"
                              ", Throughput Actual value - %s " %
                              ((tput * 100) / speed, self.expected_tp,
                               str(tput) + 'Mb/sec'))

    def tearDown(self):
        """
        Killing Iperf process in peer machine
        """
        cmd = "pkill iperf; rm -rf /tmp/%s" % self.version
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("Either the ssh to peer machine machine\
                       failed or iperf process was not killed")
        self.obj.stop()
        if self.networkinterface.set_mtu('1500') is not None:
            self.cancel("Failed to set mtu in host")
        if self.peer_networkinterface.set_mtu('1500') is not None:
            self.cancel("Failed to set mtu in peer")
        self.networkinterface.remove_ipaddr(self.ipaddr, self.netmask)
Beispiel #16
0
class Uperf(Test):
    """
    Uperf Test
    """

    def setUp(self):
        """
        To check and install dependencies for the test
        """
        self.peer_ip = self.params.get("peer_ip", default="")
        self.peer_public_ip = self.params.get("peer_public_ip", default="")
        self.peer_user = self.params.get("peer_user_name", default="root")
        self.peer_password = self.params.get("peer_password", '*',
                                             default="None")
        interfaces = netifaces.interfaces()
        self.iface = self.params.get("interface", default="")
        if self.iface not in interfaces:
            self.cancel("%s interface is not available" % self.iface)
        self.ipaddr = self.params.get("host_ip", default="")
        self.netmask = self.params.get("netmask", default="")
        local = LocalHost()
        self.networkinterface = NetworkInterface(self.iface, local)
        try:
            self.networkinterface.add_ipaddr(self.ipaddr, self.netmask)
            self.networkinterface.save(self.ipaddr, self.netmask)
        except Exception:
            self.networkinterface.save(self.ipaddr, self.netmask)
        self.networkinterface.bring_up()
        self.session = Session(self.peer_ip, user=self.peer_user,
                               password=self.peer_password)
        if not self.session.connect():
            self.cancel("failed connecting to peer")
        smm = SoftwareManager()
        detected_distro = distro.detect()
        pkgs = ["gcc", "autoconf", "perl", "m4", "git-core", "automake"]
        if detected_distro.name == "Ubuntu":
            pkgs.extend(["libsctp1", "libsctp-dev", "lksctp-tools"])
        else:
            pkgs.extend(["lksctp-tools", "lksctp-tools-devel"])
        for pkg in pkgs:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("%s package is need to test" % pkg)
            cmd = "%s install %s" % (smm.backend.base_command, pkg)
            output = self.session.cmd(cmd)
            if not output.exit_status == 0:
                self.cancel("unable to install the package %s on peer machine "
                            % pkg)
        if self.peer_ip == "":
            self.cancel("%s peer machine is not available" % self.peer_ip)
        self.mtu = self.params.get("mtu", default=1500)
        self.remotehost = RemoteHost(self.peer_ip, self.peer_user,
                                     password=self.peer_password)
        self.peer_interface = self.remotehost.get_interface_by_ipaddr(self.peer_ip).name
        self.peer_networkinterface = NetworkInterface(self.peer_interface,
                                                      self.remotehost)
        self.remotehost_public = RemoteHost(self.peer_public_ip, self.peer_user,
                                            password=self.peer_password)
        self.peer_public_networkinterface = NetworkInterface(self.peer_interface,
                                                             self.remotehost_public)
        if self.peer_networkinterface.set_mtu(self.mtu) is not None:
            self.cancel("Failed to set mtu in peer")
        if self.networkinterface.set_mtu(self.mtu) is not None:
            self.cancel("Failed to set mtu in host")
        uperf_download = self.params.get("uperf_download", default="https:"
                                         "//github.com/uperf/uperf/"
                                         "archive/master.zip")
        tarball = self.fetch_asset("uperf.zip", locations=[uperf_download],
                                   expire='7d')
        archive.extract(tarball, self.teststmpdir)
        self.uperf_dir = os.path.join(self.teststmpdir, "uperf-master")
        destination = "%s:/tmp" % self.peer_ip
        output = self.session.copy_files(self.uperf_dir, destination,
                                         recursive=True)
        if not output:
            self.cancel("unable to copy the uperf into peer machine")
        cmd = "cd /tmp/uperf-master;autoreconf -fi;./configure ppc64le;make"
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.cancel("Unable to compile Uperf into peer machine")
        self.uperf_run = str(self.params.get("UPERF_SERVER_RUN", default=0))
        if self.uperf_run == '1':
            cmd = "/tmp/uperf-master/src/uperf -s &"
            cmd = self.session.get_raw_ssh_command(cmd)
            self.obj = SubProcess(cmd)
            self.obj.start()
        os.chdir(self.uperf_dir)
        process.system('autoreconf -fi', shell=True)
        process.system('./configure ppc64le', shell=True)
        build.make(self.uperf_dir)
        self.expected_tp = self.params.get("EXPECTED_THROUGHPUT", default="85")

    def test(self):
        """
        Test run is a One way throughput test. In this test, we have one host
        transmitting (or receiving) data from a client. This transmit large
        messages using multiple threads or processes.
        """
        speed = int(read_file("/sys/class/net/%s/speed" % self.iface))
        cmd = "h=%s proto=tcp ./src/uperf -m manual/throughput.xml -a" \
            % self.peer_ip
        result = process.run(cmd, shell=True, ignore_status=True)
        if result.exit_status:
            self.fail("FAIL: Uperf Run failed")
        for line in result.stdout.decode("utf-8").splitlines():
            if self.peer_ip in line:
                if 'Mb/s' in line:
                    tput = int(line.split()[3].split('.')[0])
                else:
                    # Converting the throughput calculated in Gb to Mb
                    tput = int(line.split()[3].split('.')[0]) * 1000
                if tput < (int(self.expected_tp) * speed) / 100:
                    self.fail("FAIL: Throughput Actual - %s%%, Expected - %s%%"
                              ", Throughput Actual value - %s "
                              % ((tput*100)/speed, self.expected_tp,
                                 str(tput)+'Mb/sec'))
        if 'WARNING' in result.stdout.decode("utf-8"):
            self.log.warn('Test completed with warning')

    def tearDown(self):
        """
        Killing Uperf process in peer machine
        """
        self.obj.stop()
        cmd = "pkill uperf; rm -rf /tmp/uperf-master"
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("Either the ssh to peer machine machine\
                       failed or uperf process was not killed")
        if self.networkinterface.set_mtu('1500') is not None:
            self.cancel("Failed to set mtu in host")
        try:
            self.peer_networkinterface.set_mtu('1500')
        except Exception:
            self.peer_public_networkinterface.set_mtu('1500')
        self.networkinterface.remove_ipaddr(self.ipaddr, self.netmask)
        try:
            self.networkinterface.restore_from_backup()
        except Exception:
            self.log.info("backup file not availbale, could not restore file.")
        self.remotehost.remote_session.quit()
        self.remotehost_public.remote_session.quit()
        self.session.quit()
Beispiel #17
0
class Iperf(Test):
    """
    Iperf Test
    """
    def setUp(self):
        """
        To check and install dependencies for the test
        """
        self.peer_user = self.params.get("peer_user", default="root")
        self.peer_ip = self.params.get("peer_ip", default="")
        self.peer_public_ip = self.params.get("peer_public_ip", default="")
        self.peer_password = self.params.get("peer_password",
                                             '*',
                                             default=None)
        interfaces = netifaces.interfaces()
        self.iface = self.params.get("interface", default="")
        if self.iface not in interfaces:
            self.cancel("%s interface is not available" % self.iface)
        self.ipaddr = self.params.get("host_ip", default="")
        self.netmask = self.params.get("netmask", default="")
        self.hbond = self.params.get("hbond", default=False)
        localhost = LocalHost()
        if self.hbond:
            self.networkinterface = NetworkInterface(self.iface,
                                                     localhost,
                                                     if_type='Bond')
        else:
            self.networkinterface = NetworkInterface(self.iface, localhost)
        try:
            self.networkinterface.add_ipaddr(self.ipaddr, self.netmask)
            self.networkinterface.save(self.ipaddr, self.netmask)
        except Exception:
            self.networkinterface.save(self.ipaddr, self.netmask)
        self.networkinterface.bring_up()
        self.session = Session(self.peer_ip,
                               user=self.peer_user,
                               password=self.peer_password)
        if not self.session.connect():
            self.cancel("failed connecting to peer")
        smm = SoftwareManager()
        for pkg in ["gcc", "autoconf", "perl", "m4", "libtool", "gcc-c++"]:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("%s package is need to test" % pkg)
            cmd = "%s install %s" % (smm.backend.base_command, pkg)
            output = self.session.cmd(cmd)
            if not output.exit_status == 0:
                self.cancel(
                    "unable to install the package %s on peer machine " % pkg)

        detected_distro = distro.detect()
        pkg = "nmap"
        if detected_distro.name == 'rhel':
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("%s package Can not install" % pkg)
        if detected_distro.name == "SuSE":
            self.nmap = os.path.join(self.teststmpdir, 'nmap')
            nmap_download = self.params.get("nmap_download",
                                            default="https:"
                                            "//nmap.org/dist/"
                                            "nmap-7.80.tar.bz2")
            tarball = self.fetch_asset(nmap_download)
            self.version = os.path.basename(tarball.split('.tar')[0])
            self.n_map = os.path.join(self.nmap, self.version)
            archive.extract(tarball, self.nmap)
            os.chdir(self.n_map)
            process.system('./configure ppc64le', shell=True)
            build.make(self.n_map)
            process.system('./nping/nping -h', shell=True)

        if self.peer_ip == "":
            self.cancel("%s peer machine is not available" % self.peer_ip)
        self.mtu = self.params.get("mtu", default=1500)
        self.remotehost = RemoteHost(self.peer_ip,
                                     self.peer_user,
                                     password=self.peer_password)
        self.peer_interface = self.remotehost.get_interface_by_ipaddr(
            self.peer_ip).name
        self.peer_networkinterface = NetworkInterface(self.peer_interface,
                                                      self.remotehost)
        self.remotehost_public = RemoteHost(self.peer_public_ip,
                                            self.peer_user,
                                            password=self.peer_password)
        self.peer_public_networkinterface = NetworkInterface(
            self.peer_interface, self.remotehost_public)
        if self.peer_networkinterface.set_mtu(self.mtu) is not None:
            self.cancel("Failed to set mtu in peer")
        if self.networkinterface.set_mtu(self.mtu) is not None:
            self.cancel("Failed to set mtu in host")
        self.iperf = os.path.join(self.teststmpdir, 'iperf')
        iperf_download = self.params.get("iperf_download",
                                         default="https:"
                                         "//sourceforge.net/projects/iperf2/"
                                         "files/iperf-2.0.13.tar.gz")
        tarball = self.fetch_asset(iperf_download, expire='7d')
        archive.extract(tarball, self.iperf)
        self.version = os.path.basename(tarball.split('.tar')[0])
        self.iperf_dir = os.path.join(self.iperf, self.version)
        destination = "%s:/tmp" % self.peer_ip
        output = self.session.copy_files(self.iperf_dir,
                                         destination,
                                         recursive=True)
        if not output:
            self.cancel("unable to copy the iperf into peer machine")
        cmd = "cd /tmp/%s;./configure ppc64le;make" % self.version
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.cancel("Unable to compile Iperf into peer machine")
        self.iperf_run = str(self.params.get("IPERF_SERVER_RUN", default=0))
        if self.iperf_run == '1':
            cmd = "/tmp/%s/src/iperf -s" % self.version
            cmd = self.session.get_raw_ssh_command(cmd)
            self.obj = SubProcess(cmd)
            self.obj.start()
        os.chdir(self.iperf_dir)
        process.system('./configure', shell=True)
        build.make(self.iperf_dir)
        self.iperf = os.path.join(self.iperf_dir, 'src')
        self.expected_tp = self.params.get("EXPECTED_THROUGHPUT", default="85")

    def nping(self):
        """
        Run nping test with tcp packets
        """
        detected_distro = distro.detect()
        if detected_distro.name == "SuSE":
            os.chdir(self.n_map)
            cmd = "./nping/nping --tcp %s -c 10" % self.peer_ip
            return process.run(cmd, verbose=False, shell=True)
        else:
            cmd = "nping --tcp %s -c 10" % self.peer_ip
            return process.run(cmd, verbose=False, shell=True)

    def test(self):
        """
        Test run is a One way throughput test. In this test, we have one host
        transmitting (or receiving) data from a client. This transmit large
        messages using multiple threads or processes.
        """
        speed = int(read_file("/sys/class/net/%s/speed" % self.iface))
        os.chdir(self.iperf)
        cmd = "./iperf -c %s" % self.peer_ip
        result = process.run(cmd, shell=True, ignore_status=True)
        nping_result = self.nping()
        if result.exit_status:
            self.fail("FAIL: Iperf Run failed")
        for line in result.stdout.decode("utf-8").splitlines():
            if 'local {}'.format(self.ipaddr) in line:
                id = line[3]
        for line in result.stdout.decode("utf-8").splitlines():
            if id in line and 'Mbits/sec' in line:
                tput = int(line.split()[6])
            elif id in line and 'Gbits/sec' in line:
                tput = int(float(line.split()[6])) * 1000
        if tput < (int(self.expected_tp) * speed) / 100:
            self.fail(
                "FAIL: Throughput Actual - %s%%, Expected - %s%%"
                ", Throughput Actual value - %s " %
                ((tput * 100) / speed, self.expected_tp, str(tput) + 'Mb/sec'))
        for line in nping_result.stdout.decode("utf-8").splitlines():
            if 'Raw packets' in line:
                lost = int(line.split("|")[2].split(" ")[2]) * 10
                if lost > 60:
                    self.fail("FAIL: Ping fails after iperf test")

    def tearDown(self):
        """
        Killing Iperf process in peer machine
        """
        cmd = "pkill iperf; rm -rf /tmp/%s" % self.version
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("Either the ssh to peer machine machine\
                       failed or iperf process was not killed")
        self.obj.stop()
        if self.networkinterface.set_mtu('1500') is not None:
            self.cancel("Failed to set mtu in host")
        try:
            self.peer_networkinterface.set_mtu('1500')
        except Exception:
            self.peer_public_networkinterface.set_mtu('1500')
        self.networkinterface.remove_ipaddr(self.ipaddr, self.netmask)
        try:
            self.networkinterface.restore_from_backup()
        except Exception:
            self.networkinterface.remove_cfg_file()
            self.log.info("backup file not availbale, could not restore file.")
        if self.hbond:
            self.networkinterface.restore_slave_cfg_file()
        self.remotehost.remote_session.quit()
        self.remotehost_public.remote_session.quit()
        self.session.quit()
Beispiel #18
0
class VirtualFC(Test):
    '''
    Removing and Adding and Fibre Chanel Virtualized devices from the HMC
    '''
    @skipUnless("ppc" in distro.detect().arch,
                "supported only on Power platform")
    @skipIf(IS_POWER_NV or IS_KVM_GUEST,
            "This test is not supported on KVM guest or PowerNV platform")
    def setUp(self):
        '''
        set up required packages and gather necessary test inputs
        '''
        self.install_packages()
        self.rsct_service_start()
        self.hmc_ip = self.get_mcp_component("HMCIPAddr")
        if not self.hmc_ip:
            self.cancel("HMC IP not got")
        self.hmc_pwd = self.params.get("hmc_pwd", '*', default=None)
        self.hmc_username = self.params.get("hmc_username", '*', default=None)
        self.count = self.params.get("count", default=1)
        self.skip_drc = self.params.get("skip_drc_name", default=None)
        self.opp_sleep_time = 150
        self.lpar = self.get_partition_name("Partition Name")
        if not self.lpar:
            self.cancel("LPAR Name not got from lparstat command")
        self.session = Session(self.hmc_ip, user=self.hmc_username,
                               password=self.hmc_pwd)
        if not self.session.connect():
            self.cancel("failed connecting to HMC")
        cmd = 'lssyscfg -r sys  -F name'
        output = self.session.cmd(cmd)
        self.server = ''
        for line in output.stdout_text.splitlines():
            if line in self.lpar:
                self.server = line
        if not self.server:
            self.cancel("Managed System not got")
        self.dic_list = []
        cmd = 'lshwres -r virtualio --rsubtype fc --level lpar -m %s \
               --filter "lpar_names=%s"' % (self.server, self.lpar)
        for line in self.session.cmd(cmd).stdout_text.splitlines():
            self.vfc_dic = {}
            for i in line.split(","):
                if i.split("=")[0] == "slot_num":
                    self.vfc_dic["c_slot"] = i.split("=")[-1]
                elif i.split("=")[0] == "remote_slot_num":
                    self.vfc_dic["r_slot"] = i.split("=")[-1]
                elif i.split("=")[0] == "remote_lpar_name":
                    self.vfc_dic["r_lpar"] = i.split("=")[-1]
            self.vfc_dic["wwpn"] = self.get_wwpn(self.vfc_dic["c_slot"])
            self.vfc_dic["drc"] = self.get_drc_name(self.vfc_dic["c_slot"])
            self.vfc_dic["paths"] = self.get_paths(self.vfc_dic["drc"])
            if self.vfc_dic["drc"] != self.skip_drc:
                self.dic_list.append(self.vfc_dic)
        self.log.info("complete list : %s" % self.dic_list)

    @staticmethod
    def get_mcp_component(component):
        '''
        probes IBM.MCP class for mentioned component and returns it.
        '''
        for line in process.system_output('lsrsrc IBM.MCP %s' % component,
                                          ignore_status=True, shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split()[-1].strip('{}\"')
        return ''

    @staticmethod
    def get_partition_name(component):
        '''
        get partition name from lparstat -i
        '''

        for line in process.system_output('lparstat -i', ignore_status=True,
                                          shell=True,
                                          sudo=True).decode("utf-8") \
                                                    .splitlines():
            if component in line:
                return line.split(':')[-1].strip()
        return ''

    def rsct_service_start(self):
        '''
        Running rsct services which is necessary for Network
        virtualization tests
        '''
        try:
            for svc in ["rsct", "rsct_rm"]:
                process.run('startsrc -g %s' % svc, shell=True, sudo=True)
        except CmdError as details:
            self.log.debug(str(details))
            self.fail("Starting service %s failed", svc)

        output = process.system_output("lssrc -a", ignore_status=True,
                                       shell=True, sudo=True).decode("utf-8")
        if "inoperative" in output:
            self.fail("Failed to start the rsct and rsct_rm services")

    def install_packages(self):
        '''
        Install required packages
        '''
        smm = SoftwareManager()
        detected_distro = distro.detect()
        self.log.info("Test is running on: %s", detected_distro.name)
        for pkg in ['ksh', 'src', 'rsct.basic', 'rsct.core.utils',
                    'rsct.core', 'DynamicRM']:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel('%s is needed for the test to be run' % pkg)

    def test(self):
        '''
        Remove and add vfc interfaces Dynamically from HMC
        '''
        for _ in range(self.count):
            for vfc_dic in self.dic_list:
                self.device_add_remove("remove", vfc_dic)
                time.sleep(self.opp_sleep_time)
                self.device_add_remove("add", vfc_dic)

    def get_drc_name(self, c_slot):
        '''
        Returns the drc_name i,e vfc slot name mapped to lpar
        '''
        cmd = 'lshwres -r virtualio --rsubtype slot --level slot -m %s -F \
               slot_num,lpar_name,drc_name | grep -i %s' \
               % (self.server, self.lpar)
        for line in self.session.cmd(cmd).stdout_text.splitlines():
            if c_slot in line:
                return line.split(",")[-1]
        return None

    def get_linux_name_drc(self, drc):
        '''
        returns the linux_name of corresponding drc_name
        '''
        cmd = 'lsslot -c slot'
        output = process.system_output(cmd).decode('utf-8').splitlines()
        self.log.info("output value : %s" % output)
        for line in output:
            if drc in line:
                linux_name = " ".join(line.split())
                return linux_name.split(" ")[-2]
        return None

    def get_paths(self, drc_name):
        '''
        returns the mpaths corresponding to linux name
        '''
        paths = []
        linux_name = self.get_linux_name_drc(drc_name)
        cmd = "ls -l /sys/block/"
        output = process.system_output(cmd).decode('utf-8').splitlines()
        for line in output:
            if "/%s/" % linux_name in line:
                paths.append(line.split("/")[-1])
        return paths

    def get_wwpn(self, client_slot):
        '''
        Returns the WWPNs of give client slot number
        '''
        cmd = 'lshwres -r virtualio --rsubtype fc --level lpar -m %s -F \
               lpar_name,slot_num,wwpns | grep -i %s' \
               % (self.server, self.lpar)
        output = self.session.cmd(cmd)
        for line in output.stdout_text.splitlines():
            if self.lpar and client_slot in line:
                wwpn = line.split('"')[1]
        self.log.info("wwpns of slot %s is : %s" % (client_slot, wwpn))
        return wwpn
        if output.exit_status != 0:
            self.log.debug(output.stderr)
            self.fail("Failed to get the wwpn, from give slot")

    def device_add_remove(self, operation, vfc_dic):
        '''
        Adds and removes a Network virtualized device based
        on the operation
        '''
        if operation == 'add':
            cmd = 'chhwres -r virtualio -m %s -o a -p %s --rsubtype fc -s %s \
                   -a "adapter_type=client,remote_lpar_name=%s, \
                   remote_slot_num=%s,\\"wwpns=%s\\""' \
                   % (self.server, self.lpar, vfc_dic["c_slot"],
                      vfc_dic["r_lpar"], vfc_dic["r_slot"], vfc_dic["wwpn"])
        else:
            cmd = 'chhwres -r virtualio -m %s -o r -p %s  -s %s' \
                   % (self.server, self.lpar, vfc_dic["c_slot"])

        output = self.session.cmd(cmd)
        if output.exit_status != 0:
            self.log.debug(output.stderr)
            self.fail("Network virtualization %s device operation \
                       failed" % operation)
        time.sleep(self.opp_sleep_time)
        self.drc_name_verification_hmc(operation, vfc_dic["c_slot"])
        self.linux_name_verification_host(operation, vfc_dic["drc"])
        self.mpath_verification(operation, vfc_dic["paths"],
                                vfc_dic["drc"])

    def drc_name_verification_hmc(self, operation, c_slot):
        '''
        verify the vfc slot/rdc_name exists in HMC
        '''
        err_slot = []
        drc_name = self.get_drc_name(c_slot)
        if operation == "add":
            if not drc_name:
                err_slot.append(c_slot)
        elif operation == "remove":
            if drc_name:
                err_slot.append(c_slot)

        if err_slot:
            self.fail("HMC verifction fail for %s: %s" % (drc_name, operation))
        else:
            self.log.info("HMC verfction succes %s:%s" % (drc_name, operation))

    def linux_name_verification_host(self, operation, drc_name):
        '''
        verify the linux_name or drc_name in host
        '''
        err_slot = []
        linux_name = self.get_linux_name_drc(drc_name)
        if operation == "add":
            if not linux_name:
                err_slot.append(drc_name)
        elif operation == "remove":
            if linux_name:
                err_slot.append(drc_name)

        if err_slot:
            self.fail("Host verifction fail for %s:%s" % (drc_name, operation))
        else:
            self.log.info("Host verfction suces %s:%s" % (drc_name, operation))

    def mpath_verification(self, operation, paths, drc):
        '''
        verify the paths status on add or remove operations of vfc
        '''
        err_paths = []
        curr_paths = self.get_paths(drc)
        if operation == "add":
            for path in paths:
                path_stat = multipath.get_path_status(path)
                if path_stat[0] != "active" or path_stat[2] != "ready":
                    err_paths.append(path)
        elif curr_paths:
            for path in paths:
                path_stat = multipath.get_path_status(path)
                if path_stat[0] != "failed" or path_stat[2] != "faulty":
                    err_paths.append(path)

        if err_paths:
            self.fail("path verfction failed for drc %s:%s" % (drc, err_paths))
        else:
            self.log.info("path verfction success for drc :%s" % drc)

    def tearDown(self):
        '''
        close ssh session gracefully
        '''
        self.session.quit()
Beispiel #19
0
class PingPong(Test):
    '''
    ibv_ud_pingpong test
    ibv_ud_pingpong tool should be installed
    '''

    def setUp(self):
        '''
        To check and install dependencies for the test
        '''
        interfaces = netifaces.interfaces()
        self.flag = self.params.get("ext_flag", default="0")
        self.iface = self.params.get("interface", default="")
        self.peer_ip = self.params.get("peer_ip", default="")
        self.peer_user = self.params.get("peer_user_name", default="root")
        self.peer_password = self.params.get("peer_password", '*',
                                             default="None")
        self.ipaddr = self.params.get("host_ip", default="")
        self.netmask = self.params.get("netmask", default="")
        local = LocalHost()
        if self.iface[0:2] == 'ib':
            self.networkinterface = NetworkInterface(self.iface, local,
                                                     if_type='Infiniband')
            try:
                self.networkinterface.add_ipaddr(self.ipaddr, self.netmask)
                self.networkinterface.save(self.ipaddr, self.netmask)
            except Exception:
                self.networkinterface.save(self.ipaddr, self.netmask)
        else:
            self.networkinterface = NetworkInterface(self.iface, local)
            try:
                self.networkinterface.add_ipaddr(self.ipaddr, self.netmask)
                self.networkinterface.save(self.ipaddr, self.netmask)
            except Exception:
                self.networkinterface.save(self.ipaddr, self.netmask)
        self.networkinterface.bring_up()
        self.session = Session(self.peer_ip, user=self.peer_user,
                               password=self.peer_password)
        if self.iface not in interfaces:
            self.cancel("%s interface is not available" % self.iface)
        if self.peer_ip == "":
            self.cancel("%s peer machine is not available" % self.peer_ip)
        self.ca_name = self.params.get("CA_NAME", default="mlx4_0")
        self.gid = int(self.params.get("GID_NUM", default="0"))
        self.port = int(self.params.get("PORT_NUM", default="1"))
        self.peer_ca = self.params.get("PEERCA", default="mlx4_0")
        self.peer_gid = int(self.params.get("PEERGID", default="0"))
        self.peer_port = int(self.params.get("PEERPORT", default="1"))
        self.tmo = self.params.get("TIMEOUT", default="120")
        self.mtu = self.params.get("mtu", default=1500)
        self.remotehost = RemoteHost(self.peer_ip, self.peer_user,
                                     password=self.peer_password)
        self.peer_interface = self.remotehost.get_interface_by_ipaddr(self.peer_ip).name
        self.peer_networkinterface = NetworkInterface(self.peer_interface,
                                                      self.remotehost)
        smm = SoftwareManager()
        detected_distro = distro.detect()
        pkgs = []
        if detected_distro.name == "Ubuntu":
            pkgs.extend(["ibverbs-utils", 'openssh-client'])
            cmd = "service ufw stop"
        # FIXME: "redhat" as the distro name for RHEL is deprecated
        # on Avocado versions >= 50.0.  This is a temporary compatibility
        # enabler for older runners, but should be removed soon
        elif detected_distro.name in ['rhel', 'fedora', 'redhat']:
            pkgs.extend(["libibverbs", 'openssh-clients'])
            cmd = "systemctl stop firewalld"
        elif detected_distro.name == "SuSE":
            pkgs.append('openssh')
            if detected_distro.version == 15:
                cmd = "systemctl stop firewalld"
            else:
                cmd = "rcSuSEfirewall2 stop"
        elif detected_distro.name == "centos":
            pkgs.extend(['libibverbs', 'openssh-clients'])
            cmd = "service iptables stop"
        else:
            self.cancel("Distro not supported")
        if process.system(cmd, ignore_status=True, shell=True) != 0:
            self.cancel("Unable to disable firewall")
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.cancel("Unable to disable firewall on peer")
        for pkg in pkgs:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("%s package is need to test" % pkg)
        if process.system("ibstat", shell=True, ignore_status=True) != 0:
            self.cancel("infiniband adaptors not available")
        self.tool_name = self.params.get("tool")
        self.log.info("test with %s", self.tool_name)
        self.peer_iface = ''
        cmd = "ip addr show"
        output = self.session.cmd(cmd)
        for line in output.stdout.decode("utf-8").splitlines():
            if self.peer_ip in line:
                self.peer_iface = line.split()[-1]
                break

    def pingpong_exec(self, arg1, arg2, arg3):
        '''
        ping pong exec function
        '''
        test = arg2
        logs = "> /tmp/ib_log 2>&1 &"
        if test == "basic":
            test = ""
        cmd = "timeout %s %s -d %s -g %d -i %d %s %s %s" \
            % (self.tmo, arg1, self.peer_ca, self.peer_gid, self.peer_port,
               test, arg3, logs)
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("ssh failed to remote machine")
        time.sleep(2)
        self.log.info("client data for %s(%s)", arg1, arg2)
        self.log.info("%s -d %s -g %d %s -i %d %s %s", arg1, self.ca_name,
                      self.gid, self.peer_ip, self.port, test, arg3)
        tmp = "timeout %s %s -d %s -g %d -i %d %s %s %s" \
            % (self.tmo, arg1, self.ca_name, self.gid, self.port, self.peer_ip,
               test, arg3)
        if process.system(tmp, shell=True, ignore_status=True) != 0:
            self.fail("test failed")
        self.log.info("server data for %s(%s)", arg1, arg2)
        self.log.info("%s -d %s -g %d -i %d %s %s", arg1, self.peer_ca,
                      self.peer_gid, self.peer_port, test, arg3)
        cmd = "timeout %s cat /tmp/ib_log && rm -rf /tmp/ib_log" \
            % self.tmo
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("test failed")

    def test_ib_pingpong(self):
        '''
        test options are mandatory
        ext test options are depends upon user
        '''
        # change MTU to 9000 for non-IB tests
        if "ib" not in self.iface and self.tool_name == "ibv_ud_pingpong":
            self.mtu = "9000"
        if self.peer_networkinterface.set_mtu(self.mtu) is not None:
            self.fail("Failed to set mtu in peer")
        if self.networkinterface.set_mtu(self.mtu) is not None:
            self.fail("Failed to set mtu in host")
        time.sleep(10)
        val1 = ""
        val2 = ""
        test_op = self.params.get("test_opt", default="").split(",")
        for val in test_op:
            try:
                val1, val2 = val.split()
            except ValueError:
                pass
            self.pingpong_exec(self.tool_name, val1, val2)
        ext_test_op = self.params.get("ext_test_opt", default="").split(",")
        if self.flag == "1":
            for val in ext_test_op:
                self.pingpong_exec(self.tool_name, val, "")
        else:
            self.log.info("Extended test option skipped")

    def tearDown(self):
        if self.networkinterface.set_mtu('1500') is not None:
            self.fail("Failed to set mtu in host")
        if self.peer_networkinterface.set_mtu('1500') is not None:
            self.fail("Failed to set mtu in peer")
        self.remotehost.remote_session.quit()
Beispiel #20
0
class NetworkTest(Test):
    '''
    To test different types of pings
    '''
    def setUp(self):
        '''
        To check and install dependencies for the test
        '''
        smm = SoftwareManager()
        pkgs = ["ethtool", "net-tools"]
        detected_distro = distro.detect()
        if detected_distro.name == "Ubuntu":
            pkgs.extend(["openssh-client", "iputils-ping"])
        elif detected_distro.name == "SuSE":
            pkgs.extend(["openssh", "iputils"])
        else:
            pkgs.extend(["openssh-clients", "iputils"])
        for pkg in pkgs:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("%s package is need to test" % pkg)
        interfaces = netifaces.interfaces()
        interface = self.params.get("interface")
        if interface not in interfaces:
            self.cancel("%s interface is not available" % interface)
        self.iface = interface
        self.ipaddr = self.params.get("host_ip", default="")
        self.netmask = self.params.get("netmask", default="")
        self.ip_config = self.params.get("ip_config", default=True)
        local = LocalHost()
        self.networkinterface = NetworkInterface(self.iface, local)
        if self.ip_config:
            try:
                self.networkinterface.add_ipaddr(self.ipaddr, self.netmask)
                self.networkinterface.save(self.ipaddr, self.netmask)
            except Exception:
                self.networkinterface.save(self.ipaddr, self.netmask)
            self.networkinterface.bring_up()
        if not wait.wait_for(self.networkinterface.is_link_up, timeout=120):
            self.fail("Link up of interface is taking longer than 120 seconds")
        self.peer = self.params.get("peer_ip")
        if not self.peer:
            self.cancel("No peer provided")
        self.mtu = self.params.get("mtu", default=1500)
        self.peer_public_ip = self.params.get("peer_public_ip", default="")
        self.peer_user = self.params.get("peer_user", default="root")
        self.peer_password = self.params.get("peer_password",
                                             '*',
                                             default=None)
        if 'scp' or 'ssh' in str(self.name.name):
            self.session = Session(self.peer,
                                   user=self.peer_user,
                                   password=self.peer_password)
            if not self.session.connect():
                self.cancel("failed connecting to peer")
        self.remotehost = RemoteHost(self.peer,
                                     self.peer_user,
                                     password=self.peer_password)
        self.peer_interface = self.remotehost.get_interface_by_ipaddr(
            self.peer).name
        self.peer_networkinterface = NetworkInterface(self.peer_interface,
                                                      self.remotehost)
        self.remotehost_public = RemoteHost(self.peer_public_ip,
                                            self.peer_user,
                                            password=self.peer_password)
        self.peer_public_networkinterface = NetworkInterface(
            self.peer_interface, self.remotehost_public)
        self.mtu = self.params.get("mtu", default=1500)
        self.mtu_set()
        if self.networkinterface.ping_check(self.peer, count=5) is not None:
            self.cancel("No connection to peer")

    def mtu_set(self):
        '''
        set mtu size
        '''
        if self.peer_networkinterface.set_mtu(self.mtu) is not None:
            self.cancel("Failed to set mtu in peer")
        if self.networkinterface.set_mtu(self.mtu) is not None:
            self.cancel("Failed to set mtu in host")

    def test_gro(self):
        '''
        Test GRO
        '''
        ro_type = "gro"
        ro_type_full = "generic-receive-offload"
        if not self.offload_state(ro_type_full):
            self.fail("Could not get state of %s" % ro_type)
        if self.offload_state(ro_type_full) == 'fixed':
            self.fail("Can not change the state of %s" % ro_type)
        self.offload_toggle_test(ro_type, ro_type_full)

    def test_gso(self):
        '''
        Test GSO
        '''
        ro_type = "gso"
        ro_type_full = "generic-segmentation-offload"
        if not self.offload_state(ro_type_full):
            self.fail("Could not get state of %s" % ro_type)
        if self.offload_state(ro_type_full) == 'fixed':
            self.fail("Can not change the state of %s" % ro_type)
        self.offload_toggle_test(ro_type, ro_type_full)

    def test_lro(self):
        '''
        Test LRO
        '''
        ro_type = "lro"
        ro_type_full = "large-receive-offload"
        path = '/sys/class/net/%s/device/uevent' % self.iface
        if os.path.exists(path):
            output = open(path, 'r').read()
            for line in output.splitlines():
                if "OF_NAME" in line:
                    if 'vnic' in line.split('=')[-1]:
                        self.cancel("Unsupported on vNIC")
        if not self.offload_state(ro_type_full):
            self.fail("Could not get state of %s" % ro_type)
        if self.offload_state(ro_type_full) == 'fixed':
            self.fail("Can not change the state of %s" % ro_type)
        self.offload_toggle_test(ro_type, ro_type_full)

    def test_tso(self):
        '''
        Test TSO
        '''
        ro_type = "tso"
        ro_type_full = "tcp-segmentation-offload"
        if not self.offload_state(ro_type_full):
            self.fail("Could not get state of %s" % ro_type)
        if self.offload_state(ro_type_full) == 'fixed':
            self.fail("Can not change the state of %s" % ro_type)
        self.offload_toggle_test(ro_type, ro_type_full)

    def test_ping(self):
        '''
        ping to peer machine
        '''
        if self.networkinterface.ping_check(self.peer, count=10) is not None:
            self.fail("ping test failed")

    def test_floodping(self):
        '''
        Flood ping to peer machine
        '''
        if self.networkinterface.ping_check(self.peer,
                                            count=500000,
                                            options='-f') is not None:
            self.fail("flood ping test failed")

    def test_ssh(self):
        '''
        Test ssh
        '''
        cmd = "echo hi"
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("unable to ssh into peer machine")

    def test_scp(self):
        '''
        Test scp
        '''
        process.run("dd if=/dev/zero of=/tmp/tempfile bs=1024000000 count=1",
                    shell=True)
        md_val1 = hashlib.md5(open('/tmp/tempfile', 'rb').read()).hexdigest()
        destination = "%s:/tmp" % self.peer
        output = self.session.copy_files('/tmp/tempfile', destination)
        if not output:
            self.fail("unable to copy into peer machine")

        source = "%s:/tmp/tempfile" % self.peer
        output = self.session.copy_files(source, '/tmp')
        if not output:
            self.fail("unable to copy from peer machine")

        md_val2 = hashlib.md5(open('/tmp/tempfile', 'rb').read()).hexdigest()
        if md_val1 != md_val2:
            self.fail("Test Failed")

    def test_jumbo_frame(self):
        '''
        Test jumbo frames
        '''
        if self.networkinterface.ping_check(self.peer,
                                            count=30,
                                            options='-i 0.1 -s %d' %
                                            (int(self.mtu) - 28)) is not None:
            self.fail("jumbo frame test failed")

    def test_statistics(self):
        '''
        Test Statistics
        '''
        rx_file = "/sys/class/net/%s/statistics/rx_packets" % self.iface
        tx_file = "/sys/class/net/%s/statistics/tx_packets" % self.iface
        rx_before = genio.read_file(rx_file)
        tx_before = genio.read_file(tx_file)
        self.networkinterface.ping_check(self.peer, count=500000, options='-f')
        rx_after = genio.read_file(rx_file)
        tx_after = genio.read_file(tx_file)
        if (rx_after <= rx_before) or (tx_after <= tx_before):
            self.log.debug("Before\nrx: %s tx: %s" % (rx_before, tx_before))
            self.log.debug("After\nrx: %s tx: %s" % (rx_after, tx_after))
            self.fail("Statistics not incremented properly")

    def mtu_set_back(self):
        '''
        Test set mtu back to 1500
        '''
        try:
            self.peer_networkinterface.set_mtu('1500')
        except Exception:
            self.peer_public_networkinterface.set_mtu('1500')
        if self.networkinterface.set_mtu('1500') is not None:
            self.cancel("Failed to set mtu in host")

    def offload_toggle_test(self, ro_type, ro_type_full):
        '''
        Check to toggle the LRO / GRO / GSO / TSO
        '''
        for state in ["off", "on"]:
            if not self.offload_state_change(ro_type, ro_type_full, state):
                self.fail("%s %s failed" % (ro_type, state))
            if self.networkinterface.ping_check(self.peer,
                                                count=500000,
                                                options='-f') is not None:
                self.fail("ping failed in %s %s" % (ro_type, state))

    def offload_state_change(self, ro_type, ro_type_full, state):
        '''
        Change the state of LRO / GRO / GSO / TSO to specified state
        '''
        cmd = "ethtool -K %s %s %s" % (self.iface, ro_type, state)
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            return False
        if self.offload_state(ro_type_full) != state:
            return False
        return True

    def offload_state(self, ro_type_full):
        '''
        Return the state of LRO / GRO / GSO / TSO.
        If the state can not be changed, we return 'fixed'.
        If any other error, we return ''.
        '''
        cmd = "ethtool -k %s" % self.iface
        output = process.system_output(cmd, shell=True,
                                       ignore_status=True).decode("utf-8")
        for line in output.splitlines():
            if ro_type_full in line:
                if 'fixed' in line.split()[-1]:
                    return 'fixed'
                return line.split()[-1]
        return ''

    def test_promisc(self):
        '''
        promisc mode testing
        '''
        cmd = "ip link set %s promisc on" % self.iface
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            self.fail("failed to enable promisc mode")
        self.networkinterface.ping_check(self.peer, count=100000, options='-f')
        cmd = "ip link set %s promisc off" % self.iface
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            self.fail("failed to disable promisc mode")
        self.networkinterface.ping_check(self.peer, count=5)

    def tearDown(self):
        '''
        Remove the files created
        '''
        self.mtu_set_back()
        if 'scp' in str(self.name.name):
            process.run("rm -rf /tmp/tempfile")
            cmd = "rm -rf /tmp/tempfile"
            self.session.cmd(cmd)
        if self.ip_config:
            self.networkinterface.remove_ipaddr(self.ipaddr, self.netmask)
            try:
                self.networkinterface.restore_from_backup()
            except Exception:
                self.log.info(
                    "backup file not availbale, could not restore file.")
        self.remotehost.remote_session.quit()
        self.remotehost_public.remote_session.quit()
        if 'scp' or 'ssh' in str(self.name.name):
            self.session.quit()
class ReceiveMulticastTest(Test):
    '''
    check multicast receive
    using ping tool
    '''

    def setUp(self):
        '''
        To check and install dependencies for the test
        '''
        self.peer = self.params.get("peer_ip", default="")
        self.user = self.params.get("user_name", default="root")
        self.peer_password = self.params.get("peer_password",
                                             '*', default="None")
        interfaces = netifaces.interfaces()
        self.iface = self.params.get("interface", default="")
        if self.iface not in interfaces:
            self.cancel("%s interface is not available" % self.iface)
        self.ipaddr = self.params.get("host_ip", default="")
        self.netmask = self.params.get("netmask", default="")
        self.hbond = self.params.get("hbond", default=False)
        local = LocalHost()
        if self.hbond:
            self.networkinterface = NetworkInterface(self.iface, local,
                                                     if_type='Bond')
        else:
            self.networkinterface = NetworkInterface(self.iface, local)
        try:
            self.networkinterface.add_ipaddr(self.ipaddr, self.netmask)
            self.networkinterface.save(self.ipaddr, self.netmask)
        except Exception:
            self.networkinterface.save(self.ipaddr, self.netmask)
        self.networkinterface.bring_up()

        self.session = Session(self.peer, user=self.user,
                               password=self.peer_password)
        if not self.session.connect():
            self.cancel("failed connecting to peer")
        self.count = self.params.get("count", default="500000")
        smm = SoftwareManager()
        pkgs = ["net-tools"]
        detected_distro = distro.detect()
        if detected_distro.name == "Ubuntu":
            pkgs.extend(["openssh-client", "iputils-ping"])
        elif detected_distro.name == "SuSE":
            pkgs.extend(["openssh", "iputils"])
        else:
            pkgs.extend(["openssh-clients", "iputils"])
        for pkg in pkgs:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("%s package is need to test" % pkg)
        if self.peer == "":
            self.cancel("peer ip should specify in input")
        cmd = "ip addr show  | grep %s" % self.peer
        output = self.session.cmd(cmd)
        result = ""
        result = result.join(output.stdout.decode("utf-8"))
        self.peerif = result.split()[-1]
        if self.peerif == "":
            self.cancel("unable to get peer interface")
        cmd = "ip -f inet -o addr show %s | awk '{print $4}' | cut -d / -f1"\
              % self.iface
        self.local_ip = process.system_output(cmd, shell=True).strip()
        if self.local_ip == "":
            self.cancel("unable to get local ip")

    def test_multicast(self):
        '''
        ping to peer machine
        '''
        cmd = "echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts"
        if process.system(cmd, shell=True, verbose=True,
                          ignore_status=True) != 0:
            self.fail("unable to set value to icmp_echo_ignore_broadcasts")
        cmd = "ip link set %s allmulticast on" % self.iface
        if process.system(cmd, shell=True, verbose=True,
                          ignore_status=True) != 0:
            self.fail("unable to set all mulicast option to test interface")
        cmd = "ip route add 224.0.0.0/4 dev %s" % self.peerif
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("Unable to add route for Peer interafce")
        cmd = "timeout 600 ping -I %s 224.0.0.1 -c %s -f" % (self.peerif,
                                                             self.count)
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("multicast test failed")

    def tearDown(self):
        '''
        delete multicast route and turn off multicast option
        '''
        cmd = "ip route del 224.0.0.0/4"
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.log.info("Unable to delete multicast route added for peer")
        cmd = "echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts"
        if process.system(cmd, shell=True, verbose=True,
                          ignore_status=True) != 0:
            self.log.info("unable to unset all mulicast option")
        cmd = "ip link set %s allmulticast off" % self.iface
        if process.system(cmd, shell=True, verbose=True,
                          ignore_status=True) != 0:
            self.log.info("unable to unset all mulicast option")
        self.networkinterface.remove_ipaddr(self.ipaddr, self.netmask)
        try:
            self.networkinterface.restore_from_backup()
        except Exception:
            self.networkinterface.remove_cfg_file()
            self.log.info("backup file not availbale, could not restore file.")
        if self.hbond:
            self.networkinterface.restore_slave_cfg_file()
        self.session.quit()
Beispiel #22
0
class Udady(Test):
    """
    Udaddy Test.
    """

    def setUp(self):
        """
        Setup and install dependencies for the test.
        """
        self.test_name = "udaddy"
        self.basic = self.params.get("basic_option", default="None")
        self.ext = self.params.get("ext_option", default="None")
        self.flag = self.params.get("ext_flag", default="0")
        if self.basic == "None" and self.ext == "None":
            self.cancel("No option given")
        if self.flag == "1" and self.ext != "None":
            self.option = self.ext
        else:
            self.option = self.basic
        if process.system("ibstat", shell=True, ignore_status=True) != 0:
            self.cancel("MOFED is not installed. Skipping")
        detected_distro = distro.detect()
        pkgs = []
        smm = SoftwareManager()
        if detected_distro.name == "Ubuntu":
            pkgs.extend(["openssh-client", "iputils-ping"])
        elif detected_distro.name == "SuSE":
            pkgs.extend(["openssh", "iputils"])
        else:
            pkgs.extend(["openssh-clients", "iputils"])
        for pkg in pkgs:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("Not able to install %s" % pkg)
        interfaces = netifaces.interfaces()
        self.iface = self.params.get("interface", default="")
        self.peer_ip = self.params.get("peer_ip", default="")
        self.peer_user = self.params.get("peer_user", default="root")
        self.peer_password = self.params.get("peer_password", '*',
                                             default="None")
        self.ipaddr = self.params.get("host_ip", default="")
        self.netmask = self.params.get("netmask", default="")
        local = LocalHost()
        if self.iface[0:2] == 'ib':
            self.networkinterface = NetworkInterface(self.iface, local,
                                                     if_type='Infiniband')
            try:
                self.networkinterface.add_ipaddr(self.ipaddr, self.netmask)
                self.networkinterface.save(self.ipaddr, self.netmask)
            except Exception:
                self.networkinterface.save(self.ipaddr, self.netmask)
        else:
            self.networkinterface = NetworkInterface(self.iface, local)
            try:
                self.networkinterface.add_ipaddr(self.ipaddr, self.netmask)
                self.networkinterface.save(self.ipaddr, self.netmask)
            except Exception:
                self.networkinterface.save(self.ipaddr, self.netmask)
        self.networkinterface.bring_up()
        self.session = Session(self.peer_ip, user=self.peer_user,
                               password=self.peer_password)
        if self.iface not in interfaces:
            self.cancel("%s interface is not available" % self.iface)
        if self.peer_ip == "":
            self.cancel("%s peer machine is not available" % self.peer_ip)
        self.timeout = "2m"
        self.local_ip = netifaces.ifaddresses(self.iface)[AF_INET][0]['addr']
        self.mtu = self.params.get("mtu", default=1500)
        self.remotehost = RemoteHost(self.peer_ip, self.peer_user,
                                     password=self.peer_password)
        self.peer_interface = self.remotehost.get_interface_by_ipaddr(self.peer_ip).name
        self.peer_networkinterface = NetworkInterface(self.peer_interface,
                                                      self.remotehost)

        if detected_distro.name == "Ubuntu":
            cmd = "service ufw stop"
        # FIXME: "redhat" as the distro name for RHEL is deprecated
        # on Avocado versions >= 50.0.  This is a temporary compatibility
        # enabler for older runners, but should be removed soon
        elif detected_distro.name in ['rhel', 'fedora', 'redhat']:
            cmd = "systemctl stop firewalld"
        elif detected_distro.name == "SuSE":
            if detected_distro.version == 15:
                cmd = "systemctl stop firewalld"
            else:
                cmd = "rcSuSEfirewall2 stop"
        elif detected_distro.name == "centos":
            cmd = "service iptables stop"
        else:
            self.cancel("Distro not supported")
        if process.system(cmd, ignore_status=True, shell=True) != 0:
            self.cancel("Unable to disable firewall")
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.cancel("Unable to disable firewall on peer")

    def test(self):
        """
        Test udaddy
        """
        if self.peer_networkinterface.set_mtu(self.mtu) is not None:
            self.fail("Failed to set mtu in peer")
        if self.networkinterface.set_mtu(self.mtu) is not None:
            self.fail("Failed to set mtu in host")
        self.log.info(self.test_name)
        logs = "> /tmp/ib_log 2>&1 &"
        cmd = " timeout %s %s -b %s %s %s" % (self.timeout, self.test_name,
                                              self.peer_ip, self.option, logs)
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("SSH connection (or) Server command failed")
        time.sleep(5)
        self.log.info("Client data - %s(%s)" % (self.test_name, self.option))
        cmd = "timeout %s %s -s %s -b %s %s" \
            % (self.timeout, self.test_name, self.peer_ip,
               self.local_ip, self.option)
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            self.fail("Client command failed")
        time.sleep(5)
        self.log.info("Server data - %s(%s)" % (self.test_name, self.option))
        cmd = "timeout %s cat /tmp/ib_log && rm -rf /tmp/ib_log" \
            % (self.timeout)
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("Server output retrieval failed")

    def tearDown(self):
        """
        unset ip
        """
        if self.networkinterface.set_mtu('1500') is not None:
            self.fail("Failed to set mtu in host")
        if self.peer_networkinterface.set_mtu('1500') is not None:
            self.fail("Failed to set mtu in peer")
Beispiel #23
0
class Iperf(Test):
    """
    Iperf Test
    """
    def setUp(self):
        """
        To check and install dependencies for the test
        """
        self.peer_user = self.params.get("peer_user_name", default="root")
        self.peer_ip = self.params.get("peer_ip", default="")
        self.peer_password = self.params.get("peer_password",
                                             '*',
                                             default=None)
        interfaces = netifaces.interfaces()
        self.iface = self.params.get("interface", default="")
        if self.iface not in interfaces:
            self.cancel("%s interface is not available" % self.iface)
        self.ipaddr = self.params.get("host_ip", default="")
        self.netmask = self.params.get("netmask", default="")
        configure_network.set_ip(self.ipaddr, self.netmask, self.iface)
        self.session = Session(self.peer_ip,
                               user=self.peer_user,
                               password=self.peer_password)
        smm = SoftwareManager()
        for pkg in ["gcc", "autoconf", "perl", "m4", "libtool"]:
            if not smm.check_installed(pkg) and not smm.install(pkg):
                self.cancel("%s package is need to test" % pkg)
            cmd = "%s install %s" % (smm.backend.base_command, pkg)
            output = self.session.cmd(cmd)
            if not output.exit_status == 0:
                self.cancel(
                    "unable to install the package %s on peer machine " % pkg)
        if self.peer_ip == "":
            self.cancel("%s peer machine is not available" % self.peer_ip)
        self.mtu = self.params.get("mtu", default=1500)
        self.peerinfo = PeerInfo(self.peer_ip,
                                 peer_user=self.peer_user,
                                 peer_password=self.peer_password)
        self.peer_interface = self.peerinfo.get_peer_interface(self.peer_ip)
        if not self.peerinfo.set_mtu_peer(self.peer_interface, self.mtu):
            self.cancel("Failed to set mtu in peer")
        if not configure_network.set_mtu_host(self.iface, self.mtu):
            self.cancel("Failed to set mtu in host")
        iperf_download = self.params.get("iperf_download",
                                         default="https:"
                                         "//github.com/esnet/"
                                         "iperf/archive/master.zip")
        tarball = self.fetch_asset("iperf.zip",
                                   locations=[iperf_download],
                                   expire='7d')
        archive.extract(tarball, self.teststmpdir)
        self.iperf_dir = os.path.join(self.teststmpdir, "iperf-master")
        cmd = "scp -r %s %s@%s:/tmp" % (self.iperf_dir, self.peer_user,
                                        self.peer_ip)
        if process.system(cmd, shell=True, ignore_status=True) != 0:
            self.cancel("unable to copy the iperf into peer machine")
        cmd = "cd /tmp/iperf-master;./bootstrap.sh;./configure;make"
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.cancel("Unable to compile Iperf into peer machine")
        self.iperf_run = str(self.params.get("IPERF_SERVER_RUN", default=0))
        if self.iperf_run == '1':
            cmd = "/tmp/iperf-master/src/iperf3 -s &"
            output = self.session.cmd(cmd)
            if not output.exit_status == 0:
                self.log.debug("Command %s failed %s", cmd, output)
        os.chdir(self.iperf_dir)
        process.system('./bootstrap.sh', shell=True)
        process.system('./configure', shell=True)
        build.make(self.iperf_dir)
        self.iperf = os.path.join(self.iperf_dir, 'src')
        self.expected_tp = self.params.get("EXPECTED_THROUGHPUT", default="85")

    def test(self):
        """
        Test run is a One way throughput test. In this test, we have one host
        transmitting (or receiving) data from a client. This transmit large
        messages using multiple threads or processes.
        """
        speed = int(read_file("/sys/class/net/%s/speed" % self.iface))
        os.chdir(self.iperf)
        cmd = "./iperf3 -c %s" % self.peer_ip
        result = process.run(cmd, shell=True, ignore_status=True)
        if result.exit_status:
            self.fail("FAIL: Iperf Run failed")
        for line in result.stdout.decode("utf-8").splitlines():
            if 'sender' in line:
                tput = int(line.split()[6].split('.')[0])
                if tput < (int(self.expected_tp) * speed) / 100:
                    self.fail("FAIL: Throughput Actual - %s%%, Expected - %s%%"
                              ", Throughput Actual value - %s " %
                              ((tput * 100) / speed, self.expected_tp,
                               str(tput) + 'Mb/sec'))

    def tearDown(self):
        """
        Killing Iperf process in peer machine
        """
        cmd = "pkill iperf; rm -rf /tmp/iperf-master"
        output = self.session.cmd(cmd)
        if not output.exit_status == 0:
            self.fail("Either the ssh to peer machine machine\
                       failed or iperf process was not killed")
        if not configure_network.set_mtu_host(self.iface, '1500'):
            self.cancel("Failed to set mtu in host")
        if not self.peerinfo.set_mtu_peer(self.peer_interface, '1500'):
            self.cancel("Failed to set mtu in peer")
        configure_network.unset_ip(self.iface)