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