diff options
Diffstat (limited to 'meta/lib')
34 files changed, 502 insertions, 217 deletions
diff --git a/meta/lib/bbconfigbuild/configfragments.py b/meta/lib/bbconfigbuild/configfragments.py index c1dddc3e4c..61c33ac316 100644 --- a/meta/lib/bbconfigbuild/configfragments.py +++ b/meta/lib/bbconfigbuild/configfragments.py | |||
@@ -62,7 +62,22 @@ class ConfigFragmentsPlugin(LayerPlugin): | |||
62 | else: | 62 | else: |
63 | print('Name: {}\nPath: {}\nEnabled: {}\nSummary: {}\nDescription:\n{}\n'.format(f['name'], f['path'], 'yes' if is_enabled else 'no', f['summary'],''.join(f['description']))) | 63 | print('Name: {}\nPath: {}\nEnabled: {}\nSummary: {}\nDescription:\n{}\n'.format(f['name'], f['path'], 'yes' if is_enabled else 'no', f['summary'],''.join(f['description']))) |
64 | 64 | ||
65 | def print_builtin_fragments(builtin, enabled): | ||
66 | print('Available built-in fragments:') | ||
67 | builtin_dict = {i[0]:i[1] for i in [f.split(':') for f in builtin]} | ||
68 | for prefix,var in builtin_dict.items(): | ||
69 | print('{}/...\tSets {} = ...'.format(prefix, var)) | ||
70 | print('') | ||
71 | enabled_builtin_fragments = [f for f in enabled if self.builtin_fragment_exists(f)] | ||
72 | print('Enabled built-in fragments:') | ||
73 | for f in enabled_builtin_fragments: | ||
74 | prefix, value = f.split('/', 1) | ||
75 | print('{}\tSets {} = "{}"'.format(f, builtin_dict[prefix], value)) | ||
76 | print('') | ||
77 | |||
65 | all_enabled_fragments = (self.tinfoil.config_data.getVar('OE_FRAGMENTS') or "").split() | 78 | all_enabled_fragments = (self.tinfoil.config_data.getVar('OE_FRAGMENTS') or "").split() |
79 | all_builtin_fragments = (self.tinfoil.config_data.getVar('OE_FRAGMENTS_BUILTIN') or "").split() | ||
80 | print_builtin_fragments(all_builtin_fragments, all_enabled_fragments) | ||
66 | 81 | ||
67 | for layername, layerdata in self.discover_fragments().items(): | 82 | for layername, layerdata in self.discover_fragments().items(): |
68 | layerdir = layerdata['layerdir'] | 83 | layerdir = layerdata['layerdir'] |
@@ -89,6 +104,11 @@ class ConfigFragmentsPlugin(LayerPlugin): | |||
89 | return True | 104 | return True |
90 | return False | 105 | return False |
91 | 106 | ||
107 | def builtin_fragment_exists(self, fragmentname): | ||
108 | fragment_prefix = fragmentname.split("/",1)[0] | ||
109 | fragment_prefix_defs = set([f.split(':')[0] for f in self.tinfoil.config_data.getVar('OE_FRAGMENTS_BUILTIN').split()]) | ||
110 | return fragment_prefix in fragment_prefix_defs | ||
111 | |||
92 | def create_conf(self, confpath): | 112 | def create_conf(self, confpath): |
93 | if not os.path.exists(confpath): | 113 | if not os.path.exists(confpath): |
94 | with open(confpath, 'w') as f: | 114 | with open(confpath, 'w') as f: |
@@ -112,7 +132,7 @@ class ConfigFragmentsPlugin(LayerPlugin): | |||
112 | return " ".join(enabled_fragments), None, 0, True | 132 | return " ".join(enabled_fragments), None, 0, True |
113 | 133 | ||
114 | for f in args.fragmentname: | 134 | for f in args.fragmentname: |
115 | if not self.fragment_exists(f): | 135 | if not self.fragment_exists(f) and not self.builtin_fragment_exists(f): |
116 | raise Exception("Fragment {} does not exist; use 'list-fragments' to see the full list.".format(f)) | 136 | raise Exception("Fragment {} does not exist; use 'list-fragments' to see the full list.".format(f)) |
117 | 137 | ||
118 | self.create_conf(args.confpath) | 138 | self.create_conf(args.confpath) |
diff --git a/meta/lib/oe/__init__.py b/meta/lib/oe/__init__.py index dd094a874a..73de774266 100644 --- a/meta/lib/oe/__init__.py +++ b/meta/lib/oe/__init__.py | |||
@@ -12,4 +12,4 @@ __path__ = extend_path(__path__, __name__) | |||
12 | BBIMPORTS = ["qa", "data", "path", "utils", "types", "package", "packagedata", \ | 12 | BBIMPORTS = ["qa", "data", "path", "utils", "types", "package", "packagedata", \ |
13 | "packagegroup", "sstatesig", "lsb", "cachedpath", "license", "qemu", \ | 13 | "packagegroup", "sstatesig", "lsb", "cachedpath", "license", "qemu", \ |
14 | "reproducible", "rust", "buildcfg", "go", "spdx30_tasks", "spdx_common", \ | 14 | "reproducible", "rust", "buildcfg", "go", "spdx30_tasks", "spdx_common", \ |
15 | "cve_check"] | 15 | "cve_check", "tune"] |
diff --git a/meta/lib/oe/go.py b/meta/lib/oe/go.py index dfd957d157..4559dc63b2 100644 --- a/meta/lib/oe/go.py +++ b/meta/lib/oe/go.py | |||
@@ -7,6 +7,10 @@ | |||
7 | import re | 7 | import re |
8 | 8 | ||
9 | def map_arch(a): | 9 | def map_arch(a): |
10 | """ | ||
11 | Map our architecture names to Go's GOARCH names. | ||
12 | See https://github.com/golang/go/blob/master/src/internal/syslist/syslist.go for the complete list. | ||
13 | """ | ||
10 | if re.match('i.86', a): | 14 | if re.match('i.86', a): |
11 | return '386' | 15 | return '386' |
12 | elif a == 'x86_64': | 16 | elif a == 'x86_64': |
@@ -31,4 +35,4 @@ def map_arch(a): | |||
31 | return 'riscv64' | 35 | return 'riscv64' |
32 | elif a == 'loongarch64': | 36 | elif a == 'loongarch64': |
33 | return 'loong64' | 37 | return 'loong64' |
34 | return '' | 38 | raise KeyError(f"Cannot map architecture {a}") |
diff --git a/meta/lib/oe/license.py b/meta/lib/oe/license.py index 6f882c3812..6e55fa1e7f 100644 --- a/meta/lib/oe/license.py +++ b/meta/lib/oe/license.py | |||
@@ -462,3 +462,18 @@ def skip_incompatible_package_licenses(d, pkgs): | |||
462 | skipped_pkgs[pkg] = incompatible_lic | 462 | skipped_pkgs[pkg] = incompatible_lic |
463 | 463 | ||
464 | return skipped_pkgs | 464 | return skipped_pkgs |
465 | |||
466 | def tidy_licenses(value): | ||
467 | """ | ||
468 | Flat, split and sort licenses. | ||
469 | """ | ||
470 | from oe.license import flattened_licenses | ||
471 | |||
472 | def _choose(a, b): | ||
473 | str_a, str_b = sorted((" & ".join(a), " & ".join(b)), key=str.casefold) | ||
474 | return ["(%s | %s)" % (str_a, str_b)] | ||
475 | |||
476 | if not isinstance(value, str): | ||
477 | value = " & ".join(value) | ||
478 | |||
479 | return sorted(list(set(flattened_licenses(value, _choose))), key=str.casefold) | ||
diff --git a/meta/lib/oe/reproducible.py b/meta/lib/oe/reproducible.py index cdb38d5aa4..0270024a83 100644 --- a/meta/lib/oe/reproducible.py +++ b/meta/lib/oe/reproducible.py | |||
@@ -75,10 +75,11 @@ def get_source_date_epoch_from_known_files(d, sourcedir): | |||
75 | return source_date_epoch | 75 | return source_date_epoch |
76 | 76 | ||
77 | def find_git_folder(d, sourcedir): | 77 | def find_git_folder(d, sourcedir): |
78 | # First guess: UNPACKDIR/git | 78 | # First guess: UNPACKDIR/BB_GIT_DEFAULT_DESTSUFFIX |
79 | # This is the default git fetcher unpack path | 79 | # This is the default git fetcher unpack path |
80 | unpackdir = d.getVar('UNPACKDIR') | 80 | unpackdir = d.getVar('UNPACKDIR') |
81 | gitpath = os.path.join(unpackdir, "git/.git") | 81 | default_destsuffix = d.getVar('BB_GIT_DEFAULT_DESTSUFFIX') |
82 | gitpath = os.path.join(unpackdir, default_destsuffix, ".git") | ||
82 | if os.path.isdir(gitpath): | 83 | if os.path.isdir(gitpath): |
83 | return gitpath | 84 | return gitpath |
84 | 85 | ||
diff --git a/meta/lib/oe/rust.py b/meta/lib/oe/rust.py index 185553eeeb..1dc9cf150d 100644 --- a/meta/lib/oe/rust.py +++ b/meta/lib/oe/rust.py | |||
@@ -8,6 +8,4 @@ | |||
8 | def arch_to_rust_arch(arch): | 8 | def arch_to_rust_arch(arch): |
9 | if arch == "ppc64le": | 9 | if arch == "ppc64le": |
10 | return "powerpc64le" | 10 | return "powerpc64le" |
11 | if arch in ('riscv32', 'riscv64'): | ||
12 | return arch + 'gc' | ||
13 | return arch | 11 | return arch |
diff --git a/meta/lib/oe/spdx30_tasks.py b/meta/lib/oe/spdx30_tasks.py index 61d7ba45e3..5d9f3168d9 100644 --- a/meta/lib/oe/spdx30_tasks.py +++ b/meta/lib/oe/spdx30_tasks.py | |||
@@ -156,6 +156,11 @@ def add_package_files( | |||
156 | bb.note(f"Skip {topdir}") | 156 | bb.note(f"Skip {topdir}") |
157 | return spdx_files | 157 | return spdx_files |
158 | 158 | ||
159 | check_compiled_sources = d.getVar("SPDX_INCLUDE_COMPILED_SOURCES") == "1" | ||
160 | if check_compiled_sources: | ||
161 | compiled_sources, types = oe.spdx_common.get_compiled_sources(d) | ||
162 | bb.debug(1, f"Total compiled files: {len(compiled_sources)}") | ||
163 | |||
159 | for subdir, dirs, files in os.walk(topdir, onerror=walk_error): | 164 | for subdir, dirs, files in os.walk(topdir, onerror=walk_error): |
160 | dirs[:] = [d for d in dirs if d not in ignore_dirs] | 165 | dirs[:] = [d for d in dirs if d not in ignore_dirs] |
161 | if subdir == str(topdir): | 166 | if subdir == str(topdir): |
@@ -171,6 +176,11 @@ def add_package_files( | |||
171 | filename = str(filepath.relative_to(topdir)) | 176 | filename = str(filepath.relative_to(topdir)) |
172 | file_purposes = get_purposes(filepath) | 177 | file_purposes = get_purposes(filepath) |
173 | 178 | ||
179 | # Check if file is compiled | ||
180 | if check_compiled_sources: | ||
181 | if not oe.spdx_common.is_compiled_source(filename, compiled_sources, types): | ||
182 | continue | ||
183 | |||
174 | spdx_file = objset.new_file( | 184 | spdx_file = objset.new_file( |
175 | get_spdxid(file_counter), | 185 | get_spdxid(file_counter), |
176 | filename, | 186 | filename, |
@@ -542,7 +552,7 @@ def create_spdx(d): | |||
542 | ) | 552 | ) |
543 | build_objset.new_relationship( | 553 | build_objset.new_relationship( |
544 | source_files, | 554 | source_files, |
545 | oe.spdx30.RelationshipType.hasConcludedLicense, | 555 | oe.spdx30.RelationshipType.hasDeclaredLicense, |
546 | [oe.sbom30.get_element_link_id(recipe_spdx_license)], | 556 | [oe.sbom30.get_element_link_id(recipe_spdx_license)], |
547 | ) | 557 | ) |
548 | 558 | ||
diff --git a/meta/lib/oe/spdx_common.py b/meta/lib/oe/spdx_common.py index 4caefc7673..c2dec65563 100644 --- a/meta/lib/oe/spdx_common.py +++ b/meta/lib/oe/spdx_common.py | |||
@@ -242,3 +242,44 @@ def fetch_data_to_uri(fd, name): | |||
242 | uri = uri + "@" + fd.revision | 242 | uri = uri + "@" + fd.revision |
243 | 243 | ||
244 | return uri | 244 | return uri |
245 | |||
246 | def is_compiled_source (filename, compiled_sources, types): | ||
247 | """ | ||
248 | Check if the file is a compiled file | ||
249 | """ | ||
250 | import os | ||
251 | # If we don't have compiled source, we assume all are compiled. | ||
252 | if not compiled_sources: | ||
253 | return True | ||
254 | |||
255 | # We return always true if the file type is not in the list of compiled files. | ||
256 | # Some files in the source directory are not compiled, for example, Makefiles, | ||
257 | # but also python .py file. We need to include them in the SPDX. | ||
258 | basename = os.path.basename(filename) | ||
259 | ext = basename.partition(".")[2] | ||
260 | if ext not in types: | ||
261 | return True | ||
262 | # Check that the file is in the list | ||
263 | return filename in compiled_sources | ||
264 | |||
265 | def get_compiled_sources(d): | ||
266 | """ | ||
267 | Get list of compiled sources from debug information and normalize the paths | ||
268 | """ | ||
269 | import itertools | ||
270 | source_info = oe.package.read_debugsources_info(d) | ||
271 | if not source_info: | ||
272 | bb.debug(1, "Do not have debugsources.list. Skipping") | ||
273 | return [], [] | ||
274 | |||
275 | # Sources are not split now in SPDX, so we aggregate them | ||
276 | sources = set(itertools.chain.from_iterable(source_info.values())) | ||
277 | # Check extensions of files | ||
278 | types = set() | ||
279 | for src in sources: | ||
280 | basename = os.path.basename(src) | ||
281 | ext = basename.partition(".")[2] | ||
282 | if ext not in types and ext: | ||
283 | types.add(ext) | ||
284 | bb.debug(1, f"Num of sources: {len(sources)} and types: {len(types)} {str(types)}") | ||
285 | return sources, types | ||
diff --git a/meta/lib/oe/tune.py b/meta/lib/oe/tune.py new file mode 100644 index 0000000000..7fda19430d --- /dev/null +++ b/meta/lib/oe/tune.py | |||
@@ -0,0 +1,81 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: GPL-2.0-only | ||
5 | # | ||
6 | |||
7 | # riscv_isa_to_tune(isa) | ||
8 | # | ||
9 | # Automatically translate a RISC-V ISA string to TUNE_FEATURES | ||
10 | # | ||
11 | # Abbreviations, such as rv32g -> rv32imaffd_zicsr_zifencei are supported. | ||
12 | # | ||
13 | # Profiles, such as rva22u64, are NOT supported, you must use ISA strings. | ||
14 | # | ||
15 | def riscv_isa_to_tune(isa): | ||
16 | _isa = isa.lower() | ||
17 | |||
18 | feature = [] | ||
19 | iter = 0 | ||
20 | |||
21 | # rv or riscv | ||
22 | if _isa[iter:].startswith('rv'): | ||
23 | feature.append('rv') | ||
24 | iter = iter + 2 | ||
25 | elif _isa[iter:].startswith('riscv'): | ||
26 | feature.append('rv') | ||
27 | iter = iter + 5 | ||
28 | else: | ||
29 | # Not a risc-v ISA! | ||
30 | return _isa | ||
31 | |||
32 | while (_isa[iter:]): | ||
33 | # Skip _ and whitespace | ||
34 | if _isa[iter] == '_' or _isa[iter].isspace(): | ||
35 | iter = iter + 1 | ||
36 | continue | ||
37 | |||
38 | # Length, just capture numbers here | ||
39 | if _isa[iter].isdigit(): | ||
40 | iter_end = iter | ||
41 | while iter_end < len(_isa) and _isa[iter_end].isdigit(): | ||
42 | iter_end = iter_end + 1 | ||
43 | |||
44 | feature.append(_isa[iter:iter_end]) | ||
45 | iter = iter_end | ||
46 | continue | ||
47 | |||
48 | # Typically i, e or g is next, followed by extensions. | ||
49 | # Extensions are single character, except for Z, Ss, Sh, Sm, Sv, and X | ||
50 | |||
51 | # If the extension starts with 'Z', 'S' or 'X' use the name until the next _, whitespace or end | ||
52 | if _isa[iter] in ['z', 's', 'x']: | ||
53 | ext_type = _isa[iter] | ||
54 | iter_end = iter + 1 | ||
55 | |||
56 | # Multicharacter extension, these are supposed to have a _ before the next multicharacter extension | ||
57 | # See 37.4 and 37.5: | ||
58 | # 37.4: Underscores "_" may be used to separate ISA extensions... | ||
59 | # 37.5: All multi-letter extensions ... must be separated from other multi-letter extensions by an underscore... | ||
60 | # Some extensions permit only alphabetic characters, while others allow alphanumeric chartacters | ||
61 | while iter_end < len(_isa) and _isa[iter_end] != "_" and not _isa[iter_end].isspace(): | ||
62 | iter_end = iter_end + 1 | ||
63 | |||
64 | feature.append(_isa[iter:iter_end]) | ||
65 | iter = iter_end | ||
66 | continue | ||
67 | |||
68 | # 'g' is special, it's an abbreviation for imafd_zicsr_zifencei | ||
69 | # When expanding the abbreviation, any additional letters must appear before the _z* extensions | ||
70 | if _isa[iter] == 'g': | ||
71 | _isa = 'imafd' + _isa[iter+1:] + '_zicsr_zifencei' | ||
72 | iter = 0 | ||
73 | continue | ||
74 | |||
75 | feature.append(_isa[iter]) | ||
76 | iter = iter + 1 | ||
77 | continue | ||
78 | |||
79 | # Eliminate duplicates, but preserve the order | ||
80 | feature = list(dict.fromkeys(feature)) | ||
81 | return ' '.join(feature) | ||
diff --git a/meta/lib/oeqa/sdk/buildtools-docs-cases/README b/meta/lib/oeqa/buildtools-docs/cases/README index f8edbc7dad..f8edbc7dad 100644 --- a/meta/lib/oeqa/sdk/buildtools-docs-cases/README +++ b/meta/lib/oeqa/buildtools-docs/cases/README | |||
diff --git a/meta/lib/oeqa/sdk/buildtools-docs-cases/build.py b/meta/lib/oeqa/buildtools-docs/cases/build.py index 6e3ee94292..6e3ee94292 100644 --- a/meta/lib/oeqa/sdk/buildtools-docs-cases/build.py +++ b/meta/lib/oeqa/buildtools-docs/cases/build.py | |||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/README b/meta/lib/oeqa/buildtools/cases/README index d4f20faa9f..d4f20faa9f 100644 --- a/meta/lib/oeqa/sdk/buildtools-cases/README +++ b/meta/lib/oeqa/buildtools/cases/README | |||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/build.py b/meta/lib/oeqa/buildtools/cases/build.py index c85c32496b..c85c32496b 100644 --- a/meta/lib/oeqa/sdk/buildtools-cases/build.py +++ b/meta/lib/oeqa/buildtools/cases/build.py | |||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/gcc.py b/meta/lib/oeqa/buildtools/cases/gcc.py index a62c4d0bc4..a62c4d0bc4 100644 --- a/meta/lib/oeqa/sdk/buildtools-cases/gcc.py +++ b/meta/lib/oeqa/buildtools/cases/gcc.py | |||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/https.py b/meta/lib/oeqa/buildtools/cases/https.py index 4525e3d758..4525e3d758 100644 --- a/meta/lib/oeqa/sdk/buildtools-cases/https.py +++ b/meta/lib/oeqa/buildtools/cases/https.py | |||
diff --git a/meta/lib/oeqa/sdk/buildtools-cases/sanity.py b/meta/lib/oeqa/buildtools/cases/sanity.py index a55d456656..a55d456656 100644 --- a/meta/lib/oeqa/sdk/buildtools-cases/sanity.py +++ b/meta/lib/oeqa/buildtools/cases/sanity.py | |||
diff --git a/meta/lib/oeqa/core/case.py b/meta/lib/oeqa/core/case.py index bc4446a938..ad5524a714 100644 --- a/meta/lib/oeqa/core/case.py +++ b/meta/lib/oeqa/core/case.py | |||
@@ -5,6 +5,7 @@ | |||
5 | # | 5 | # |
6 | 6 | ||
7 | import base64 | 7 | import base64 |
8 | import os | ||
8 | import zlib | 9 | import zlib |
9 | import unittest | 10 | import unittest |
10 | 11 | ||
@@ -57,6 +58,13 @@ class OETestCase(unittest.TestCase): | |||
57 | d.tearDownDecorator() | 58 | d.tearDownDecorator() |
58 | self.tearDownMethod() | 59 | self.tearDownMethod() |
59 | 60 | ||
61 | def assertFileExists(self, filename, msg=None): | ||
62 | """ | ||
63 | Test that filename exists. If it does not, the test will fail. | ||
64 | """ | ||
65 | if not os.path.exists(filename): | ||
66 | self.fail(msg or "%s does not exist" % filename) | ||
67 | |||
60 | class OEPTestResultTestCase: | 68 | class OEPTestResultTestCase: |
61 | """ | 69 | """ |
62 | Mix-in class to provide functions to make interacting with extraresults for | 70 | Mix-in class to provide functions to make interacting with extraresults for |
diff --git a/meta/lib/oeqa/runtime/cases/ethernet_ip_connman.py b/meta/lib/oeqa/runtime/cases/ethernet_ip_connman.py index 4e671ec0cc..c3be60f006 100644 --- a/meta/lib/oeqa/runtime/cases/ethernet_ip_connman.py +++ b/meta/lib/oeqa/runtime/cases/ethernet_ip_connman.py | |||
@@ -10,7 +10,6 @@ from oeqa.core.decorator.data import skipIfQemu | |||
10 | class Ethernet_Test(OERuntimeTestCase): | 10 | class Ethernet_Test(OERuntimeTestCase): |
11 | 11 | ||
12 | @skipIfQemu() | 12 | @skipIfQemu() |
13 | @OETestDepends(['ethernet_ip_connman.Ethernet_Test.test_set_virtual_ip']) | ||
14 | def test_get_ip_from_dhcp(self): | 13 | def test_get_ip_from_dhcp(self): |
15 | (status, output) = self.target.run("connmanctl services | grep -E '*AO Wired|*AR Wired' | awk '{print $3}'") | 14 | (status, output) = self.target.run("connmanctl services | grep -E '*AO Wired|*AR Wired' | awk '{print $3}'") |
16 | self.assertEqual(status, 0, msg='No wired interfaces are detected, output: %s' % output) | 15 | self.assertEqual(status, 0, msg='No wired interfaces are detected, output: %s' % output) |
diff --git a/meta/lib/oeqa/runtime/cases/stap.py b/meta/lib/oeqa/runtime/cases/stap.py index 3be4162108..6b55e7de50 100644 --- a/meta/lib/oeqa/runtime/cases/stap.py +++ b/meta/lib/oeqa/runtime/cases/stap.py | |||
@@ -21,11 +21,12 @@ class StapTest(OERuntimeTestCase): | |||
21 | status, output = self.target.run(cmd, 900) | 21 | status, output = self.target.run(cmd, 900) |
22 | self.assertEqual(status, 0, msg='\n'.join([cmd, output])) | 22 | self.assertEqual(status, 0, msg='\n'.join([cmd, output])) |
23 | 23 | ||
24 | cmd = 'stap -v -p4 -m stap-hello --disable-cache -DSTP_NO_VERREL_CHECK -e \'probe oneshot { print("Hello, "); println("SystemTap!") }\'' | 24 | cmd = 'stap -v -p4 -m stap_hello --disable-cache -DSTP_NO_VERREL_CHECK -e \'probe oneshot { print("Hello, "); println("SystemTap!") }\'' |
25 | status, output = self.target.run(cmd, 900) | 25 | status, output = self.target.run(cmd, 900) |
26 | self.assertEqual(status, 0, msg='\n'.join([cmd, output])) | 26 | self.assertEqual(status, 0, msg='\n'.join([cmd, output])) |
27 | 27 | ||
28 | cmd = 'staprun -v -R -b1 stap-hello.ko' | 28 | cmd = 'staprun -v -R -b1 stap_hello.ko' |
29 | status, output = self.target.run(cmd, 60) | ||
29 | self.assertEqual(status, 0, msg='\n'.join([cmd, output])) | 30 | self.assertEqual(status, 0, msg='\n'.join([cmd, output])) |
30 | self.assertIn('Hello, SystemTap!', output, msg='\n'.join([cmd, output])) | 31 | self.assertIn('Hello, SystemTap!', output, msg='\n'.join([cmd, output])) |
31 | except: | 32 | except: |
diff --git a/meta/lib/oeqa/sdk/testsdk.py b/meta/lib/oeqa/sdk/testsdk.py index 52b702b6a2..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 |
@@ -115,7 +137,7 @@ class TestSDK(TestSDKBase): | |||
115 | 137 | ||
116 | try: | 138 | try: |
117 | modules = (d.getVar("TESTSDK_SUITES") or "").split() | 139 | modules = (d.getVar("TESTSDK_SUITES") or "").split() |
118 | tc.loadTests(self.context_executor_class.default_cases, modules) | 140 | tc.loadTests(self.get_sdk_paths(d), modules) |
119 | except Exception as e: | 141 | except Exception as e: |
120 | import traceback | 142 | import traceback |
121 | bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) | 143 | bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) |
diff --git a/meta/lib/oeqa/selftest/cases/buildhistory.py b/meta/lib/oeqa/selftest/cases/buildhistory.py index 2d55994916..511c666554 100644 --- a/meta/lib/oeqa/selftest/cases/buildhistory.py +++ b/meta/lib/oeqa/selftest/cases/buildhistory.py | |||
@@ -9,10 +9,10 @@ import re | |||
9 | import datetime | 9 | import datetime |
10 | 10 | ||
11 | from oeqa.selftest.case import OESelftestTestCase | 11 | from oeqa.selftest.case import OESelftestTestCase |
12 | from oeqa.utils.commands import bitbake, get_bb_vars | 12 | from oeqa.utils.commands import bitbake, get_bb_vars, get_bb_var, runCmd |
13 | 13 | ||
14 | 14 | ||
15 | class BuildhistoryBase(OESelftestTestCase): | 15 | class BuildhistoryTests(OESelftestTestCase): |
16 | 16 | ||
17 | def config_buildhistory(self, tmp_bh_location=False): | 17 | def config_buildhistory(self, tmp_bh_location=False): |
18 | bb_vars = get_bb_vars(['USER_CLASSES', 'INHERIT']) | 18 | bb_vars = get_bb_vars(['USER_CLASSES', 'INHERIT']) |
@@ -48,5 +48,58 @@ class BuildhistoryBase(OESelftestTestCase): | |||
48 | else: | 48 | else: |
49 | self.assertEqual(result.status, 0, msg="Command 'bitbake %s' has failed unexpectedly: %s" % (target, result.output)) | 49 | self.assertEqual(result.status, 0, msg="Command 'bitbake %s' has failed unexpectedly: %s" % (target, result.output)) |
50 | 50 | ||
51 | # No tests should be added to the base class. | 51 | |
52 | # Please create a new class that inherit this one, or use one of those already available for adding tests. | 52 | def test_buildhistory_basic(self): |
53 | self.run_buildhistory_operation('xcursor-transparent-theme') | ||
54 | self.assertTrue(os.path.isdir(get_bb_var('BUILDHISTORY_DIR')), "buildhistory dir was not created.") | ||
55 | |||
56 | def test_buildhistory_buildtime_pr_backwards(self): | ||
57 | target = 'xcursor-transparent-theme' | ||
58 | error = "ERROR:.*QA Issue: Package version for package %s went backwards which would break package feeds \(from .*-r1.* to .*-r0.*\)" % target | ||
59 | self.run_buildhistory_operation(target, target_config="PR = \"r1\"", change_bh_location=True) | ||
60 | self.run_buildhistory_operation(target, target_config="PR = \"r0\"", change_bh_location=False, expect_error=True, error_regex=error) | ||
61 | |||
62 | def test_fileinfo(self): | ||
63 | self.config_buildhistory() | ||
64 | bitbake('hicolor-icon-theme') | ||
65 | history_dir = get_bb_var('BUILDHISTORY_DIR_PACKAGE', 'hicolor-icon-theme') | ||
66 | self.assertTrue(os.path.isdir(history_dir), 'buildhistory dir was not created.') | ||
67 | |||
68 | def load_bh(f): | ||
69 | d = {} | ||
70 | for line in open(f): | ||
71 | split = [s.strip() for s in line.split('=', 1)] | ||
72 | if len(split) > 1: | ||
73 | d[split[0]] = split[1] | ||
74 | return d | ||
75 | |||
76 | data = load_bh(os.path.join(history_dir, 'hicolor-icon-theme', 'latest')) | ||
77 | self.assertIn('FILELIST', data) | ||
78 | self.assertEqual(data['FILELIST'], '/usr/share/icons/hicolor/index.theme') | ||
79 | self.assertGreater(int(data['PKGSIZE']), 0) | ||
80 | |||
81 | data = load_bh(os.path.join(history_dir, 'hicolor-icon-theme-dev', 'latest')) | ||
82 | if 'FILELIST' in data: | ||
83 | self.assertEqual(data['FILELIST'], '/usr/share/pkgconfig/default-icon-theme.pc') | ||
84 | self.assertGreater(int(data['PKGSIZE']), 0) | ||
85 | |||
86 | def test_buildhistory_diff(self): | ||
87 | target = 'xcursor-transparent-theme' | ||
88 | self.run_buildhistory_operation(target, target_config="PR = \"r1\"", change_bh_location=True) | ||
89 | self.run_buildhistory_operation(target, target_config="PR = \"r0\"", change_bh_location=False, expect_error=True) | ||
90 | result = runCmd("oe-pkgdata-util read-value PKGV %s" % target) | ||
91 | pkgv = result.output.rstrip() | ||
92 | result = runCmd("buildhistory-diff -p %s" % get_bb_var('BUILDHISTORY_DIR')) | ||
93 | expected_endlines = [ | ||
94 | "xcursor-transparent-theme-dev: RRECOMMENDS: removed \"xcursor-transparent-theme (['= %s-r1'])\", added \"xcursor-transparent-theme (['= %s-r0'])\"" % (pkgv, pkgv), | ||
95 | "xcursor-transparent-theme-staticdev: RDEPENDS: removed \"xcursor-transparent-theme-dev (['= %s-r1'])\", added \"xcursor-transparent-theme-dev (['= %s-r0'])\"" % (pkgv, pkgv) | ||
96 | ] | ||
97 | for line in result.output.splitlines(): | ||
98 | for el in expected_endlines: | ||
99 | if line.endswith(el): | ||
100 | expected_endlines.remove(el) | ||
101 | break | ||
102 | else: | ||
103 | self.fail('Unexpected line:\n%s\nExpected line endings:\n %s' % (line, '\n '.join(expected_endlines))) | ||
104 | if expected_endlines: | ||
105 | self.fail('Missing expected line endings:\n %s' % '\n '.join(expected_endlines)) \ No newline at end of file | ||
diff --git a/meta/lib/oeqa/selftest/cases/buildoptions.py b/meta/lib/oeqa/selftest/cases/buildoptions.py index b509bcf951..767e19bd88 100644 --- a/meta/lib/oeqa/selftest/cases/buildoptions.py +++ b/meta/lib/oeqa/selftest/cases/buildoptions.py | |||
@@ -10,7 +10,6 @@ import glob as g | |||
10 | import shutil | 10 | import shutil |
11 | import tempfile | 11 | import tempfile |
12 | from oeqa.selftest.case import OESelftestTestCase | 12 | from oeqa.selftest.case import OESelftestTestCase |
13 | from oeqa.selftest.cases.buildhistory import BuildhistoryBase | ||
14 | from oeqa.core.decorator.data import skipIfMachine | 13 | from oeqa.core.decorator.data import skipIfMachine |
15 | from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars | 14 | from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars |
16 | import oeqa.utils.ftools as ftools | 15 | import oeqa.utils.ftools as ftools |
@@ -139,43 +138,6 @@ class SanityOptionsTest(OESelftestTestCase): | |||
139 | 138 | ||
140 | self.assertNotIn(err, ret.output) | 139 | self.assertNotIn(err, ret.output) |
141 | 140 | ||
142 | |||
143 | class BuildhistoryTests(BuildhistoryBase): | ||
144 | |||
145 | def test_buildhistory_basic(self): | ||
146 | self.run_buildhistory_operation('xcursor-transparent-theme') | ||
147 | self.assertTrue(os.path.isdir(get_bb_var('BUILDHISTORY_DIR')), "buildhistory dir was not created.") | ||
148 | |||
149 | def test_buildhistory_buildtime_pr_backwards(self): | ||
150 | target = 'xcursor-transparent-theme' | ||
151 | error = "ERROR:.*QA Issue: Package version for package %s went backwards which would break package feeds \(from .*-r1.* to .*-r0.*\)" % target | ||
152 | self.run_buildhistory_operation(target, target_config="PR = \"r1\"", change_bh_location=True) | ||
153 | self.run_buildhistory_operation(target, target_config="PR = \"r0\"", change_bh_location=False, expect_error=True, error_regex=error) | ||
154 | |||
155 | def test_fileinfo(self): | ||
156 | self.config_buildhistory() | ||
157 | bitbake('hicolor-icon-theme') | ||
158 | history_dir = get_bb_var('BUILDHISTORY_DIR_PACKAGE', 'hicolor-icon-theme') | ||
159 | self.assertTrue(os.path.isdir(history_dir), 'buildhistory dir was not created.') | ||
160 | |||
161 | def load_bh(f): | ||
162 | d = {} | ||
163 | for line in open(f): | ||
164 | split = [s.strip() for s in line.split('=', 1)] | ||
165 | if len(split) > 1: | ||
166 | d[split[0]] = split[1] | ||
167 | return d | ||
168 | |||
169 | data = load_bh(os.path.join(history_dir, 'hicolor-icon-theme', 'latest')) | ||
170 | self.assertIn('FILELIST', data) | ||
171 | self.assertEqual(data['FILELIST'], '/usr/share/icons/hicolor/index.theme') | ||
172 | self.assertGreater(int(data['PKGSIZE']), 0) | ||
173 | |||
174 | data = load_bh(os.path.join(history_dir, 'hicolor-icon-theme-dev', 'latest')) | ||
175 | if 'FILELIST' in data: | ||
176 | self.assertEqual(data['FILELIST'], '/usr/share/pkgconfig/default-icon-theme.pc') | ||
177 | self.assertGreater(int(data['PKGSIZE']), 0) | ||
178 | |||
179 | class ArchiverTest(OESelftestTestCase): | 141 | class ArchiverTest(OESelftestTestCase): |
180 | def test_arch_work_dir_and_export_source(self): | 142 | def test_arch_work_dir_and_export_source(self): |
181 | """ | 143 | """ |
diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 0155ee62ee..05f228f03e 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py | |||
@@ -154,7 +154,7 @@ class DevtoolTestCase(OESelftestTestCase): | |||
154 | value = invalue | 154 | value = invalue |
155 | invar = None | 155 | invar = None |
156 | elif '=' in line: | 156 | elif '=' in line: |
157 | splitline = line.split('=', 1) | 157 | splitline = re.split(r"[?+:]*=[+]?", line, 1) |
158 | var = splitline[0].rstrip() | 158 | var = splitline[0].rstrip() |
159 | value = splitline[1].strip().strip('"') | 159 | value = splitline[1].strip().strip('"') |
160 | if value.endswith('\\'): | 160 | if value.endswith('\\'): |
@@ -469,7 +469,7 @@ class DevtoolAddTests(DevtoolBase): | |||
469 | checkvars = {} | 469 | checkvars = {} |
470 | checkvars['LICENSE'] = 'GPL-2.0-only' | 470 | checkvars['LICENSE'] = 'GPL-2.0-only' |
471 | checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263' | 471 | checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263' |
472 | checkvars['S'] = '${WORKDIR}/git' | 472 | checkvars['S'] = None |
473 | checkvars['PV'] = '0.1+git' | 473 | checkvars['PV'] = '0.1+git' |
474 | checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/dbus-wait;protocol=https;branch=master' | 474 | checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/dbus-wait;protocol=https;branch=master' |
475 | checkvars['SRCREV'] = srcrev | 475 | checkvars['SRCREV'] = srcrev |
@@ -565,7 +565,7 @@ class DevtoolAddTests(DevtoolBase): | |||
565 | recipefile = get_bb_var('FILE', testrecipe) | 565 | recipefile = get_bb_var('FILE', testrecipe) |
566 | self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named') | 566 | self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named') |
567 | checkvars = {} | 567 | checkvars = {} |
568 | checkvars['S'] = '${WORKDIR}/MarkupSafe-${PV}' | 568 | checkvars['S'] = '${UNPACKDIR}/MarkupSafe-${PV}' |
569 | checkvars['SRC_URI'] = url.replace(testver, '${PV}') | 569 | checkvars['SRC_URI'] = url.replace(testver, '${PV}') |
570 | self._test_recipe_contents(recipefile, checkvars, []) | 570 | self._test_recipe_contents(recipefile, checkvars, []) |
571 | # Try with version specified | 571 | # Try with version specified |
@@ -582,7 +582,7 @@ class DevtoolAddTests(DevtoolBase): | |||
582 | recipefile = get_bb_var('FILE', testrecipe) | 582 | recipefile = get_bb_var('FILE', testrecipe) |
583 | self.assertIn('%s_%s.bb' % (testrecipe, fakever), recipefile, 'Recipe file incorrectly named') | 583 | self.assertIn('%s_%s.bb' % (testrecipe, fakever), recipefile, 'Recipe file incorrectly named') |
584 | checkvars = {} | 584 | checkvars = {} |
585 | checkvars['S'] = '${WORKDIR}/MarkupSafe-%s' % testver | 585 | checkvars['S'] = '${UNPACKDIR}/MarkupSafe-%s' % testver |
586 | checkvars['SRC_URI'] = url | 586 | checkvars['SRC_URI'] = url |
587 | self._test_recipe_contents(recipefile, checkvars, []) | 587 | self._test_recipe_contents(recipefile, checkvars, []) |
588 | 588 | ||
@@ -609,7 +609,7 @@ class DevtoolAddTests(DevtoolBase): | |||
609 | recipefile = get_bb_var('FILE', testrecipe) | 609 | recipefile = get_bb_var('FILE', testrecipe) |
610 | self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named') | 610 | self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named') |
611 | checkvars = {} | 611 | checkvars = {} |
612 | checkvars['S'] = '${WORKDIR}/git' | 612 | checkvars['S'] = None |
613 | checkvars['PV'] = '1.0+git' | 613 | checkvars['PV'] = '1.0+git' |
614 | checkvars['SRC_URI'] = url_branch | 614 | checkvars['SRC_URI'] = url_branch |
615 | checkvars['SRCREV'] = '${AUTOREV}' | 615 | checkvars['SRCREV'] = '${AUTOREV}' |
@@ -628,7 +628,7 @@ class DevtoolAddTests(DevtoolBase): | |||
628 | recipefile = get_bb_var('FILE', testrecipe) | 628 | recipefile = get_bb_var('FILE', testrecipe) |
629 | self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named') | 629 | self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named') |
630 | checkvars = {} | 630 | checkvars = {} |
631 | checkvars['S'] = '${WORKDIR}/git' | 631 | checkvars['S'] = None |
632 | checkvars['PV'] = '1.5+git' | 632 | checkvars['PV'] = '1.5+git' |
633 | checkvars['SRC_URI'] = url_branch | 633 | checkvars['SRC_URI'] = url_branch |
634 | checkvars['SRCREV'] = checkrev | 634 | checkvars['SRCREV'] = checkrev |
@@ -1627,12 +1627,12 @@ class DevtoolUpdateTests(DevtoolBase): | |||
1627 | # Check preconditions | 1627 | # Check preconditions |
1628 | testrecipe = 'dos2unix' | 1628 | testrecipe = 'dos2unix' |
1629 | self.append_config('ERROR_QA:remove:pn-dos2unix = "patch-status"\n') | 1629 | self.append_config('ERROR_QA:remove:pn-dos2unix = "patch-status"\n') |
1630 | bb_vars = get_bb_vars(['SRC_URI', 'S', 'WORKDIR', 'FILE'], testrecipe) | 1630 | bb_vars = get_bb_vars(['SRC_URI', 'S', 'UNPACKDIR', 'FILE', 'BB_GIT_DEFAULT_DESTSUFFIX'], testrecipe) |
1631 | self.assertIn('git://', bb_vars['SRC_URI'], 'This test expects the %s recipe to be a git recipe' % testrecipe) | 1631 | self.assertIn('git://', bb_vars['SRC_URI'], 'This test expects the %s recipe to be a git recipe' % testrecipe) |
1632 | workdir_git = '%s/git/' % bb_vars['WORKDIR'] | 1632 | unpackdir_git = '%s/%s/' % (bb_vars['UNPACKDIR'], bb_vars['BB_GIT_DEFAULT_DESTSUFFIX']) |
1633 | if not bb_vars['S'].startswith(workdir_git): | 1633 | if not bb_vars['S'].startswith(unpackdir_git): |
1634 | self.fail('This test expects the %s recipe to be building from a subdirectory of the git repo' % testrecipe) | 1634 | self.fail('This test expects the %s recipe to be building from a subdirectory of the git repo' % testrecipe) |
1635 | subdir = bb_vars['S'].split(workdir_git, 1)[1] | 1635 | subdir = bb_vars['S'].split(unpackdir_git, 1)[1] |
1636 | # Clean up anything in the workdir/sysroot/sstate cache | 1636 | # Clean up anything in the workdir/sysroot/sstate cache |
1637 | bitbake('%s -c cleansstate' % testrecipe) | 1637 | bitbake('%s -c cleansstate' % testrecipe) |
1638 | # Try modifying a recipe | 1638 | # Try modifying a recipe |
@@ -2414,7 +2414,7 @@ class DevtoolUpgradeTests(DevtoolBase): | |||
2414 | newsrctree = os.path.join(self.workspacedir, 'sources', newrecipename) | 2414 | newsrctree = os.path.join(self.workspacedir, 'sources', newrecipename) |
2415 | self.assertExists(newsrctree, 'Source directory not renamed') | 2415 | self.assertExists(newsrctree, 'Source directory not renamed') |
2416 | checkvars = {} | 2416 | checkvars = {} |
2417 | checkvars['S'] = '${WORKDIR}/%s-%s' % (recipename, recipever) | 2417 | checkvars['S'] = '${UNPACKDIR}/%s-%s' % (recipename, recipever) |
2418 | checkvars['SRC_URI'] = url | 2418 | checkvars['SRC_URI'] = url |
2419 | self._test_recipe_contents(newrecipefile, checkvars, []) | 2419 | self._test_recipe_contents(newrecipefile, checkvars, []) |
2420 | # Try again - change just name this time | 2420 | # Try again - change just name this time |
@@ -2426,7 +2426,7 @@ class DevtoolUpgradeTests(DevtoolBase): | |||
2426 | self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipename), 'Old recipe directory still exists') | 2426 | self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipename), 'Old recipe directory still exists') |
2427 | self.assertExists(os.path.join(self.workspacedir, 'sources', newrecipename), 'Source directory not renamed') | 2427 | self.assertExists(os.path.join(self.workspacedir, 'sources', newrecipename), 'Source directory not renamed') |
2428 | checkvars = {} | 2428 | checkvars = {} |
2429 | checkvars['S'] = '${WORKDIR}/%s-${PV}' % recipename | 2429 | checkvars['S'] = '${UNPACKDIR}/%s-${PV}' % recipename |
2430 | checkvars['SRC_URI'] = url.replace(recipever, '${PV}') | 2430 | checkvars['SRC_URI'] = url.replace(recipever, '${PV}') |
2431 | self._test_recipe_contents(newrecipefile, checkvars, []) | 2431 | self._test_recipe_contents(newrecipefile, checkvars, []) |
2432 | # Try again - change just version this time | 2432 | # Try again - change just version this time |
@@ -2437,7 +2437,7 @@ class DevtoolUpgradeTests(DevtoolBase): | |||
2437 | self.assertExists(newrecipefile, 'Recipe file not renamed') | 2437 | self.assertExists(newrecipefile, 'Recipe file not renamed') |
2438 | self.assertExists(os.path.join(self.workspacedir, 'sources', recipename), 'Source directory no longer exists') | 2438 | self.assertExists(os.path.join(self.workspacedir, 'sources', recipename), 'Source directory no longer exists') |
2439 | checkvars = {} | 2439 | checkvars = {} |
2440 | checkvars['S'] = '${WORKDIR}/${BPN}-%s' % recipever | 2440 | checkvars['S'] = '${UNPACKDIR}/${BPN}-%s' % recipever |
2441 | checkvars['SRC_URI'] = url | 2441 | checkvars['SRC_URI'] = url |
2442 | self._test_recipe_contents(newrecipefile, checkvars, []) | 2442 | self._test_recipe_contents(newrecipefile, checkvars, []) |
2443 | 2443 | ||
diff --git a/meta/lib/oeqa/selftest/cases/distrodata.py b/meta/lib/oeqa/selftest/cases/distrodata.py index 1e88ea82e6..f2c6124d70 100644 --- a/meta/lib/oeqa/selftest/cases/distrodata.py +++ b/meta/lib/oeqa/selftest/cases/distrodata.py | |||
@@ -56,7 +56,7 @@ but their recipes claim otherwise by setting UPSTREAM_VERSION_UNKNOWN. Please re | |||
56 | 56 | ||
57 | def is_maintainer_exception(entry): | 57 | def is_maintainer_exception(entry): |
58 | exceptions = ["musl", "newlib", "picolibc", "linux-yocto", "linux-dummy", "mesa-gl", "libgfortran", "libx11-compose-data", | 58 | exceptions = ["musl", "newlib", "picolibc", "linux-yocto", "linux-dummy", "mesa-gl", "libgfortran", "libx11-compose-data", |
59 | "cve-update-nvd2-native", "barebox"] | 59 | "cve-update-nvd2-native", "barebox", "libglvnd"] |
60 | for i in exceptions: | 60 | for i in exceptions: |
61 | if i in entry: | 61 | if i in entry: |
62 | return True | 62 | return True |
diff --git a/meta/lib/oeqa/selftest/cases/esdk.py b/meta/lib/oeqa/selftest/cases/esdk.py index 9f5de2cde7..7a5fe00a08 100644 --- a/meta/lib/oeqa/selftest/cases/esdk.py +++ b/meta/lib/oeqa/selftest/cases/esdk.py | |||
@@ -27,11 +27,7 @@ class oeSDKExtSelfTest(OESelftestTestCase): | |||
27 | return glob.glob(pattern)[0] | 27 | return glob.glob(pattern)[0] |
28 | 28 | ||
29 | @staticmethod | 29 | @staticmethod |
30 | def run_esdk_cmd(env_eSDK, tmpdir_eSDKQA, cmd, postconfig=None, **options): | 30 | def run_esdk_cmd(env_eSDK, tmpdir_eSDKQA, cmd, **options): |
31 | if postconfig: | ||
32 | esdk_conf_file = os.path.join(tmpdir_eSDKQA, 'conf', 'local.conf') | ||
33 | with open(esdk_conf_file, 'a+') as f: | ||
34 | f.write(postconfig) | ||
35 | if not options: | 31 | if not options: |
36 | options = {} | 32 | options = {} |
37 | if not 'shell' in options: | 33 | if not 'shell' in options: |
diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py index ca4724d1ae..3c40857747 100644 --- a/meta/lib/oeqa/selftest/cases/fitimage.py +++ b/meta/lib/oeqa/selftest/cases/fitimage.py | |||
@@ -1692,3 +1692,40 @@ FIT_SIGN_INDIVIDUAL = "1" | |||
1692 | 1692 | ||
1693 | # Just check the DTB of u-boot since there is no u-boot FIT image | 1693 | # Just check the DTB of u-boot since there is no u-boot FIT image |
1694 | self._check_kernel_dtb(bb_vars) | 1694 | self._check_kernel_dtb(bb_vars) |
1695 | |||
1696 | |||
1697 | def test_sign_uboot_fit_image_without_spl(self): | ||
1698 | """ | ||
1699 | Summary: Check if U-Boot FIT image and Image Tree Source (its) are | ||
1700 | created and signed correctly for the scenario where only | ||
1701 | the U-Boot proper fitImage is being created and signed | ||
1702 | (no SPL included). | ||
1703 | Expected: 1) U-Boot its and FIT image are built successfully | ||
1704 | 2) Scanning the its file indicates signing is enabled | ||
1705 | as requested by SPL_SIGN_ENABLE (using keys generated | ||
1706 | via UBOOT_FIT_GENERATE_KEYS) | ||
1707 | 3) Dumping the FIT image indicates signature values | ||
1708 | are present | ||
1709 | 4) Examination of the do_uboot_assemble_fitimage | ||
1710 | runfile/logfile indicate that UBOOT_MKIMAGE and | ||
1711 | UBOOT_MKIMAGE_SIGN are working as expected. | ||
1712 | Product: oe-core | ||
1713 | Author: Jamin Lin <jamin_lin@aspeedtech.com> | ||
1714 | """ | ||
1715 | config = """ | ||
1716 | # There's no U-boot defconfig with CONFIG_FIT_SIGNATURE yet, so we need at | ||
1717 | # least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set | ||
1718 | MACHINE = "qemuarm" | ||
1719 | UBOOT_MACHINE = "am57xx_evm_defconfig" | ||
1720 | # Enable creation and signing of the U-Boot fitImage (no SPL) | ||
1721 | UBOOT_FITIMAGE_ENABLE = "1" | ||
1722 | SPL_DTB_BINARY = "" | ||
1723 | SPL_SIGN_ENABLE = "1" | ||
1724 | SPL_SIGN_KEYNAME = "spl-oe-selftest" | ||
1725 | SPL_SIGN_KEYDIR = "${TOPDIR}/signing-keys" | ||
1726 | UBOOT_FIT_GENERATE_KEYS = "1" | ||
1727 | """ | ||
1728 | self.write_config(config) | ||
1729 | bb_vars = self._fit_get_bb_vars() | ||
1730 | self._test_fitimage(bb_vars) | ||
1731 | |||
diff --git a/meta/lib/oeqa/selftest/cases/oescripts.py b/meta/lib/oeqa/selftest/cases/oescripts.py index bfbc33b08d..3f9899b289 100644 --- a/meta/lib/oeqa/selftest/cases/oescripts.py +++ b/meta/lib/oeqa/selftest/cases/oescripts.py | |||
@@ -9,33 +9,9 @@ import shutil | |||
9 | import importlib | 9 | import importlib |
10 | import unittest | 10 | import unittest |
11 | from oeqa.selftest.case import OESelftestTestCase | 11 | from oeqa.selftest.case import OESelftestTestCase |
12 | from oeqa.selftest.cases.buildhistory import BuildhistoryBase | ||
13 | from oeqa.utils.commands import runCmd, bitbake, get_bb_var | 12 | from oeqa.utils.commands import runCmd, bitbake, get_bb_var |
14 | from oeqa.utils import CommandError | 13 | from oeqa.utils import CommandError |
15 | 14 | ||
16 | class BuildhistoryDiffTests(BuildhistoryBase): | ||
17 | |||
18 | def test_buildhistory_diff(self): | ||
19 | target = 'xcursor-transparent-theme' | ||
20 | self.run_buildhistory_operation(target, target_config="PR = \"r1\"", change_bh_location=True) | ||
21 | self.run_buildhistory_operation(target, target_config="PR = \"r0\"", change_bh_location=False, expect_error=True) | ||
22 | result = runCmd("oe-pkgdata-util read-value PKGV %s" % target) | ||
23 | pkgv = result.output.rstrip() | ||
24 | result = runCmd("buildhistory-diff -p %s" % get_bb_var('BUILDHISTORY_DIR')) | ||
25 | expected_endlines = [ | ||
26 | "xcursor-transparent-theme-dev: RRECOMMENDS: removed \"xcursor-transparent-theme (['= %s-r1'])\", added \"xcursor-transparent-theme (['= %s-r0'])\"" % (pkgv, pkgv), | ||
27 | "xcursor-transparent-theme-staticdev: RDEPENDS: removed \"xcursor-transparent-theme-dev (['= %s-r1'])\", added \"xcursor-transparent-theme-dev (['= %s-r0'])\"" % (pkgv, pkgv) | ||
28 | ] | ||
29 | for line in result.output.splitlines(): | ||
30 | for el in expected_endlines: | ||
31 | if line.endswith(el): | ||
32 | expected_endlines.remove(el) | ||
33 | break | ||
34 | else: | ||
35 | self.fail('Unexpected line:\n%s\nExpected line endings:\n %s' % (line, '\n '.join(expected_endlines))) | ||
36 | if expected_endlines: | ||
37 | self.fail('Missing expected line endings:\n %s' % '\n '.join(expected_endlines)) | ||
38 | |||
39 | @unittest.skipUnless(importlib.util.find_spec("cairo"), "Python cairo module is not present") | 15 | @unittest.skipUnless(importlib.util.find_spec("cairo"), "Python cairo module is not present") |
40 | class OEPybootchartguyTests(OESelftestTestCase): | 16 | class OEPybootchartguyTests(OESelftestTestCase): |
41 | 17 | ||
diff --git a/meta/lib/oeqa/selftest/cases/pokybleeding.py b/meta/lib/oeqa/selftest/cases/pokybleeding.py deleted file mode 100644 index d0940d680d..0000000000 --- a/meta/lib/oeqa/selftest/cases/pokybleeding.py +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
6 | |||
7 | from oeqa.utils.commands import bitbake, get_bb_var | ||
8 | from oeqa.selftest.case import OESelftestTestCase | ||
9 | |||
10 | class PokyBleeding(OESelftestTestCase): | ||
11 | |||
12 | def test_poky_bleeding_autorev(self): | ||
13 | """ | ||
14 | Test that poky-bleeding.bbclass sets SRCREV to "AUTOINC" for recipe | ||
15 | with a single scm in SRC_URI and for recipe with two scm's in SRC_URI. | ||
16 | """ | ||
17 | |||
18 | self.assertNotEqual( get_bb_var('SRCREV', 'pseudo'), "AUTOINC") | ||
19 | |||
20 | self.assertNotEqual( get_bb_var('SRCREV', 'hello-rs'), "AUTOINC") | ||
21 | self.assertNotEqual( get_bb_var('SRCREV_hello-lib', 'hello-rs'), "AUTOINC") | ||
22 | |||
23 | features = ''' | ||
24 | INHERIT += "poky-bleeding" | ||
25 | POKY_AUTOREV_RECIPES = "hello-rs pseudo" | ||
26 | ''' | ||
27 | self.write_config(features) | ||
28 | |||
29 | self.assertEqual( get_bb_var('SRCREV', 'pseudo'), "AUTOINC") | ||
30 | |||
31 | self.assertEqual( get_bb_var('SRCREV', 'hello-rs'), "AUTOINC") | ||
32 | self.assertEqual( get_bb_var('SRCREV_hello-lib', 'hello-rs'), "AUTOINC") | ||
diff --git a/meta/lib/oeqa/selftest/cases/recipetool.py b/meta/lib/oeqa/selftest/cases/recipetool.py index 36557f270f..0bd724c8ee 100644 --- a/meta/lib/oeqa/selftest/cases/recipetool.py +++ b/meta/lib/oeqa/selftest/cases/recipetool.py | |||
@@ -385,7 +385,7 @@ class RecipetoolCreateTests(RecipetoolBase): | |||
385 | checkvars = {} | 385 | checkvars = {} |
386 | checkvars['LICENSE'] = 'LGPL-2.1-only' | 386 | checkvars['LICENSE'] = 'LGPL-2.1-only' |
387 | checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=7fbc338309ac38fefcd64b04bb903e34' | 387 | checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=7fbc338309ac38fefcd64b04bb903e34' |
388 | checkvars['S'] = '${WORKDIR}/git' | 388 | checkvars['S'] = None |
389 | checkvars['PV'] = '1.11+git' | 389 | checkvars['PV'] = '1.11+git' |
390 | checkvars['SRC_URI'] = srcuri + ';branch=master' | 390 | checkvars['SRC_URI'] = srcuri + ';branch=master' |
391 | checkvars['DEPENDS'] = set(['libcheck', 'libjpeg-turbo', 'libpng', 'libx11', 'libxext', 'pango']) | 391 | checkvars['DEPENDS'] = set(['libcheck', 'libjpeg-turbo', 'libpng', 'libx11', 'libxext', 'pango']) |
@@ -757,13 +757,12 @@ class RecipetoolCreateTests(RecipetoolBase): | |||
757 | 757 | ||
758 | def test_recipetool_create_go(self): | 758 | def test_recipetool_create_go(self): |
759 | # Basic test to check go recipe generation | 759 | # Basic test to check go recipe generation |
760 | self.maxDiff = None | ||
761 | |||
760 | temprecipe = os.path.join(self.tempdir, 'recipe') | 762 | temprecipe = os.path.join(self.tempdir, 'recipe') |
761 | os.makedirs(temprecipe) | 763 | os.makedirs(temprecipe) |
762 | 764 | ||
763 | recipefile = os.path.join(temprecipe, 'recipetool-go-test_git.bb') | 765 | recipefile = os.path.join(temprecipe, 'recipetool-go-test_git.bb') |
764 | deps_require_file = os.path.join(temprecipe, 'recipetool-go-test', 'recipetool-go-test-modules.inc') | ||
765 | lics_require_file = os.path.join(temprecipe, 'recipetool-go-test', 'recipetool-go-test-licenses.inc') | ||
766 | modules_txt_file = os.path.join(temprecipe, 'recipetool-go-test', 'modules.txt') | ||
767 | 766 | ||
768 | srcuri = 'https://git.yoctoproject.org/recipetool-go-test.git' | 767 | srcuri = 'https://git.yoctoproject.org/recipetool-go-test.git' |
769 | srcrev = "c3e213c01b6c1406b430df03ef0d1ae77de5d2f7" | 768 | srcrev = "c3e213c01b6c1406b430df03ef0d1ae77de5d2f7" |
@@ -771,13 +770,11 @@ class RecipetoolCreateTests(RecipetoolBase): | |||
771 | 770 | ||
772 | result = runCmd('recipetool create -o %s %s -S %s -B %s' % (temprecipe, srcuri, srcrev, srcbranch)) | 771 | result = runCmd('recipetool create -o %s %s -S %s -B %s' % (temprecipe, srcuri, srcrev, srcbranch)) |
773 | 772 | ||
774 | self.maxDiff = None | 773 | inherits = ['go-mod', 'go-mod-update-modules'] |
775 | inherits = ['go-vendor'] | ||
776 | 774 | ||
777 | checkvars = {} | 775 | checkvars = {} |
778 | checkvars['GO_IMPORT'] = "git.yoctoproject.org/recipetool-go-test" | 776 | checkvars['GO_IMPORT'] = "git.yoctoproject.org/recipetool-go-test" |
779 | checkvars['SRC_URI'] = {'git://${GO_IMPORT};destsuffix=git/src/${GO_IMPORT};nobranch=1;name=${BPN};protocol=https', | 777 | checkvars['SRC_URI'] = {'git://${GO_IMPORT};protocol=https;nobranch=1;destsuffix=${GO_SRCURI_DESTSUFFIX}'} |
780 | 'file://modules.txt'} | ||
781 | checkvars['LIC_FILES_CHKSUM'] = { | 778 | checkvars['LIC_FILES_CHKSUM'] = { |
782 | 'file://src/${GO_IMPORT}/LICENSE;md5=4e3933dd47afbf115e484d11385fb3bd', | 779 | 'file://src/${GO_IMPORT}/LICENSE;md5=4e3933dd47afbf115e484d11385fb3bd', |
783 | 'file://src/${GO_IMPORT}/is/LICENSE;md5=62beaee5a116dd1e80161667b1df39ab' | 780 | 'file://src/${GO_IMPORT}/is/LICENSE;md5=62beaee5a116dd1e80161667b1df39ab' |
@@ -786,26 +783,16 @@ class RecipetoolCreateTests(RecipetoolBase): | |||
786 | self._test_recipe_contents(recipefile, checkvars, inherits) | 783 | self._test_recipe_contents(recipefile, checkvars, inherits) |
787 | self.assertNotIn('Traceback', result.output) | 784 | self.assertNotIn('Traceback', result.output) |
788 | 785 | ||
786 | lics_require_file = os.path.join(temprecipe, 'recipetool-go-test-licenses.inc') | ||
787 | self.assertFileExists(lics_require_file) | ||
789 | checkvars = {} | 788 | checkvars = {} |
790 | checkvars['VENDORED_LIC_FILES_CHKSUM'] = set( | 789 | checkvars['LIC_FILES_CHKSUM'] = {'file://pkg/mod/github.com/godbus/dbus/v5@v5.1.0/LICENSE;md5=09042bd5c6c96a2b9e45ddf1bc517eed;spdx=BSD-2-Clause'} |
791 | ['file://src/${GO_IMPORT}/vendor/github.com/godbus/dbus/v5/LICENSE;md5=09042bd5c6c96a2b9e45ddf1bc517eed', | ||
792 | 'file://src/${GO_IMPORT}/vendor/github.com/matryer/is/LICENSE;md5=62beaee5a116dd1e80161667b1df39ab']) | ||
793 | self.assertTrue(os.path.isfile(lics_require_file)) | ||
794 | self._test_recipe_contents(lics_require_file, checkvars, []) | 790 | self._test_recipe_contents(lics_require_file, checkvars, []) |
795 | 791 | ||
796 | # make sure that dependencies don't mention local directory ./matryer/is | 792 | deps_require_file = os.path.join(temprecipe, 'recipetool-go-test-go-mods.inc') |
797 | dependencies = \ | 793 | self.assertFileExists(deps_require_file) |
798 | [ ('github.com/godbus/dbus','v5.1.0', 'github.com/godbus/dbus/v5', '/v5', ''), | ||
799 | ] | ||
800 | |||
801 | src_uri = set() | ||
802 | for d in dependencies: | ||
803 | src_uri.add(self._go_urifiy(*d)) | ||
804 | |||
805 | checkvars = {} | 794 | checkvars = {} |
806 | checkvars['GO_DEPENDENCIES_SRC_URI'] = src_uri | 795 | checkvars['SRC_URI'] = {'gomod://github.com/godbus/dbus/v5;version=v5.1.0;sha256sum=03dfa8e71089a6f477310d15c4d3a036d82d028532881b50fee254358e782ad9'} |
807 | |||
808 | self.assertTrue(os.path.isfile(deps_require_file)) | ||
809 | self._test_recipe_contents(deps_require_file, checkvars, []) | 796 | self._test_recipe_contents(deps_require_file, checkvars, []) |
810 | 797 | ||
811 | class RecipetoolTests(RecipetoolBase): | 798 | class RecipetoolTests(RecipetoolBase): |
@@ -1144,10 +1131,10 @@ class RecipetoolAppendsrcTests(RecipetoolAppendsrcBase): | |||
1144 | 1131 | ||
1145 | def test_recipetool_appendsrcfile_srcdir_basic(self): | 1132 | def test_recipetool_appendsrcfile_srcdir_basic(self): |
1146 | testrecipe = 'bash' | 1133 | testrecipe = 'bash' |
1147 | bb_vars = get_bb_vars(['S', 'WORKDIR'], testrecipe) | 1134 | bb_vars = get_bb_vars(['S', 'UNPACKDIR'], testrecipe) |
1148 | srcdir = bb_vars['S'] | 1135 | srcdir = bb_vars['S'] |
1149 | workdir = bb_vars['WORKDIR'] | 1136 | unpackdir = bb_vars['UNPACKDIR'] |
1150 | subdir = os.path.relpath(srcdir, workdir) | 1137 | subdir = os.path.relpath(srcdir, unpackdir) |
1151 | self._test_appendsrcfile(testrecipe, 'a-file', srcdir=subdir) | 1138 | self._test_appendsrcfile(testrecipe, 'a-file', srcdir=subdir) |
1152 | 1139 | ||
1153 | def test_recipetool_appendsrcfile_existing_in_src_uri(self): | 1140 | def test_recipetool_appendsrcfile_existing_in_src_uri(self): |
@@ -1196,10 +1183,10 @@ class RecipetoolAppendsrcTests(RecipetoolAppendsrcBase): | |||
1196 | def test_recipetool_appendsrcfile_replace_file_srcdir(self): | 1183 | def test_recipetool_appendsrcfile_replace_file_srcdir(self): |
1197 | testrecipe = 'bash' | 1184 | testrecipe = 'bash' |
1198 | filepath = 'Makefile.in' | 1185 | filepath = 'Makefile.in' |
1199 | bb_vars = get_bb_vars(['S', 'WORKDIR'], testrecipe) | 1186 | bb_vars = get_bb_vars(['S', 'UNPACKDIR'], testrecipe) |
1200 | srcdir = bb_vars['S'] | 1187 | srcdir = bb_vars['S'] |
1201 | workdir = bb_vars['WORKDIR'] | 1188 | unpackdir = bb_vars['UNPACKDIR'] |
1202 | subdir = os.path.relpath(srcdir, workdir) | 1189 | subdir = os.path.relpath(srcdir, unpackdir) |
1203 | 1190 | ||
1204 | self._test_appendsrcfile(testrecipe, filepath, srcdir=subdir) | 1191 | self._test_appendsrcfile(testrecipe, filepath, srcdir=subdir) |
1205 | bitbake('%s:do_unpack' % testrecipe) | 1192 | bitbake('%s:do_unpack' % testrecipe) |
diff --git a/meta/lib/oeqa/selftest/cases/recipeutils.py b/meta/lib/oeqa/selftest/cases/recipeutils.py index 9949737172..e697fd2920 100644 --- a/meta/lib/oeqa/selftest/cases/recipeutils.py +++ b/meta/lib/oeqa/selftest/cases/recipeutils.py | |||
@@ -72,7 +72,7 @@ class RecipeUtilsTests(OESelftestTestCase): | |||
72 | expected_patch = """ | 72 | expected_patch = """ |
73 | --- a/recipes-test/recipeutils/recipeutils-test_1.2.bb | 73 | --- a/recipes-test/recipeutils/recipeutils-test_1.2.bb |
74 | +++ b/recipes-test/recipeutils/recipeutils-test_1.2.bb | 74 | +++ b/recipes-test/recipeutils/recipeutils-test_1.2.bb |
75 | @@ -11,6 +11,4 @@ | 75 | @@ -10,6 +10,4 @@ |
76 | 76 | ||
77 | BBCLASSEXTEND = "native nativesdk" | 77 | BBCLASSEXTEND = "native nativesdk" |
78 | 78 | ||
@@ -97,7 +97,7 @@ class RecipeUtilsTests(OESelftestTestCase): | |||
97 | expected_patch = """ | 97 | expected_patch = """ |
98 | --- a/recipes-test/recipeutils/recipeutils-test_1.2.bb | 98 | --- a/recipes-test/recipeutils/recipeutils-test_1.2.bb |
99 | +++ b/recipes-test/recipeutils/recipeutils-test_1.2.bb | 99 | +++ b/recipes-test/recipeutils/recipeutils-test_1.2.bb |
100 | @@ -11,6 +11,3 @@ | 100 | @@ -10,6 +10,3 @@ |
101 | 101 | ||
102 | BBCLASSEXTEND = "native nativesdk" | 102 | BBCLASSEXTEND = "native nativesdk" |
103 | 103 | ||
diff --git a/meta/lib/oeqa/selftest/cases/sstatetests.py b/meta/lib/oeqa/selftest/cases/sstatetests.py index 487995acc3..08f94b168a 100644 --- a/meta/lib/oeqa/selftest/cases/sstatetests.py +++ b/meta/lib/oeqa/selftest/cases/sstatetests.py | |||
@@ -27,17 +27,15 @@ class SStateBase(OESelftestTestCase): | |||
27 | def setUpLocal(self): | 27 | def setUpLocal(self): |
28 | super(SStateBase, self).setUpLocal() | 28 | super(SStateBase, self).setUpLocal() |
29 | self.temp_sstate_location = None | 29 | self.temp_sstate_location = None |
30 | needed_vars = ['SSTATE_DIR', 'NATIVELSBSTRING', 'TCLIBC', 'TUNE_ARCH', | 30 | needed_vars = ['SSTATE_DIR', 'TCLIBC', 'TUNE_ARCH', |
31 | 'TOPDIR', 'TARGET_VENDOR', 'TARGET_OS'] | 31 | 'TOPDIR', 'TARGET_VENDOR', 'TARGET_OS'] |
32 | bb_vars = get_bb_vars(needed_vars) | 32 | bb_vars = get_bb_vars(needed_vars) |
33 | self.sstate_path = bb_vars['SSTATE_DIR'] | 33 | self.sstate_path = bb_vars['SSTATE_DIR'] |
34 | self.hostdistro = bb_vars['NATIVELSBSTRING'] | ||
35 | self.tclibc = bb_vars['TCLIBC'] | 34 | self.tclibc = bb_vars['TCLIBC'] |
36 | self.tune_arch = bb_vars['TUNE_ARCH'] | 35 | self.tune_arch = bb_vars['TUNE_ARCH'] |
37 | self.topdir = bb_vars['TOPDIR'] | 36 | self.topdir = bb_vars['TOPDIR'] |
38 | self.target_vendor = bb_vars['TARGET_VENDOR'] | 37 | self.target_vendor = bb_vars['TARGET_VENDOR'] |
39 | self.target_os = bb_vars['TARGET_OS'] | 38 | self.target_os = bb_vars['TARGET_OS'] |
40 | self.distro_specific_sstate = os.path.join(self.sstate_path, self.hostdistro) | ||
41 | 39 | ||
42 | def track_for_cleanup(self, path): | 40 | def track_for_cleanup(self, path): |
43 | if not keep_temp_files: | 41 | if not keep_temp_files: |
@@ -52,10 +50,7 @@ class SStateBase(OESelftestTestCase): | |||
52 | config_temp_sstate = "SSTATE_DIR = \"%s\"" % temp_sstate_path | 50 | config_temp_sstate = "SSTATE_DIR = \"%s\"" % temp_sstate_path |
53 | self.append_config(config_temp_sstate) | 51 | self.append_config(config_temp_sstate) |
54 | self.track_for_cleanup(temp_sstate_path) | 52 | self.track_for_cleanup(temp_sstate_path) |
55 | bb_vars = get_bb_vars(['SSTATE_DIR', 'NATIVELSBSTRING']) | 53 | self.sstate_path = get_bb_var('SSTATE_DIR') |
56 | self.sstate_path = bb_vars['SSTATE_DIR'] | ||
57 | self.hostdistro = bb_vars['NATIVELSBSTRING'] | ||
58 | self.distro_specific_sstate = os.path.join(self.sstate_path, self.hostdistro) | ||
59 | 54 | ||
60 | if add_local_mirrors: | 55 | if add_local_mirrors: |
61 | config_set_sstate_if_not_set = 'SSTATE_MIRRORS ?= ""' | 56 | config_set_sstate_if_not_set = 'SSTATE_MIRRORS ?= ""' |
@@ -65,8 +60,16 @@ class SStateBase(OESelftestTestCase): | |||
65 | config_sstate_mirror = "SSTATE_MIRRORS += \"file://.* file:///%s/PATH\"" % local_mirror | 60 | config_sstate_mirror = "SSTATE_MIRRORS += \"file://.* file:///%s/PATH\"" % local_mirror |
66 | self.append_config(config_sstate_mirror) | 61 | self.append_config(config_sstate_mirror) |
67 | 62 | ||
63 | def set_hostdistro(self): | ||
64 | # This needs to be read after a BuildStarted event in case it gets changed by event | ||
65 | # handling in uninative.bbclass | ||
66 | self.hostdistro = get_bb_var('NATIVELSBSTRING') | ||
67 | self.distro_specific_sstate = os.path.join(self.sstate_path, self.hostdistro) | ||
68 | |||
68 | # Returns a list containing sstate files | 69 | # Returns a list containing sstate files |
69 | def search_sstate(self, filename_regex, distro_specific=True, distro_nonspecific=True): | 70 | def search_sstate(self, filename_regex, distro_specific=True, distro_nonspecific=True): |
71 | self.set_hostdistro() | ||
72 | |||
70 | result = [] | 73 | result = [] |
71 | for root, dirs, files in os.walk(self.sstate_path): | 74 | for root, dirs, files in os.walk(self.sstate_path): |
72 | if distro_specific and re.search(r"%s/%s/[a-z0-9]{2}/[a-z0-9]{2}$" % (self.sstate_path, self.hostdistro), root): | 75 | if distro_specific and re.search(r"%s/%s/[a-z0-9]{2}/[a-z0-9]{2}$" % (self.sstate_path, self.hostdistro), root): |
@@ -80,55 +83,43 @@ class SStateBase(OESelftestTestCase): | |||
80 | return result | 83 | return result |
81 | 84 | ||
82 | # Test sstate files creation and their location and directory perms | 85 | # Test sstate files creation and their location and directory perms |
83 | def run_test_sstate_creation(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True, should_pass=True): | 86 | def run_test_sstate_creation(self, targets, hostdistro_specific): |
84 | self.config_sstate(temp_sstate_location, [self.sstate_path]) | 87 | self.config_sstate(True, [self.sstate_path]) |
88 | |||
89 | bitbake(['-cclean'] + targets) | ||
85 | 90 | ||
86 | if self.temp_sstate_location: | ||
87 | bitbake(['-cclean'] + targets) | ||
88 | else: | ||
89 | bitbake(['-ccleansstate'] + targets) | ||
90 | |||
91 | # We need to test that the env umask have does not effect sstate directory creation | ||
92 | # So, first, we'll get the current umask and set it to something we know incorrect | ||
93 | # See: sstate_task_postfunc for correct umask of os.umask(0o002) | ||
94 | import os | ||
95 | def current_umask(): | ||
96 | current_umask = os.umask(0) | ||
97 | os.umask(current_umask) | ||
98 | return current_umask | ||
99 | |||
100 | orig_umask = current_umask() | ||
101 | # Set it to a umask we know will be 'wrong' | 91 | # Set it to a umask we know will be 'wrong' |
102 | os.umask(0o022) | 92 | with bb.utils.umask(0o022): |
93 | bitbake(targets) | ||
103 | 94 | ||
104 | bitbake(targets) | 95 | # Distro specific files |
105 | file_tracker = [] | 96 | distro_specific_files = self.search_sstate('|'.join(map(str, targets)), True, False) |
106 | results = self.search_sstate('|'.join(map(str, targets)), distro_specific, distro_nonspecific) | 97 | |
107 | if distro_nonspecific: | 98 | # Distro non-specific |
108 | for r in results: | 99 | distro_non_specific_files = [] |
109 | if r.endswith(("_populate_lic.tar.zst", "_populate_lic.tar.zst.siginfo", "_fetch.tar.zst.siginfo", "_unpack.tar.zst.siginfo", "_patch.tar.zst.siginfo")): | 100 | results = self.search_sstate('|'.join(map(str, targets)), False, True) |
110 | continue | 101 | for r in results: |
111 | file_tracker.append(r) | 102 | if r.endswith(("_populate_lic.tar.zst", "_populate_lic.tar.zst.siginfo", "_fetch.tar.zst.siginfo", "_unpack.tar.zst.siginfo", "_patch.tar.zst.siginfo")): |
112 | else: | 103 | continue |
113 | file_tracker = results | 104 | distro_non_specific_files.append(r) |
114 | 105 | ||
115 | if should_pass: | 106 | if hostdistro_specific: |
116 | self.assertTrue(file_tracker , msg="Could not find sstate files for: %s" % ', '.join(map(str, targets))) | 107 | self.assertTrue(distro_specific_files , msg="Could not find sstate files for: %s" % ', '.join(map(str, targets))) |
108 | self.assertFalse(distro_non_specific_files, msg="Found sstate files in the wrong place for: %s (found %s)" % (', '.join(map(str, targets)), str(distro_non_specific_files))) | ||
117 | else: | 109 | else: |
118 | self.assertTrue(not file_tracker , msg="Found sstate files in the wrong place for: %s (found %s)" % (', '.join(map(str, targets)), str(file_tracker))) | 110 | self.assertTrue(distro_non_specific_files , msg="Could not find sstate files for: %s" % ', '.join(map(str, targets))) |
111 | self.assertFalse(distro_specific_files, msg="Found sstate files in the wrong place for: %s (found %s)" % (', '.join(map(str, targets)), str(distro_specific_files))) | ||
119 | 112 | ||
120 | # Now we'll walk the tree to check the mode and see if things are incorrect. | 113 | # Now we'll walk the tree to check the mode and see if things are incorrect. |
121 | badperms = [] | 114 | badperms = [] |
122 | for root, dirs, files in os.walk(self.sstate_path): | 115 | for root, dirs, files in os.walk(self.sstate_path): |
123 | for directory in dirs: | 116 | for directory in dirs: |
124 | if (os.stat(os.path.join(root, directory)).st_mode & 0o777) != 0o775: | 117 | mode = os.stat(os.path.join(root, directory)).st_mode & 0o777 |
125 | badperms.append(os.path.join(root, directory)) | 118 | if mode != 0o775: |
126 | 119 | badperms.append("%s: %s vs %s" % (os.path.join(root, directory), mode, 0o775)) | |
127 | # Return to original umask | ||
128 | os.umask(orig_umask) | ||
129 | 120 | ||
130 | if should_pass: | 121 | # Check badperms is empty |
131 | self.assertTrue(badperms , msg="Found sstate directories with the wrong permissions: %s (found %s)" % (', '.join(map(str, targets)), str(badperms))) | 122 | self.assertFalse(badperms , msg="Found sstate directories with the wrong permissions: %s (found %s)" % (', '.join(map(str, targets)), str(badperms))) |
132 | 123 | ||
133 | # Test the sstate files deletion part of the do_cleansstate task | 124 | # Test the sstate files deletion part of the do_cleansstate task |
134 | def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True): | 125 | def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True): |
@@ -153,6 +144,8 @@ class SStateBase(OESelftestTestCase): | |||
153 | 144 | ||
154 | bitbake(['-ccleansstate'] + targets) | 145 | bitbake(['-ccleansstate'] + targets) |
155 | 146 | ||
147 | self.set_hostdistro() | ||
148 | |||
156 | bitbake(targets) | 149 | bitbake(targets) |
157 | results = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=False, distro_nonspecific=True) | 150 | results = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=False, distro_nonspecific=True) |
158 | filtered_results = [] | 151 | filtered_results = [] |
@@ -251,17 +244,11 @@ class SStateTests(SStateBase): | |||
251 | bitbake("dbus-wait-test -c unpack") | 244 | bitbake("dbus-wait-test -c unpack") |
252 | 245 | ||
253 | class SStateCreation(SStateBase): | 246 | class SStateCreation(SStateBase): |
254 | def test_sstate_creation_distro_specific_pass(self): | 247 | def test_sstate_creation_distro_specific(self): |
255 | self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True) | 248 | self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], hostdistro_specific=True) |
256 | |||
257 | def test_sstate_creation_distro_specific_fail(self): | ||
258 | self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True, should_pass=False) | ||
259 | |||
260 | def test_sstate_creation_distro_nonspecific_pass(self): | ||
261 | self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True) | ||
262 | 249 | ||
263 | def test_sstate_creation_distro_nonspecific_fail(self): | 250 | def test_sstate_creation_distro_nonspecific(self): |
264 | self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True, should_pass=False) | 251 | self.run_test_sstate_creation(['linux-libc-headers'], hostdistro_specific=False) |
265 | 252 | ||
266 | class SStateCleanup(SStateBase): | 253 | class SStateCleanup(SStateBase): |
267 | def test_cleansstate_task_distro_specific_nonspecific(self): | 254 | def test_cleansstate_task_distro_specific_nonspecific(self): |
diff --git a/meta/lib/oeqa/selftest/cases/toolchain.py b/meta/lib/oeqa/selftest/cases/toolchain.py new file mode 100644 index 0000000000..b4b280d037 --- /dev/null +++ b/meta/lib/oeqa/selftest/cases/toolchain.py | |||
@@ -0,0 +1,71 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
6 | |||
7 | import shutil | ||
8 | import subprocess | ||
9 | import tempfile | ||
10 | from types import SimpleNamespace | ||
11 | |||
12 | import oe.path | ||
13 | from oeqa.selftest.case import OESelftestTestCase | ||
14 | from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars | ||
15 | |||
16 | class ToolchainTests(OESelftestTestCase): | ||
17 | |||
18 | def test_toolchain_switching(self): | ||
19 | """ | ||
20 | Test that a configuration that uses GCC by default but clang for one | ||
21 | specific recipe does infact do that. | ||
22 | """ | ||
23 | |||
24 | def extract_comment(objcopy, filename): | ||
25 | """ | ||
26 | Using the specified `objcopy`, return the .comment segment from | ||
27 | `filename` as a bytes(). | ||
28 | """ | ||
29 | with tempfile.NamedTemporaryFile(prefix="comment-") as f: | ||
30 | cmd = [objcopy, "--dump-section", ".comment=" + f.name, filename] | ||
31 | subprocess.run(cmd, check=True) | ||
32 | # clang's objcopy writes to a temporary file and renames, so we need to re-open. | ||
33 | with open(f.name, "rb") as f2: | ||
34 | return f2.read() | ||
35 | |||
36 | def check_recipe(recipe, filename, override, comment_present, comment_absent=None): | ||
37 | """ | ||
38 | Check that `filename` in `recipe`'s bindir contains `comment`, and | ||
39 | the overrides contain `override`. | ||
40 | """ | ||
41 | d = SimpleNamespace(**get_bb_vars(("D", "bindir", "OBJCOPY", "OVERRIDES", "PATH"), target=recipe)) | ||
42 | |||
43 | self.assertIn(override, d.OVERRIDES) | ||
44 | |||
45 | binary = oe.path.join(d.D, d.bindir, filename) | ||
46 | |||
47 | objcopy = shutil.which(d.OBJCOPY, path=d.PATH) | ||
48 | self.assertIsNotNone(objcopy) | ||
49 | |||
50 | comment = extract_comment(objcopy, binary) | ||
51 | self.assertIn(comment_present, comment) | ||
52 | if comment_absent: | ||
53 | self.assertNotIn(comment_absent, comment) | ||
54 | |||
55 | |||
56 | # GCC by default, clang for selftest-hello. | ||
57 | self.write_config(""" | ||
58 | TOOLCHAIN = "gcc" | ||
59 | TOOLCHAIN:pn-selftest-hello = "clang" | ||
60 | """) | ||
61 | |||
62 | # Force these recipes to re-install so we can extract the .comments from | ||
63 | # the install directory, as they're stripped out of the final packages. | ||
64 | bitbake("m4 selftest-hello -C install") | ||
65 | |||
66 | # m4 should be built with GCC and only GCC | ||
67 | check_recipe("m4", "m4", "toolchain-gcc", b"GCC: (GNU)", b"clang") | ||
68 | |||
69 | # helloworld should be built with clang. We can't assert that GCC is not | ||
70 | # present as it will be linked against glibc which is built with GCC. | ||
71 | check_recipe("selftest-hello", "helloworld", "toolchain-clang", b"clang version") | ||
diff --git a/meta/lib/oeqa/selftest/cases/wic.py b/meta/lib/oeqa/selftest/cases/wic.py index f45608172f..680f99d381 100644 --- a/meta/lib/oeqa/selftest/cases/wic.py +++ b/meta/lib/oeqa/selftest/cases/wic.py | |||
@@ -1021,6 +1021,18 @@ class Wic2(WicTestCase): | |||
1021 | """Test building wic images by bitbake""" | 1021 | """Test building wic images by bitbake""" |
1022 | config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\ | 1022 | config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\ |
1023 | 'MACHINE_FEATURES:append = " efi"\n' | 1023 | 'MACHINE_FEATURES:append = " efi"\n' |
1024 | image_recipe_append = """ | ||
1025 | do_image_wic[postfuncs] += "run_wic_cmd" | ||
1026 | run_wic_cmd() { | ||
1027 | echo "test" >> ${WORKDIR}/test.wic-cp | ||
1028 | wic cp --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${WORKDIR}/test.wic-cp ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/ | ||
1029 | wic ls --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/ | ||
1030 | wic rm --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/test.wic-cp | ||
1031 | wic cp --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${WORKDIR}/test.wic-cp ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/ | ||
1032 | } | ||
1033 | """ | ||
1034 | self.write_recipeinc('images', image_recipe_append) | ||
1035 | |||
1024 | self.append_config(config) | 1036 | self.append_config(config) |
1025 | image = 'wic-image-minimal' | 1037 | image = 'wic-image-minimal' |
1026 | bitbake(image) | 1038 | bitbake(image) |
@@ -1029,6 +1041,11 @@ class Wic2(WicTestCase): | |||
1029 | bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_LINK_NAME'], image) | 1041 | bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_LINK_NAME'], image) |
1030 | prefix = os.path.join(bb_vars['DEPLOY_DIR_IMAGE'], '%s.' % bb_vars['IMAGE_LINK_NAME']) | 1042 | prefix = os.path.join(bb_vars['DEPLOY_DIR_IMAGE'], '%s.' % bb_vars['IMAGE_LINK_NAME']) |
1031 | 1043 | ||
1044 | sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools') | ||
1045 | # check if file is there | ||
1046 | result = runCmd("wic ls %s:1/ -n %s" % (prefix+"wic", sysroot)) | ||
1047 | self.assertIn("test.wic-cp", result.output) | ||
1048 | |||
1032 | # check if we have result image and manifests symlinks | 1049 | # check if we have result image and manifests symlinks |
1033 | # pointing to existing files | 1050 | # pointing to existing files |
1034 | for suffix in ('wic', 'manifest'): | 1051 | for suffix in ('wic', 'manifest'): |
@@ -1044,7 +1061,25 @@ class Wic2(WicTestCase): | |||
1044 | config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\ | 1061 | config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\ |
1045 | 'MACHINE_FEATURES:append = " efi"\n' | 1062 | 'MACHINE_FEATURES:append = " efi"\n' |
1046 | self.append_config(config) | 1063 | self.append_config(config) |
1064 | image_recipe_append = """ | ||
1065 | do_image_wic[postfuncs] += "run_wic_cmd" | ||
1066 | run_wic_cmd() { | ||
1067 | echo "test" >> ${WORKDIR}/test.wic-cp | ||
1068 | wic cp --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${WORKDIR}/test.wic-cp ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/ | ||
1069 | wic ls --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/ | ||
1070 | wic rm --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/test.wic-cp | ||
1071 | wic cp --vars "${STAGING_DIR}/${MACHINE}/imgdata/" -e "${IMAGE_BASENAME}" ${WORKDIR}/test.wic-cp ${IMGDEPLOYDIR}/${IMAGE_NAME}.wic:1/ | ||
1072 | } | ||
1073 | """ | ||
1074 | self.write_recipeinc('images', image_recipe_append) | ||
1047 | bitbake('wic-image-minimal') | 1075 | bitbake('wic-image-minimal') |
1076 | |||
1077 | sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools') | ||
1078 | bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_LINK_NAME'], "wic-image-minimal") | ||
1079 | image_path = os.path.join(bb_vars['DEPLOY_DIR_IMAGE'], bb_vars['IMAGE_LINK_NAME']) | ||
1080 | # check if file is there | ||
1081 | result = runCmd("wic ls %s:1/ -n %s" % (image_path+".wic", sysroot)) | ||
1082 | self.assertIn("test.wic-cp", result.output) | ||
1048 | self.remove_config(config) | 1083 | self.remove_config(config) |
1049 | 1084 | ||
1050 | runqemu_params = get_bb_var('TEST_RUNQEMUPARAMS', 'wic-image-minimal') or "" | 1085 | runqemu_params = get_bb_var('TEST_RUNQEMUPARAMS', 'wic-image-minimal') or "" |
diff --git a/meta/lib/oeqa/utils/commands.py b/meta/lib/oeqa/utils/commands.py index 2a47f90e32..b60a6e6c38 100644 --- a/meta/lib/oeqa/utils/commands.py +++ b/meta/lib/oeqa/utils/commands.py | |||
@@ -285,7 +285,20 @@ def get_bb_vars(variables=None, target=None, postconfig=None): | |||
285 | return values | 285 | return values |
286 | 286 | ||
287 | def get_bb_var(var, target=None, postconfig=None): | 287 | def get_bb_var(var, target=None, postconfig=None): |
288 | return get_bb_vars([var], target, postconfig)[var] | 288 | if postconfig: |
289 | return bitbake("-e %s" % target or "", postconfig=postconfig).output | ||
290 | else: | ||
291 | # Fast-path for the non-postconfig case | ||
292 | cmd = ["bitbake-getvar", "--quiet", "--value", var] | ||
293 | if target: | ||
294 | cmd.extend(["--recipe", target]) | ||
295 | try: | ||
296 | return subprocess.run(cmd, check=True, text=True, stdout=subprocess.PIPE).stdout.strip() | ||
297 | except subprocess.CalledProcessError as e: | ||
298 | # We need to return None not the empty string if the variable hasn't been set. | ||
299 | if e.returncode == 1: | ||
300 | return None | ||
301 | raise | ||
289 | 302 | ||
290 | def get_test_layer(bblayers=None): | 303 | def get_test_layer(bblayers=None): |
291 | if bblayers is None: | 304 | if bblayers is None: |