blob: 6757a0ec6898864c2d16d492fc69c207fc27a381 [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
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
22 tempdir = tempfile.mkdtemp(prefix='oeqa')
23 self.track_for_cleanup(tempdir)
24 create_temp_layer(tempdir, 'selftestrecipetool')
25 self.add_command_to_tearDown('bitbake-layers remove-layer %s' % tempdir)
26 runCmd('bitbake-layers add-layer %s' % tempdir)
27
28 # Use dbus-wait as a local git repo we can add a commit between two builds in
29 pn = 'dbus-wait'
30 srcrev = '6cc6077a36fe2648a5f993fe7c16c9632f946517'
31 url = 'git://git.yoctoproject.org/dbus-wait'
32 result = runCmd('git clone %s noname' % url, cwd=tempdir)
33 srcdir = os.path.join(tempdir, 'noname')
34 result = runCmd('git reset --hard %s' % srcrev, cwd=srcdir)
35 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure script in source directory')
36
37 recipefile = os.path.join(tempdir, "recipes-test", "dbus-wait-test", 'dbus-wait-test_git.bb')
38 os.makedirs(os.path.dirname(recipefile))
39 srcuri = 'git://' + srcdir + ';protocol=file'
40 result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri])
41 self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output)
42
43 with open(recipefile, 'a') as f:
44 f.write('SRCREV = "${AUTOREV}"\n')
45 f.write('PV = "1.0"\n')
46
47 bitbake("dbus-wait-test -c fetch")
48 with open(os.path.join(srcdir, "bar.txt"), "w") as f:
49 f.write("foo")
50 result = runCmd('git add bar.txt; git commit -asm "add bar"', cwd=srcdir)
51 bitbake("dbus-wait-test -c unpack")
52
Brad Bishopd7bf8c12018-02-25 22:55:05 -050053
54 # Test sstate files creation and their location
55 def run_test_sstate_creation(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True, should_pass=True):
56 self.config_sstate(temp_sstate_location, [self.sstate_path])
57
58 if self.temp_sstate_location:
59 bitbake(['-cclean'] + targets)
60 else:
61 bitbake(['-ccleansstate'] + targets)
62
63 bitbake(targets)
64 file_tracker = []
65 results = self.search_sstate('|'.join(map(str, targets)), distro_specific, distro_nonspecific)
66 if distro_nonspecific:
67 for r in results:
68 if r.endswith(("_populate_lic.tgz", "_populate_lic.tgz.siginfo", "_fetch.tgz.siginfo", "_unpack.tgz.siginfo", "_patch.tgz.siginfo")):
69 continue
70 file_tracker.append(r)
71 else:
72 file_tracker = results
73
74 if should_pass:
75 self.assertTrue(file_tracker , msg="Could not find sstate files for: %s" % ', '.join(map(str, targets)))
76 else:
77 self.assertTrue(not file_tracker , msg="Found sstate files in the wrong place for: %s (found %s)" % (', '.join(map(str, targets)), str(file_tracker)))
78
Brad Bishopd7bf8c12018-02-25 22:55:05 -050079 def test_sstate_creation_distro_specific_pass(self):
80 self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
81
Brad Bishopd7bf8c12018-02-25 22:55:05 -050082 def test_sstate_creation_distro_specific_fail(self):
83 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)
84
Brad Bishopd7bf8c12018-02-25 22:55:05 -050085 def test_sstate_creation_distro_nonspecific_pass(self):
86 self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
87
Brad Bishopd7bf8c12018-02-25 22:55:05 -050088 def test_sstate_creation_distro_nonspecific_fail(self):
89 self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True, should_pass=False)
90
91 # Test the sstate files deletion part of the do_cleansstate task
92 def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True):
93 self.config_sstate(temp_sstate_location, [self.sstate_path])
94
95 bitbake(['-ccleansstate'] + targets)
96
97 bitbake(targets)
Brad Bishop19323692019-04-05 15:28:33 -040098 tgz_created = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific, distro_nonspecific)
Brad Bishopd7bf8c12018-02-25 22:55:05 -050099 self.assertTrue(tgz_created, msg="Could not find sstate .tgz files for: %s (%s)" % (', '.join(map(str, targets)), str(tgz_created)))
100
Brad Bishop19323692019-04-05 15:28:33 -0400101 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 -0500102 self.assertTrue(siginfo_created, msg="Could not find sstate .siginfo files for: %s (%s)" % (', '.join(map(str, targets)), str(siginfo_created)))
103
104 bitbake(['-ccleansstate'] + targets)
Brad Bishop19323692019-04-05 15:28:33 -0400105 tgz_removed = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific, distro_nonspecific)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500106 self.assertTrue(not tgz_removed, msg="do_cleansstate didn't remove .tgz sstate files for: %s (%s)" % (', '.join(map(str, targets)), str(tgz_removed)))
107
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500108 def test_cleansstate_task_distro_specific_nonspecific(self):
109 targets = ['binutils-cross-'+ self.tune_arch, 'binutils-native']
110 targets.append('linux-libc-headers')
111 self.run_test_cleansstate_task(targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True)
112
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500113 def test_cleansstate_task_distro_nonspecific(self):
114 self.run_test_cleansstate_task(['linux-libc-headers'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
115
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500116 def test_cleansstate_task_distro_specific(self):
117 targets = ['binutils-cross-'+ self.tune_arch, 'binutils-native']
118 targets.append('linux-libc-headers')
119 self.run_test_cleansstate_task(targets, distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
120
121
122 # Test rebuilding of distro-specific sstate files
123 def run_test_rebuild_distro_specific_sstate(self, targets, temp_sstate_location=True):
124 self.config_sstate(temp_sstate_location, [self.sstate_path])
125
126 bitbake(['-ccleansstate'] + targets)
127
128 bitbake(targets)
Brad Bishop19323692019-04-05 15:28:33 -0400129 results = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific=False, distro_nonspecific=True)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500130 filtered_results = []
131 for r in results:
132 if r.endswith(("_populate_lic.tgz", "_populate_lic.tgz.siginfo")):
133 continue
134 filtered_results.append(r)
135 self.assertTrue(filtered_results == [], msg="Found distro non-specific sstate for: %s (%s)" % (', '.join(map(str, targets)), str(filtered_results)))
Brad Bishop19323692019-04-05 15:28:33 -0400136 file_tracker_1 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500137 self.assertTrue(len(file_tracker_1) >= len(targets), msg = "Not all sstate files ware created for: %s" % ', '.join(map(str, targets)))
138
139 self.track_for_cleanup(self.distro_specific_sstate + "_old")
140 shutil.copytree(self.distro_specific_sstate, self.distro_specific_sstate + "_old")
141 shutil.rmtree(self.distro_specific_sstate)
142
143 bitbake(['-cclean'] + targets)
144 bitbake(targets)
Brad Bishop19323692019-04-05 15:28:33 -0400145 file_tracker_2 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500146 self.assertTrue(len(file_tracker_2) >= len(targets), msg = "Not all sstate files ware created for: %s" % ', '.join(map(str, targets)))
147
148 not_recreated = [x for x in file_tracker_1 if x not in file_tracker_2]
149 self.assertTrue(not_recreated == [], msg="The following sstate files ware not recreated: %s" % ', '.join(map(str, not_recreated)))
150
151 created_once = [x for x in file_tracker_2 if x not in file_tracker_1]
152 self.assertTrue(created_once == [], msg="The following sstate files ware created only in the second run: %s" % ', '.join(map(str, created_once)))
153
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500154 def test_rebuild_distro_specific_sstate_cross_native_targets(self):
155 self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch, 'binutils-native'], temp_sstate_location=True)
156
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500157 def test_rebuild_distro_specific_sstate_cross_target(self):
158 self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch], temp_sstate_location=True)
159
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500160 def test_rebuild_distro_specific_sstate_native_target(self):
161 self.run_test_rebuild_distro_specific_sstate(['binutils-native'], temp_sstate_location=True)
162
163
164 # Test the sstate-cache-management script. Each element in the global_config list is used with the corresponding element in the target_config list
165 # 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)
166 def run_test_sstate_cache_management_script(self, target, global_config=[''], target_config=[''], ignore_patterns=[]):
167 self.assertTrue(global_config)
168 self.assertTrue(target_config)
169 self.assertTrue(len(global_config) == len(target_config), msg='Lists global_config and target_config should have the same number of elements')
170 self.config_sstate(temp_sstate_location=True, add_local_mirrors=[self.sstate_path])
171
172 # If buildhistory is enabled, we need to disable version-going-backwards
173 # QA checks for this test. It may report errors otherwise.
174 self.append_config('ERROR_QA_remove = "version-going-backwards"')
175
176 # For not this only checks if random sstate tasks are handled correctly as a group.
177 # In the future we should add control over what tasks we check for.
178
179 sstate_archs_list = []
180 expected_remaining_sstate = []
181 for idx in range(len(target_config)):
182 self.append_config(global_config[idx])
183 self.append_recipeinc(target, target_config[idx])
184 sstate_arch = get_bb_var('SSTATE_PKGARCH', target)
185 if not sstate_arch in sstate_archs_list:
186 sstate_archs_list.append(sstate_arch)
187 if target_config[idx] == target_config[-1]:
Brad Bishop19323692019-04-05 15:28:33 -0400188 target_sstate_before_build = self.search_sstate(target + r'.*?\.tgz$')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500189 bitbake("-cclean %s" % target)
190 result = bitbake(target, ignore_status=True)
191 if target_config[idx] == target_config[-1]:
Brad Bishop19323692019-04-05 15:28:33 -0400192 target_sstate_after_build = self.search_sstate(target + r'.*?\.tgz$')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500193 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)]
194 self.remove_config(global_config[idx])
195 self.remove_recipeinc(target, target_config[idx])
196 self.assertEqual(result.status, 0, msg = "build of %s failed with %s" % (target, result.output))
197
198 runCmd("sstate-cache-management.sh -y --cache-dir=%s --remove-duplicated --extra-archs=%s" % (self.sstate_path, ','.join(map(str, sstate_archs_list))))
Brad Bishop19323692019-04-05 15:28:33 -0400199 actual_remaining_sstate = [x for x in self.search_sstate(target + r'.*?\.tgz$') if not any(pattern in x for pattern in ignore_patterns)]
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500200
201 actual_not_expected = [x for x in actual_remaining_sstate if x not in expected_remaining_sstate]
202 self.assertFalse(actual_not_expected, msg="Files should have been removed but ware not: %s" % ', '.join(map(str, actual_not_expected)))
203 expected_not_actual = [x for x in expected_remaining_sstate if x not in actual_remaining_sstate]
204 self.assertFalse(expected_not_actual, msg="Extra files ware removed: %s" ', '.join(map(str, expected_not_actual)))
205
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500206 def test_sstate_cache_management_script_using_pr_1(self):
207 global_config = []
208 target_config = []
209 global_config.append('')
210 target_config.append('PR = "0"')
211 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
212
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500213 def test_sstate_cache_management_script_using_pr_2(self):
214 global_config = []
215 target_config = []
216 global_config.append('')
217 target_config.append('PR = "0"')
218 global_config.append('')
219 target_config.append('PR = "1"')
220 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
221
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500222 def test_sstate_cache_management_script_using_pr_3(self):
223 global_config = []
224 target_config = []
225 global_config.append('MACHINE = "qemux86-64"')
226 target_config.append('PR = "0"')
227 global_config.append(global_config[0])
228 target_config.append('PR = "1"')
229 global_config.append('MACHINE = "qemux86"')
230 target_config.append('PR = "1"')
231 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
232
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500233 def test_sstate_cache_management_script_using_machine(self):
234 global_config = []
235 target_config = []
236 global_config.append('MACHINE = "qemux86-64"')
237 target_config.append('')
238 global_config.append('MACHINE = "qemux86"')
239 target_config.append('')
240 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
241
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500242 def test_sstate_32_64_same_hash(self):
243 """
244 The sstate checksums for both native and target should not vary whether
245 they're built on a 32 or 64 bit system. Rather than requiring two different
246 build machines and running a builds, override the variables calling uname()
247 manually and check using bitbake -S.
248 """
249
250 self.write_config("""
251MACHINE = "qemux86"
252TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800253TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500254BUILD_ARCH = "x86_64"
255BUILD_OS = "linux"
256SDKMACHINE = "x86_64"
257PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500258BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500259""")
260 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
261 bitbake("core-image-sato -S none")
262 self.write_config("""
263MACHINE = "qemux86"
264TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800265TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500266BUILD_ARCH = "i686"
267BUILD_OS = "linux"
268SDKMACHINE = "i686"
269PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500270BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500271""")
272 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
273 bitbake("core-image-sato -S none")
274
275 def get_files(d):
276 f = []
277 for root, dirs, files in os.walk(d):
278 if "core-image-sato" in root:
279 # SDKMACHINE changing will change
280 # do_rootfs/do_testimage/do_build stamps of images which
281 # is safe to ignore.
282 continue
283 f.extend(os.path.join(root, name) for name in files)
284 return f
285 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
286 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
287 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]
288 self.maxDiff = None
289 self.assertCountEqual(files1, files2)
290
291
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500292 def test_sstate_nativelsbstring_same_hash(self):
293 """
294 The sstate checksums should be independent of whichever NATIVELSBSTRING is
295 detected. Rather than requiring two different build machines and running
296 builds, override the variables manually and check using bitbake -S.
297 """
298
299 self.write_config("""
300TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800301TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500302NATIVELSBSTRING = \"DistroA\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500303BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500304""")
305 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
306 bitbake("core-image-sato -S none")
307 self.write_config("""
308TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800309TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500310NATIVELSBSTRING = \"DistroB\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500311BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500312""")
313 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
314 bitbake("core-image-sato -S none")
315
316 def get_files(d):
317 f = []
318 for root, dirs, files in os.walk(d):
319 f.extend(os.path.join(root, name) for name in files)
320 return f
321 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
322 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
323 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
324 self.maxDiff = None
325 self.assertCountEqual(files1, files2)
326
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500327 def test_sstate_allarch_samesigs(self):
328 """
329 The sstate checksums of allarch packages should be independent of whichever
330 MACHINE is set. Check this using bitbake -S.
331 Also, rather than duplicate the test, check nativesdk stamps are the same between
332 the two MACHINE values.
333 """
334
335 configA = """
336TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800337TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500338MACHINE = \"qemux86-64\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500339BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500340"""
341 configB = """
342TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800343TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500344MACHINE = \"qemuarm\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500345BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500346"""
347 self.sstate_allarch_samesigs(configA, configB)
348
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800349 def test_sstate_nativesdk_samesigs_multilib(self):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500350 """
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800351 check nativesdk stamps are the same between the two MACHINE values.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500352 """
353
354 configA = """
355TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800356TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500357MACHINE = \"qemux86-64\"
358require conf/multilib.conf
359MULTILIBS = \"multilib:lib32\"
360DEFAULTTUNE_virtclass-multilib-lib32 = \"x86\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500361BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500362"""
363 configB = """
364TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800365TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500366MACHINE = \"qemuarm\"
367require conf/multilib.conf
368MULTILIBS = \"\"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500369BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500370"""
371 self.sstate_allarch_samesigs(configA, configB)
372
373 def sstate_allarch_samesigs(self, configA, configB):
374
375 self.write_config(configA)
376 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
377 bitbake("world meta-toolchain -S none")
378 self.write_config(configB)
379 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
380 bitbake("world meta-toolchain -S none")
381
382 def get_files(d):
383 f = {}
384 for root, dirs, files in os.walk(d):
385 for name in files:
386 if "meta-environment" in root or "cross-canadian" in root:
387 continue
388 if "do_build" not in name:
389 # 1.4.1+gitAUTOINC+302fca9f4c-r0.do_package_write_ipk.sigdata.f3a2a38697da743f0dbed8b56aafcf79
390 (_, task, _, shash) = name.rsplit(".", 3)
391 f[os.path.join(os.path.basename(root), task)] = shash
392 return f
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500393
394 nativesdkdir = os.path.basename(glob.glob(self.topdir + "/tmp-sstatesamehash/stamps/*-nativesdk*-linux")[0])
395
396 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/" + nativesdkdir)
397 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/" + nativesdkdir)
398 self.maxDiff = None
399 self.assertEqual(files1, files2)
400
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500401 def test_sstate_sametune_samesigs(self):
402 """
403 The sstate checksums of two identical machines (using the same tune) should be the
404 same, apart from changes within the machine specific stamps directory. We use the
405 qemux86copy machine to test this. Also include multilibs in the test.
406 """
407
408 self.write_config("""
409TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800410TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500411MACHINE = \"qemux86\"
412require conf/multilib.conf
413MULTILIBS = "multilib:lib32"
414DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500415BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500416""")
417 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
418 bitbake("world meta-toolchain -S none")
419 self.write_config("""
420TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800421TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500422MACHINE = \"qemux86copy\"
423require conf/multilib.conf
424MULTILIBS = "multilib:lib32"
425DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500426BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500427""")
428 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
429 bitbake("world meta-toolchain -S none")
430
431 def get_files(d):
432 f = []
433 for root, dirs, files in os.walk(d):
434 for name in files:
435 if "meta-environment" in root or "cross-canadian" in root:
436 continue
437 if "qemux86copy-" in root or "qemux86-" in root:
438 continue
439 if "do_build" not in name and "do_populate_sdk" not in name:
440 f.append(os.path.join(root, name))
441 return f
442 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps")
443 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps")
444 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
445 self.maxDiff = None
446 self.assertCountEqual(files1, files2)
447
448
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500449 def test_sstate_noop_samesigs(self):
450 """
451 The sstate checksums of two builds with these variables changed or
452 classes inherits should be the same.
453 """
454
455 self.write_config("""
456TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800457TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500458BB_NUMBER_THREADS = "${@oe.utils.cpu_count()}"
459PARALLEL_MAKE = "-j 1"
460DL_DIR = "${TOPDIR}/download1"
461TIME = "111111"
462DATE = "20161111"
463INHERIT_remove = "buildstats-summary buildhistory uninative"
464http_proxy = ""
Brad Bishop6dbb3162019-11-25 09:41:34 -0500465BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500466""")
467 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
468 self.track_for_cleanup(self.topdir + "/download1")
469 bitbake("world meta-toolchain -S none")
470 self.write_config("""
471TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800472TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500473BB_NUMBER_THREADS = "${@oe.utils.cpu_count()+1}"
474PARALLEL_MAKE = "-j 2"
475DL_DIR = "${TOPDIR}/download2"
476TIME = "222222"
477DATE = "20161212"
478# Always remove uninative as we're changing proxies
479INHERIT_remove = "uninative"
480INHERIT += "buildstats-summary buildhistory"
481http_proxy = "http://example.com/"
Brad Bishop6dbb3162019-11-25 09:41:34 -0500482BB_SIGNATURE_HANDLER = "OEBasicHash"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500483""")
484 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
485 self.track_for_cleanup(self.topdir + "/download2")
486 bitbake("world meta-toolchain -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 name, shash = name.rsplit('.', 1)
493 # Extract just the machine and recipe name
494 base = os.sep.join(root.rsplit(os.sep, 2)[-2:] + [name])
495 f[base] = shash
496 return f
497
498 def compare_sigfiles(files, files1, files2, compare=False):
499 for k in files:
500 if k in files1 and k in files2:
501 print("%s differs:" % k)
502 if compare:
503 sigdatafile1 = self.topdir + "/tmp-sstatesamehash/stamps/" + k + "." + files1[k]
504 sigdatafile2 = self.topdir + "/tmp-sstatesamehash2/stamps/" + k + "." + files2[k]
505 output = bb.siggen.compare_sigfiles(sigdatafile1, sigdatafile2)
506 if output:
507 print('\n'.join(output))
508 elif k in files1 and k not in files2:
509 print("%s in files1" % k)
510 elif k not in files1 and k in files2:
511 print("%s in files2" % k)
512 else:
513 assert "shouldn't reach here"
514
515 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
516 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
517 # Remove items that are identical in both sets
518 for k,v in files1.items() & files2.items():
519 del files1[k]
520 del files2[k]
521 if not files1 and not files2:
522 # No changes, so we're done
523 return
524
525 files = list(files1.keys() | files2.keys())
526 # this is an expensive computation, thus just compare the first 'max_sigfiles_to_compare' k files
527 max_sigfiles_to_compare = 20
528 first, rest = files[:max_sigfiles_to_compare], files[max_sigfiles_to_compare:]
Brad Bishop316dfdd2018-06-25 12:45:53 -0400529 compare_sigfiles(first, files1, files2, compare=True)
530 compare_sigfiles(rest, files1, files2, compare=False)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500531
532 self.fail("sstate hashes not identical.")