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