1c342db35SBrad Bishop# 2*92b42cb3SPatrick Williams# Copyright OpenEmbedded Contributors 3*92b42cb3SPatrick Williams# 4c342db35SBrad Bishop# SPDX-License-Identifier: MIT 5c342db35SBrad Bishop# 6c342db35SBrad Bishop 7eb8dc403SDave Cobbleyimport os 8eb8dc403SDave Cobbleyimport json 9eb8dc403SDave Cobbleyimport shutil 10eb8dc403SDave Cobbley 11eb8dc403SDave Cobbleyfrom oeqa.core.utils.test import getCaseFile, getCaseMethod 12eb8dc403SDave Cobbley 13eb8dc403SDave Cobbleydef get_package_manager(d, root_path): 14eb8dc403SDave Cobbley """ 15eb8dc403SDave Cobbley Returns an OE package manager that can install packages in root_path. 16eb8dc403SDave Cobbley """ 17635e0e46SAndrew Geissler from oe.package_manager.rpm import RpmPM 18635e0e46SAndrew Geissler from oe.package_manager.ipk import OpkgPM 19635e0e46SAndrew Geissler from oe.package_manager.deb import DpkgPM 20eb8dc403SDave Cobbley 21eb8dc403SDave Cobbley pkg_class = d.getVar("IMAGE_PKGTYPE") 22eb8dc403SDave Cobbley if pkg_class == "rpm": 23eb8dc403SDave Cobbley pm = RpmPM(d, 24eb8dc403SDave Cobbley root_path, 25eb8dc403SDave Cobbley d.getVar('TARGET_VENDOR'), 26eb8dc403SDave Cobbley filterbydependencies=False) 27eb8dc403SDave Cobbley pm.create_configs() 28eb8dc403SDave Cobbley 29eb8dc403SDave Cobbley elif pkg_class == "ipk": 30eb8dc403SDave Cobbley pm = OpkgPM(d, 31eb8dc403SDave Cobbley root_path, 32eb8dc403SDave Cobbley d.getVar("IPKGCONF_TARGET"), 331a4b7ee2SBrad Bishop d.getVar("ALL_MULTILIB_PACKAGE_ARCHS"), 341a4b7ee2SBrad Bishop filterbydependencies=False) 35eb8dc403SDave Cobbley 36eb8dc403SDave Cobbley elif pkg_class == "deb": 37eb8dc403SDave Cobbley pm = DpkgPM(d, 38eb8dc403SDave Cobbley root_path, 39eb8dc403SDave Cobbley d.getVar('PACKAGE_ARCHS'), 401a4b7ee2SBrad Bishop d.getVar('DPKG_ARCH'), 411a4b7ee2SBrad Bishop filterbydependencies=False) 42eb8dc403SDave Cobbley 43eb8dc403SDave Cobbley pm.write_index() 44eb8dc403SDave Cobbley pm.update() 45eb8dc403SDave Cobbley 46eb8dc403SDave Cobbley return pm 47eb8dc403SDave Cobbley 48eb8dc403SDave Cobbleydef find_packages_to_extract(test_suite): 49eb8dc403SDave Cobbley """ 50eb8dc403SDave Cobbley Returns packages to extract required by runtime tests. 51eb8dc403SDave Cobbley """ 52eb8dc403SDave Cobbley from oeqa.core.utils.test import getSuiteCasesFiles 53eb8dc403SDave Cobbley 54eb8dc403SDave Cobbley needed_packages = {} 55eb8dc403SDave Cobbley files = getSuiteCasesFiles(test_suite) 56eb8dc403SDave Cobbley 57eb8dc403SDave Cobbley for f in set(files): 58eb8dc403SDave Cobbley json_file = _get_json_file(f) 59eb8dc403SDave Cobbley if json_file: 60eb8dc403SDave Cobbley needed_packages.update(_get_needed_packages(json_file)) 61eb8dc403SDave Cobbley 62eb8dc403SDave Cobbley return needed_packages 63eb8dc403SDave Cobbley 64eb8dc403SDave Cobbleydef _get_json_file(module_path): 65eb8dc403SDave Cobbley """ 66eb8dc403SDave Cobbley Returns the path of the JSON file for a module, empty if doesn't exitst. 67eb8dc403SDave Cobbley """ 68eb8dc403SDave Cobbley 69eb8dc403SDave Cobbley json_file = '%s.json' % module_path.rsplit('.', 1)[0] 70eb8dc403SDave Cobbley if os.path.isfile(module_path) and os.path.isfile(json_file): 71eb8dc403SDave Cobbley return json_file 72eb8dc403SDave Cobbley else: 73eb8dc403SDave Cobbley return '' 74eb8dc403SDave Cobbley 75eb8dc403SDave Cobbleydef _get_needed_packages(json_file, test=None): 76eb8dc403SDave Cobbley """ 77eb8dc403SDave Cobbley Returns a dict with needed packages based on a JSON file. 78eb8dc403SDave Cobbley 79eb8dc403SDave Cobbley If a test is specified it will return the dict just for that test. 80eb8dc403SDave Cobbley """ 81eb8dc403SDave Cobbley needed_packages = {} 82eb8dc403SDave Cobbley 83eb8dc403SDave Cobbley with open(json_file) as f: 84eb8dc403SDave Cobbley test_packages = json.load(f) 85eb8dc403SDave Cobbley for key,value in test_packages.items(): 86eb8dc403SDave Cobbley needed_packages[key] = value 87eb8dc403SDave Cobbley 88eb8dc403SDave Cobbley if test: 89eb8dc403SDave Cobbley if test in needed_packages: 90eb8dc403SDave Cobbley needed_packages = needed_packages[test] 91eb8dc403SDave Cobbley else: 92eb8dc403SDave Cobbley needed_packages = {} 93eb8dc403SDave Cobbley 94eb8dc403SDave Cobbley return needed_packages 95eb8dc403SDave Cobbley 96eb8dc403SDave Cobbleydef extract_packages(d, needed_packages): 97eb8dc403SDave Cobbley """ 98eb8dc403SDave Cobbley Extract packages that will be needed during runtime. 99eb8dc403SDave Cobbley """ 100eb8dc403SDave Cobbley 101eb8dc403SDave Cobbley import bb 102eb8dc403SDave Cobbley import oe.path 103eb8dc403SDave Cobbley 104eb8dc403SDave Cobbley extracted_path = d.getVar('TEST_EXTRACTED_DIR') 105eb8dc403SDave Cobbley 106eb8dc403SDave Cobbley for key,value in needed_packages.items(): 107eb8dc403SDave Cobbley packages = () 108eb8dc403SDave Cobbley if isinstance(value, dict): 109eb8dc403SDave Cobbley packages = (value, ) 110eb8dc403SDave Cobbley elif isinstance(value, list): 111eb8dc403SDave Cobbley packages = value 112eb8dc403SDave Cobbley else: 113eb8dc403SDave Cobbley bb.fatal('Failed to process needed packages for %s; ' 114eb8dc403SDave Cobbley 'Value must be a dict or list' % key) 115eb8dc403SDave Cobbley 116eb8dc403SDave Cobbley for package in packages: 117eb8dc403SDave Cobbley pkg = package['pkg'] 118eb8dc403SDave Cobbley rm = package.get('rm', False) 119eb8dc403SDave Cobbley extract = package.get('extract', True) 120eb8dc403SDave Cobbley 121eb8dc403SDave Cobbley if extract: 122d1e89497SAndrew Geissler #logger.debug('Extracting %s' % pkg) 123eb8dc403SDave Cobbley dst_dir = os.path.join(extracted_path, pkg) 124eb8dc403SDave Cobbley # Same package used for more than one test, 125eb8dc403SDave Cobbley # don't need to extract again. 126eb8dc403SDave Cobbley if os.path.exists(dst_dir): 127eb8dc403SDave Cobbley continue 128eb8dc403SDave Cobbley 129eb8dc403SDave Cobbley # Extract package and copy it to TEST_EXTRACTED_DIR 130eb8dc403SDave Cobbley pkg_dir = _extract_in_tmpdir(d, pkg) 131eb8dc403SDave Cobbley oe.path.copytree(pkg_dir, dst_dir) 132eb8dc403SDave Cobbley shutil.rmtree(pkg_dir) 133eb8dc403SDave Cobbley 134eb8dc403SDave Cobbley else: 135d1e89497SAndrew Geissler #logger.debug('Copying %s' % pkg) 136eb8dc403SDave Cobbley _copy_package(d, pkg) 137eb8dc403SDave Cobbley 138eb8dc403SDave Cobbleydef _extract_in_tmpdir(d, pkg): 139eb8dc403SDave Cobbley """" 140eb8dc403SDave Cobbley Returns path to a temp directory where the package was 141eb8dc403SDave Cobbley extracted without dependencies. 142eb8dc403SDave Cobbley """ 143eb8dc403SDave Cobbley 144eb8dc403SDave Cobbley from oeqa.utils.package_manager import get_package_manager 145eb8dc403SDave Cobbley 146eb8dc403SDave Cobbley pkg_path = os.path.join(d.getVar('TEST_INSTALL_TMP_DIR'), pkg) 147eb8dc403SDave Cobbley pm = get_package_manager(d, pkg_path) 148eb8dc403SDave Cobbley extract_dir = pm.extract(pkg) 149eb8dc403SDave Cobbley shutil.rmtree(pkg_path) 150eb8dc403SDave Cobbley 151eb8dc403SDave Cobbley return extract_dir 152eb8dc403SDave Cobbley 153eb8dc403SDave Cobbleydef _copy_package(d, pkg): 154eb8dc403SDave Cobbley """ 155eb8dc403SDave Cobbley Copy the RPM, DEB or IPK package to dst_dir 156eb8dc403SDave Cobbley """ 157eb8dc403SDave Cobbley 158eb8dc403SDave Cobbley from oeqa.utils.package_manager import get_package_manager 159eb8dc403SDave Cobbley 160eb8dc403SDave Cobbley pkg_path = os.path.join(d.getVar('TEST_INSTALL_TMP_DIR'), pkg) 161eb8dc403SDave Cobbley dst_dir = d.getVar('TEST_PACKAGED_DIR') 162eb8dc403SDave Cobbley pm = get_package_manager(d, pkg_path) 163eb8dc403SDave Cobbley pkg_info = pm.package_info(pkg) 164eb8dc403SDave Cobbley file_path = pkg_info[pkg]['filepath'] 165eb8dc403SDave Cobbley shutil.copy2(file_path, dst_dir) 166eb8dc403SDave Cobbley shutil.rmtree(pkg_path) 167eb8dc403SDave Cobbley 168eb8dc403SDave Cobbleydef install_package(test_case): 169eb8dc403SDave Cobbley """ 170eb8dc403SDave Cobbley Installs package in DUT if required. 171eb8dc403SDave Cobbley """ 172eb8dc403SDave Cobbley needed_packages = test_needs_package(test_case) 173eb8dc403SDave Cobbley if needed_packages: 174eb8dc403SDave Cobbley _install_uninstall_packages(needed_packages, test_case, True) 175eb8dc403SDave Cobbley 176eb8dc403SDave Cobbleydef uninstall_package(test_case): 177eb8dc403SDave Cobbley """ 178eb8dc403SDave Cobbley Uninstalls package in DUT if required. 179eb8dc403SDave Cobbley """ 180eb8dc403SDave Cobbley needed_packages = test_needs_package(test_case) 181eb8dc403SDave Cobbley if needed_packages: 182eb8dc403SDave Cobbley _install_uninstall_packages(needed_packages, test_case, False) 183eb8dc403SDave Cobbley 184eb8dc403SDave Cobbleydef test_needs_package(test_case): 185eb8dc403SDave Cobbley """ 186eb8dc403SDave Cobbley Checks if a test case requires to install/uninstall packages. 187eb8dc403SDave Cobbley """ 188eb8dc403SDave Cobbley test_file = getCaseFile(test_case) 189eb8dc403SDave Cobbley json_file = _get_json_file(test_file) 190eb8dc403SDave Cobbley 191eb8dc403SDave Cobbley if json_file: 192eb8dc403SDave Cobbley test_method = getCaseMethod(test_case) 193eb8dc403SDave Cobbley needed_packages = _get_needed_packages(json_file, test_method) 194eb8dc403SDave Cobbley if needed_packages: 195eb8dc403SDave Cobbley return needed_packages 196eb8dc403SDave Cobbley 197eb8dc403SDave Cobbley return None 198eb8dc403SDave Cobbley 199eb8dc403SDave Cobbleydef _install_uninstall_packages(needed_packages, test_case, install=True): 200eb8dc403SDave Cobbley """ 201eb8dc403SDave Cobbley Install/Uninstall packages in the DUT without using a package manager 202eb8dc403SDave Cobbley """ 203eb8dc403SDave Cobbley 204eb8dc403SDave Cobbley if isinstance(needed_packages, dict): 205eb8dc403SDave Cobbley packages = [needed_packages] 206eb8dc403SDave Cobbley elif isinstance(needed_packages, list): 207eb8dc403SDave Cobbley packages = needed_packages 208eb8dc403SDave Cobbley 209eb8dc403SDave Cobbley for package in packages: 210eb8dc403SDave Cobbley pkg = package['pkg'] 211eb8dc403SDave Cobbley rm = package.get('rm', False) 212eb8dc403SDave Cobbley extract = package.get('extract', True) 213eb8dc403SDave Cobbley src_dir = os.path.join(test_case.tc.extract_dir, pkg) 214eb8dc403SDave Cobbley 215eb8dc403SDave Cobbley # Install package 216eb8dc403SDave Cobbley if install and extract: 217eb8dc403SDave Cobbley test_case.tc.target.copyDirTo(src_dir, '/') 218eb8dc403SDave Cobbley 219eb8dc403SDave Cobbley # Uninstall package 220eb8dc403SDave Cobbley elif not install and rm: 221eb8dc403SDave Cobbley test_case.tc.target.deleteDirStructure(src_dir, '/') 222