X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2FDUTSetup.py;h=efc588783a2a27425be31ae9aee1794ec1b314d4;hp=275a546fd86a2d4994a766269fe00a00350d5d43;hb=665b506d4f3b229e05d14eda9def5e46c56518e9;hpb=80a11ac1d0f9da305bb9ec97507294f56c794496 diff --git a/resources/libraries/python/DUTSetup.py b/resources/libraries/python/DUTSetup.py index 275a546fd8..efc588783a 100644 --- a/resources/libraries/python/DUTSetup.py +++ b/resources/libraries/python/DUTSetup.py @@ -16,6 +16,7 @@ from robot.api import logger from resources.libraries.python.topology import NodeType +from resources.libraries.python.topology import Topology from resources.libraries.python.ssh import SSH from resources.libraries.python.constants import Constants from resources.libraries.python.VatExecutor import VatExecutor @@ -112,25 +113,31 @@ class DUTSetup(object): ssh = SSH() ssh.connect(node) - ret_code, stdout, stderr = ssh.exec_command('pidof vpp') - logger.trace(stdout) - logger.trace(stderr) + for i in range(3): + logger.trace('Try {}: Get VPP PID'.format(i)) + ret_code, stdout, stderr = ssh.exec_command('pidof vpp') - if int(ret_code) != 0: - logger.debug('Not possible to get PID of VPP process on node: ' - '{0}\n {1}'.format(node['host'], stdout + stderr)) - raise RuntimeError('Not possible to get PID of VPP process on node:' - ' {}'.format(node['host'])) - - if len(stdout.splitlines()) == 1: - return int(stdout) - elif len(stdout.splitlines()) == 0: - raise RuntimeError("No VPP PID found on node {0}". - format(node['host'])) - else: - raise RuntimeError("More then one VPP PID found on node {0}". - format(node['host'])) + if int(ret_code) != 0: + raise RuntimeError('Not possible to get PID of VPP process ' + 'on node: {0}\n {1}'. + format(node['host'], stdout + stderr)) + + if len(stdout.splitlines()) == 1: + return int(stdout) + elif len(stdout.splitlines()) == 0: + logger.debug("No VPP PID found on node {0}". + format(node['host'])) + continue + else: + logger.debug("More then one VPP PID found on node {0}". + format(node['host'])) + ret_list = () + for line in stdout.splitlines(): + ret_list.append(int(line)) + return ret_list + + return None @staticmethod def get_vpp_pids(nodes): @@ -147,3 +154,186 @@ class DUTSetup(object): if node['type'] == NodeType.DUT: pids[node['host']] = DUTSetup.get_vpp_pid(node) return pids + + @staticmethod + def vpp_show_crypto_device_mapping(node): + """Run "show crypto device mapping" CLI command. + + :param node: Node to run command on. + :type node: dict + """ + vat = VatExecutor() + vat.execute_script("show_crypto_device_mapping.vat", node, + json_out=False) + + @staticmethod + def crypto_device_verify(node, force_init=False, numvfs=32): + """Verify if Crypto QAT device virtual functions are initialized on all + DUTs. If parameter force initialization is set to True, then try to + initialize or disable QAT. + + :param node: DUT node. + :param force_init: If True then try to initialize to specific value. + :param numvfs: Number of VFs to initialize, 0 - disable the VFs. + :type node: dict + :type force_init: bool + :type numvfs: int + :returns: nothing + :raises RuntimeError: If QAT is not initialized or failed to initialize. + """ + + ssh = SSH() + ssh.connect(node) + + cryptodev = Topology.get_cryptodev(node) + cmd = 'cat /sys/bus/pci/devices/{}/sriov_numvfs'.format( + cryptodev.replace(':', r'\:')) + + # Try to read number of VFs from PCI address of QAT device + for _ in range(3): + ret_code, stdout, _ = ssh.exec_command(cmd) + if int(ret_code) == 0: + try: + sriov_numvfs = int(stdout) + except ValueError: + logger.trace('Reading sriov_numvfs info failed on: {}'\ + .format(node['host'])) + else: + if sriov_numvfs != numvfs: + if force_init: + # QAT is not initialized and we want to initialize + # with numvfs + DUTSetup.crypto_device_init(node, numvfs) + else: + raise RuntimeError('QAT device {} is not '\ + 'initialized to {} on host: {}'.format(\ + cryptodev, numvfs, node['host'])) + break + + @staticmethod + def crypto_device_init(node, numvfs): + """Init Crypto QAT device virtual functions on DUT. + + :param node: DUT node. + :param numvfs: Number of VFs to initialize, 0 - disable the VFs. + :type node: dict + :type numvfs: int + :returns: nothing + :raises RuntimeError: If QAT failed to initialize. + """ + + ssh = SSH() + ssh.connect(node) + + cryptodev = Topology.get_cryptodev(node) + + # QAT device must be bind to kernel driver before initialization + DUTSetup.pci_driver_unbind(node, cryptodev) + DUTSetup.pci_driver_bind(node, cryptodev, "dh895xcc") + + # Initialize QAT VFs + ret_code, _, _ = ssh.exec_command( + "sudo sh -c 'echo {} | tee /sys/bus/pci/devices/{}/sriov_numvfs'" + .format(numvfs, cryptodev.replace(':', r'\:'))) + + if int(ret_code) != 0: + raise RuntimeError('Failed to initialize {} VFs on QAT device on ' + 'host: {}'.format(numvfs, node['host'])) + + @staticmethod + def pci_driver_unbind(node, pci_addr): + """Unbind PCI device from current driver on node. + + :param node: DUT node. + :param pci_addr: PCI device address. + :type node: dict + :type pci_addr: str + :returns: nothing + :raises RuntimeError: If PCI device unbind failed. + """ + + ssh = SSH() + ssh.connect(node) + + ret_code, _, _ = ssh.exec_command( + "sudo sh -c 'echo {} | tee /sys/bus/pci/devices/{}/driver/unbind'" + .format(pci_addr, pci_addr.replace(':', r'\:'))) + + if int(ret_code) != 0: + raise RuntimeError('Failed to unbind PCI device from driver on ' + 'host: {}'.format(node['host'])) + + @staticmethod + def pci_driver_bind(node, pci_addr, driver): + """Bind PCI device to driver on node. + + :param node: DUT node. + :param pci_addr: PCI device address. + :param driver: Driver to bind. + :type node: dict + :type pci_addr: str + :type driver: str + :returns: nothing + :raises RuntimeError: If PCI device bind failed. + """ + + ssh = SSH() + ssh.connect(node) + + ret_code, _, _ = ssh.exec_command( + "sudo sh -c 'echo {} | tee /sys/bus/pci/drivers/{}/bind'" + .format(pci_addr, driver)) + + if int(ret_code) != 0: + raise RuntimeError('Failed to bind PCI device to {} driver on ' + 'host: {}'.format(driver, node['host'])) + + @staticmethod + def kernel_module_verify(node, module, force_load=False): + """Verify if kernel module is loaded on all DUTs. If parameter force + load is set to True, then try to load the modules. + + :param node: DUT node. + :param module: Module to verify. + :param force_load: If True then try to load module. + :type node: dict + :type module: str + :type force_init: bool + :returns: nothing + :raises RuntimeError: If module is not loaded or failed to load. + """ + + ssh = SSH() + ssh.connect(node) + + cmd = 'grep -w {} /proc/modules'.format(module) + ret_code, _, _ = ssh.exec_command(cmd) + + if int(ret_code) != 0: + if force_load: + # Module is not loaded and we want to load it + DUTSetup.kernel_module_load(node, module) + else: + raise RuntimeError('Kernel module {} is not loaded on host: '\ + '{}'.format(module, node['host'])) + + @staticmethod + def kernel_module_load(node, module): + """Load kernel module on node. + + :param node: DUT node. + :param module: Module to load. + :type node: dict + :type module: str + :returns: nothing + :raises RuntimeError: If loading failed. + """ + + ssh = SSH() + ssh.connect(node) + + ret_code, _, _ = ssh.exec_command_sudo("modprobe {}".format(module)) + + if int(ret_code) != 0: + raise RuntimeError('Failed to load {} kernel module on host: '\ + '{}'.format(module, node['host']))