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 | |
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>
-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, '/') | ||