blob: 63827f306800e9dfa7ced6ab8974dc73a8da66d6 [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
Patrick Williams45852732022-04-02 08:58:32 -050011from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer
Brad Bishopd7bf8c12018-02-25 22:55:05 -050012from oeqa.selftest.cases.sstate import SStateBase
Andrew Geissler595f6302022-01-24 19:11:47 +000013import oe
Brad Bishopd7bf8c12018-02-25 22:55:05 -050014
15import bb.siggen
16
17class SStateTests(SStateBase):
Brad Bishop316dfdd2018-06-25 12:45:53 -040018 def test_autorev_sstate_works(self):
19 # Test that a git repository which changes is correctly handled by SRCREV = ${AUTOREV}
20 # when PV does not contain SRCPV
21
Andrew Geisslerb7d28612020-07-24 16:15:54 -050022 tempdir = tempfile.mkdtemp(prefix='sstate_autorev')
23 tempdldir = tempfile.mkdtemp(prefix='sstate_autorev_dldir')
Brad Bishop316dfdd2018-06-25 12:45:53 -040024 self.track_for_cleanup(tempdir)
Andrew Geisslerb7d28612020-07-24 16:15:54 -050025 self.track_for_cleanup(tempdldir)
Brad Bishop316dfdd2018-06-25 12:45:53 -040026 create_temp_layer(tempdir, 'selftestrecipetool')
27 self.add_command_to_tearDown('bitbake-layers remove-layer %s' % tempdir)
Andrew Geisslerb7d28612020-07-24 16:15:54 -050028 self.append_config("DL_DIR = \"%s\"" % tempdldir)
Brad Bishop316dfdd2018-06-25 12:45:53 -040029 runCmd('bitbake-layers add-layer %s' % tempdir)
30
31 # Use dbus-wait as a local git repo we can add a commit between two builds in
32 pn = 'dbus-wait'
33 srcrev = '6cc6077a36fe2648a5f993fe7c16c9632f946517'
34 url = 'git://git.yoctoproject.org/dbus-wait'
35 result = runCmd('git clone %s noname' % url, cwd=tempdir)
36 srcdir = os.path.join(tempdir, 'noname')
37 result = runCmd('git reset --hard %s' % srcrev, cwd=srcdir)
38 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure script in source directory')
39
40 recipefile = os.path.join(tempdir, "recipes-test", "dbus-wait-test", 'dbus-wait-test_git.bb')
41 os.makedirs(os.path.dirname(recipefile))
Andrew Geissler595f6302022-01-24 19:11:47 +000042 srcuri = 'git://' + srcdir + ';protocol=file;branch=master'
Brad Bishop316dfdd2018-06-25 12:45:53 -040043 result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri])
44 self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output)
45
46 with open(recipefile, 'a') as f:
47 f.write('SRCREV = "${AUTOREV}"\n')
48 f.write('PV = "1.0"\n')
49
50 bitbake("dbus-wait-test -c fetch")
51 with open(os.path.join(srcdir, "bar.txt"), "w") as f:
52 f.write("foo")
53 result = runCmd('git add bar.txt; git commit -asm "add bar"', cwd=srcdir)
54 bitbake("dbus-wait-test -c unpack")
55
Brad Bishopd7bf8c12018-02-25 22:55:05 -050056
57 # Test sstate files creation and their location
58 def run_test_sstate_creation(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True, should_pass=True):
59 self.config_sstate(temp_sstate_location, [self.sstate_path])
60
61 if self.temp_sstate_location:
62 bitbake(['-cclean'] + targets)
63 else:
64 bitbake(['-ccleansstate'] + targets)
65
66 bitbake(targets)
67 file_tracker = []
68 results = self.search_sstate('|'.join(map(str, targets)), distro_specific, distro_nonspecific)
69 if distro_nonspecific:
70 for r in results:
Andrew Geisslereff27472021-10-29 15:35:00 -050071 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 -050072 continue
73 file_tracker.append(r)
74 else:
75 file_tracker = results
76
77 if should_pass:
78 self.assertTrue(file_tracker , msg="Could not find sstate files for: %s" % ', '.join(map(str, targets)))
79 else:
80 self.assertTrue(not file_tracker , msg="Found sstate files in the wrong place for: %s (found %s)" % (', '.join(map(str, targets)), str(file_tracker)))
81
Brad Bishopd7bf8c12018-02-25 22:55:05 -050082 def test_sstate_creation_distro_specific_pass(self):
83 self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
84
Brad Bishopd7bf8c12018-02-25 22:55:05 -050085 def test_sstate_creation_distro_specific_fail(self):
86 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)
87
Brad Bishopd7bf8c12018-02-25 22:55:05 -050088 def test_sstate_creation_distro_nonspecific_pass(self):
89 self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
90
Brad Bishopd7bf8c12018-02-25 22:55:05 -050091 def test_sstate_creation_distro_nonspecific_fail(self):
92 self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True, should_pass=False)
93
94 # Test the sstate files deletion part of the do_cleansstate task
95 def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True):
96 self.config_sstate(temp_sstate_location, [self.sstate_path])
97
98 bitbake(['-ccleansstate'] + targets)
99
100 bitbake(targets)
Andrew Geisslereff27472021-10-29 15:35:00 -0500101 archives_created = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific, distro_nonspecific)
102 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 -0500103
Brad Bishop19323692019-04-05 15:28:33 -0400104 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 -0500105 self.assertTrue(siginfo_created, msg="Could not find sstate .siginfo files for: %s (%s)" % (', '.join(map(str, targets)), str(siginfo_created)))
106
107 bitbake(['-ccleansstate'] + targets)
Andrew Geisslereff27472021-10-29 15:35:00 -0500108 archives_removed = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific, distro_nonspecific)
109 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 -0500110
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500111 def test_cleansstate_task_distro_specific_nonspecific(self):
112 targets = ['binutils-cross-'+ self.tune_arch, 'binutils-native']
113 targets.append('linux-libc-headers')
114 self.run_test_cleansstate_task(targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True)
115
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500116 def test_cleansstate_task_distro_nonspecific(self):
117 self.run_test_cleansstate_task(['linux-libc-headers'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
118
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500119 def test_cleansstate_task_distro_specific(self):
120 targets = ['binutils-cross-'+ self.tune_arch, 'binutils-native']
121 targets.append('linux-libc-headers')
122 self.run_test_cleansstate_task(targets, distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
123
124
125 # Test rebuilding of distro-specific sstate files
126 def run_test_rebuild_distro_specific_sstate(self, targets, temp_sstate_location=True):
127 self.config_sstate(temp_sstate_location, [self.sstate_path])
128
129 bitbake(['-ccleansstate'] + targets)
130
131 bitbake(targets)
Andrew Geisslereff27472021-10-29 15:35:00 -0500132 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 -0500133 filtered_results = []
134 for r in results:
Andrew Geisslereff27472021-10-29 15:35:00 -0500135 if r.endswith(("_populate_lic.tar.zst", "_populate_lic.tar.zst.siginfo")):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500136 continue
137 filtered_results.append(r)
138 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 -0500139 file_tracker_1 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=True, distro_nonspecific=False)
140 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 -0500141
142 self.track_for_cleanup(self.distro_specific_sstate + "_old")
143 shutil.copytree(self.distro_specific_sstate, self.distro_specific_sstate + "_old")
144 shutil.rmtree(self.distro_specific_sstate)
145
146 bitbake(['-cclean'] + targets)
147 bitbake(targets)
Andrew Geisslereff27472021-10-29 15:35:00 -0500148 file_tracker_2 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tar.zst$' for s in targets])), distro_specific=True, distro_nonspecific=False)
149 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 -0500150
151 not_recreated = [x for x in file_tracker_1 if x not in file_tracker_2]
Andrew Geisslereff27472021-10-29 15:35:00 -0500152 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 -0500153
154 created_once = [x for x in file_tracker_2 if x not in file_tracker_1]
Andrew Geisslereff27472021-10-29 15:35:00 -0500155 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 -0500156
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500157 def test_rebuild_distro_specific_sstate_cross_native_targets(self):
158 self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch, 'binutils-native'], temp_sstate_location=True)
159
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500160 def test_rebuild_distro_specific_sstate_cross_target(self):
161 self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch], temp_sstate_location=True)
162
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500163 def test_rebuild_distro_specific_sstate_native_target(self):
164 self.run_test_rebuild_distro_specific_sstate(['binutils-native'], temp_sstate_location=True)
165
166
167 # Test the sstate-cache-management script. Each element in the global_config list is used with the corresponding element in the target_config list
168 # 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)
169 def run_test_sstate_cache_management_script(self, target, global_config=[''], target_config=[''], ignore_patterns=[]):
170 self.assertTrue(global_config)
171 self.assertTrue(target_config)
172 self.assertTrue(len(global_config) == len(target_config), msg='Lists global_config and target_config should have the same number of elements')
173 self.config_sstate(temp_sstate_location=True, add_local_mirrors=[self.sstate_path])
174
175 # If buildhistory is enabled, we need to disable version-going-backwards
176 # QA checks for this test. It may report errors otherwise.
Patrick Williams213cb262021-08-07 19:21:33 -0500177 self.append_config('ERROR_QA:remove = "version-going-backwards"')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500178
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000179 # For now this only checks if random sstate tasks are handled correctly as a group.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500180 # In the future we should add control over what tasks we check for.
181
182 sstate_archs_list = []
183 expected_remaining_sstate = []
184 for idx in range(len(target_config)):
185 self.append_config(global_config[idx])
186 self.append_recipeinc(target, target_config[idx])
187 sstate_arch = get_bb_var('SSTATE_PKGARCH', target)
188 if not sstate_arch in sstate_archs_list:
189 sstate_archs_list.append(sstate_arch)
190 if target_config[idx] == target_config[-1]:
Andrew Geisslereff27472021-10-29 15:35:00 -0500191 target_sstate_before_build = self.search_sstate(target + r'.*?\.tar.zst$')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500192 bitbake("-cclean %s" % target)
193 result = bitbake(target, ignore_status=True)
194 if target_config[idx] == target_config[-1]:
Andrew Geisslereff27472021-10-29 15:35:00 -0500195 target_sstate_after_build = self.search_sstate(target + r'.*?\.tar.zst$')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500196 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)]
197 self.remove_config(global_config[idx])
198 self.remove_recipeinc(target, target_config[idx])
199 self.assertEqual(result.status, 0, msg = "build of %s failed with %s" % (target, result.output))
200
201 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 -0500202 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 -0500203
204 actual_not_expected = [x for x in actual_remaining_sstate if x not in expected_remaining_sstate]
Andrew Geisslereff27472021-10-29 15:35:00 -0500205 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 -0500206 expected_not_actual = [x for x in expected_remaining_sstate if x not in actual_remaining_sstate]
Andrew Geisslereff27472021-10-29 15:35:00 -0500207 self.assertFalse(expected_not_actual, msg="Extra files were removed: %s" ', '.join(map(str, expected_not_actual)))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500208
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500209 def test_sstate_cache_management_script_using_pr_1(self):
210 global_config = []
211 target_config = []
212 global_config.append('')
213 target_config.append('PR = "0"')
214 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
215
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500216 def test_sstate_cache_management_script_using_pr_2(self):
217 global_config = []
218 target_config = []
219 global_config.append('')
220 target_config.append('PR = "0"')
221 global_config.append('')
222 target_config.append('PR = "1"')
223 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
224
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500225 def test_sstate_cache_management_script_using_pr_3(self):
226 global_config = []
227 target_config = []
228 global_config.append('MACHINE = "qemux86-64"')
229 target_config.append('PR = "0"')
230 global_config.append(global_config[0])
231 target_config.append('PR = "1"')
232 global_config.append('MACHINE = "qemux86"')
233 target_config.append('PR = "1"')
234 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
235
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500236 def test_sstate_cache_management_script_using_machine(self):
237 global_config = []
238 target_config = []
239 global_config.append('MACHINE = "qemux86-64"')
240 target_config.append('')
241 global_config.append('MACHINE = "qemux86"')
242 target_config.append('')
243 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
244
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500245 def test_sstate_32_64_same_hash(self):
246 """
247 The sstate checksums for both native and target should not vary whether
248 they're built on a 32 or 64 bit system. Rather than requiring two different
249 build machines and running a builds, override the variables calling uname()
250 manually and check using bitbake -S.
251 """
252
253 self.write_config("""
254MACHINE = "qemux86"
255TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800256TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500257BUILD_ARCH = "x86_64"
258BUILD_OS = "linux"
259SDKMACHINE = "x86_64"
260PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500261BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500262""")
263 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500264 bitbake("core-image-weston -S none")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500265 self.write_config("""
266MACHINE = "qemux86"
267TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800268TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500269BUILD_ARCH = "i686"
270BUILD_OS = "linux"
271SDKMACHINE = "i686"
272PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500273BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500274""")
275 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500276 bitbake("core-image-weston -S none")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500277
278 def get_files(d):
279 f = []
280 for root, dirs, files in os.walk(d):
Andrew Geisslerc926e172021-05-07 16:11:35 -0500281 if "core-image-weston" in root:
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500282 # SDKMACHINE changing will change
283 # do_rootfs/do_testimage/do_build stamps of images which
284 # is safe to ignore.
285 continue
286 f.extend(os.path.join(root, name) for name in files)
287 return f
288 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
289 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
290 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]
291 self.maxDiff = None
292 self.assertCountEqual(files1, files2)
293
294
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500295 def test_sstate_nativelsbstring_same_hash(self):
296 """
297 The sstate checksums should be independent of whichever NATIVELSBSTRING is
298 detected. Rather than requiring two different build machines and running
299 builds, override the variables manually and check using bitbake -S.
300 """
301
302 self.write_config("""
303TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800304TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500305NATIVELSBSTRING = \"DistroA\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500306BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500307""")
308 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500309 bitbake("core-image-weston -S none")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500310 self.write_config("""
311TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800312TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500313NATIVELSBSTRING = \"DistroB\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500314BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500315""")
316 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
Andrew Geisslerc926e172021-05-07 16:11:35 -0500317 bitbake("core-image-weston -S none")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500318
319 def get_files(d):
320 f = []
321 for root, dirs, files in os.walk(d):
322 f.extend(os.path.join(root, name) for name in files)
323 return f
324 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
325 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
326 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
327 self.maxDiff = None
328 self.assertCountEqual(files1, files2)
329
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500330 def test_sstate_allarch_samesigs(self):
331 """
332 The sstate checksums of allarch packages should be independent of whichever
333 MACHINE is set. Check this using bitbake -S.
334 Also, rather than duplicate the test, check nativesdk stamps are the same between
335 the two MACHINE values.
336 """
337
338 configA = """
339TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800340TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500341MACHINE = \"qemux86-64\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500342BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500343"""
Andrew Geissler595f6302022-01-24 19:11:47 +0000344 #OLDEST_KERNEL is arch specific so set to a different value here for testing
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500345 configB = """
346TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800347TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500348MACHINE = \"qemuarm\"
Andrew Geissler595f6302022-01-24 19:11:47 +0000349OLDEST_KERNEL = \"3.3.0\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500350BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500351"""
Andrew Geissler595f6302022-01-24 19:11:47 +0000352 self.sstate_common_samesigs(configA, configB, allarch=True)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500353
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800354 def test_sstate_nativesdk_samesigs_multilib(self):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500355 """
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800356 check nativesdk stamps are the same between the two MACHINE values.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500357 """
358
359 configA = """
360TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800361TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500362MACHINE = \"qemux86-64\"
363require conf/multilib.conf
364MULTILIBS = \"multilib:lib32\"
Patrick Williams213cb262021-08-07 19:21:33 -0500365DEFAULTTUNE:virtclass-multilib-lib32 = \"x86\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500366BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500367"""
368 configB = """
369TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800370TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500371MACHINE = \"qemuarm\"
372require conf/multilib.conf
373MULTILIBS = \"\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500374BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500375"""
Andrew Geissler595f6302022-01-24 19:11:47 +0000376 self.sstate_common_samesigs(configA, configB)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500377
Andrew Geissler595f6302022-01-24 19:11:47 +0000378 def sstate_common_samesigs(self, configA, configB, allarch=False):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500379
380 self.write_config(configA)
381 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
382 bitbake("world meta-toolchain -S none")
383 self.write_config(configB)
384 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
385 bitbake("world meta-toolchain -S none")
386
387 def get_files(d):
388 f = {}
389 for root, dirs, files in os.walk(d):
390 for name in files:
391 if "meta-environment" in root or "cross-canadian" in root:
392 continue
393 if "do_build" not in name:
394 # 1.4.1+gitAUTOINC+302fca9f4c-r0.do_package_write_ipk.sigdata.f3a2a38697da743f0dbed8b56aafcf79
395 (_, task, _, shash) = name.rsplit(".", 3)
396 f[os.path.join(os.path.basename(root), task)] = shash
397 return f
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500398
399 nativesdkdir = os.path.basename(glob.glob(self.topdir + "/tmp-sstatesamehash/stamps/*-nativesdk*-linux")[0])
400
401 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/" + nativesdkdir)
402 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/" + nativesdkdir)
403 self.maxDiff = None
404 self.assertEqual(files1, files2)
405
Andrew Geissler595f6302022-01-24 19:11:47 +0000406 if allarch:
407 allarchdir = os.path.basename(glob.glob(self.topdir + "/tmp-sstatesamehash/stamps/all-*-linux")[0])
408
409 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/" + allarchdir)
410 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/" + allarchdir)
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