xref: /openbmc/openbmc/poky/meta/lib/oeqa/sdk/case.py (revision c9537f57ab488bf5d90132917b0184e2527970a5)
1#
2# Copyright (C) 2016 Intel Corporation
3#
4# SPDX-License-Identifier: MIT
5#
6
7import os
8import subprocess
9import shutil
10import unittest
11
12from oeqa.core.case import OETestCase
13from oeqa.sdkext.context import OESDKExtTestContext
14
15class OESDKTestCase(OETestCase):
16    def _run(self, cmd):
17        return subprocess.check_output(". %s > /dev/null; %s;" % \
18                (self.tc.sdk_env, cmd), shell=True, executable="/bin/bash",
19                stderr=subprocess.STDOUT, universal_newlines=True)
20
21    def ensure_host_package(self, *packages, recipe=None):
22        """
23        Check that the host variation of one of the packages listed is available
24        in the SDK (nativesdk-foo for SDK, foo-native for eSDK). The package is
25        a list for the case where debian-renaming may have occured, and the
26        manifest could contain 'foo' or 'libfoo'.
27
28        If testing an eSDK and the package is not found, then try to install the
29        specified recipe to install it from sstate.
30        """
31
32        # In a SDK the manifest is correct. In an eSDK the manifest may be
33        # correct (type=full) or not include packages that exist in sstate but
34        # not installed yet (minimal) so we should try to install the recipe.
35        for package in packages:
36            if isinstance(self.tc, OESDKExtTestContext):
37                package = package + "-native"
38            else:
39                package = "nativesdk-" + package
40
41            if self.tc.hasHostPackage(package):
42                break
43        else:
44            if isinstance(self.tc, OESDKExtTestContext):
45                recipe = (recipe or packages[0]) + "-native"
46                print("Trying to install %s..." % recipe)
47                self._run('devtool sdk-install %s' % recipe)
48            else:
49                raise unittest.SkipTest("Test %s needs one of %s" % (self.id(), ", ".join(packages)))
50
51    def ensure_target_package(self, *packages, multilib=False, recipe=None):
52        """
53        Check that at least one of the packages listed is available in the SDK,
54        adding the multilib prefix if required. The target package is a list for
55        the case where debian-renaming may have occured, and the manifest could
56        contain 'foo' or 'libfoo'.
57
58        If testing an eSDK and the package is not found, then try to install the
59        specified recipe to install it from sstate.
60        """
61
62        # In a SDK the manifest is correct. In an eSDK the manifest may be
63        # correct (type=full) or not include packages that exist in sstate but
64        # not installed yet (minimal) so we should try to install the recipe.
65        for package in packages:
66            if self.tc.hasTargetPackage(package, multilib=multilib):
67                break
68        else:
69            if isinstance(self.tc, OESDKExtTestContext):
70                recipe = recipe or packages[0]
71                print("Trying to install %s..." % recipe)
72                self._run('devtool sdk-install %s' % recipe)
73            else:
74                raise unittest.SkipTest("Test %s needs one of %s" % (self.id(), ", ".join(packages)))
75
76
77    def fetch(self, workdir, dl_dir, url, archive=None):
78        if not archive:
79            from urllib.parse import urlparse
80            archive = os.path.basename(urlparse(url).path)
81
82        if dl_dir:
83            archive_tarball = os.path.join(dl_dir, archive)
84            if os.path.exists(archive_tarball):
85                return archive_tarball
86
87        tarball = os.path.join(workdir, archive)
88        subprocess.check_output(["wget", "-O", tarball, url], stderr=subprocess.STDOUT)
89        if dl_dir and not os.path.exists(archive_tarball):
90            shutil.copyfile(tarball, archive_tarball)
91        return tarball
92
93    def check_elf(self, path, target_os=None, target_arch=None):
94        """
95        Verify that the ELF binary $path matches the specified target
96        OS/architecture, or if not specified the currently configured MACHINE's
97        OS/architecture.
98        """
99        import oe.qa, oe.elf
100
101        if not target_os or not target_arch:
102            output = self._run("echo $OECORE_TARGET_OS:$OECORE_TARGET_ARCH")
103            target_os, target_arch = output.strip().split(":")
104
105        machine_data = oe.elf.machine_dict(None)[target_os][target_arch]
106        (machine, osabi, abiversion, endian, bits) = machine_data
107
108        elf = oe.qa.ELFFile(path)
109        elf.open()
110
111        self.assertEqual(machine, elf.machine(),
112                         "Binary was %s but expected %s" %
113                         (oe.qa.elf_machine_to_string(elf.machine()), oe.qa.elf_machine_to_string(machine)))
114        self.assertEqual(bits, elf.abiSize())
115        self.assertEqual(endian, elf.isLittleEndian())
116