blob: 077d6e53746517547fc4b1c8a0f1607eaad25877 [file] [log] [blame]
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001import os
2import shutil
3import glob
4import subprocess
Brad Bishop316dfdd2018-06-25 12:45:53 -04005import tempfile
Brad Bishopd7bf8c12018-02-25 22:55:05 -05006
7from oeqa.selftest.case import OESelftestTestCase
Brad Bishop316dfdd2018-06-25 12:45:53 -04008from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_test_layer, create_temp_layer
Brad Bishopd7bf8c12018-02-25 22:55:05 -05009from oeqa.selftest.cases.sstate import SStateBase
10from oeqa.core.decorator.oeid import OETestID
11
12import bb.siggen
13
14class SStateTests(SStateBase):
Brad Bishop316dfdd2018-06-25 12:45:53 -040015 def test_autorev_sstate_works(self):
16 # Test that a git repository which changes is correctly handled by SRCREV = ${AUTOREV}
17 # when PV does not contain SRCPV
18
19 tempdir = tempfile.mkdtemp(prefix='oeqa')
20 self.track_for_cleanup(tempdir)
21 create_temp_layer(tempdir, 'selftestrecipetool')
22 self.add_command_to_tearDown('bitbake-layers remove-layer %s' % tempdir)
23 runCmd('bitbake-layers add-layer %s' % tempdir)
24
25 # Use dbus-wait as a local git repo we can add a commit between two builds in
26 pn = 'dbus-wait'
27 srcrev = '6cc6077a36fe2648a5f993fe7c16c9632f946517'
28 url = 'git://git.yoctoproject.org/dbus-wait'
29 result = runCmd('git clone %s noname' % url, cwd=tempdir)
30 srcdir = os.path.join(tempdir, 'noname')
31 result = runCmd('git reset --hard %s' % srcrev, cwd=srcdir)
32 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure script in source directory')
33
34 recipefile = os.path.join(tempdir, "recipes-test", "dbus-wait-test", 'dbus-wait-test_git.bb')
35 os.makedirs(os.path.dirname(recipefile))
36 srcuri = 'git://' + srcdir + ';protocol=file'
37 result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri])
38 self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output)
39
40 with open(recipefile, 'a') as f:
41 f.write('SRCREV = "${AUTOREV}"\n')
42 f.write('PV = "1.0"\n')
43
44 bitbake("dbus-wait-test -c fetch")
45 with open(os.path.join(srcdir, "bar.txt"), "w") as f:
46 f.write("foo")
47 result = runCmd('git add bar.txt; git commit -asm "add bar"', cwd=srcdir)
48 bitbake("dbus-wait-test -c unpack")
49
Brad Bishopd7bf8c12018-02-25 22:55:05 -050050
51 # Test sstate files creation and their location
52 def run_test_sstate_creation(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True, should_pass=True):
53 self.config_sstate(temp_sstate_location, [self.sstate_path])
54
55 if self.temp_sstate_location:
56 bitbake(['-cclean'] + targets)
57 else:
58 bitbake(['-ccleansstate'] + targets)
59
60 bitbake(targets)
61 file_tracker = []
62 results = self.search_sstate('|'.join(map(str, targets)), distro_specific, distro_nonspecific)
63 if distro_nonspecific:
64 for r in results:
65 if r.endswith(("_populate_lic.tgz", "_populate_lic.tgz.siginfo", "_fetch.tgz.siginfo", "_unpack.tgz.siginfo", "_patch.tgz.siginfo")):
66 continue
67 file_tracker.append(r)
68 else:
69 file_tracker = results
70
71 if should_pass:
72 self.assertTrue(file_tracker , msg="Could not find sstate files for: %s" % ', '.join(map(str, targets)))
73 else:
74 self.assertTrue(not file_tracker , msg="Found sstate files in the wrong place for: %s (found %s)" % (', '.join(map(str, targets)), str(file_tracker)))
75
76 @OETestID(975)
77 def test_sstate_creation_distro_specific_pass(self):
78 self.run_test_sstate_creation(['binutils-cross-'+ self.tune_arch, 'binutils-native'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
79
80 @OETestID(1374)
81 def test_sstate_creation_distro_specific_fail(self):
82 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)
83
84 @OETestID(976)
85 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
88 @OETestID(1375)
89 def test_sstate_creation_distro_nonspecific_fail(self):
90 self.run_test_sstate_creation(['linux-libc-headers'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True, should_pass=False)
91
92 # Test the sstate files deletion part of the do_cleansstate task
93 def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True):
94 self.config_sstate(temp_sstate_location, [self.sstate_path])
95
96 bitbake(['-ccleansstate'] + targets)
97
98 bitbake(targets)
99 tgz_created = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific, distro_nonspecific)
100 self.assertTrue(tgz_created, msg="Could not find sstate .tgz files for: %s (%s)" % (', '.join(map(str, targets)), str(tgz_created)))
101
102 siginfo_created = self.search_sstate('|'.join(map(str, [s + '.*?\.siginfo$' for s in targets])), distro_specific, distro_nonspecific)
103 self.assertTrue(siginfo_created, msg="Could not find sstate .siginfo files for: %s (%s)" % (', '.join(map(str, targets)), str(siginfo_created)))
104
105 bitbake(['-ccleansstate'] + targets)
106 tgz_removed = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific, distro_nonspecific)
107 self.assertTrue(not tgz_removed, msg="do_cleansstate didn't remove .tgz sstate files for: %s (%s)" % (', '.join(map(str, targets)), str(tgz_removed)))
108
109 @OETestID(977)
110 def test_cleansstate_task_distro_specific_nonspecific(self):
111 targets = ['binutils-cross-'+ self.tune_arch, 'binutils-native']
112 targets.append('linux-libc-headers')
113 self.run_test_cleansstate_task(targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True)
114
115 @OETestID(1376)
116 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
119 @OETestID(1377)
120 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)
133 results = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific=False, distro_nonspecific=True)
134 filtered_results = []
135 for r in results:
136 if r.endswith(("_populate_lic.tgz", "_populate_lic.tgz.siginfo")):
137 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)))
140 file_tracker_1 = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False)
141 self.assertTrue(len(file_tracker_1) >= len(targets), msg = "Not all sstate files ware created for: %s" % ', '.join(map(str, targets)))
142
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)
149 file_tracker_2 = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False)
150 self.assertTrue(len(file_tracker_2) >= len(targets), msg = "Not all sstate files ware created for: %s" % ', '.join(map(str, targets)))
151
152 not_recreated = [x for x in file_tracker_1 if x not in file_tracker_2]
153 self.assertTrue(not_recreated == [], msg="The following sstate files ware not recreated: %s" % ', '.join(map(str, not_recreated)))
154
155 created_once = [x for x in file_tracker_2 if x not in file_tracker_1]
156 self.assertTrue(created_once == [], msg="The following sstate files ware created only in the second run: %s" % ', '.join(map(str, created_once)))
157
158 @OETestID(175)
159 def test_rebuild_distro_specific_sstate_cross_native_targets(self):
160 self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch, 'binutils-native'], temp_sstate_location=True)
161
162 @OETestID(1372)
163 def test_rebuild_distro_specific_sstate_cross_target(self):
164 self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch], temp_sstate_location=True)
165
166 @OETestID(1373)
167 def test_rebuild_distro_specific_sstate_native_target(self):
168 self.run_test_rebuild_distro_specific_sstate(['binutils-native'], temp_sstate_location=True)
169
170
171 # Test the sstate-cache-management script. Each element in the global_config list is used with the corresponding element in the target_config list
172 # 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)
173 def run_test_sstate_cache_management_script(self, target, global_config=[''], target_config=[''], ignore_patterns=[]):
174 self.assertTrue(global_config)
175 self.assertTrue(target_config)
176 self.assertTrue(len(global_config) == len(target_config), msg='Lists global_config and target_config should have the same number of elements')
177 self.config_sstate(temp_sstate_location=True, add_local_mirrors=[self.sstate_path])
178
179 # If buildhistory is enabled, we need to disable version-going-backwards
180 # QA checks for this test. It may report errors otherwise.
181 self.append_config('ERROR_QA_remove = "version-going-backwards"')
182
183 # For not this only checks if random sstate tasks are handled correctly as a group.
184 # In the future we should add control over what tasks we check for.
185
186 sstate_archs_list = []
187 expected_remaining_sstate = []
188 for idx in range(len(target_config)):
189 self.append_config(global_config[idx])
190 self.append_recipeinc(target, target_config[idx])
191 sstate_arch = get_bb_var('SSTATE_PKGARCH', target)
192 if not sstate_arch in sstate_archs_list:
193 sstate_archs_list.append(sstate_arch)
194 if target_config[idx] == target_config[-1]:
195 target_sstate_before_build = self.search_sstate(target + '.*?\.tgz$')
196 bitbake("-cclean %s" % target)
197 result = bitbake(target, ignore_status=True)
198 if target_config[idx] == target_config[-1]:
199 target_sstate_after_build = self.search_sstate(target + '.*?\.tgz$')
200 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)]
201 self.remove_config(global_config[idx])
202 self.remove_recipeinc(target, target_config[idx])
203 self.assertEqual(result.status, 0, msg = "build of %s failed with %s" % (target, result.output))
204
205 runCmd("sstate-cache-management.sh -y --cache-dir=%s --remove-duplicated --extra-archs=%s" % (self.sstate_path, ','.join(map(str, sstate_archs_list))))
206 actual_remaining_sstate = [x for x in self.search_sstate(target + '.*?\.tgz$') if not any(pattern in x for pattern in ignore_patterns)]
207
208 actual_not_expected = [x for x in actual_remaining_sstate if x not in expected_remaining_sstate]
209 self.assertFalse(actual_not_expected, msg="Files should have been removed but ware not: %s" % ', '.join(map(str, actual_not_expected)))
210 expected_not_actual = [x for x in expected_remaining_sstate if x not in actual_remaining_sstate]
211 self.assertFalse(expected_not_actual, msg="Extra files ware removed: %s" ', '.join(map(str, expected_not_actual)))
212
213 @OETestID(973)
214 def test_sstate_cache_management_script_using_pr_1(self):
215 global_config = []
216 target_config = []
217 global_config.append('')
218 target_config.append('PR = "0"')
219 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
220
221 @OETestID(978)
222 def test_sstate_cache_management_script_using_pr_2(self):
223 global_config = []
224 target_config = []
225 global_config.append('')
226 target_config.append('PR = "0"')
227 global_config.append('')
228 target_config.append('PR = "1"')
229 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
230
231 @OETestID(979)
232 def test_sstate_cache_management_script_using_pr_3(self):
233 global_config = []
234 target_config = []
235 global_config.append('MACHINE = "qemux86-64"')
236 target_config.append('PR = "0"')
237 global_config.append(global_config[0])
238 target_config.append('PR = "1"')
239 global_config.append('MACHINE = "qemux86"')
240 target_config.append('PR = "1"')
241 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
242
243 @OETestID(974)
244 def test_sstate_cache_management_script_using_machine(self):
245 global_config = []
246 target_config = []
247 global_config.append('MACHINE = "qemux86-64"')
248 target_config.append('')
249 global_config.append('MACHINE = "qemux86"')
250 target_config.append('')
251 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
252
253 @OETestID(1270)
254 def test_sstate_32_64_same_hash(self):
255 """
256 The sstate checksums for both native and target should not vary whether
257 they're built on a 32 or 64 bit system. Rather than requiring two different
258 build machines and running a builds, override the variables calling uname()
259 manually and check using bitbake -S.
260 """
261
262 self.write_config("""
263MACHINE = "qemux86"
264TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800265TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500266BUILD_ARCH = "x86_64"
267BUILD_OS = "linux"
268SDKMACHINE = "x86_64"
269PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
270""")
271 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
272 bitbake("core-image-sato -S none")
273 self.write_config("""
274MACHINE = "qemux86"
275TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800276TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500277BUILD_ARCH = "i686"
278BUILD_OS = "linux"
279SDKMACHINE = "i686"
280PACKAGE_CLASSES = "package_rpm package_ipk package_deb"
281""")
282 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
283 bitbake("core-image-sato -S none")
284
285 def get_files(d):
286 f = []
287 for root, dirs, files in os.walk(d):
288 if "core-image-sato" in root:
289 # SDKMACHINE changing will change
290 # do_rootfs/do_testimage/do_build stamps of images which
291 # is safe to ignore.
292 continue
293 f.extend(os.path.join(root, name) for name in files)
294 return f
295 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
296 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
297 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]
298 self.maxDiff = None
299 self.assertCountEqual(files1, files2)
300
301
302 @OETestID(1271)
303 def test_sstate_nativelsbstring_same_hash(self):
304 """
305 The sstate checksums should be independent of whichever NATIVELSBSTRING is
306 detected. Rather than requiring two different build machines and running
307 builds, override the variables manually and check using bitbake -S.
308 """
309
310 self.write_config("""
311TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800312TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500313NATIVELSBSTRING = \"DistroA\"
314""")
315 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
316 bitbake("core-image-sato -S none")
317 self.write_config("""
318TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800319TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500320NATIVELSBSTRING = \"DistroB\"
321""")
322 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
323 bitbake("core-image-sato -S none")
324
325 def get_files(d):
326 f = []
327 for root, dirs, files in os.walk(d):
328 f.extend(os.path.join(root, name) for name in files)
329 return f
330 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
331 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
332 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
333 self.maxDiff = None
334 self.assertCountEqual(files1, files2)
335
336 @OETestID(1368)
337 def test_sstate_allarch_samesigs(self):
338 """
339 The sstate checksums of allarch packages should be independent of whichever
340 MACHINE is set. Check this using bitbake -S.
341 Also, rather than duplicate the test, check nativesdk stamps are the same between
342 the two MACHINE values.
343 """
344
345 configA = """
346TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800347TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500348MACHINE = \"qemux86-64\"
349"""
350 configB = """
351TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800352TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500353MACHINE = \"qemuarm\"
354"""
355 self.sstate_allarch_samesigs(configA, configB)
356
357 @OETestID(1645)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800358 def test_sstate_nativesdk_samesigs_multilib(self):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500359 """
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800360 check nativesdk stamps are the same between the two MACHINE values.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500361 """
362
363 configA = """
364TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800365TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500366MACHINE = \"qemux86-64\"
367require conf/multilib.conf
368MULTILIBS = \"multilib:lib32\"
369DEFAULTTUNE_virtclass-multilib-lib32 = \"x86\"
370"""
371 configB = """
372TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800373TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500374MACHINE = \"qemuarm\"
375require conf/multilib.conf
376MULTILIBS = \"\"
377"""
378 self.sstate_allarch_samesigs(configA, configB)
379
380 def sstate_allarch_samesigs(self, configA, configB):
381
382 self.write_config(configA)
383 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
384 bitbake("world meta-toolchain -S none")
385 self.write_config(configB)
386 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
387 bitbake("world meta-toolchain -S none")
388
389 def get_files(d):
390 f = {}
391 for root, dirs, files in os.walk(d):
392 for name in files:
393 if "meta-environment" in root or "cross-canadian" in root:
394 continue
395 if "do_build" not in name:
396 # 1.4.1+gitAUTOINC+302fca9f4c-r0.do_package_write_ipk.sigdata.f3a2a38697da743f0dbed8b56aafcf79
397 (_, task, _, shash) = name.rsplit(".", 3)
398 f[os.path.join(os.path.basename(root), task)] = shash
399 return f
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500400
401 nativesdkdir = os.path.basename(glob.glob(self.topdir + "/tmp-sstatesamehash/stamps/*-nativesdk*-linux")[0])
402
403 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/" + nativesdkdir)
404 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/" + nativesdkdir)
405 self.maxDiff = None
406 self.assertEqual(files1, files2)
407
408 @OETestID(1369)
409 def test_sstate_sametune_samesigs(self):
410 """
411 The sstate checksums of two identical machines (using the same tune) should be the
412 same, apart from changes within the machine specific stamps directory. We use the
413 qemux86copy machine to test this. Also include multilibs in the test.
414 """
415
416 self.write_config("""
417TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800418TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500419MACHINE = \"qemux86\"
420require conf/multilib.conf
421MULTILIBS = "multilib:lib32"
422DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
423""")
424 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
425 bitbake("world meta-toolchain -S none")
426 self.write_config("""
427TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800428TCLIBCAPPEND = \"\"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500429MACHINE = \"qemux86copy\"
430require conf/multilib.conf
431MULTILIBS = "multilib:lib32"
432DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
433""")
434 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
435 bitbake("world meta-toolchain -S none")
436
437 def get_files(d):
438 f = []
439 for root, dirs, files in os.walk(d):
440 for name in files:
441 if "meta-environment" in root or "cross-canadian" in root:
442 continue
443 if "qemux86copy-" in root or "qemux86-" in root:
444 continue
445 if "do_build" not in name and "do_populate_sdk" not in name:
446 f.append(os.path.join(root, name))
447 return f
448 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps")
449 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps")
450 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
451 self.maxDiff = None
452 self.assertCountEqual(files1, files2)
453
454
455 @OETestID(1498)
456 def test_sstate_noop_samesigs(self):
457 """
458 The sstate checksums of two builds with these variables changed or
459 classes inherits should be the same.
460 """
461
462 self.write_config("""
463TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800464TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500465BB_NUMBER_THREADS = "${@oe.utils.cpu_count()}"
466PARALLEL_MAKE = "-j 1"
467DL_DIR = "${TOPDIR}/download1"
468TIME = "111111"
469DATE = "20161111"
470INHERIT_remove = "buildstats-summary buildhistory uninative"
471http_proxy = ""
472""")
473 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash")
474 self.track_for_cleanup(self.topdir + "/download1")
475 bitbake("world meta-toolchain -S none")
476 self.write_config("""
477TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800478TCLIBCAPPEND = ""
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500479BB_NUMBER_THREADS = "${@oe.utils.cpu_count()+1}"
480PARALLEL_MAKE = "-j 2"
481DL_DIR = "${TOPDIR}/download2"
482TIME = "222222"
483DATE = "20161212"
484# Always remove uninative as we're changing proxies
485INHERIT_remove = "uninative"
486INHERIT += "buildstats-summary buildhistory"
487http_proxy = "http://example.com/"
488""")
489 self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2")
490 self.track_for_cleanup(self.topdir + "/download2")
491 bitbake("world meta-toolchain -S none")
492
493 def get_files(d):
494 f = {}
495 for root, dirs, files in os.walk(d):
496 for name in files:
497 name, shash = name.rsplit('.', 1)
498 # Extract just the machine and recipe name
499 base = os.sep.join(root.rsplit(os.sep, 2)[-2:] + [name])
500 f[base] = shash
501 return f
502
503 def compare_sigfiles(files, files1, files2, compare=False):
504 for k in files:
505 if k in files1 and k in files2:
506 print("%s differs:" % k)
507 if compare:
508 sigdatafile1 = self.topdir + "/tmp-sstatesamehash/stamps/" + k + "." + files1[k]
509 sigdatafile2 = self.topdir + "/tmp-sstatesamehash2/stamps/" + k + "." + files2[k]
510 output = bb.siggen.compare_sigfiles(sigdatafile1, sigdatafile2)
511 if output:
512 print('\n'.join(output))
513 elif k in files1 and k not in files2:
514 print("%s in files1" % k)
515 elif k not in files1 and k in files2:
516 print("%s in files2" % k)
517 else:
518 assert "shouldn't reach here"
519
520 files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/")
521 files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/")
522 # Remove items that are identical in both sets
523 for k,v in files1.items() & files2.items():
524 del files1[k]
525 del files2[k]
526 if not files1 and not files2:
527 # No changes, so we're done
528 return
529
530 files = list(files1.keys() | files2.keys())
531 # this is an expensive computation, thus just compare the first 'max_sigfiles_to_compare' k files
532 max_sigfiles_to_compare = 20
533 first, rest = files[:max_sigfiles_to_compare], files[max_sigfiles_to_compare:]
Brad Bishop316dfdd2018-06-25 12:45:53 -0400534 compare_sigfiles(first, files1, files2, compare=True)
535 compare_sigfiles(rest, files1, files2, compare=False)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500536
537 self.fail("sstate hashes not identical.")