blob: ae766f91bd8ada092310e21ac5d00d737f222b53 [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
Patrick Williams92b42cb2022-09-03 06:53:57 -05002# Copyright OpenEmbedded Contributors
3#
Brad Bishopc342db32019-05-15 21:57:59 -04004# SPDX-License-Identifier: MIT
5#
6
Brad Bishopd7bf8c12018-02-25 22:55:05 -05007import os
8import shutil
9import glob
10import subprocess
Brad Bishop316dfdd2018-06-25 12:45:53 -040011import tempfile
Brad Bishopd7bf8c12018-02-25 22:55:05 -050012
Patrick Williams45852732022-04-02 08:58:32 -050013from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer
Brad Bishopd7bf8c12018-02-25 22:55:05 -050014from oeqa.selftest.cases.sstate import SStateBase
Andrew Geissler595f6302022-01-24 19:11:47 +000015import oe
Brad Bishopd7bf8c12018-02-25 22:55:05 -050016
17import bb.siggen
18
19class SStateTests(SStateBase):
Brad Bishop316dfdd2018-06-25 12:45:53 -040020 def test_autorev_sstate_works(self):
21 # Test that a git repository which changes is correctly handled by SRCREV = ${AUTOREV}
22 # when PV does not contain SRCPV
23
Andrew Geisslerb7d28612020-07-24 16:15:54 -050024 tempdir = tempfile.mkdtemp(prefix='sstate_autorev')
25 tempdldir = tempfile.mkdtemp(prefix='sstate_autorev_dldir')
Brad Bishop316dfdd2018-06-25 12:45:53 -040026 self.track_for_cleanup(tempdir)
Andrew Geisslerb7d28612020-07-24 16:15:54 -050027 self.track_for_cleanup(tempdldir)
Brad Bishop316dfdd2018-06-25 12:45:53 -040028 create_temp_layer(tempdir, 'selftestrecipetool')
29 self.add_command_to_tearDown('bitbake-layers remove-layer %s' % tempdir)
Andrew Geisslerb7d28612020-07-24 16:15:54 -050030 self.append_config("DL_DIR = \"%s\"" % tempdldir)
Brad Bishop316dfdd2018-06-25 12:45:53 -040031 runCmd('bitbake-layers add-layer %s' % tempdir)
32
33 # Use dbus-wait as a local git repo we can add a commit between two builds in
34 pn = 'dbus-wait'
35 srcrev = '6cc6077a36fe2648a5f993fe7c16c9632f946517'
36 url = 'git://git.yoctoproject.org/dbus-wait'
37 result = runCmd('git clone %s noname' % url, cwd=tempdir)
38 srcdir = os.path.join(tempdir, 'noname')
39 result = runCmd('git reset --hard %s' % srcrev, cwd=srcdir)
40 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure script in source directory')
41
42 recipefile = os.path.join(tempdir, "recipes-test", "dbus-wait-test", 'dbus-wait-test_git.bb')
43 os.makedirs(os.path.dirname(recipefile))
Andrew Geissler595f6302022-01-24 19:11:47 +000044 srcuri = 'git://' + srcdir + ';protocol=file;branch=master'
Brad Bishop316dfdd2018-06-25 12:45:53 -040045 result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri])
46 self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output)
47
48 with open(recipefile, 'a') as f:
49 f.write('SRCREV = "${AUTOREV}"\n')
50 f.write('PV = "1.0"\n')
51
52 bitbake("dbus-wait-test -c fetch")
53 with open(os.path.join(srcdir, "bar.txt"), "w") as f:
54 f.write("foo")
55 result = runCmd('git add bar.txt; git commit -asm "add bar"', cwd=srcdir)
56 bitbake("dbus-wait-test -c unpack")
57
Brad Bishopd7bf8c12018-02-25 22:55:05 -050058
59 # Test sstate files creation and their location
60 def run_test_sstate_creation(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True, should_pass=True):
61 self.config_sstate(temp_sstate_location, [self.sstate_path])
62
63 if self.temp_sstate_location:
64 bitbake(['-cclean'] + targets)
65 else:
66 bitbake(['-ccleansstate'] + targets)
67
68 bitbake(targets)
69 file_tracker = []
70 results = self.search_sstate('|'.join(map(str, targets)), distro_specific, distro_nonspecific)
71 if distro_nonspecific:
72 for r in results:
Andrew Geisslereff27472021-10-29 15:35:00 -050073 if r.endswith(("_populate_lic.tar.zst", "_populate_lic.tar.zst.siginfo", "_fetch.tar.zst.siginfo", "_unpack.tar.zst.siginfo", "_patch.tar.zst.siginfo")):
Brad Bishopd7bf8c12018-02-25 22:55:05 -050074 continue
75 file_tracker.append(r)
76 else:
77 file_tracker = results
78
79 if should_pass:
80 self.assertTrue(file_tracker , msg="Could not find sstate files for: %s" % ', '.join(map(str, targets)))
81 else:
82 self.assertTrue(not file_tracker , msg="Found sstate files in the wrong place for: %s (found %s)" % (', '.join(map(str, targets)), str(file_tracker)))
83
Brad Bishopd7bf8c12018-02-25 22:55:05 -050084 def test_sstate_creation_distro_specific_pass(self):
85 self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
86
Brad Bishopd7bf8c12018-02-25 22:55:05 -050087 def test_sstate_creation_distro_specific_fail(self):
88 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)
89
Brad Bishopd7bf8c12018-02-25 22:55:05 -050090 def test_sstate_creation_distro_nonspecific_pass(self):
91 self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
92
Brad Bishopd7bf8c12018-02-25 22:55:05 -050093 def test_sstate_creation_distro_nonspecific_fail(self):
94 self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True, should_pass=False)
95
96 # Test the sstate files deletion part of the do_cleansstate task
97 def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True):
98 self.config_sstate(temp_sstate_location, [self.sstate_path])
99
100 bitbake(['-ccleansstate'] + targets)
101
102 bitbake(targets)
Andrew Geisslereff27472021-10-29 15:35:00 -0500103 archives_created = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific, distro_nonspecific)
104 self.assertTrue(archives_created, msg="Could not find sstate .tar.zst files for: %s (%s)" % (', '.join(map(str, targets)), str(archives_created)))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500105
Brad Bishop19323692019-04-05 15:28:33 -0400106 siginfo_created = self.search_sstate('|'.join(map(str, [s + r'.*?\.siginfo$' for s in targets])), distro_specific, distro_nonspecific)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500107 self.assertTrue(siginfo_created, msg="Could not find sstate .siginfo files for: %s (%s)" % (', '.join(map(str, targets)), str(siginfo_created)))
108
109 bitbake(['-ccleansstate'] + targets)
Andrew Geisslereff27472021-10-29 15:35:00 -0500110 archives_removed = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific, distro_nonspecific)
111 self.assertTrue(not archives_removed, msg="do_cleansstate didn't remove .tar.zst sstate files for: %s (%s)" % (', '.join(map(str, targets)), str(archives_removed)))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500112
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500113 def test_cleansstate_task_distro_specific_nonspecific(self):
114 targets = ['binutils-cross-'+ self.tune_arch, 'binutils-native']
115 targets.append('linux-libc-headers')
116 self.run_test_cleansstate_task(targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True)
117
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500118 def test_cleansstate_task_distro_nonspecific(self):
119 self.run_test_cleansstate_task(['linux-libc-headers'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
120
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500121 def test_cleansstate_task_distro_specific(self):
122 targets = ['binutils-cross-'+ self.tune_arch, 'binutils-native']
123 targets.append('linux-libc-headers')
124 self.run_test_cleansstate_task(targets, distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
125
126
127 # Test rebuilding of distro-specific sstate files
128 def run_test_rebuild_distro_specific_sstate(self, targets, temp_sstate_location=True):
129 self.config_sstate(temp_sstate_location, [self.sstate_path])
130
131 bitbake(['-ccleansstate'] + targets)
132
133 bitbake(targets)
Andrew Geisslereff27472021-10-29 15:35:00 -0500134 results = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=False, distro_nonspecific=True)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500135 filtered_results = []
136 for r in results:
Andrew Geisslereff27472021-10-29 15:35:00 -0500137 if r.endswith(("_populate_lic.tar.zst", "_populate_lic.tar.zst.siginfo")):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500138 continue
139 filtered_results.append(r)
140 self.assertTrue(filtered_results == [], msg="Found distro non-specific sstate for: %s (%s)" % (', '.join(map(str, targets)), str(filtered_results)))
Andrew Geisslereff27472021-10-29 15:35:00 -0500141 file_tracker_1 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=True, distro_nonspecific=False)
142 self.assertTrue(len(file_tracker_1) >= len(targets), msg = "Not all sstate files were created for: %s" % ', '.join(map(str, targets)))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500143
144 self.track_for_cleanup(self.distro_specific_sstate + "_old")
145 shutil.copytree(self.distro_specific_sstate, self.distro_specific_sstate + "_old")
146 shutil.rmtree(self.distro_specific_sstate)
147
148 bitbake(['-cclean'] + targets)
149 bitbake(targets)
Andrew Geisslereff27472021-10-29 15:35:00 -0500150 file_tracker_2 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=True, distro_nonspecific=False)
151 self.assertTrue(len(file_tracker_2) >= len(targets), msg = "Not all sstate files were created for: %s" % ', '.join(map(str, targets)))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500152
153 not_recreated = [x for x in file_tracker_1 if x not in file_tracker_2]
Andrew Geisslereff27472021-10-29 15:35:00 -0500154 self.assertTrue(not_recreated == [], msg="The following sstate files were not recreated: %s" % ', '.join(map(str, not_recreated)))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500155
156 created_once = [x for x in file_tracker_2 if x not in file_tracker_1]
Andrew Geisslereff27472021-10-29 15:35:00 -0500157 self.assertTrue(created_once == [], msg="The following sstate files were created only in the second run: %s" % ', '.join(map(str, created_once)))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500158
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500159 def test_rebuild_distro_specific_sstate_cross_native_targets(self):
160 self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch, 'binutils-native'], temp_sstate_location=True)
161
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500162 def test_rebuild_distro_specific_sstate_cross_target(self):
163 self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch], temp_sstate_location=True)
164
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500165 def test_rebuild_distro_specific_sstate_native_target(self):
166 self.run_test_rebuild_distro_specific_sstate(['binutils-native'], temp_sstate_location=True)
167
168
169 # Test the sstate-cache-management script. Each element in the global_config list is used with the corresponding element in the target_config list
170 # global_config elements are expected to not generate any sstate files that would be removed by sstate-cache-management.sh (such as changing the value of MACHINE)
171 def run_test_sstate_cache_management_script(self, target, global_config=[''], target_config=[''], ignore_patterns=[]):
172 self.assertTrue(global_config)
173 self.assertTrue(target_config)
174 self.assertTrue(len(global_config) == len(target_config), msg='Lists global_config and target_config should have the same number of elements')
175 self.config_sstate(temp_sstate_location=True, add_local_mirrors=[self.sstate_path])
176
177 # If buildhistory is enabled, we need to disable version-going-backwards
178 # QA checks for this test. It may report errors otherwise.
Patrick Williams213cb262021-08-07 19:21:33 -0500179 self.append_config('ERROR_QA:remove = "version-going-backwards"')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500180
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000181 # For now this only checks if random sstate tasks are handled correctly as a group.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500182 # In the future we should add control over what tasks we check for.
183
184 sstate_archs_list = []
185 expected_remaining_sstate = []
186 for idx in range(len(target_config)):
187 self.append_config(global_config[idx])
188 self.append_recipeinc(target, target_config[idx])
189 sstate_arch = get_bb_var('SSTATE_PKGARCH', target)
190 if not sstate_arch in sstate_archs_list:
191 sstate_archs_list.append(sstate_arch)
192 if target_config[idx] == target_config[-1]:
Andrew Geisslereff27472021-10-29 15:35:00 -0500193 target_sstate_before_build = self.search_sstate(target + r'.*?\.tar.zst$')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500194 bitbake("-cclean %s" % target)
195 result = bitbake(target, ignore_status=True)
196 if target_config[idx] == target_config[-1]:
Andrew Geisslereff27472021-10-29 15:35:00 -0500197 target_sstate_after_build = self.search_sstate(target + r'.*?\.tar.zst$')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500198 expected_remaining_sstate += [x for x in target_sstate_after_build if x not in target_sstate_before_build if not any(pattern in x for pattern in ignore_patterns)]
199 self.remove_config(global_config[idx])
200 self.remove_recipeinc(target, target_config[idx])
201 self.assertEqual(result.status, 0, msg = "build of %s failed with %s" % (target, result.output))
202
203 runCmd("sstate-cache-management.sh -y --cache-dir=%s --remove-duplicated --extra-archs=%s" % (self.sstate_path, ','.join(map(str, sstate_archs_list))))
Andrew Geisslereff27472021-10-29 15:35:00 -0500204 actual_remaining_sstate = [x for x in self.search_sstate(target + r'.*?\.tar.zst$') if not any(pattern in x for pattern in ignore_patterns)]
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500205
206 actual_not_expected = [x for x in actual_remaining_sstate if x not in expected_remaining_sstate]
Andrew Geisslereff27472021-10-29 15:35:00 -0500207 self.assertFalse(actual_not_expected, msg="Files should have been removed but were not: %s" % ', '.join(map(str, actual_not_expected)))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500208 expected_not_actual = [x for x in expected_remaining_sstate if x not in actual_remaining_sstate]
Andrew Geisslereff27472021-10-29 15:35:00 -0500209 self.assertFalse(expected_not_actual, msg="Extra files were removed: %s" ', '.join(map(str, expected_not_actual)))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500210
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500211 def test_sstate_cache_management_script_using_pr_1(self):
212 global_config = []
213 target_config = []
214 global_config.append('')
215 target_config.append('PR = "0"')
216 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
217
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500218 def test_sstate_cache_management_script_using_pr_2(self):
219 global_config = []
220 target_config = []
221 global_config.append('')
222 target_config.append('PR = "0"')
223 global_config.append('')
224 target_config.append('PR = "1"')
225 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
226
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500227 def test_sstate_cache_management_script_using_pr_3(self):
228 global_config = []
229 target_config = []
230 global_config.append('MACHINE = "qemux86-64"')
231 target_config.append('PR = "0"')
232 global_config.append(global_config[0])
233 target_config.append('PR = "1"')
234 global_config.append('MACHINE = "qemux86"')
235 target_config.append('PR = "1"')
236 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
237
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500238 def test_sstate_cache_management_script_using_machine(self):
239 global_config = []
240 target_config = []
241 global_config.append('MACHINE = "qemux86-64"')
242 target_config.append('')
243 global_config.append('MACHINE = "qemux86"')
244 target_config.append('')
245 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
246
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500247 def test_sstate_32_64_same_hash(self):
248 """
249 The sstate checksums for both native and target should not vary whether
250 they're built on a 32 or 64 bit system. Rather than requiring two different
251 build machines and running a builds, override the variables calling uname()
252 manually and check using bitbake -S.
253 """
254
255 self.write_config("""
256MACHINE = "qemux86"
257TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800258TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500259BUILD_ARCH = "x86_64"
260BUILD_OS = "linux"
261SDKMACHINE = "x86_64"
262PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500263BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500264""")
265 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500266 bitbake("core-image-weston -S none")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500267 self.write_config("""
268MACHINE = "qemux86"
269TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800270TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500271BUILD_ARCH = "i686"
272BUILD_OS = "linux"
273SDKMACHINE = "i686"
274PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500275BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500276""")
277 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500278 bitbake("core-image-weston -S none")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500279
280 def get_files(d):
281 f = []
282 for root, dirs, files in os.walk(d):
Andrew Geisslerc926e172021-05-07 16:11:35 -0500283 if "core-image-weston" in root:
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500284 # SDKMACHINE changing will change
285 # do_rootfs/do_testimage/do_build stamps of images which
286 # is safe to ignore.
287 continue
288 f.extend(os.path.join(root, name) for name in files)
289 return f
290 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
291 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
292 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash").replace("i686-linux", "x86_64-linux").replace("i686" + self.target_vendor + "-linux", "x86_64" + self.target_vendor + "-linux", ) for x in files2]
293 self.maxDiff = None
294 self.assertCountEqual(files1, files2)
295
296
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500297 def test_sstate_nativelsbstring_same_hash(self):
298 """
299 The sstate checksums should be independent of whichever NATIVELSBSTRING is
300 detected. Rather than requiring two different build machines and running
301 builds, override the variables manually and check using bitbake -S.
302 """
303
304 self.write_config("""
305TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800306TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500307NATIVELSBSTRING = \"DistroA\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500308BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500309""")
310 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500311 bitbake("core-image-weston -S none")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500312 self.write_config("""
313TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800314TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500315NATIVELSBSTRING = \"DistroB\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500316BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500317""")
318 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500319 bitbake("core-image-weston -S none")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500320
321 def get_files(d):
322 f = []
323 for root, dirs, files in os.walk(d):
324 f.extend(os.path.join(root, name) for name in files)
325 return f
326 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
327 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
328 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
329 self.maxDiff = None
330 self.assertCountEqual(files1, files2)
331
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500332 def test_sstate_allarch_samesigs(self):
333 """
334 The sstate checksums of allarch packages should be independent of whichever
335 MACHINE is set. Check this using bitbake -S.
336 Also, rather than duplicate the test, check nativesdk stamps are the same between
337 the two MACHINE values.
338 """
339
340 configA = """
341TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800342TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500343MACHINE = \"qemux86-64\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500344BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500345"""
Andrew Geissler595f6302022-01-24 19:11:47 +0000346 #OLDEST_KERNEL is arch specific so set to a different value here for testing
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500347 configB = """
348TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800349TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500350MACHINE = \"qemuarm\"
Andrew Geissler595f6302022-01-24 19:11:47 +0000351OLDEST_KERNEL = \"3.3.0\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500352BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500353"""
Andrew Geissler595f6302022-01-24 19:11:47 +0000354 self.sstate_common_samesigs(configA, configB, allarch=True)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500355
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800356 def test_sstate_nativesdk_samesigs_multilib(self):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500357 """
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800358 check nativesdk stamps are the same between the two MACHINE values.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500359 """
360
361 configA = """
362TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800363TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500364MACHINE = \"qemux86-64\"
365require conf/multilib.conf
366MULTILIBS = \"multilib:lib32\"
Patrick Williams213cb262021-08-07 19:21:33 -0500367DEFAULTTUNE:virtclass-multilib-lib32 = \"x86\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500368BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500369"""
370 configB = """
371TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800372TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500373MACHINE = \"qemuarm\"
374require conf/multilib.conf
375MULTILIBS = \"\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500376BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500377"""
Andrew Geissler595f6302022-01-24 19:11:47 +0000378 self.sstate_common_samesigs(configA, configB)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500379
Andrew Geissler595f6302022-01-24 19:11:47 +0000380 def sstate_common_samesigs(self, configA, configB, allarch=False):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500381
382 self.write_config(configA)
383 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
384 bitbake("world meta-toolchain -S none")
385 self.write_config(configB)
386 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
387 bitbake("world meta-toolchain -S none")
388
Patrick Williams92b42cb2022-09-03 06:53:57 -0500389 def get_files(d, result):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500390 for root, dirs, files in os.walk(d):
391 for name in files:
392 if "meta-environment" in root or "cross-canadian" in root:
393 continue
394 if "do_build" not in name:
395 # 1.4.1+gitAUTOINC+302fca9f4c-r0.do_package_write_ipk.sigdata.f3a2a38697da743f0dbed8b56aafcf79
396 (_, task, _, shash) = name.rsplit(".", 3)
Patrick Williams92b42cb2022-09-03 06:53:57 -0500397 result[os.path.join(os.path.basename(root), task)] = shash
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500398
Patrick Williams92b42cb2022-09-03 06:53:57 -0500399 files1 = {}
400 files2 = {}
401 subdirs = sorted(glob.glob(self.topdir + "/tmp-sstatesamehash/stamps/*-nativesdk*-linux"))
402 if allarch:
403 subdirs.extend(sorted(glob.glob(self.topdir + "/tmp-sstatesamehash/stamps/all-*-linux")))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500404
Patrick Williams92b42cb2022-09-03 06:53:57 -0500405 for subdir in subdirs:
406 nativesdkdir = os.path.basename(subdir)
407 get_files(self.topdir + "/tmp-sstatesamehash/stamps/" + nativesdkdir, files1)
408 get_files(self.topdir + "/tmp-sstatesamehash2/stamps/" + nativesdkdir, files2)
409
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500410 self.maxDiff = None
411 self.assertEqual(files1, files2)
412
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500413 def test_sstate_sametune_samesigs(self):
414 """
415 The sstate checksums of two identical machines (using the same tune) should be the
416 same, apart from changes within the machine specific stamps directory. We use the
417 qemux86copy machine to test this. Also include multilibs in the test.
418 """
419
420 self.write_config("""
421TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800422TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500423MACHINE = \"qemux86\"
424require conf/multilib.conf
425MULTILIBS = "multilib:lib32"
Patrick Williams213cb262021-08-07 19:21:33 -0500426DEFAULTTUNE:virtclass-multilib-lib32 = "x86"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500427BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500428""")
429 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
430 bitbake("world meta-toolchain -S none")
431 self.write_config("""
432TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800433TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500434MACHINE = \"qemux86copy\"
435require conf/multilib.conf
436MULTILIBS = "multilib:lib32"
Patrick Williams213cb262021-08-07 19:21:33 -0500437DEFAULTTUNE:virtclass-multilib-lib32 = "x86"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500438BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500439""")
440 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
441 bitbake("world meta-toolchain -S none")
442
443 def get_files(d):
444 f = []
445 for root, dirs, files in os.walk(d):
446 for name in files:
Patrick Williamsdb4c27e2022-08-05 08:10:29 -0500447 if "meta-environment" in root or "cross-canadian" in root or 'meta-ide-support' in root:
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500448 continue
449 if "qemux86copy-" in root or "qemux86-" in root:
450 continue
451 if "do_build" not in name and "do_populate_sdk" not in name:
452 f.append(os.path.join(root, name))
453 return f
454 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps")
455 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps")
456 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
457 self.maxDiff = None
458 self.assertCountEqual(files1, files2)
459
460
Andrew Geissler82c905d2020-04-13 13:39:40 -0500461 def test_sstate_multilib_or_not_native_samesigs(self):
462 """The sstate checksums of two native recipes (and their dependencies)
463 where the target is using multilib in one but not the other
464 should be the same. We use the qemux86copy machine to test
465 this.
466 """
467
468 self.write_config("""
469TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
470TCLIBCAPPEND = \"\"
471MACHINE = \"qemux86\"
472require conf/multilib.conf
473MULTILIBS = "multilib:lib32"
Patrick Williams213cb262021-08-07 19:21:33 -0500474DEFAULTTUNE:virtclass-multilib-lib32 = "x86"
Andrew Geissler82c905d2020-04-13 13:39:40 -0500475BB_SIGNATURE_HANDLER = "OEBasicHash"
476""")
477 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
478 bitbake("binutils-native -S none")
479 self.write_config("""
480TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
481TCLIBCAPPEND = \"\"
482MACHINE = \"qemux86copy\"
483BB_SIGNATURE_HANDLER = "OEBasicHash"
484""")
485 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
486 bitbake("binutils-native -S none")
487
488 def get_files(d):
489 f = []
490 for root, dirs, files in os.walk(d):
491 for name in files:
492 f.append(os.path.join(root, name))
493 return f
494 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps")
495 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps")
496 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
497 self.maxDiff = None
498 self.assertCountEqual(files1, files2)
499
500
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500501 def test_sstate_noop_samesigs(self):
502 """
503 The sstate checksums of two builds with these variables changed or
504 classes inherits should be the same.
505 """
506
507 self.write_config("""
508TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800509TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500510BB_NUMBER_THREADS = "${@oe.utils.cpu_count()}"
511PARALLEL_MAKE = "-j 1"
512DL_DIR = "${TOPDIR}/download1"
513TIME = "111111"
514DATE = "20161111"
Patrick Williams213cb262021-08-07 19:21:33 -0500515INHERIT:remove = "buildstats-summary buildhistory uninative"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500516http_proxy = ""
Brad Bishop6dbb3162019-11-25 09:41:34 -0500517BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500518""")
519 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
520 self.track_for_cleanup(self.topdir + "/download1")
521 bitbake("world meta-toolchain -S none")
522 self.write_config("""
523TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800524TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500525BB_NUMBER_THREADS = "${@oe.utils.cpu_count()+1}"
526PARALLEL_MAKE = "-j 2"
527DL_DIR = "${TOPDIR}/download2"
528TIME = "222222"
529DATE = "20161212"
530# Always remove uninative as we're changing proxies
Patrick Williams213cb262021-08-07 19:21:33 -0500531INHERIT:remove = "uninative"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500532INHERIT += "buildstats-summary buildhistory"
533http_proxy = "http://example.com/"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500534BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500535""")
536 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
537 self.track_for_cleanup(self.topdir + "/download2")
538 bitbake("world meta-toolchain -S none")
539
540 def get_files(d):
541 f = {}
542 for root, dirs, files in os.walk(d):
543 for name in files:
544 name, shash = name.rsplit('.', 1)
545 # Extract just the machine and recipe name
546 base = os.sep.join(root.rsplit(os.sep, 2)[-2:] + [name])
547 f[base] = shash
548 return f
549
550 def compare_sigfiles(files, files1, files2, compare=False):
551 for k in files:
552 if k in files1 and k in files2:
553 print("%s differs:" % k)
554 if compare:
555 sigdatafile1 = self.topdir + "/tmp-sstatesamehash/stamps/" + k + "." + files1[k]
556 sigdatafile2 = self.topdir + "/tmp-sstatesamehash2/stamps/" + k + "." + files2[k]
557 output = bb.siggen.compare_sigfiles(sigdatafile1, sigdatafile2)
558 if output:
559 print('\n'.join(output))
560 elif k in files1 and k not in files2:
561 print("%s in files1" % k)
562 elif k not in files1 and k in files2:
563 print("%s in files2" % k)
564 else:
565 assert "shouldn't reach here"
566
567 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
568 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
569 # Remove items that are identical in both sets
570 for k,v in files1.items() & files2.items():
571 del files1[k]
572 del files2[k]
573 if not files1 and not files2:
574 # No changes, so we're done
575 return
576
577 files = list(files1.keys() | files2.keys())
578 # this is an expensive computation, thus just compare the first 'max_sigfiles_to_compare' k files
579 max_sigfiles_to_compare = 20
580 first, rest = files[:max_sigfiles_to_compare], files[max_sigfiles_to_compare:]
Brad Bishop316dfdd2018-06-25 12:45:53 -0400581 compare_sigfiles(first, files1, files2, compare=True)
582 compare_sigfiles(rest, files1, files2, compare=False)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500583
584 self.fail("sstate hashes not identical.")
Andrew Geissler595f6302022-01-24 19:11:47 +0000585
586 def test_sstate_movelayer_samesigs(self):
587 """
588 The sstate checksums of two builds with the same oe-core layer in two
589 different locations should be the same.
590 """
591 core_layer = os.path.join(
592 self.tc.td["COREBASE"], 'meta')
593 copy_layer_1 = self.topdir + "/meta-copy1/meta"
594 copy_layer_2 = self.topdir + "/meta-copy2/meta"
595
596 oe.path.copytree(core_layer, copy_layer_1)
Andrew Geissler615f2f12022-07-15 14:00:58 -0500597 os.symlink(os.path.dirname(core_layer) + "/scripts", self.topdir + "/meta-copy1/scripts")
Andrew Geissler595f6302022-01-24 19:11:47 +0000598 self.write_config("""
599TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
600""")
601 bblayers_conf = 'BBLAYERS += "%s"\nBBLAYERS:remove = "%s"' % (copy_layer_1, core_layer)
602 self.write_bblayers_config(bblayers_conf)
603 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
604 bitbake("bash -S none")
605
606 oe.path.copytree(core_layer, copy_layer_2)
Andrew Geissler615f2f12022-07-15 14:00:58 -0500607 os.symlink(os.path.dirname(core_layer) + "/scripts", self.topdir + "/meta-copy2/scripts")
Andrew Geissler595f6302022-01-24 19:11:47 +0000608 self.write_config("""
609TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
610""")
611 bblayers_conf = 'BBLAYERS += "%s"\nBBLAYERS:remove = "%s"' % (copy_layer_2, core_layer)
612 self.write_bblayers_config(bblayers_conf)
613 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
614 bitbake("bash -S none")
615
616 def get_files(d):
617 f = []
618 for root, dirs, files in os.walk(d):
619 for name in files:
620 f.append(os.path.join(root, name))
621 return f
622 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps")
623 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps")
624 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
625 self.maxDiff = None
626 self.assertCountEqual(files1, files2)
627