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