diff options
Diffstat (limited to 'meta/lib/oeqa/sdk')
27 files changed, 543 insertions, 370 deletions
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/README b/meta/lib/oeqa/sdk/buildtools-cases/README deleted file mode 100644 index d4f20faa9f..0000000000 --- a/meta/lib/oeqa/sdk/buildtools-cases/README +++ /dev/null | |||
| @@ -1,2 +0,0 @@ | |||
| 1 | These test cases are used by buildtools-tarball, and are not used by the testsdk | ||
| 2 | class. | ||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/build.py b/meta/lib/oeqa/sdk/buildtools-cases/build.py deleted file mode 100644 index c85c32496b..0000000000 --- a/meta/lib/oeqa/sdk/buildtools-cases/build.py +++ /dev/null | |||
| @@ -1,32 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import os, tempfile | ||
| 8 | import time | ||
| 9 | from oeqa.sdk.case import OESDKTestCase | ||
| 10 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 11 | errors_have_output() | ||
| 12 | |||
| 13 | class BuildTests(OESDKTestCase): | ||
| 14 | """ | ||
| 15 | Verify that bitbake can build virtual/libc inside the buildtools. | ||
| 16 | """ | ||
| 17 | def test_libc(self): | ||
| 18 | with tempfile.TemporaryDirectory(prefix='bitbake-build-', dir=self.tc.sdk_dir) as testdir: | ||
| 19 | corebase = self.td['COREBASE'] | ||
| 20 | |||
| 21 | self._run('. %s/oe-init-build-env %s' % (corebase, testdir)) | ||
| 22 | with open(os.path.join(testdir, 'conf', 'local.conf'), 'ta') as conf: | ||
| 23 | conf.write('\n') | ||
| 24 | conf.write('DL_DIR = "%s"\n' % self.td['DL_DIR']) | ||
| 25 | |||
| 26 | try: | ||
| 27 | self._run('. %s/oe-init-build-env %s && bitbake virtual/libc' % (corebase, testdir)) | ||
| 28 | finally: | ||
| 29 | delay = 10 | ||
| 30 | while delay and (os.path.exists(testdir + "/bitbake.lock") or os.path.exists(testdir + "/cache/hashserv.db-wal")): | ||
| 31 | time.sleep(1) | ||
| 32 | delay = delay - 1 | ||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/gcc.py b/meta/lib/oeqa/sdk/buildtools-cases/gcc.py deleted file mode 100644 index a62c4d0bc4..0000000000 --- a/meta/lib/oeqa/sdk/buildtools-cases/gcc.py +++ /dev/null | |||
| @@ -1,31 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import os.path | ||
| 8 | from oeqa.sdk.case import OESDKTestCase | ||
| 9 | |||
| 10 | class GccTests(OESDKTestCase): | ||
| 11 | def test_verify_specs(self): | ||
| 12 | """ | ||
| 13 | Verify that the compiler has been relocated successfully and isn't | ||
| 14 | looking in the hard-coded prefix. | ||
| 15 | """ | ||
| 16 | # Canonicalise the SDK root | ||
| 17 | sdk_base = os.path.realpath(self.tc.sdk_dir) | ||
| 18 | # Canonicalise the location of GCC | ||
| 19 | gcc_path = os.path.realpath(self._run("command -v gcc").strip()) | ||
| 20 | # Skip the test if the GCC didn't come from the buildtools, as it only | ||
| 21 | # comes with buildtools-extended-tarball. | ||
| 22 | if os.path.commonprefix((sdk_base, gcc_path)) != sdk_base: | ||
| 23 | self.skipTest("Buildtools does not provide GCC") | ||
| 24 | |||
| 25 | # This is the prefix that GCC is build with, and should be replaced at | ||
| 26 | # installation time. | ||
| 27 | sdkpath = self.td.get("SDKPATH") | ||
| 28 | self.assertTrue(sdkpath) | ||
| 29 | |||
| 30 | for line in self._run('gcc -dumpspecs').splitlines(): | ||
| 31 | self.assertNotIn(sdkpath, line) | ||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/https.py b/meta/lib/oeqa/sdk/buildtools-cases/https.py deleted file mode 100644 index 4525e3d758..0000000000 --- a/meta/lib/oeqa/sdk/buildtools-cases/https.py +++ /dev/null | |||
| @@ -1,22 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | from oeqa.sdk.case import OESDKTestCase | ||
| 8 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 9 | errors_have_output() | ||
| 10 | |||
| 11 | class HTTPTests(OESDKTestCase): | ||
| 12 | """ | ||
| 13 | Verify that HTTPS certificates are working correctly, as this depends on | ||
| 14 | environment variables being set correctly. | ||
| 15 | """ | ||
| 16 | |||
| 17 | def test_wget(self): | ||
| 18 | self._run('env -i wget --debug --output-document /dev/null https://yoctoproject.org/connectivity.html') | ||
| 19 | |||
| 20 | def test_python(self): | ||
| 21 | # urlopen() returns a file-like object on success and throws an exception otherwise | ||
| 22 | self._run('python3 -c \'import urllib.request; urllib.request.urlopen("https://yoctoproject.org/connectivity.html")\'') | ||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/sanity.py b/meta/lib/oeqa/sdk/buildtools-cases/sanity.py deleted file mode 100644 index a55d456656..0000000000 --- a/meta/lib/oeqa/sdk/buildtools-cases/sanity.py +++ /dev/null | |||
| @@ -1,24 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import shutil | ||
| 8 | import os.path | ||
| 9 | from oeqa.sdk.case import OESDKTestCase | ||
| 10 | |||
| 11 | class SanityTests(OESDKTestCase): | ||
| 12 | def test_tools(self): | ||
| 13 | """ | ||
| 14 | Test that wget and tar come from the buildtools, not the host. This | ||
| 15 | verifies that the buildtools have installed correctly. We can't check | ||
| 16 | for gcc as that is only installed by buildtools-extended. | ||
| 17 | """ | ||
| 18 | for command in ("tar", "wget"): | ||
| 19 | # Canonicalise the SDK root | ||
| 20 | sdk_base = os.path.realpath(self.tc.sdk_dir) | ||
| 21 | # Canonicalise the location of this command | ||
| 22 | tool_path = os.path.realpath(self._run("command -v %s" % command).strip()) | ||
| 23 | # Assert that the tool was found inside the SDK root | ||
| 24 | self.assertEqual(os.path.commonprefix((sdk_base, tool_path)), sdk_base) | ||
diff --git a/meta/lib/oeqa/sdk/buildtools-docs-cases/README b/meta/lib/oeqa/sdk/buildtools-docs-cases/README deleted file mode 100644 index f8edbc7dad..0000000000 --- a/meta/lib/oeqa/sdk/buildtools-docs-cases/README +++ /dev/null | |||
| @@ -1,2 +0,0 @@ | |||
| 1 | These test cases are used by build-docs-tarball, and are not used by the testsdk | ||
| 2 | class. | ||
diff --git a/meta/lib/oeqa/sdk/buildtools-docs-cases/build.py b/meta/lib/oeqa/sdk/buildtools-docs-cases/build.py deleted file mode 100644 index 6e3ee94292..0000000000 --- a/meta/lib/oeqa/sdk/buildtools-docs-cases/build.py +++ /dev/null | |||
| @@ -1,19 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import tempfile | ||
| 8 | from oeqa.sdk.case import OESDKTestCase | ||
| 9 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 10 | errors_have_output() | ||
| 11 | |||
| 12 | class BuildTests(OESDKTestCase): | ||
| 13 | """ | ||
| 14 | Verify that our docs can build using our docs tools tarball. | ||
| 15 | """ | ||
| 16 | def test_docs_build(self): | ||
| 17 | with tempfile.TemporaryDirectory(prefix='docs-tarball-build-', dir=self.tc.sdk_dir) as testdir: | ||
| 18 | self._run('git clone git://git.yoctoproject.org/yocto-docs %s' % testdir) | ||
| 19 | self._run('cd %s/documentation && make html' % testdir) | ||
diff --git a/meta/lib/oeqa/sdk/case.py b/meta/lib/oeqa/sdk/case.py index c45882689c..03cfde88ff 100644 --- a/meta/lib/oeqa/sdk/case.py +++ b/meta/lib/oeqa/sdk/case.py | |||
| @@ -6,8 +6,11 @@ | |||
| 6 | 6 | ||
| 7 | import os | 7 | import os |
| 8 | import subprocess | 8 | import subprocess |
| 9 | import shutil | ||
| 10 | import unittest | ||
| 9 | 11 | ||
| 10 | from oeqa.core.case import OETestCase | 12 | from oeqa.core.case import OETestCase |
| 13 | from oeqa.sdkext.context import OESDKExtTestContext | ||
| 11 | 14 | ||
| 12 | class OESDKTestCase(OETestCase): | 15 | class OESDKTestCase(OETestCase): |
| 13 | def _run(self, cmd): | 16 | def _run(self, cmd): |
| @@ -15,18 +18,79 @@ class OESDKTestCase(OETestCase): | |||
| 15 | (self.tc.sdk_env, cmd), shell=True, executable="/bin/bash", | 18 | (self.tc.sdk_env, cmd), shell=True, executable="/bin/bash", |
| 16 | stderr=subprocess.STDOUT, universal_newlines=True) | 19 | stderr=subprocess.STDOUT, universal_newlines=True) |
| 17 | 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 | try: | ||
| 48 | self._run('devtool sdk-install %s' % recipe) | ||
| 49 | except subprocess.CalledProcessError: | ||
| 50 | raise unittest.SkipTest("Test %s needs one of %s" % (self.id(), ", ".join(packages))) | ||
| 51 | else: | ||
| 52 | raise unittest.SkipTest("Test %s needs one of %s" % (self.id(), ", ".join(packages))) | ||
| 53 | |||
| 54 | def ensure_target_package(self, *packages, multilib=False, recipe=None): | ||
| 55 | """ | ||
| 56 | Check that at least one of the packages listed is available in the SDK, | ||
| 57 | adding the multilib prefix if required. The target package is a list for | ||
| 58 | the case where debian-renaming may have occured, and the manifest could | ||
| 59 | contain 'foo' or 'libfoo'. | ||
| 60 | |||
| 61 | If testing an eSDK and the package is not found, then try to install the | ||
| 62 | specified recipe to install it from sstate. | ||
| 63 | """ | ||
| 64 | |||
| 65 | # In a SDK the manifest is correct. In an eSDK the manifest may be | ||
| 66 | # correct (type=full) or not include packages that exist in sstate but | ||
| 67 | # not installed yet (minimal) so we should try to install the recipe. | ||
| 68 | for package in packages: | ||
| 69 | if self.tc.hasTargetPackage(package, multilib=multilib): | ||
| 70 | break | ||
| 71 | else: | ||
| 72 | if isinstance(self.tc, OESDKExtTestContext): | ||
| 73 | recipe = recipe or packages[0] | ||
| 74 | print("Trying to install %s..." % recipe) | ||
| 75 | self._run('devtool sdk-install %s' % recipe) | ||
| 76 | else: | ||
| 77 | raise unittest.SkipTest("Test %s needs one of %s" % (self.id(), ", ".join(packages))) | ||
| 78 | |||
| 79 | |||
| 18 | def fetch(self, workdir, dl_dir, url, archive=None): | 80 | def fetch(self, workdir, dl_dir, url, archive=None): |
| 19 | if not archive: | 81 | if not archive: |
| 20 | from urllib.parse import urlparse | 82 | from urllib.parse import urlparse |
| 21 | archive = os.path.basename(urlparse(url).path) | 83 | archive = os.path.basename(urlparse(url).path) |
| 22 | 84 | ||
| 23 | if dl_dir: | 85 | if dl_dir: |
| 24 | tarball = os.path.join(dl_dir, archive) | 86 | archive_tarball = os.path.join(dl_dir, archive) |
| 25 | if os.path.exists(tarball): | 87 | if os.path.exists(archive_tarball): |
| 26 | return tarball | 88 | return archive_tarball |
| 27 | 89 | ||
| 28 | tarball = os.path.join(workdir, archive) | 90 | tarball = os.path.join(workdir, archive) |
| 29 | subprocess.check_output(["wget", "-O", tarball, url], stderr=subprocess.STDOUT) | 91 | subprocess.check_output(["wget", "-O", tarball, url], stderr=subprocess.STDOUT) |
| 92 | if dl_dir and not os.path.exists(archive_tarball): | ||
| 93 | shutil.copyfile(tarball, archive_tarball) | ||
| 30 | return tarball | 94 | return tarball |
| 31 | 95 | ||
| 32 | def check_elf(self, path, target_os=None, target_arch=None): | 96 | def check_elf(self, path, target_os=None, target_arch=None): |
diff --git a/meta/lib/oeqa/sdk/cases/assimp.py b/meta/lib/oeqa/sdk/cases/assimp.py deleted file mode 100644 index e986838aea..0000000000 --- a/meta/lib/oeqa/sdk/cases/assimp.py +++ /dev/null | |||
| @@ -1,45 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import os | ||
| 8 | import subprocess | ||
| 9 | import tempfile | ||
| 10 | import unittest | ||
| 11 | from oeqa.sdk.case import OESDKTestCase | ||
| 12 | |||
| 13 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 14 | errors_have_output() | ||
| 15 | |||
| 16 | class BuildAssimp(OESDKTestCase): | ||
| 17 | """ | ||
| 18 | Test case to build a project using cmake. | ||
| 19 | """ | ||
| 20 | |||
| 21 | def setUp(self): | ||
| 22 | if not (self.tc.hasHostPackage("nativesdk-cmake") or | ||
| 23 | self.tc.hasHostPackage("cmake-native")): | ||
| 24 | raise unittest.SkipTest("Needs cmake") | ||
| 25 | |||
| 26 | def test_assimp(self): | ||
| 27 | with tempfile.TemporaryDirectory(prefix="assimp", dir=self.tc.sdk_dir) as testdir: | ||
| 28 | tarball = self.fetch(testdir, self.td["DL_DIR"], "https://github.com/assimp/assimp/archive/v5.3.1.tar.gz") | ||
| 29 | |||
| 30 | dirs = {} | ||
| 31 | dirs["source"] = os.path.join(testdir, "assimp-5.3.1") | ||
| 32 | dirs["build"] = os.path.join(testdir, "build") | ||
| 33 | dirs["install"] = os.path.join(testdir, "install") | ||
| 34 | |||
| 35 | subprocess.check_output(["tar", "xf", tarball, "-C", testdir], stderr=subprocess.STDOUT) | ||
| 36 | self.assertTrue(os.path.isdir(dirs["source"])) | ||
| 37 | # Apply the zlib patch https://github.com/madler/zlib/commit/a566e156b3fa07b566ddbf6801b517a9dba04fa3 | ||
| 38 | # this sed wont be needed once assimp moves its zlib copy to v1.3.1+ | ||
| 39 | self._run("sed -i '/# ifdef _FILE_OFFSET_BITS/I,+2 d' {source}/contrib/zlib/gzguts.h".format(**dirs)) | ||
| 40 | os.makedirs(dirs["build"]) | ||
| 41 | |||
| 42 | self._run("cd {build} && cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DASSIMP_BUILD_ZLIB=ON {source}".format(**dirs)) | ||
| 43 | self._run("cmake --build {build} -- -j".format(**dirs)) | ||
| 44 | self._run("cmake --build {build} --target install -- DESTDIR={install}".format(**dirs)) | ||
| 45 | self.check_elf(os.path.join(dirs["install"], "usr", "local", "lib", "libassimp.so.5.3.0")) | ||
diff --git a/meta/lib/oeqa/sdk/cases/autotools.py b/meta/lib/oeqa/sdk/cases/autotools.py new file mode 100644 index 0000000000..ecafafa7d6 --- /dev/null +++ b/meta/lib/oeqa/sdk/cases/autotools.py | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import os | ||
| 8 | import tempfile | ||
| 9 | import subprocess | ||
| 10 | import unittest | ||
| 11 | |||
| 12 | from oeqa.sdk.case import OESDKTestCase | ||
| 13 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 14 | errors_have_output() | ||
| 15 | |||
| 16 | class AutotoolsTest(OESDKTestCase): | ||
| 17 | """ | ||
| 18 | Check that autotools will cross-compile correctly. | ||
| 19 | """ | ||
| 20 | def setUp(self): | ||
| 21 | libc = self.td.get("TCLIBC") | ||
| 22 | if libc in [ 'newlib' ]: | ||
| 23 | raise unittest.SkipTest("AutotoolsTest class: SDK doesn't contain a supported C library") | ||
| 24 | |||
| 25 | def test_cpio(self): | ||
| 26 | from oe.utils import parallel_make_value | ||
| 27 | pmv = parallel_make_value((self.td.get('PARALLEL_MAKE') or '').split()) | ||
| 28 | |||
| 29 | with tempfile.TemporaryDirectory(prefix="cpio-", dir=self.tc.sdk_dir) as testdir: | ||
| 30 | tarball = self.fetch(testdir, self.td["DL_DIR"], "https://ftpmirror.gnu.org/gnu/cpio/cpio-2.15.tar.gz") | ||
| 31 | |||
| 32 | opts = {} | ||
| 33 | opts["source"] = os.path.join(testdir, "cpio-2.15") | ||
| 34 | opts["build"] = os.path.join(testdir, "build") | ||
| 35 | opts["install"] = os.path.join(testdir, "install") | ||
| 36 | opts["parallel_make"] = "-j %d" % (pmv) if pmv else "" | ||
| 37 | |||
| 38 | subprocess.check_output(["tar", "xf", tarball, "-C", testdir], stderr=subprocess.STDOUT) | ||
| 39 | self.assertTrue(os.path.isdir(opts["source"])) | ||
| 40 | os.makedirs(opts["build"]) | ||
| 41 | |||
| 42 | self._run("cd {build} && {source}/configure CFLAGS='-std=gnu17 -Dbool=int -Dtrue=1 -Dfalse=0 -Wno-error=implicit-function-declaration' $CONFIGURE_FLAGS".format(**opts)) | ||
| 43 | |||
| 44 | # Check that configure detected the target correctly | ||
| 45 | with open(os.path.join(opts["build"], "config.log")) as f: | ||
| 46 | host_sys = self.td["HOST_SYS"] | ||
| 47 | self.assertIn(f"host_alias='{host_sys}'\n", f.readlines()) | ||
| 48 | |||
| 49 | self._run("cd {build} && make CFLAGS='-std=gnu17 -Dbool=int -Dtrue=1 -Dfalse=0 -Wno-error=implicit-function-declaration' {parallel_make}".format(**opts)) | ||
| 50 | self._run("cd {build} && make install DESTDIR={install}".format(**opts)) | ||
| 51 | |||
| 52 | self.check_elf(os.path.join(opts["install"], "usr", "local", "bin", "cpio")) | ||
diff --git a/meta/lib/oeqa/sdk/cases/buildcpio.py b/meta/lib/oeqa/sdk/cases/buildcpio.py deleted file mode 100644 index 51003b19cd..0000000000 --- a/meta/lib/oeqa/sdk/cases/buildcpio.py +++ /dev/null | |||
| @@ -1,37 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import os | ||
| 8 | import tempfile | ||
| 9 | import subprocess | ||
| 10 | import unittest | ||
| 11 | |||
| 12 | from oeqa.sdk.case import OESDKTestCase | ||
| 13 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 14 | errors_have_output() | ||
| 15 | |||
| 16 | class BuildCpioTest(OESDKTestCase): | ||
| 17 | """ | ||
| 18 | Check that autotools will cross-compile correctly. | ||
| 19 | """ | ||
| 20 | def test_cpio(self): | ||
| 21 | with tempfile.TemporaryDirectory(prefix="cpio-", dir=self.tc.sdk_dir) as testdir: | ||
| 22 | tarball = self.fetch(testdir, self.td["DL_DIR"], "https://ftp.gnu.org/gnu/cpio/cpio-2.15.tar.gz") | ||
| 23 | |||
| 24 | dirs = {} | ||
| 25 | dirs["source"] = os.path.join(testdir, "cpio-2.15") | ||
| 26 | dirs["build"] = os.path.join(testdir, "build") | ||
| 27 | dirs["install"] = os.path.join(testdir, "install") | ||
| 28 | |||
| 29 | subprocess.check_output(["tar", "xf", tarball, "-C", testdir], stderr=subprocess.STDOUT) | ||
| 30 | self.assertTrue(os.path.isdir(dirs["source"])) | ||
| 31 | os.makedirs(dirs["build"]) | ||
| 32 | |||
| 33 | self._run("cd {build} && {source}/configure $CONFIGURE_FLAGS".format(**dirs)) | ||
| 34 | self._run("cd {build} && make -j".format(**dirs)) | ||
| 35 | self._run("cd {build} && make install DESTDIR={install}".format(**dirs)) | ||
| 36 | |||
| 37 | self.check_elf(os.path.join(dirs["install"], "usr", "local", "bin", "cpio")) | ||
diff --git a/meta/lib/oeqa/sdk/cases/buildepoxy.py b/meta/lib/oeqa/sdk/cases/buildepoxy.py deleted file mode 100644 index 147ee3e0ee..0000000000 --- a/meta/lib/oeqa/sdk/cases/buildepoxy.py +++ /dev/null | |||
| @@ -1,44 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import os | ||
| 8 | import subprocess | ||
| 9 | import tempfile | ||
| 10 | import unittest | ||
| 11 | |||
| 12 | from oeqa.sdk.case import OESDKTestCase | ||
| 13 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 14 | errors_have_output() | ||
| 15 | |||
| 16 | class EpoxyTest(OESDKTestCase): | ||
| 17 | """ | ||
| 18 | Test that Meson builds correctly. | ||
| 19 | """ | ||
| 20 | def setUp(self): | ||
| 21 | if not (self.tc.hasHostPackage("nativesdk-meson") or | ||
| 22 | self.tc.hasHostPackage("meson-native")): | ||
| 23 | raise unittest.SkipTest("EpoxyTest class: SDK doesn't contain Meson") | ||
| 24 | |||
| 25 | def test_epoxy(self): | ||
| 26 | with tempfile.TemporaryDirectory(prefix="epoxy", dir=self.tc.sdk_dir) as testdir: | ||
| 27 | tarball = self.fetch(testdir, self.td["DL_DIR"], "https://github.com/anholt/libepoxy/releases/download/1.5.3/libepoxy-1.5.3.tar.xz") | ||
| 28 | |||
| 29 | dirs = {} | ||
| 30 | dirs["source"] = os.path.join(testdir, "libepoxy-1.5.3") | ||
| 31 | dirs["build"] = os.path.join(testdir, "build") | ||
| 32 | dirs["install"] = os.path.join(testdir, "install") | ||
| 33 | |||
| 34 | subprocess.check_output(["tar", "xf", tarball, "-C", testdir], stderr=subprocess.STDOUT) | ||
| 35 | self.assertTrue(os.path.isdir(dirs["source"])) | ||
| 36 | os.makedirs(dirs["build"]) | ||
| 37 | |||
| 38 | log = self._run("meson --warnlevel 1 -Degl=no -Dglx=no -Dx11=false {build} {source}".format(**dirs)) | ||
| 39 | # Check that Meson thinks we're doing a cross build and not a native | ||
| 40 | self.assertIn("Build type: cross build", log) | ||
| 41 | self._run("ninja -C {build} -v".format(**dirs)) | ||
| 42 | self._run("DESTDIR={install} ninja -C {build} -v install".format(**dirs)) | ||
| 43 | |||
| 44 | self.check_elf(os.path.join(dirs["install"], "usr", "local", "lib", "libepoxy.so")) | ||
diff --git a/meta/lib/oeqa/sdk/cases/buildgalculator.py b/meta/lib/oeqa/sdk/cases/buildgalculator.py deleted file mode 100644 index 178f07472d..0000000000 --- a/meta/lib/oeqa/sdk/cases/buildgalculator.py +++ /dev/null | |||
| @@ -1,46 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import os | ||
| 8 | import subprocess | ||
| 9 | import tempfile | ||
| 10 | import unittest | ||
| 11 | |||
| 12 | from oeqa.sdk.case import OESDKTestCase | ||
| 13 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 14 | errors_have_output() | ||
| 15 | |||
| 16 | class GalculatorTest(OESDKTestCase): | ||
| 17 | """ | ||
| 18 | Test that autotools and GTK+ 3 compiles correctly. | ||
| 19 | """ | ||
| 20 | def setUp(self): | ||
| 21 | if not (self.tc.hasTargetPackage("gtk+3", multilib=True) or \ | ||
| 22 | self.tc.hasTargetPackage("libgtk-3.0", multilib=True)): | ||
| 23 | raise unittest.SkipTest("GalculatorTest class: SDK don't support gtk+3") | ||
| 24 | if not (self.tc.hasHostPackage("nativesdk-gettext-dev") or | ||
| 25 | self.tc.hasHostPackage("gettext-native")): | ||
| 26 | raise unittest.SkipTest("GalculatorTest class: SDK doesn't contain gettext") | ||
| 27 | |||
| 28 | def test_galculator(self): | ||
| 29 | with tempfile.TemporaryDirectory(prefix="galculator", dir=self.tc.sdk_dir) as testdir: | ||
| 30 | tarball = self.fetch(testdir, self.td["DL_DIR"], "http://galculator.mnim.org/downloads/galculator-2.1.4.tar.bz2") | ||
| 31 | |||
| 32 | dirs = {} | ||
| 33 | dirs["source"] = os.path.join(testdir, "galculator-2.1.4") | ||
| 34 | dirs["build"] = os.path.join(testdir, "build") | ||
| 35 | dirs["install"] = os.path.join(testdir, "install") | ||
| 36 | |||
| 37 | subprocess.check_output(["tar", "xf", tarball, "-C", testdir], stderr=subprocess.STDOUT) | ||
| 38 | self.assertTrue(os.path.isdir(dirs["source"])) | ||
| 39 | os.makedirs(dirs["build"]) | ||
| 40 | |||
| 41 | self._run("cd {source} && sed -i -e '/s_preferences.*prefs;/d' src/main.c && autoreconf -i -f -I $OECORE_TARGET_SYSROOT/usr/share/aclocal -I m4".format(**dirs)) | ||
| 42 | self._run("cd {build} && {source}/configure $CONFIGURE_FLAGS".format(**dirs)) | ||
| 43 | self._run("cd {build} && make -j".format(**dirs)) | ||
| 44 | self._run("cd {build} && make install DESTDIR={install}".format(**dirs)) | ||
| 45 | |||
| 46 | self.check_elf(os.path.join(dirs["install"], "usr", "local", "bin", "galculator")) | ||
diff --git a/meta/lib/oeqa/sdk/cases/cmake.py b/meta/lib/oeqa/sdk/cases/cmake.py new file mode 100644 index 0000000000..81fd327ca3 --- /dev/null +++ b/meta/lib/oeqa/sdk/cases/cmake.py | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import os | ||
| 8 | import subprocess | ||
| 9 | import tempfile | ||
| 10 | import unittest | ||
| 11 | from oeqa.sdk.case import OESDKTestCase | ||
| 12 | |||
| 13 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 14 | errors_have_output() | ||
| 15 | |||
| 16 | class CMakeTest(OESDKTestCase): | ||
| 17 | """ | ||
| 18 | Test case to build a project using cmake. | ||
| 19 | """ | ||
| 20 | |||
| 21 | def setUp(self): | ||
| 22 | libc = self.td.get("TCLIBC") | ||
| 23 | if libc in [ 'newlib' ]: | ||
| 24 | raise unittest.SkipTest("CMakeTest class: SDK doesn't contain a supported C library") | ||
| 25 | |||
| 26 | self.ensure_host_package("cmake") | ||
| 27 | |||
| 28 | def test_assimp(self): | ||
| 29 | from oe.utils import parallel_make_value | ||
| 30 | pmv = parallel_make_value((self.td.get('PARALLEL_MAKE') or '').split()) | ||
| 31 | |||
| 32 | with tempfile.TemporaryDirectory(prefix="assimp", dir=self.tc.sdk_dir) as testdir: | ||
| 33 | tarball = self.fetch(testdir, self.td["DL_DIR"], "https://github.com/assimp/assimp/archive/v5.4.1.tar.gz") | ||
| 34 | |||
| 35 | opts = {} | ||
| 36 | opts["source"] = os.path.join(testdir, "assimp-5.4.1") | ||
| 37 | opts["build"] = os.path.join(testdir, "build") | ||
| 38 | opts["install"] = os.path.join(testdir, "install") | ||
| 39 | opts["parallel_make"] = "-j %d" % (pmv) if pmv else "" | ||
| 40 | |||
| 41 | subprocess.check_output(["tar", "xf", tarball, "-C", testdir], stderr=subprocess.STDOUT) | ||
| 42 | self.assertTrue(os.path.isdir(opts["source"])) | ||
| 43 | # Apply the zlib patch https://github.com/madler/zlib/commit/a566e156b3fa07b566ddbf6801b517a9dba04fa3 | ||
| 44 | # this sed wont be needed once assimp moves its zlib copy to v1.3.1+ | ||
| 45 | self._run("sed -i '/# ifdef _FILE_OFFSET_BITS/I,+2 d' {source}/contrib/zlib/gzguts.h".format(**opts)) | ||
| 46 | os.makedirs(opts["build"]) | ||
| 47 | |||
| 48 | self._run("cd {build} && cmake -DASSIMP_WARNINGS_AS_ERRORS=OFF -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DASSIMP_BUILD_ZLIB=ON {source}".format(**opts)) | ||
| 49 | self._run("cmake --build {build} -- {parallel_make}".format(**opts)) | ||
| 50 | self._run("cmake --build {build} --target install -- DESTDIR={install}".format(**opts)) | ||
| 51 | self.check_elf(os.path.join(opts["install"], "usr", "local", "lib", "libassimp.so.5.4.1")) | ||
diff --git a/meta/lib/oeqa/sdk/cases/gcc.py b/meta/lib/oeqa/sdk/cases/gcc.py index fc28b9c3d4..e810d2c42b 100644 --- a/meta/lib/oeqa/sdk/cases/gcc.py +++ b/meta/lib/oeqa/sdk/cases/gcc.py | |||
| @@ -26,6 +26,10 @@ class GccCompileTest(OESDKTestCase): | |||
| 26 | os.path.join(self.tc.sdk_dir, f)) | 26 | os.path.join(self.tc.sdk_dir, f)) |
| 27 | 27 | ||
| 28 | def setUp(self): | 28 | def setUp(self): |
| 29 | libc = self.td.get("TCLIBC") | ||
| 30 | if libc in [ 'newlib' ]: | ||
| 31 | raise unittest.SkipTest("GccCompileTest class: SDK doesn't contain a supported C library") | ||
| 32 | |||
| 29 | machine = self.td.get("MACHINE") | 33 | machine = self.td.get("MACHINE") |
| 30 | if not (self.tc.hasHostPackage("packagegroup-cross-canadian-%s" % machine) or | 34 | if not (self.tc.hasHostPackage("packagegroup-cross-canadian-%s" % machine) or |
| 31 | self.tc.hasHostPackage("^gcc-", regex=True)): | 35 | self.tc.hasHostPackage("^gcc-", regex=True)): |
diff --git a/meta/lib/oeqa/sdk/cases/go.py b/meta/lib/oeqa/sdk/cases/go.py new file mode 100644 index 0000000000..a050df7a9f --- /dev/null +++ b/meta/lib/oeqa/sdk/cases/go.py | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import os | ||
| 8 | import shutil | ||
| 9 | import unittest | ||
| 10 | |||
| 11 | from oeqa.core.utils.path import remove_safe | ||
| 12 | from oeqa.sdk.case import OESDKTestCase | ||
| 13 | |||
| 14 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 15 | from oe.go import map_arch | ||
| 16 | errors_have_output() | ||
| 17 | |||
| 18 | class GoCompileTest(OESDKTestCase): | ||
| 19 | td_vars = ['MACHINE', 'TARGET_ARCH'] | ||
| 20 | |||
| 21 | @classmethod | ||
| 22 | def setUpClass(self): | ||
| 23 | # Copy test.go file to SDK directory (same as GCC test uses files_dir) | ||
| 24 | shutil.copyfile(os.path.join(self.tc.files_dir, 'test.go'), | ||
| 25 | os.path.join(self.tc.sdk_dir, 'test.go')) | ||
| 26 | |||
| 27 | def setUp(self): | ||
| 28 | target_arch = self.td.get("TARGET_ARCH") | ||
| 29 | # Check for go-cross-canadian package (uses target architecture) | ||
| 30 | if not self.tc.hasHostPackage("go-cross-canadian-%s" % target_arch): | ||
| 31 | raise unittest.SkipTest("GoCompileTest class: SDK doesn't contain a Go cross-canadian toolchain") | ||
| 32 | |||
| 33 | # Additional runtime check for go command availability | ||
| 34 | try: | ||
| 35 | self._run('which go') | ||
| 36 | except Exception as e: | ||
| 37 | raise unittest.SkipTest("GoCompileTest class: go command not available: %s" % str(e)) | ||
| 38 | |||
| 39 | def test_go_build(self): | ||
| 40 | """Test Go build command (native compilation)""" | ||
| 41 | self._run('cd %s; go build -o test test.go' % self.tc.sdk_dir) | ||
| 42 | |||
| 43 | def test_go_module(self): | ||
| 44 | """Test Go module creation and building""" | ||
| 45 | # Create a simple Go module | ||
| 46 | self._run('cd %s; go mod init hello-go' % self.tc.sdk_dir) | ||
| 47 | self._run('cd %s; go build -o hello-go' % self.tc.sdk_dir) | ||
| 48 | |||
| 49 | @classmethod | ||
| 50 | def tearDownClass(self): | ||
| 51 | files = [os.path.join(self.tc.sdk_dir, f) \ | ||
| 52 | for f in ['test.go', 'test', 'hello-go', 'go.mod', 'go.sum']] | ||
| 53 | for f in files: | ||
| 54 | remove_safe(f) | ||
| 55 | |||
| 56 | class GoHostCompileTest(OESDKTestCase): | ||
| 57 | td_vars = ['MACHINE', 'SDK_SYS', 'TARGET_ARCH'] | ||
| 58 | |||
| 59 | @classmethod | ||
| 60 | def setUpClass(self): | ||
| 61 | # Copy test.go file to SDK directory (same as GCC test uses files_dir) | ||
| 62 | shutil.copyfile(os.path.join(self.tc.files_dir, 'test.go'), | ||
| 63 | os.path.join(self.tc.sdk_dir, 'test.go')) | ||
| 64 | |||
| 65 | def setUp(self): | ||
| 66 | target_arch = self.td.get("TARGET_ARCH") | ||
| 67 | # Check for go-cross-canadian package (uses target architecture) | ||
| 68 | if not self.tc.hasHostPackage("go-cross-canadian-%s" % target_arch): | ||
| 69 | raise unittest.SkipTest("GoHostCompileTest class: SDK doesn't contain a Go cross-canadian toolchain") | ||
| 70 | |||
| 71 | # Additional runtime check for go command availability | ||
| 72 | try: | ||
| 73 | self._run('which go') | ||
| 74 | except Exception as e: | ||
| 75 | raise unittest.SkipTest("GoHostCompileTest class: go command not available: %s" % str(e)) | ||
| 76 | |||
| 77 | def _get_go_arch(self): | ||
| 78 | """Get Go architecture from SDK_SYS""" | ||
| 79 | sdksys = self.td.get("SDK_SYS") | ||
| 80 | arch = sdksys.split('-')[0] | ||
| 81 | |||
| 82 | # Use mapping for other architectures | ||
| 83 | return map_arch(arch) | ||
| 84 | |||
| 85 | def test_go_cross_compile(self): | ||
| 86 | """Test Go cross-compilation for target""" | ||
| 87 | goarch = self._get_go_arch() | ||
| 88 | self._run('cd %s; GOOS=linux GOARCH=%s go build -o test-%s test.go' % (self.tc.sdk_dir, goarch, goarch)) | ||
| 89 | |||
| 90 | def test_go_module_cross_compile(self): | ||
| 91 | """Test Go module cross-compilation""" | ||
| 92 | goarch = self._get_go_arch() | ||
| 93 | self._run('cd %s; go mod init hello-go' % self.tc.sdk_dir) | ||
| 94 | self._run('cd %s; GOOS=linux GOARCH=%s go build -o hello-go-%s' % (self.tc.sdk_dir, goarch, goarch)) | ||
| 95 | |||
| 96 | @classmethod | ||
| 97 | def tearDownClass(self): | ||
| 98 | # Clean up files with dynamic architecture names | ||
| 99 | files = [os.path.join(self.tc.sdk_dir, f) \ | ||
| 100 | for f in ['test.go', 'go.mod', 'go.sum']] | ||
| 101 | # Add common architecture-specific files that might be created | ||
| 102 | common_archs = ['arm64', 'arm', 'amd64', '386', 'mips', 'mipsle', 'ppc64', 'ppc64le', 'riscv64'] | ||
| 103 | for arch in common_archs: | ||
| 104 | files.extend([os.path.join(self.tc.sdk_dir, f) \ | ||
| 105 | for f in ['test-%s' % arch, 'hello-go-%s' % arch]]) | ||
| 106 | for f in files: | ||
| 107 | remove_safe(f) | ||
diff --git a/meta/lib/oeqa/sdk/cases/gtk3.py b/meta/lib/oeqa/sdk/cases/gtk3.py new file mode 100644 index 0000000000..cdaf50ed38 --- /dev/null +++ b/meta/lib/oeqa/sdk/cases/gtk3.py | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import os | ||
| 8 | import subprocess | ||
| 9 | import tempfile | ||
| 10 | |||
| 11 | from oeqa.sdk.cases.meson import MesonTestBase | ||
| 12 | |||
| 13 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 14 | errors_have_output() | ||
| 15 | |||
| 16 | class GTK3Test(MesonTestBase): | ||
| 17 | |||
| 18 | def setUp(self): | ||
| 19 | super().setUp() | ||
| 20 | self.ensure_target_package("gtk+3", "libgtk-3.0", recipe="gtk+3") | ||
| 21 | self.ensure_host_package("glib-2.0-utils", "libglib-2.0-utils", recipe="glib-2.0") | ||
| 22 | |||
| 23 | """ | ||
| 24 | Test that autotools and GTK+ 3 compiles correctly. | ||
| 25 | """ | ||
| 26 | def test_libhandy(self): | ||
| 27 | with tempfile.TemporaryDirectory(prefix="libhandy", dir=self.tc.sdk_dir) as testdir: | ||
| 28 | tarball = self.fetch(testdir, self.td["DL_DIR"], "https://download.gnome.org/sources/libhandy/1.8/libhandy-1.8.3.tar.xz") | ||
| 29 | |||
| 30 | sourcedir = os.path.join(testdir, "libhandy-1.8.3") | ||
| 31 | builddir = os.path.join(testdir, "build") | ||
| 32 | installdir = os.path.join(testdir, "install") | ||
| 33 | |||
| 34 | subprocess.check_output(["tar", "xf", tarball, "-C", testdir], stderr=subprocess.STDOUT) | ||
| 35 | self.assertTrue(os.path.isdir(sourcedir)) | ||
| 36 | os.makedirs(builddir) | ||
| 37 | |||
| 38 | self.build_meson(sourcedir, builddir, installdir, "-Dglade_catalog=disabled -Dintrospection=disabled -Dvapi=false") | ||
| 39 | self.assertTrue(os.path.isdir(installdir)) | ||
| 40 | self.check_elf(os.path.join(installdir, "usr", "local", "lib", "libhandy-1.so")) | ||
diff --git a/meta/lib/oeqa/sdk/cases/kmod.py b/meta/lib/oeqa/sdk/cases/kmod.py new file mode 100644 index 0000000000..0c4d8ddb54 --- /dev/null +++ b/meta/lib/oeqa/sdk/cases/kmod.py | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import os | ||
| 8 | import subprocess | ||
| 9 | import tempfile | ||
| 10 | |||
| 11 | from oeqa.sdk.case import OESDKTestCase | ||
| 12 | from oeqa.sdkext.context import OESDKExtTestContext | ||
| 13 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 14 | errors_have_output() | ||
| 15 | |||
| 16 | class KernelModuleTest(OESDKTestCase): | ||
| 17 | """ | ||
| 18 | Test that out-of-tree kernel modules build. | ||
| 19 | """ | ||
| 20 | def test_cryptodev(self): | ||
| 21 | if isinstance(self.tc, OESDKExtTestContext): | ||
| 22 | self.skipTest(f"{self.id()} does not support eSDK (https://bugzilla.yoctoproject.org/show_bug.cgi?id=15850)") | ||
| 23 | |||
| 24 | from oe.utils import parallel_make_value | ||
| 25 | pmv = parallel_make_value((self.td.get('PARALLEL_MAKE') or '').split()) | ||
| 26 | parallel_make = "-j %d" % (pmv) if pmv else "" | ||
| 27 | |||
| 28 | self.ensure_target_package("kernel-devsrc") | ||
| 29 | # These targets need to be built before kernel modules can be built. | ||
| 30 | self._run("make %s -C $OECORE_TARGET_SYSROOT/usr/src/kernel prepare scripts" % (parallel_make)) | ||
| 31 | |||
| 32 | with tempfile.TemporaryDirectory(prefix="cryptodev", dir=self.tc.sdk_dir) as testdir: | ||
| 33 | git_url = "https://github.com/cryptodev-linux/cryptodev-linux" | ||
| 34 | # This is a knnown-good commit post-1.13 that builds with kernel 6.7+ | ||
| 35 | git_sha = "bb8bc7cf60d2c0b097c8b3b0e807f805b577a53f" | ||
| 36 | |||
| 37 | sourcedir = os.path.join(testdir, "cryptodev-linux") | ||
| 38 | subprocess.check_output(["git", "clone", git_url, sourcedir], stderr=subprocess.STDOUT) | ||
| 39 | self.assertTrue(os.path.isdir(sourcedir)) | ||
| 40 | subprocess.check_output(["git", "-C", sourcedir, "checkout", git_sha], stderr=subprocess.STDOUT) | ||
| 41 | |||
| 42 | self._run("make -C %s V=1 KERNEL_DIR=$OECORE_TARGET_SYSROOT/usr/src/kernel" % sourcedir) | ||
| 43 | self.check_elf(os.path.join(sourcedir, "cryptodev.ko")) | ||
diff --git a/meta/lib/oeqa/sdk/cases/buildlzip.py b/meta/lib/oeqa/sdk/cases/makefile.py index b4b7d85b88..fc041ca8d8 100644 --- a/meta/lib/oeqa/sdk/cases/buildlzip.py +++ b/meta/lib/oeqa/sdk/cases/makefile.py | |||
| @@ -4,27 +4,37 @@ | |||
| 4 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
| 5 | # | 5 | # |
| 6 | 6 | ||
| 7 | import os, tempfile, subprocess, unittest | 7 | import os, tempfile, subprocess |
| 8 | import unittest | ||
| 8 | from oeqa.sdk.case import OESDKTestCase | 9 | from oeqa.sdk.case import OESDKTestCase |
| 9 | from oeqa.utils.subprocesstweak import errors_have_output | 10 | from oeqa.utils.subprocesstweak import errors_have_output |
| 10 | errors_have_output() | 11 | errors_have_output() |
| 11 | 12 | ||
| 12 | class BuildLzipTest(OESDKTestCase): | 13 | class MakefileTest(OESDKTestCase): |
| 13 | """ | 14 | """ |
| 14 | Test that "plain" compilation works, using just $CC $CFLAGS etc. | 15 | Test that "plain" compilation works, using just $CC $CFLAGS etc. |
| 15 | """ | 16 | """ |
| 17 | def setUp(self): | ||
| 18 | libc = self.td.get("TCLIBC") | ||
| 19 | if libc in [ 'newlib' ]: | ||
| 20 | raise unittest.SkipTest("MakefileTest class: SDK doesn't contain a supported C library") | ||
| 21 | |||
| 16 | def test_lzip(self): | 22 | def test_lzip(self): |
| 23 | from oe.utils import parallel_make_value | ||
| 24 | pmv = parallel_make_value((self.td.get('PARALLEL_MAKE') or '').split()) | ||
| 25 | |||
| 17 | with tempfile.TemporaryDirectory(prefix="lzip", dir=self.tc.sdk_dir) as testdir: | 26 | with tempfile.TemporaryDirectory(prefix="lzip", dir=self.tc.sdk_dir) as testdir: |
| 18 | tarball = self.fetch(testdir, self.td["DL_DIR"], "http://downloads.yoctoproject.org/mirror/sources/lzip-1.19.tar.gz") | 27 | tarball = self.fetch(testdir, self.td["DL_DIR"], "http://downloads.yoctoproject.org/mirror/sources/lzip-1.19.tar.gz") |
| 19 | 28 | ||
| 20 | dirs = {} | 29 | opts = {} |
| 21 | dirs["source"] = os.path.join(testdir, "lzip-1.19") | 30 | opts["source"] = os.path.join(testdir, "lzip-1.19") |
| 22 | dirs["build"] = os.path.join(testdir, "build") | 31 | opts["build"] = os.path.join(testdir, "build") |
| 23 | dirs["install"] = os.path.join(testdir, "install") | 32 | opts["install"] = os.path.join(testdir, "install") |
| 33 | opts["parallel_make"] = "-j %d" % (pmv) if pmv else "" | ||
| 24 | 34 | ||
| 25 | subprocess.check_output(["tar", "xf", tarball, "-C", testdir], stderr=subprocess.STDOUT) | 35 | subprocess.check_output(["tar", "xf", tarball, "-C", testdir], stderr=subprocess.STDOUT) |
| 26 | self.assertTrue(os.path.isdir(dirs["source"])) | 36 | self.assertTrue(os.path.isdir(opts["source"])) |
| 27 | os.makedirs(dirs["build"]) | 37 | os.makedirs(opts["build"]) |
| 28 | 38 | ||
| 29 | cmd = """cd {build} && \ | 39 | cmd = """cd {build} && \ |
| 30 | {source}/configure --srcdir {source} \ | 40 | {source}/configure --srcdir {source} \ |
| @@ -33,7 +43,7 @@ class BuildLzipTest(OESDKTestCase): | |||
| 33 | CXXFLAGS="$CXXFLAGS" \ | 43 | CXXFLAGS="$CXXFLAGS" \ |
| 34 | LDFLAGS="$LDFLAGS" \ | 44 | LDFLAGS="$LDFLAGS" \ |
| 35 | """ | 45 | """ |
| 36 | self._run(cmd.format(**dirs)) | 46 | self._run(cmd.format(**opts)) |
| 37 | self._run("cd {build} && make -j".format(**dirs)) | 47 | self._run("cd {build} && make {parallel_make}".format(**opts)) |
| 38 | self._run("cd {build} && make install DESTDIR={install}".format(**dirs)) | 48 | self._run("cd {build} && make install DESTDIR={install}".format(**opts)) |
| 39 | self.check_elf(os.path.join(dirs["install"], "usr", "local", "bin", "lzip")) | 49 | self.check_elf(os.path.join(opts["install"], "usr", "local", "bin", "lzip")) |
diff --git a/meta/lib/oeqa/sdk/cases/manifest.py b/meta/lib/oeqa/sdk/cases/manifest.py new file mode 100644 index 0000000000..ee59a5f338 --- /dev/null +++ b/meta/lib/oeqa/sdk/cases/manifest.py | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | from oeqa.sdk.case import OESDKTestCase | ||
| 8 | from oeqa.sdkext.context import OESDKExtTestContext | ||
| 9 | |||
| 10 | |||
| 11 | class ManifestTest(OESDKTestCase): | ||
| 12 | def test_manifests(self): | ||
| 13 | """ | ||
| 14 | Verify that the host and target manifests are not empty, unless this is | ||
| 15 | a minimal eSDK without toolchain in which case they should be empty. | ||
| 16 | """ | ||
| 17 | if ( | ||
| 18 | isinstance(self.tc, OESDKExtTestContext) | ||
| 19 | and self.td.get("SDK_EXT_TYPE") == "minimal" | ||
| 20 | and self.td.get("SDK_INCLUDE_TOOLCHAIN") == "0" | ||
| 21 | ): | ||
| 22 | self.assertEqual(self.tc.target_pkg_manifest, {}) | ||
| 23 | self.assertEqual(self.tc.host_pkg_manifest, {}) | ||
| 24 | else: | ||
| 25 | self.assertNotEqual(self.tc.target_pkg_manifest, {}) | ||
| 26 | self.assertNotEqual(self.tc.host_pkg_manifest, {}) | ||
diff --git a/meta/lib/oeqa/sdk/cases/maturin.py b/meta/lib/oeqa/sdk/cases/maturin.py index ea10f568b2..e3e8edc781 100644 --- a/meta/lib/oeqa/sdk/cases/maturin.py +++ b/meta/lib/oeqa/sdk/cases/maturin.py | |||
| @@ -8,7 +8,6 @@ import os | |||
| 8 | import shutil | 8 | import shutil |
| 9 | import unittest | 9 | import unittest |
| 10 | 10 | ||
| 11 | from oeqa.core.utils.path import remove_safe | ||
| 12 | from oeqa.sdk.case import OESDKTestCase | 11 | from oeqa.sdk.case import OESDKTestCase |
| 13 | from oeqa.utils.subprocesstweak import errors_have_output | 12 | from oeqa.utils.subprocesstweak import errors_have_output |
| 14 | 13 | ||
| @@ -17,44 +16,24 @@ errors_have_output() | |||
| 17 | 16 | ||
| 18 | class MaturinTest(OESDKTestCase): | 17 | class MaturinTest(OESDKTestCase): |
| 19 | def setUp(self): | 18 | def setUp(self): |
| 20 | if not ( | 19 | self.ensure_host_package("python3-maturin") |
| 21 | self.tc.hasHostPackage("nativesdk-python3-maturin") | ||
| 22 | or self.tc.hasHostPackage("python3-maturin-native") | ||
| 23 | ): | ||
| 24 | raise unittest.SkipTest("No python3-maturin package in the SDK") | ||
| 25 | 20 | ||
| 26 | def test_maturin_list_python(self): | 21 | def test_maturin_list_python(self): |
| 27 | py_major = self._run("python3 -c 'import sys; print(sys.version_info.major)'") | 22 | out = self._run(r"""python3 -c 'import sys; print(f"{sys.executable}\n{sys.version_info.major}.{sys.version_info.minor}")'""") |
| 28 | py_minor = self._run("python3 -c 'import sys; print(sys.version_info.minor)'") | 23 | executable, version = out.splitlines() |
| 29 | python_version = "%s.%s" % (py_major.strip(), py_minor.strip()) | ||
| 30 | cmd = "maturin list-python" | ||
| 31 | output = self._run(cmd) | ||
| 32 | self.assertRegex(output, r"^🐍 1 python interpreter found:\n") | ||
| 33 | self.assertRegex( | ||
| 34 | output, | ||
| 35 | r" - CPython %s (.+)/usr/bin/python%s$" % (python_version, python_version), | ||
| 36 | ) | ||
| 37 | 24 | ||
| 25 | output = self._run("maturin list-python") | ||
| 26 | # The output looks like this: | ||
| 27 | # - CPython 3.13 at /usr/bin/python3 | ||
| 28 | # We don't want to assume CPython so just check for the version and path. | ||
| 29 | expected = f"{version} at {executable}" | ||
| 30 | self.assertIn(expected, output) | ||
| 38 | 31 | ||
| 39 | class MaturinDevelopTest(OESDKTestCase): | 32 | class MaturinDevelopTest(OESDKTestCase): |
| 40 | @classmethod | ||
| 41 | def setUpClass(self): | ||
| 42 | targetdir = os.path.join(self.tc.sdk_dir, "guessing-game") | ||
| 43 | try: | ||
| 44 | shutil.rmtree(targetdir) | ||
| 45 | except FileNotFoundError: | ||
| 46 | pass | ||
| 47 | shutil.copytree( | ||
| 48 | os.path.join(self.tc.files_dir, "maturin/guessing-game"), targetdir | ||
| 49 | ) | ||
| 50 | |||
| 51 | def setUp(self): | 33 | def setUp(self): |
| 52 | machine = self.td.get("MACHINE") | 34 | machine = self.td.get("MACHINE") |
| 53 | if not ( | 35 | self.ensure_host_package("python3-maturin") |
| 54 | self.tc.hasHostPackage("nativesdk-python3-maturin") | 36 | |
| 55 | or self.tc.hasHostPackage("python3-maturin-native") | ||
| 56 | ): | ||
| 57 | raise unittest.SkipTest("No python3-maturin package in the SDK") | ||
| 58 | if not ( | 37 | if not ( |
| 59 | self.tc.hasHostPackage("packagegroup-rust-cross-canadian-%s" % machine) | 38 | self.tc.hasHostPackage("packagegroup-rust-cross-canadian-%s" % machine) |
| 60 | ): | 39 | ): |
| @@ -68,9 +47,17 @@ class MaturinDevelopTest(OESDKTestCase): | |||
| 68 | (1) that a .venv can been created. | 47 | (1) that a .venv can been created. |
| 69 | (2) a functional 'rustc' and 'cargo' | 48 | (2) a functional 'rustc' and 'cargo' |
| 70 | """ | 49 | """ |
| 71 | self._run("cd %s/guessing-game; python3 -m venv .venv" % self.tc.sdk_dir) | 50 | targetdir = os.path.join(self.tc.sdk_dir, "guessing-game") |
| 72 | cmd = "cd %s/guessing-game; maturin develop" % self.tc.sdk_dir | 51 | try: |
| 73 | output = self._run(cmd) | 52 | shutil.rmtree(targetdir) |
| 53 | except FileNotFoundError: | ||
| 54 | pass | ||
| 55 | shutil.copytree( | ||
| 56 | os.path.join(self.tc.files_dir, "maturin/guessing-game"), targetdir | ||
| 57 | ) | ||
| 58 | |||
| 59 | self._run("cd %s; python3 -m venv .venv" % targetdir) | ||
| 60 | output = self._run("cd %s; maturin develop" % targetdir) | ||
| 74 | self.assertRegex(output, r"🔗 Found pyo3 bindings with abi3 support for Python ≥ 3.8") | 61 | self.assertRegex(output, r"🔗 Found pyo3 bindings with abi3 support for Python ≥ 3.8") |
| 75 | self.assertRegex(output, r"🐍 Not using a specific python interpreter") | 62 | self.assertRegex(output, r"🐍 Not using a specific python interpreter") |
| 76 | self.assertRegex(output, r"📡 Using build options features from pyproject.toml") | 63 | self.assertRegex(output, r"📡 Using build options features from pyproject.toml") |
diff --git a/meta/lib/oeqa/sdk/cases/meson.py b/meta/lib/oeqa/sdk/cases/meson.py new file mode 100644 index 0000000000..a809ca3a53 --- /dev/null +++ b/meta/lib/oeqa/sdk/cases/meson.py | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | # | ||
| 2 | # Copyright OpenEmbedded Contributors | ||
| 3 | # | ||
| 4 | # SPDX-License-Identifier: MIT | ||
| 5 | # | ||
| 6 | |||
| 7 | import json | ||
| 8 | import os | ||
| 9 | import subprocess | ||
| 10 | import tempfile | ||
| 11 | import unittest | ||
| 12 | |||
| 13 | from oeqa.sdk.case import OESDKTestCase | ||
| 14 | from oeqa.sdkext.context import OESDKExtTestContext | ||
| 15 | from oeqa.utils.subprocesstweak import errors_have_output | ||
| 16 | errors_have_output() | ||
| 17 | |||
| 18 | class MesonTestBase(OESDKTestCase): | ||
| 19 | def setUp(self): | ||
| 20 | libc = self.td.get("TCLIBC") | ||
| 21 | if libc in [ 'newlib' ]: | ||
| 22 | raise unittest.SkipTest("MesonTest class: SDK doesn't contain a supported C library") | ||
| 23 | |||
| 24 | if isinstance(self.tc, OESDKExtTestContext): | ||
| 25 | self.skipTest(f"{self.id()} does not support eSDK (https://bugzilla.yoctoproject.org/show_bug.cgi?id=15854)") | ||
| 26 | |||
| 27 | self.ensure_host_package("meson") | ||
| 28 | self.ensure_host_package("pkgconfig") | ||
| 29 | |||
| 30 | def build_meson(self, sourcedir, builddir, installdir=None, options=""): | ||
| 31 | """ | ||
| 32 | Given a source tree in sourcedir, configure it to build in builddir with | ||
| 33 | the specified options, and if installdir is set also install. | ||
| 34 | """ | ||
| 35 | log = self._run(f"meson setup --warnlevel 1 {builddir} {sourcedir} {options}") | ||
| 36 | |||
| 37 | # Check that Meson thinks we're doing a cross build and not a native | ||
| 38 | self.assertIn("Build type: cross build", log) | ||
| 39 | |||
| 40 | # Check that the cross-compiler used is the one we set. | ||
| 41 | data = json.loads(self._run(f"meson introspect --compilers {builddir}")) | ||
| 42 | self.assertIn(self.td.get("CC").split()[0], data["host"]["c"]["exelist"]) | ||
| 43 | |||
| 44 | # Check that the target architectures was set correctly. | ||
| 45 | data = json.loads(self._run(f"meson introspect --machines {builddir}")) | ||
| 46 | self.assertEqual(data["host"]["cpu"], self.td["HOST_ARCH"]) | ||
| 47 | |||
| 48 | self._run(f"meson compile -C {builddir} -v") | ||
| 49 | |||
| 50 | if installdir: | ||
| 51 | self._run(f"meson install -C {builddir} --destdir {installdir}") | ||
| 52 | |||
| 53 | class MesonTest(MesonTestBase): | ||
| 54 | """ | ||
| 55 | Test that Meson builds correctly. | ||
| 56 | """ | ||
| 57 | |||
| 58 | def test_epoxy(self): | ||
| 59 | with tempfile.TemporaryDirectory(prefix="epoxy", dir=self.tc.sdk_dir) as testdir: | ||
| 60 | tarball = self.fetch(testdir, self.td["DL_DIR"], "https://github.com/anholt/libepoxy/releases/download/1.5.3/libepoxy-1.5.3.tar.xz") | ||
| 61 | |||
| 62 | sourcedir = os.path.join(testdir, "libepoxy-1.5.3") | ||
| 63 | builddir = os.path.join(testdir, "build") | ||
| 64 | installdir = os.path.join(testdir, "install") | ||
| 65 | |||
| 66 | subprocess.check_output(["tar", "xf", tarball, "-C", testdir], stderr=subprocess.STDOUT) | ||
| 67 | self.assertTrue(os.path.isdir(sourcedir)) | ||
| 68 | |||
| 69 | os.makedirs(builddir) | ||
| 70 | self.build_meson(sourcedir, builddir, installdir, "-Degl=no -Dglx=no -Dx11=false") | ||
| 71 | self.assertTrue(os.path.isdir(installdir)) | ||
| 72 | self.check_elf(os.path.join(installdir, "usr", "local", "lib", "libepoxy.so")) | ||
diff --git a/meta/lib/oeqa/sdk/cases/perl.py b/meta/lib/oeqa/sdk/cases/perl.py index 8eab4442e8..a72bd2461a 100644 --- a/meta/lib/oeqa/sdk/cases/perl.py +++ b/meta/lib/oeqa/sdk/cases/perl.py | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
| 5 | # | 5 | # |
| 6 | 6 | ||
| 7 | import unittest | ||
| 8 | from oeqa.sdk.case import OESDKTestCase | 7 | from oeqa.sdk.case import OESDKTestCase |
| 9 | 8 | ||
| 10 | from oeqa.utils.subprocesstweak import errors_have_output | 9 | from oeqa.utils.subprocesstweak import errors_have_output |
| @@ -12,9 +11,7 @@ errors_have_output() | |||
| 12 | 11 | ||
| 13 | class PerlTest(OESDKTestCase): | 12 | class PerlTest(OESDKTestCase): |
| 14 | def setUp(self): | 13 | def setUp(self): |
| 15 | if not (self.tc.hasHostPackage("nativesdk-perl") or | 14 | self.ensure_host_package("perl") |
| 16 | self.tc.hasHostPackage("perl-native")): | ||
| 17 | raise unittest.SkipTest("No perl package in the SDK") | ||
| 18 | 15 | ||
| 19 | def test_perl(self): | 16 | def test_perl(self): |
| 20 | cmd = "perl -e '$_=\"Uryyb, jbeyq\"; tr/a-zA-Z/n-za-mN-ZA-M/;print'" | 17 | cmd = "perl -e '$_=\"Uryyb, jbeyq\"; tr/a-zA-Z/n-za-mN-ZA-M/;print'" |
diff --git a/meta/lib/oeqa/sdk/cases/python.py b/meta/lib/oeqa/sdk/cases/python.py index 5ea992b9f3..b990cd889a 100644 --- a/meta/lib/oeqa/sdk/cases/python.py +++ b/meta/lib/oeqa/sdk/cases/python.py | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | # SPDX-License-Identifier: MIT | 4 | # SPDX-License-Identifier: MIT |
| 5 | # | 5 | # |
| 6 | 6 | ||
| 7 | import subprocess, unittest | ||
| 8 | from oeqa.sdk.case import OESDKTestCase | 7 | from oeqa.sdk.case import OESDKTestCase |
| 9 | 8 | ||
| 10 | from oeqa.utils.subprocesstweak import errors_have_output | 9 | from oeqa.utils.subprocesstweak import errors_have_output |
| @@ -12,9 +11,7 @@ errors_have_output() | |||
| 12 | 11 | ||
| 13 | class Python3Test(OESDKTestCase): | 12 | class Python3Test(OESDKTestCase): |
| 14 | def setUp(self): | 13 | def setUp(self): |
| 15 | if not (self.tc.hasHostPackage("nativesdk-python3-core") or | 14 | self.ensure_host_package("python3-core", recipe="python3") |
| 16 | self.tc.hasHostPackage("python3-core-native")): | ||
| 17 | raise unittest.SkipTest("No python3 package in the SDK") | ||
| 18 | 15 | ||
| 19 | def test_python3(self): | 16 | def test_python3(self): |
| 20 | cmd = "python3 -c \"import codecs; print(codecs.encode('Uryyb, jbeyq', 'rot13'))\"" | 17 | cmd = "python3 -c \"import codecs; print(codecs.encode('Uryyb, jbeyq', 'rot13'))\"" |
diff --git a/meta/lib/oeqa/sdk/cases/rust.py b/meta/lib/oeqa/sdk/cases/rust.py index f5d437bb19..4b115bebf5 100644 --- a/meta/lib/oeqa/sdk/cases/rust.py +++ b/meta/lib/oeqa/sdk/cases/rust.py | |||
| @@ -8,7 +8,6 @@ import os | |||
| 8 | import shutil | 8 | import shutil |
| 9 | import unittest | 9 | import unittest |
| 10 | 10 | ||
| 11 | from oeqa.core.utils.path import remove_safe | ||
| 12 | from oeqa.sdk.case import OESDKTestCase | 11 | from oeqa.sdk.case import OESDKTestCase |
| 13 | 12 | ||
| 14 | from oeqa.utils.subprocesstweak import errors_have_output | 13 | from oeqa.utils.subprocesstweak import errors_have_output |
| @@ -32,6 +31,7 @@ class RustCompileTest(OESDKTestCase): | |||
| 32 | raise unittest.SkipTest("RustCompileTest class: SDK doesn't contain a Rust cross-canadian toolchain") | 31 | raise unittest.SkipTest("RustCompileTest class: SDK doesn't contain a Rust cross-canadian toolchain") |
| 33 | 32 | ||
| 34 | def test_cargo_build(self): | 33 | def test_cargo_build(self): |
| 34 | self._run('cd %s/hello; cargo add zstd' % (self.tc.sdk_dir)) | ||
| 35 | self._run('cd %s/hello; cargo build' % self.tc.sdk_dir) | 35 | self._run('cd %s/hello; cargo build' % self.tc.sdk_dir) |
| 36 | 36 | ||
| 37 | class RustHostCompileTest(OESDKTestCase): | 37 | class RustHostCompileTest(OESDKTestCase): |
| @@ -53,5 +53,6 @@ class RustHostCompileTest(OESDKTestCase): | |||
| 53 | 53 | ||
| 54 | def test_cargo_build(self): | 54 | def test_cargo_build(self): |
| 55 | sdksys = self.td.get("SDK_SYS") | 55 | sdksys = self.td.get("SDK_SYS") |
| 56 | self._run('cd %s/hello; cargo add zstd' % (self.tc.sdk_dir)) | ||
| 56 | self._run('cd %s/hello; cargo build --target %s-gnu' % (self.tc.sdk_dir, sdksys)) | 57 | self._run('cd %s/hello; cargo build --target %s-gnu' % (self.tc.sdk_dir, sdksys)) |
| 57 | self._run('cd %s/hello; cargo run --target %s-gnu' % (self.tc.sdk_dir, sdksys)) | 58 | self._run('cd %s/hello; cargo run --target %s-gnu' % (self.tc.sdk_dir, sdksys)) |
diff --git a/meta/lib/oeqa/sdk/context.py b/meta/lib/oeqa/sdk/context.py index 01c38c24e6..d4fdd83207 100644 --- a/meta/lib/oeqa/sdk/context.py +++ b/meta/lib/oeqa/sdk/context.py | |||
| @@ -23,6 +23,13 @@ class OESDKTestContext(OETestContext): | |||
| 23 | self.target_pkg_manifest = target_pkg_manifest | 23 | self.target_pkg_manifest = target_pkg_manifest |
| 24 | self.host_pkg_manifest = host_pkg_manifest | 24 | self.host_pkg_manifest = host_pkg_manifest |
| 25 | 25 | ||
| 26 | # match multilib according to sdk_env | ||
| 27 | self.multilib = "" | ||
| 28 | multilibs = self.td.get('MULTILIB_VARIANTS', '').split() | ||
| 29 | for ml in multilibs: | ||
| 30 | if ml in os.path.basename(self.sdk_env): | ||
| 31 | self.multilib = ml | ||
| 32 | |||
| 26 | def _hasPackage(self, manifest, pkg, regex=False): | 33 | def _hasPackage(self, manifest, pkg, regex=False): |
| 27 | if regex: | 34 | if regex: |
| 28 | # do regex match | 35 | # do regex match |
| @@ -40,12 +47,8 @@ class OESDKTestContext(OETestContext): | |||
| 40 | return self._hasPackage(self.host_pkg_manifest, pkg, regex=regex) | 47 | return self._hasPackage(self.host_pkg_manifest, pkg, regex=regex) |
| 41 | 48 | ||
| 42 | def hasTargetPackage(self, pkg, multilib=False, regex=False): | 49 | def hasTargetPackage(self, pkg, multilib=False, regex=False): |
| 43 | if multilib: | 50 | if multilib and self.multilib: |
| 44 | # match multilib according to sdk_env | 51 | pkg = self.multilib + '-' + pkg |
| 45 | mls = self.td.get('MULTILIB_VARIANTS', '').split() | ||
| 46 | for ml in mls: | ||
| 47 | if ('ml'+ml) in self.sdk_env: | ||
| 48 | pkg = ml + '-' + pkg | ||
| 49 | return self._hasPackage(self.target_pkg_manifest, pkg, regex=regex) | 52 | return self._hasPackage(self.target_pkg_manifest, pkg, regex=regex) |
| 50 | 53 | ||
| 51 | class OESDKTestContextExecutor(OETestContextExecutor): | 54 | class OESDKTestContextExecutor(OETestContextExecutor): |
diff --git a/meta/lib/oeqa/sdk/testsdk.py b/meta/lib/oeqa/sdk/testsdk.py index 518b09febb..cffcf9f49a 100644 --- a/meta/lib/oeqa/sdk/testsdk.py +++ b/meta/lib/oeqa/sdk/testsdk.py | |||
| @@ -31,6 +31,28 @@ class TestSDK(TestSDKBase): | |||
| 31 | context_class = OESDKTestContext | 31 | context_class = OESDKTestContext |
| 32 | test_type = 'sdk' | 32 | test_type = 'sdk' |
| 33 | 33 | ||
| 34 | def sdk_dir_names(self, d): | ||
| 35 | """Return list from TESTSDK_CASE_DIRS.""" | ||
| 36 | testdirs = d.getVar("TESTSDK_CASE_DIRS") | ||
| 37 | if testdirs: | ||
| 38 | return testdirs.split() | ||
| 39 | |||
| 40 | bb.fatal("TESTSDK_CASE_DIRS unset, can't find SDK test directories.") | ||
| 41 | |||
| 42 | def get_sdk_paths(self, d): | ||
| 43 | """ | ||
| 44 | Return a list of paths where SDK test cases reside. | ||
| 45 | |||
| 46 | SDK tests are expected in <LAYER_DIR>/lib/oeqa/<dirname>/cases | ||
| 47 | """ | ||
| 48 | paths = [] | ||
| 49 | for layer in d.getVar("BBLAYERS").split(): | ||
| 50 | for dirname in self.sdk_dir_names(d): | ||
| 51 | case_path = os.path.join(layer, "lib", "oeqa", dirname, "cases") | ||
| 52 | if os.path.isdir(case_path): | ||
| 53 | paths.append(case_path) | ||
| 54 | return paths | ||
| 55 | |||
| 34 | def get_tcname(self, d): | 56 | def get_tcname(self, d): |
| 35 | """ | 57 | """ |
| 36 | Get the name of the SDK file | 58 | Get the name of the SDK file |
| @@ -114,7 +136,8 @@ class TestSDK(TestSDKBase): | |||
| 114 | host_pkg_manifest=host_pkg_manifest, **context_args) | 136 | host_pkg_manifest=host_pkg_manifest, **context_args) |
| 115 | 137 | ||
| 116 | try: | 138 | try: |
| 117 | tc.loadTests(self.context_executor_class.default_cases) | 139 | modules = (d.getVar("TESTSDK_SUITES") or "").split() |
| 140 | tc.loadTests(self.get_sdk_paths(d), modules) | ||
| 118 | except Exception as e: | 141 | except Exception as e: |
| 119 | import traceback | 142 | import traceback |
| 120 | bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) | 143 | bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) |
