diff options
| author | Mariano Lopez <mariano.lopez@linux.intel.com> | 2017-01-09 14:49:57 +0000 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2017-01-23 12:05:20 +0000 |
| commit | f8d7db1905902c048d22c86ecddd1be98419bbaf (patch) | |
| tree | b1b237d11f714606c029d07d8db18209eb05293a /meta | |
| parent | 8970ed4b1fd5673fd3472934a000d10bcce297c2 (diff) | |
| download | poky-f8d7db1905902c048d22c86ecddd1be98419bbaf.tar.gz | |
testimage.bbclass: Add support for package extraction
testimage support the installation of packages without a package
manager in the target. This adds support for package extraction
required to support the installation feature.
[YOCTO #10234]
(From OE-Core rev: 8c7335290cb00ed0683241249297ca573ebd353a)
Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
| -rw-r--r-- | meta/classes/testimage.bbclass | 12 | ||||
| -rw-r--r-- | meta/lib/oeqa/utils/package_manager.py | 161 |
2 files changed, 173 insertions, 0 deletions
diff --git a/meta/classes/testimage.bbclass b/meta/classes/testimage.bbclass index abcecca472..1dfbc490de 100644 --- a/meta/classes/testimage.bbclass +++ b/meta/classes/testimage.bbclass | |||
| @@ -243,6 +243,8 @@ def testimage_main(d): | |||
| 243 | test_modules = d.getVar('TEST_SUITES') | 243 | test_modules = d.getVar('TEST_SUITES') |
| 244 | tc.loadTests(test_paths, modules=test_modules) | 244 | tc.loadTests(test_paths, modules=test_modules) |
| 245 | 245 | ||
| 246 | package_extraction(d, tc.suites) | ||
| 247 | |||
| 246 | bootparams = None | 248 | bootparams = None |
| 247 | if d.getVar('VIRTUAL-RUNTIME_init_manager', '') == 'systemd': | 249 | if d.getVar('VIRTUAL-RUNTIME_init_manager', '') == 'systemd': |
| 248 | bootparams = 'systemd.log_level=debug systemd.log_target=console' | 250 | bootparams = 'systemd.log_level=debug systemd.log_target=console' |
| @@ -337,12 +339,22 @@ def create_rpm_index(d): | |||
| 337 | if result: | 339 | if result: |
| 338 | bb.fatal('%s' % ('\n'.join(result))) | 340 | bb.fatal('%s' % ('\n'.join(result))) |
| 339 | 341 | ||
| 342 | def package_extraction(d, test_suites): | ||
| 343 | from oeqa.utils.package_manager import find_packages_to_extract | ||
| 344 | from oeqa.utils.package_manager import extract_packages | ||
| 345 | |||
| 346 | test_create_extract_dirs(d) | ||
| 347 | packages = find_packages_to_extract(test_suites) | ||
| 348 | extract_packages(d, packages) | ||
| 349 | |||
| 340 | def test_create_extract_dirs(d): | 350 | def test_create_extract_dirs(d): |
| 341 | install_path = d.getVar("TEST_INSTALL_TMP_DIR") | 351 | install_path = d.getVar("TEST_INSTALL_TMP_DIR") |
| 342 | package_path = d.getVar("TEST_PACKAGED_DIR") | 352 | package_path = d.getVar("TEST_PACKAGED_DIR") |
| 343 | extracted_path = d.getVar("TEST_EXTRACTED_DIR") | 353 | extracted_path = d.getVar("TEST_EXTRACTED_DIR") |
| 344 | bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR")) | 354 | bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR")) |
| 355 | bb.utils.remove(install_path, recurse=True) | ||
| 345 | bb.utils.remove(package_path, recurse=True) | 356 | bb.utils.remove(package_path, recurse=True) |
| 357 | bb.utils.remove(extracted_path, recurse=True) | ||
| 346 | bb.utils.mkdirhier(install_path) | 358 | bb.utils.mkdirhier(install_path) |
| 347 | bb.utils.mkdirhier(package_path) | 359 | bb.utils.mkdirhier(package_path) |
| 348 | bb.utils.mkdirhier(extracted_path) | 360 | bb.utils.mkdirhier(extracted_path) |
diff --git a/meta/lib/oeqa/utils/package_manager.py b/meta/lib/oeqa/utils/package_manager.py index 0f6bdbc542..ab0d3e5564 100644 --- a/meta/lib/oeqa/utils/package_manager.py +++ b/meta/lib/oeqa/utils/package_manager.py | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | import bb | ||
| 2 | import json | ||
| 3 | import shutil | ||
| 4 | |||
| 5 | |||
| 1 | def get_package_manager(d, root_path): | 6 | def get_package_manager(d, root_path): |
| 2 | """ | 7 | """ |
| 3 | Returns an OE package manager that can install packages in root_path. | 8 | Returns an OE package manager that can install packages in root_path. |
| @@ -27,3 +32,159 @@ def get_package_manager(d, root_path): | |||
| 27 | pm.update() | 32 | pm.update() |
| 28 | 33 | ||
| 29 | return pm | 34 | return pm |
| 35 | |||
| 36 | def find_packages_to_extract(test_suite): | ||
| 37 | """ | ||
| 38 | Returns packages to extract required by runtime tests. | ||
| 39 | """ | ||
| 40 | from oeqa.core.utils.test import getSuiteCasesFiles | ||
| 41 | |||
| 42 | needed_packages = {} | ||
| 43 | files = getSuiteCasesFiles(test_suite) | ||
| 44 | |||
| 45 | for f in set(files): | ||
| 46 | json_file = _get_json_file(f) | ||
| 47 | if json_file: | ||
| 48 | needed_packages.update(_get_needed_packages(json_file)) | ||
| 49 | |||
| 50 | return needed_packages | ||
| 51 | |||
| 52 | def _get_json_file(module_path): | ||
| 53 | """ | ||
| 54 | Returns the path of the JSON file for a module, empty if doesn't exitst. | ||
| 55 | """ | ||
| 56 | |||
| 57 | json_file = '%s.json' % module_path.rsplit('.', 1)[0] | ||
| 58 | if os.path.isfile(module_path) and os.path.isfile(json_file): | ||
| 59 | return json_file | ||
| 60 | else: | ||
| 61 | return '' | ||
| 62 | |||
| 63 | def _get_needed_packages(json_file, test=None): | ||
| 64 | """ | ||
| 65 | Returns a dict with needed packages based on a JSON file. | ||
| 66 | |||
| 67 | If a test is specified it will return the dict just for that test. | ||
| 68 | """ | ||
| 69 | needed_packages = {} | ||
| 70 | |||
| 71 | with open(json_file) as f: | ||
| 72 | test_packages = json.load(f) | ||
| 73 | for key,value in test_packages.items(): | ||
| 74 | needed_packages[key] = value | ||
| 75 | |||
| 76 | if test: | ||
| 77 | if test in needed_packages: | ||
| 78 | needed_packages = needed_packages[test] | ||
| 79 | else: | ||
| 80 | needed_packages = {} | ||
| 81 | |||
| 82 | return needed_packages | ||
| 83 | |||
| 84 | def extract_packages(d, needed_packages): | ||
| 85 | """ | ||
| 86 | Extract packages that will be needed during runtime. | ||
| 87 | """ | ||
| 88 | |||
| 89 | import oe.path | ||
| 90 | |||
| 91 | extracted_path = d.getVar('TEST_EXTRACTED_DIR') | ||
| 92 | |||
| 93 | for key,value in needed_packages.items(): | ||
| 94 | packages = () | ||
| 95 | if isinstance(value, dict): | ||
| 96 | packages = (value, ) | ||
| 97 | elif isinstance(value, list): | ||
| 98 | packages = value | ||
| 99 | else: | ||
| 100 | bb.fatal('Failed to process needed packages for %s; ' | ||
| 101 | 'Value must be a dict or list' % key) | ||
| 102 | |||
| 103 | for package in packages: | ||
| 104 | pkg = package['pkg'] | ||
| 105 | rm = package.get('rm', False) | ||
| 106 | extract = package.get('extract', True) | ||
| 107 | |||
| 108 | if extract: | ||
| 109 | #logger.debug(1, 'Extracting %s' % pkg) | ||
| 110 | dst_dir = os.path.join(extracted_path, pkg) | ||
| 111 | # Same package used for more than one test, | ||
| 112 | # don't need to extract again. | ||
| 113 | if os.path.exists(dst_dir): | ||
| 114 | continue | ||
| 115 | |||
| 116 | # Extract package and copy it to TEST_EXTRACTED_DIR | ||
| 117 | pkg_dir = _extract_in_tmpdir(d, pkg) | ||
| 118 | oe.path.copytree(pkg_dir, dst_dir) | ||
| 119 | shutil.rmtree(pkg_dir) | ||
| 120 | |||
| 121 | else: | ||
| 122 | #logger.debug(1, 'Copying %s' % pkg) | ||
| 123 | _copy_package(d, pkg) | ||
| 124 | |||
| 125 | def _extract_in_tmpdir(d, pkg): | ||
| 126 | """" | ||
| 127 | Returns path to a temp directory where the package was | ||
| 128 | extracted without dependencies. | ||
| 129 | """ | ||
| 130 | |||
| 131 | from oeqa.utils.package_manager import get_package_manager | ||
| 132 | |||
| 133 | pkg_path = os.path.join(d.getVar('TEST_INSTALL_TMP_DIR'), pkg) | ||
| 134 | pm = get_package_manager(d, pkg_path) | ||
| 135 | extract_dir = pm.extract(pkg) | ||
| 136 | shutil.rmtree(pkg_path) | ||
| 137 | |||
| 138 | return extract_dir | ||
| 139 | |||
| 140 | def _copy_package(d, pkg): | ||
| 141 | """ | ||
| 142 | Copy the RPM, DEB or IPK package to dst_dir | ||
| 143 | """ | ||
| 144 | |||
| 145 | from oeqa.utils.package_manager import get_package_manager | ||
| 146 | |||
| 147 | pkg_path = os.path.join(d.getVar('TEST_INSTALL_TMP_DIR'), pkg) | ||
| 148 | dst_dir = d.getVar('TEST_PACKAGED_DIR') | ||
| 149 | pm = get_package_manager(d, pkg_path) | ||
| 150 | pkg_info = pm.package_info(pkg) | ||
| 151 | file_path = pkg_info[pkg]['filepath'] | ||
| 152 | shutil.copy2(file_path, dst_dir) | ||
| 153 | shutil.rmtree(pkg_path) | ||
| 154 | |||
| 155 | def install_uninstall_packages(self, test_id, pkg_dir, install): | ||
| 156 | """ | ||
| 157 | Check if the test requires a package and Install/Unistall it in the DUT | ||
| 158 | """ | ||
| 159 | |||
| 160 | test = test_id.split('.')[4] | ||
| 161 | module = self.getModulefromID(test_id) | ||
| 162 | json = self._getJsonFile(module) | ||
| 163 | if json: | ||
| 164 | needed_packages = self._getNeededPackages(json, test) | ||
| 165 | if needed_packages: | ||
| 166 | self._install_uninstall_packages(needed_packages, pkg_dir, install) | ||
| 167 | |||
| 168 | def _install_uninstall_packages(self, needed_packages, pkg_dir, install=True): | ||
| 169 | """ | ||
| 170 | Install/Unistall packages in the DUT without using a package manager | ||
| 171 | """ | ||
| 172 | |||
| 173 | if isinstance(needed_packages, dict): | ||
| 174 | packages = [needed_packages] | ||
| 175 | elif isinstance(needed_packages, list): | ||
| 176 | packages = needed_packages | ||
| 177 | |||
| 178 | for package in packages: | ||
| 179 | pkg = package['pkg'] | ||
| 180 | rm = package.get('rm', False) | ||
| 181 | extract = package.get('extract', True) | ||
| 182 | src_dir = os.path.join(pkg_dir, pkg) | ||
| 183 | |||
| 184 | # Install package | ||
| 185 | if install and extract: | ||
| 186 | self.target.connection.copy_dir_to(src_dir, '/') | ||
| 187 | |||
| 188 | # Unistall package | ||
| 189 | elif not install and rm: | ||
| 190 | self.target.connection.delete_dir_structure(src_dir, '/') | ||
