blob: 3038b4002151d109c932089706f5dcd90c3ac666 [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
2# SPDX-License-Identifier: MIT
3#
4
Brad Bishopd7bf8c12018-02-25 22:55:05 -05005import os
6import shutil
7import glob
8import subprocess
Brad Bishop316dfdd2018-06-25 12:45:53 -04009import tempfile
Brad Bishopd7bf8c12018-02-25 22:55:05 -050010
11from oeqa.selftest.case import OESelftestTestCase
Brad Bishop316dfdd2018-06-25 12:45:53 -040012from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_test_layer, create_temp_layer
Brad Bishopd7bf8c12018-02-25 22:55:05 -050013from oeqa.selftest.cases.sstate import SStateBase
Andrew Geissler595f6302022-01-24 19:11:47 +000014import oe
Brad Bishopd7bf8c12018-02-25 22:55:05 -050015
16import bb.siggen
17
18class SStateTests(SStateBase):
Brad Bishop316dfdd2018-06-25 12:45:53 -040019 def test_autorev_sstate_works(self):
20 # Test that a git repository which changes is correctly handled by SRCREV = ${AUTOREV}
21 # when PV does not contain SRCPV
22
Andrew Geisslerb7d28612020-07-24 16:15:54 -050023 tempdir = tempfile.mkdtemp(prefix='sstate_autorev')
24 tempdldir = tempfile.mkdtemp(prefix='sstate_autorev_dldir')
Brad Bishop316dfdd2018-06-25 12:45:53 -040025 self.track_for_cleanup(tempdir)
Andrew Geisslerb7d28612020-07-24 16:15:54 -050026 self.track_for_cleanup(tempdldir)
Brad Bishop316dfdd2018-06-25 12:45:53 -040027 create_temp_layer(tempdir, 'selftestrecipetool')
28 self.add_command_to_tearDown('bitbake-layers remove-layer %s' % tempdir)
Andrew Geisslerb7d28612020-07-24 16:15:54 -050029 self.append_config("DL_DIR = \"%s\"" % tempdldir)
Brad Bishop316dfdd2018-06-25 12:45:53 -040030 runCmd('bitbake-layers add-layer %s' % tempdir)
31
32 # Use dbus-wait as a local git repo we can add a commit between two builds in
33 pn = 'dbus-wait'
34 srcrev = '6cc6077a36fe2648a5f993fe7c16c9632f946517'
35 url = 'git://git.yoctoproject.org/dbus-wait'
36 result = runCmd('git clone %s noname' % url, cwd=tempdir)
37 srcdir = os.path.join(tempdir, 'noname')
38 result = runCmd('git reset --hard %s' % srcrev, cwd=srcdir)
39 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure script in source directory')
40
41 recipefile = os.path.join(tempdir, "recipes-test", "dbus-wait-test", 'dbus-wait-test_git.bb')
42 os.makedirs(os.path.dirname(recipefile))
Andrew Geissler595f6302022-01-24 19:11:47 +000043 srcuri = 'git://' + srcdir + ';protocol=file;branch=master'
Brad Bishop316dfdd2018-06-25 12:45:53 -040044 result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri])
45 self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output)
46
47 with open(recipefile, 'a') as f:
48 f.write('SRCREV = "${AUTOREV}"\n')
49 f.write('PV = "1.0"\n')
50
51 bitbake("dbus-wait-test -c fetch")
52 with open(os.path.join(srcdir, "bar.txt"), "w") as f:
53 f.write("foo")
54 result = runCmd('git add bar.txt; git commit -asm "add bar"', cwd=srcdir)
55 bitbake("dbus-wait-test -c unpack")
56
Brad Bishopd7bf8c12018-02-25 22:55:05 -050057
58 # Test sstate files creation and their location
59 def run_test_sstate_creation(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True, should_pass=True):
60 self.config_sstate(temp_sstate_location, [self.sstate_path])
61
62 if self.temp_sstate_location:
63 bitbake(['-cclean'] + targets)
64 else:
65 bitbake(['-ccleansstate'] + targets)
66
67 bitbake(targets)
68 file_tracker = []
69 results = self.search_sstate('|'.join(map(str, targets)), distro_specific, distro_nonspecific)
70 if distro_nonspecific:
71 for r in results:
Andrew Geisslereff27472021-10-29 15:35:00 -050072 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 -050073 continue
74 file_tracker.append(r)
75 else:
76 file_tracker = results
77
78 if should_pass:
79 self.assertTrue(file_tracker , msg="Could not find sstate files for: %s" % ', '.join(map(str, targets)))
80 else:
81 self.assertTrue(not file_tracker , msg="Found sstate files in the wrong place for: %s (found %s)" % (', '.join(map(str, targets)), str(file_tracker)))
82
Brad Bishopd7bf8c12018-02-25 22:55:05 -050083 def test_sstate_creation_distro_specific_pass(self):
84 self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
85
Brad Bishopd7bf8c12018-02-25 22:55:05 -050086 def test_sstate_creation_distro_specific_fail(self):
87 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)
88
Brad Bishopd7bf8c12018-02-25 22:55:05 -050089 def test_sstate_creation_distro_nonspecific_pass(self):
90 self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
91
Brad Bishopd7bf8c12018-02-25 22:55:05 -050092 def test_sstate_creation_distro_nonspecific_fail(self):
93 self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True, should_pass=False)
94
95 # Test the sstate files deletion part of the do_cleansstate task
96 def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True):
97 self.config_sstate(temp_sstate_location, [self.sstate_path])
98
99 bitbake(['-ccleansstate'] + targets)
100
101 bitbake(targets)
Andrew Geisslereff27472021-10-29 15:35:00 -0500102 archives_created = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific, distro_nonspecific)
103 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 -0500104
Brad Bishop19323692019-04-05 15:28:33 -0400105 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 -0500106 self.assertTrue(siginfo_created, msg="Could not find sstate .siginfo files for: %s (%s)" % (', '.join(map(str, targets)), str(siginfo_created)))
107
108 bitbake(['-ccleansstate'] + targets)
Andrew Geisslereff27472021-10-29 15:35:00 -0500109 archives_removed = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific, distro_nonspecific)
110 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 -0500111
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500112 def test_cleansstate_task_distro_specific_nonspecific(self):
113 targets = ['binutils-cross-'+ self.tune_arch, 'binutils-native']
114 targets.append('linux-libc-headers')
115 self.run_test_cleansstate_task(targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True)
116
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500117 def test_cleansstate_task_distro_nonspecific(self):
118 self.run_test_cleansstate_task(['linux-libc-headers'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
119
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500120 def test_cleansstate_task_distro_specific(self):
121 targets = ['binutils-cross-'+ self.tune_arch, 'binutils-native']
122 targets.append('linux-libc-headers')
123 self.run_test_cleansstate_task(targets, distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
124
125
126 # Test rebuilding of distro-specific sstate files
127 def run_test_rebuild_distro_specific_sstate(self, targets, temp_sstate_location=True):
128 self.config_sstate(temp_sstate_location, [self.sstate_path])
129
130 bitbake(['-ccleansstate'] + targets)
131
132 bitbake(targets)
Andrew Geisslereff27472021-10-29 15:35:00 -0500133 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 -0500134 filtered_results = []
135 for r in results:
Andrew Geisslereff27472021-10-29 15:35:00 -0500136 if r.endswith(("_populate_lic.tar.zst", "_populate_lic.tar.zst.siginfo")):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500137 continue
138 filtered_results.append(r)
139 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 -0500140 file_tracker_1 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=True, distro_nonspecific=False)
141 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 -0500142
143 self.track_for_cleanup(self.distro_specific_sstate + "_old")
144 shutil.copytree(self.distro_specific_sstate, self.distro_specific_sstate + "_old")
145 shutil.rmtree(self.distro_specific_sstate)
146
147 bitbake(['-cclean'] + targets)
148 bitbake(targets)
Andrew Geisslereff27472021-10-29 15:35:00 -0500149 file_tracker_2 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=True, distro_nonspecific=False)
150 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 -0500151
152 not_recreated = [x for x in file_tracker_1 if x not in file_tracker_2]
Andrew Geisslereff27472021-10-29 15:35:00 -0500153 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 -0500154
155 created_once = [x for x in file_tracker_2 if x not in file_tracker_1]
Andrew Geisslereff27472021-10-29 15:35:00 -0500156 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 -0500157
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500158 def test_rebuild_distro_specific_sstate_cross_native_targets(self):
159 self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch, 'binutils-native'], temp_sstate_location=True)
160
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500161 def test_rebuild_distro_specific_sstate_cross_target(self):
162 self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch], temp_sstate_location=True)
163
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500164 def test_rebuild_distro_specific_sstate_native_target(self):
165 self.run_test_rebuild_distro_specific_sstate(['binutils-native'], temp_sstate_location=True)
166
167
168 # Test the sstate-cache-management script. Each element in the global_config list is used with the corresponding element in the target_config list
169 # 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)
170 def run_test_sstate_cache_management_script(self, target, global_config=[''], target_config=[''], ignore_patterns=[]):
171 self.assertTrue(global_config)
172 self.assertTrue(target_config)
173 self.assertTrue(len(global_config) == len(target_config), msg='Lists global_config and target_config should have the same number of elements')
174 self.config_sstate(temp_sstate_location=True, add_local_mirrors=[self.sstate_path])
175
176 # If buildhistory is enabled, we need to disable version-going-backwards
177 # QA checks for this test. It may report errors otherwise.
Patrick Williams213cb262021-08-07 19:21:33 -0500178 self.append_config('ERROR_QA:remove = "version-going-backwards"')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500179
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000180 # For now this only checks if random sstate tasks are handled correctly as a group.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500181 # In the future we should add control over what tasks we check for.
182
183 sstate_archs_list = []
184 expected_remaining_sstate = []
185 for idx in range(len(target_config)):
186 self.append_config(global_config[idx])
187 self.append_recipeinc(target, target_config[idx])
188 sstate_arch = get_bb_var('SSTATE_PKGARCH', target)
189 if not sstate_arch in sstate_archs_list:
190 sstate_archs_list.append(sstate_arch)
191 if target_config[idx] == target_config[-1]:
Andrew Geisslereff27472021-10-29 15:35:00 -0500192 target_sstate_before_build = self.search_sstate(target + r'.*?\.tar.zst$')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500193 bitbake("-cclean %s" % target)
194 result = bitbake(target, ignore_status=True)
195 if target_config[idx] == target_config[-1]:
Andrew Geisslereff27472021-10-29 15:35:00 -0500196 target_sstate_after_build = self.search_sstate(target + r'.*?\.tar.zst$')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500197 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)]
198 self.remove_config(global_config[idx])
199 self.remove_recipeinc(target, target_config[idx])
200 self.assertEqual(result.status, 0, msg = "build of %s failed with %s" % (target, result.output))
201
202 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 -0500203 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 -0500204
205 actual_not_expected = [x for x in actual_remaining_sstate if x not in expected_remaining_sstate]
Andrew Geisslereff27472021-10-29 15:35:00 -0500206 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 -0500207 expected_not_actual = [x for x in expected_remaining_sstate if x not in actual_remaining_sstate]
Andrew Geisslereff27472021-10-29 15:35:00 -0500208 self.assertFalse(expected_not_actual, msg="Extra files were removed: %s" ', '.join(map(str, expected_not_actual)))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500209
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500210 def test_sstate_cache_management_script_using_pr_1(self):
211 global_config = []
212 target_config = []
213 global_config.append('')
214 target_config.append('PR = "0"')
215 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
216
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500217 def test_sstate_cache_management_script_using_pr_2(self):
218 global_config = []
219 target_config = []
220 global_config.append('')
221 target_config.append('PR = "0"')
222 global_config.append('')
223 target_config.append('PR = "1"')
224 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
225
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500226 def test_sstate_cache_management_script_using_pr_3(self):
227 global_config = []
228 target_config = []
229 global_config.append('MACHINE = "qemux86-64"')
230 target_config.append('PR = "0"')
231 global_config.append(global_config[0])
232 target_config.append('PR = "1"')
233 global_config.append('MACHINE = "qemux86"')
234 target_config.append('PR = "1"')
235 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
236
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500237 def test_sstate_cache_management_script_using_machine(self):
238 global_config = []
239 target_config = []
240 global_config.append('MACHINE = "qemux86-64"')
241 target_config.append('')
242 global_config.append('MACHINE = "qemux86"')
243 target_config.append('')
244 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
245
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500246 def test_sstate_32_64_same_hash(self):
247 """
248 The sstate checksums for both native and target should not vary whether
249 they're built on a 32 or 64 bit system. Rather than requiring two different
250 build machines and running a builds, override the variables calling uname()
251 manually and check using bitbake -S.
252 """
253
254 self.write_config("""
255MACHINE = "qemux86"
256TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800257TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500258BUILD_ARCH = "x86_64"
259BUILD_OS = "linux"
260SDKMACHINE = "x86_64"
261PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500262BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500263""")
264 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500265 bitbake("core-image-weston -S none")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500266 self.write_config("""
267MACHINE = "qemux86"
268TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800269TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500270BUILD_ARCH = "i686"
271BUILD_OS = "linux"
272SDKMACHINE = "i686"
273PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500274BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500275""")
276 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500277 bitbake("core-image-weston -S none")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500278
279 def get_files(d):
280 f = []
281 for root, dirs, files in os.walk(d):
Andrew Geisslerc926e172021-05-07 16:11:35 -0500282 if "core-image-weston" in root:
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500283 # SDKMACHINE changing will change
284 # do_rootfs/do_testimage/do_build stamps of images which
285 # is safe to ignore.
286 continue
287 f.extend(os.path.join(root, name) for name in files)
288 return f
289 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
290 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
291 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]
292 self.maxDiff = None
293 self.assertCountEqual(files1, files2)
294
295
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500296 def test_sstate_nativelsbstring_same_hash(self):
297 """
298 The sstate checksums should be independent of whichever NATIVELSBSTRING is
299 detected. Rather than requiring two different build machines and running
300 builds, override the variables manually and check using bitbake -S.
301 """
302
303 self.write_config("""
304TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800305TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500306NATIVELSBSTRING = \"DistroA\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500307BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500308""")
309 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500310 bitbake("core-image-weston -S none")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500311 self.write_config("""
312TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800313TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500314NATIVELSBSTRING = \"DistroB\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500315BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500316""")
317 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500318 bitbake("core-image-weston -S none")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500319
320 def get_files(d):
321 f = []
322 for root, dirs, files in os.walk(d):
323 f.extend(os.path.join(root, name) for name in files)
324 return f
325 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
326 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
327 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
328 self.maxDiff = None
329 self.assertCountEqual(files1, files2)
330
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500331 def test_sstate_allarch_samesigs(self):
332 """
333 The sstate checksums of allarch packages should be independent of whichever
334 MACHINE is set. Check this using bitbake -S.
335 Also, rather than duplicate the test, check nativesdk stamps are the same between
336 the two MACHINE values.
337 """
338
339 configA = """
340TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800341TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500342MACHINE = \"qemux86-64\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500343BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500344"""
Andrew Geissler595f6302022-01-24 19:11:47 +0000345 #OLDEST_KERNEL is arch specific so set to a different value here for testing
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500346 configB = """
347TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800348TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500349MACHINE = \"qemuarm\"
Andrew Geissler595f6302022-01-24 19:11:47 +0000350OLDEST_KERNEL = \"3.3.0\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500351BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500352"""
Andrew Geissler595f6302022-01-24 19:11:47 +0000353 self.sstate_common_samesigs(configA, configB, allarch=True)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500354
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800355 def test_sstate_nativesdk_samesigs_multilib(self):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500356 """
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800357 check nativesdk stamps are the same between the two MACHINE values.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500358 """
359
360 configA = """
361TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800362TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500363MACHINE = \"qemux86-64\"
364require conf/multilib.conf
365MULTILIBS = \"multilib:lib32\"
Patrick Williams213cb262021-08-07 19:21:33 -0500366DEFAULTTUNE:virtclass-multilib-lib32 = \"x86\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500367BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500368"""
369 configB = """
370TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800371TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500372MACHINE = \"qemuarm\"
373require conf/multilib.conf
374MULTILIBS = \"\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500375BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500376"""
Andrew Geissler595f6302022-01-24 19:11:47 +0000377 self.sstate_common_samesigs(configA, configB)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500378
Andrew Geissler595f6302022-01-24 19:11:47 +0000379 def sstate_common_samesigs(self, configA, configB, allarch=False):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500380
381 self.write_config(configA)
382 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
383 bitbake("world meta-toolchain -S none")
384 self.write_config(configB)
385 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
386 bitbake("world meta-toolchain -S none")
387
388 def get_files(d):
389 f = {}
390 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)
397 f[os.path.join(os.path.basename(root), task)] = shash
398 return f
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500399
400 nativesdkdir = os.path.basename(glob.glob(self.topdir + "/tmp-sstatesamehash/stamps/*-nativesdk*-linux")[0])
401
402 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/" + nativesdkdir)
403 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/" + nativesdkdir)
404 self.maxDiff = None
405 self.assertEqual(files1, files2)
406
Andrew Geissler595f6302022-01-24 19:11:47 +0000407 if allarch:
408 allarchdir = os.path.basename(glob.glob(self.topdir + "/tmp-sstatesamehash/stamps/all-*-linux")[0])
409
410 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/" + allarchdir)
411 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/" + allarchdir)
412 self.assertEqual(files1, files2)
413
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500414 def test_sstate_sametune_samesigs(self):
415 """
416 The sstate checksums of two identical machines (using the same tune) should be the
417 same, apart from changes within the machine specific stamps directory. We use the
418 qemux86copy machine to test this. Also include multilibs in the test.
419 """
420
421 self.write_config("""
422TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800423TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500424MACHINE = \"qemux86\"
425require conf/multilib.conf
426MULTILIBS = "multilib:lib32"
Patrick Williams213cb262021-08-07 19:21:33 -0500427DEFAULTTUNE:virtclass-multilib-lib32 = "x86"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500428BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500429""")
430 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
431 bitbake("world meta-toolchain -S none")
432 self.write_config("""
433TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800434TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500435MACHINE = \"qemux86copy\"
436require conf/multilib.conf
437MULTILIBS = "multilib:lib32"
Patrick Williams213cb262021-08-07 19:21:33 -0500438DEFAULTTUNE:virtclass-multilib-lib32 = "x86"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500439BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500440""")
441 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
442 bitbake("world meta-toolchain -S none")
443
444 def get_files(d):
445 f = []
446 for root, dirs, files in os.walk(d):
447 for name in files:
448 if "meta-environment" in root or "cross-canadian" in root:
449 continue
450 if "qemux86copy-" in root or "qemux86-" in root:
451 continue
452 if "do_build" not in name and "do_populate_sdk" not in name:
453 f.append(os.path.join(root, name))
454 return f
455 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps")
456 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps")
457 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
458 self.maxDiff = None
459 self.assertCountEqual(files1, files2)
460
461
Andrew Geissler82c905d2020-04-13 13:39:40 -0500462 def test_sstate_multilib_or_not_native_samesigs(self):
463 """The sstate checksums of two native recipes (and their dependencies)
464 where the target is using multilib in one but not the other
465 should be the same. We use the qemux86copy machine to test
466 this.
467 """
468
469 self.write_config("""
470TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
471TCLIBCAPPEND = \"\"
472MACHINE = \"qemux86\"
473require conf/multilib.conf
474MULTILIBS = "multilib:lib32"
Patrick Williams213cb262021-08-07 19:21:33 -0500475DEFAULTTUNE:virtclass-multilib-lib32 = "x86"
Andrew Geissler82c905d2020-04-13 13:39:40 -0500476BB_SIGNATURE_HANDLER = "OEBasicHash"
477""")
478 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
479 bitbake("binutils-native -S none")
480 self.write_config("""
481TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
482TCLIBCAPPEND = \"\"
483MACHINE = \"qemux86copy\"
484BB_SIGNATURE_HANDLER = "OEBasicHash"
485""")
486 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
487 bitbake("binutils-native -S none")
488
489 def get_files(d):
490 f = []
491 for root, dirs, files in os.walk(d):
492 for name in files:
493 f.append(os.path.join(root, name))
494 return f
495 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps")
496 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps")
497 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
498 self.maxDiff = None
499 self.assertCountEqual(files1, files2)
500
501
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500502 def test_sstate_noop_samesigs(self):
503 """
504 The sstate checksums of two builds with these variables changed or
505 classes inherits should be the same.
506 """
507
508 self.write_config("""
509TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800510TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500511BB_NUMBER_THREADS = "${@oe.utils.cpu_count()}"
512PARALLEL_MAKE = "-j 1"
513DL_DIR = "${TOPDIR}/download1"
514TIME = "111111"
515DATE = "20161111"
Patrick Williams213cb262021-08-07 19:21:33 -0500516INHERIT:remove = "buildstats-summary buildhistory uninative"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500517http_proxy = ""
Brad Bishop6dbb3162019-11-25 09:41:34 -0500518BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500519""")
520 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
521 self.track_for_cleanup(self.topdir + "/download1")
522 bitbake("world meta-toolchain -S none")
523 self.write_config("""
524TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800525TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500526BB_NUMBER_THREADS = "${@oe.utils.cpu_count()+1}"
527PARALLEL_MAKE = "-j 2"
528DL_DIR = "${TOPDIR}/download2"
529TIME = "222222"
530DATE = "20161212"
531# Always remove uninative as we're changing proxies
Patrick Williams213cb262021-08-07 19:21:33 -0500532INHERIT:remove = "uninative"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500533INHERIT += "buildstats-summary buildhistory"
534http_proxy = "http://example.com/"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500535BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500536""")
537 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
538 self.track_for_cleanup(self.topdir + "/download2")
539 bitbake("world meta-toolchain -S none")
540
541 def get_files(d):
542 f = {}
543 for root, dirs, files in os.walk(d):
544 for name in files:
545 name, shash = name.rsplit('.', 1)
546 # Extract just the machine and recipe name
547 base = os.sep.join(root.rsplit(os.sep, 2)[-2:] + [name])
548 f[base] = shash
549 return f
550
551 def compare_sigfiles(files, files1, files2, compare=False):
552 for k in files:
553 if k in files1 and k in files2:
554 print("%s differs:" % k)
555 if compare:
556 sigdatafile1 = self.topdir + "/tmp-sstatesamehash/stamps/" + k + "." + files1[k]
557 sigdatafile2 = self.topdir + "/tmp-sstatesamehash2/stamps/" + k + "." + files2[k]
558 output = bb.siggen.compare_sigfiles(sigdatafile1, sigdatafile2)
559 if output:
560 print('\n'.join(output))
561 elif k in files1 and k not in files2:
562 print("%s in files1" % k)
563 elif k not in files1 and k in files2:
564 print("%s in files2" % k)
565 else:
566 assert "shouldn't reach here"
567
568 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
569 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
570 # Remove items that are identical in both sets
571 for k,v in files1.items() & files2.items():
572 del files1[k]
573 del files2[k]
574 if not files1 and not files2:
575 # No changes, so we're done
576 return
577
578 files = list(files1.keys() | files2.keys())
579 # this is an expensive computation, thus just compare the first 'max_sigfiles_to_compare' k files
580 max_sigfiles_to_compare = 20
581 first, rest = files[:max_sigfiles_to_compare], files[max_sigfiles_to_compare:]
Brad Bishop316dfdd2018-06-25 12:45:53 -0400582 compare_sigfiles(first, files1, files2, compare=True)
583 compare_sigfiles(rest, files1, files2, compare=False)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500584
585 self.fail("sstate hashes not identical.")
Andrew Geissler595f6302022-01-24 19:11:47 +0000586
587 def test_sstate_movelayer_samesigs(self):
588 """
589 The sstate checksums of two builds with the same oe-core layer in two
590 different locations should be the same.
591 """
592 core_layer = os.path.join(
593 self.tc.td["COREBASE"], 'meta')
594 copy_layer_1 = self.topdir + "/meta-copy1/meta"
595 copy_layer_2 = self.topdir + "/meta-copy2/meta"
596
597 oe.path.copytree(core_layer, copy_layer_1)
598 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)
607 self.write_config("""
608TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
609""")
610 bblayers_conf = 'BBLAYERS += "%s"\nBBLAYERS:remove = "%s"' % (copy_layer_2, core_layer)
611 self.write_bblayers_config(bblayers_conf)
612 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
613 bitbake("bash -S none")
614
615 def get_files(d):
616 f = []
617 for root, dirs, files in os.walk(d):
618 for name in files:
619 f.append(os.path.join(root, name))
620 return f
621 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps")
622 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps")
623 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
624 self.maxDiff = None
625 self.assertCountEqual(files1, files2)
626