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