blob: 3c230620edb4ee78c26ac423b9d66c74add37df2 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001import datetime
2import unittest
3import os
4import re
5import shutil
Patrick Williamsd7e96312015-09-22 08:09:05 -05006import glob
Patrick Williamsc124f4f2015-09-15 14:41:29 -05007
8import oeqa.utils.ftools as ftools
9from oeqa.selftest.base import oeSelfTest
10from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_test_layer
11from oeqa.selftest.sstate import SStateBase
12from oeqa.utils.decorators import testcase
13
14class SStateTests(SStateBase):
15
16 # Test sstate files creation and their location
17 def run_test_sstate_creation(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True, should_pass=True):
18 self.config_sstate(temp_sstate_location)
19
20 if self.temp_sstate_location:
21 bitbake(['-cclean'] + targets)
22 else:
23 bitbake(['-ccleansstate'] + targets)
24
25 bitbake(targets)
26 file_tracker = self.search_sstate('|'.join(map(str, targets)), distro_specific, distro_nonspecific)
27 if should_pass:
28 self.assertTrue(file_tracker , msg="Could not find sstate files for: %s" % ', '.join(map(str, targets)))
29 else:
30 self.assertTrue(not file_tracker , msg="Found sstate files in the wrong place for: %s" % ', '.join(map(str, targets)))
31
32 @testcase(975)
33 def test_sstate_creation_distro_specific_pass(self):
34 targetarch = get_bb_var('TUNE_ARCH')
35 self.run_test_sstate_creation(['binutils-cross-'+ targetarch, 'binutils-native'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
36
Patrick Williamsf1e5d692016-03-30 15:21:19 -050037 @testcase(1374)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050038 def test_sstate_creation_distro_specific_fail(self):
39 targetarch = get_bb_var('TUNE_ARCH')
40 self.run_test_sstate_creation(['binutils-cross-'+ targetarch, 'binutils-native'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True, should_pass=False)
41
42 @testcase(976)
43 def test_sstate_creation_distro_nonspecific_pass(self):
44 self.run_test_sstate_creation(['glibc-initial'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
45
Patrick Williamsf1e5d692016-03-30 15:21:19 -050046 @testcase(1375)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050047 def test_sstate_creation_distro_nonspecific_fail(self):
48 self.run_test_sstate_creation(['glibc-initial'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True, should_pass=False)
49
50
51 # Test the sstate files deletion part of the do_cleansstate task
52 def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True):
53 self.config_sstate(temp_sstate_location)
54
55 bitbake(['-ccleansstate'] + targets)
56
57 bitbake(targets)
58 tgz_created = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific, distro_nonspecific)
59 self.assertTrue(tgz_created, msg="Could not find sstate .tgz files for: %s" % ', '.join(map(str, targets)))
60
61 siginfo_created = self.search_sstate('|'.join(map(str, [s + '.*?\.siginfo$' for s in targets])), distro_specific, distro_nonspecific)
62 self.assertTrue(siginfo_created, msg="Could not find sstate .siginfo files for: %s" % ', '.join(map(str, targets)))
63
64 bitbake(['-ccleansstate'] + targets)
65 tgz_removed = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific, distro_nonspecific)
66 self.assertTrue(not tgz_removed, msg="do_cleansstate didn't remove .tgz sstate files for: %s" % ', '.join(map(str, targets)))
67
68 @testcase(977)
69 def test_cleansstate_task_distro_specific_nonspecific(self):
70 targetarch = get_bb_var('TUNE_ARCH')
71 self.run_test_cleansstate_task(['binutils-cross-' + targetarch, 'binutils-native', 'glibc-initial'], distro_specific=True, distro_nonspecific=True, temp_sstate_location=True)
72
Patrick Williamsf1e5d692016-03-30 15:21:19 -050073 @testcase(1376)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050074 def test_cleansstate_task_distro_nonspecific(self):
75 self.run_test_cleansstate_task(['glibc-initial'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True)
76
Patrick Williamsf1e5d692016-03-30 15:21:19 -050077 @testcase(1377)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050078 def test_cleansstate_task_distro_specific(self):
79 targetarch = get_bb_var('TUNE_ARCH')
80 self.run_test_cleansstate_task(['binutils-cross-'+ targetarch, 'binutils-native', 'glibc-initial'], distro_specific=True, distro_nonspecific=False, temp_sstate_location=True)
81
82
83 # Test rebuilding of distro-specific sstate files
84 def run_test_rebuild_distro_specific_sstate(self, targets, temp_sstate_location=True):
85 self.config_sstate(temp_sstate_location)
86
87 bitbake(['-ccleansstate'] + targets)
88
89 bitbake(targets)
90 self.assertTrue(self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific=False, distro_nonspecific=True) == [], msg="Found distro non-specific sstate for: %s" % ', '.join(map(str, targets)))
91 file_tracker_1 = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False)
92 self.assertTrue(len(file_tracker_1) >= len(targets), msg = "Not all sstate files ware created for: %s" % ', '.join(map(str, targets)))
93
94 self.track_for_cleanup(self.distro_specific_sstate + "_old")
95 shutil.copytree(self.distro_specific_sstate, self.distro_specific_sstate + "_old")
96 shutil.rmtree(self.distro_specific_sstate)
97
98 bitbake(['-cclean'] + targets)
99 bitbake(targets)
100 file_tracker_2 = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False)
101 self.assertTrue(len(file_tracker_2) >= len(targets), msg = "Not all sstate files ware created for: %s" % ', '.join(map(str, targets)))
102
103 not_recreated = [x for x in file_tracker_1 if x not in file_tracker_2]
104 self.assertTrue(not_recreated == [], msg="The following sstate files ware not recreated: %s" % ', '.join(map(str, not_recreated)))
105
106 created_once = [x for x in file_tracker_2 if x not in file_tracker_1]
107 self.assertTrue(created_once == [], msg="The following sstate files ware created only in the second run: %s" % ', '.join(map(str, created_once)))
108
109 @testcase(175)
110 def test_rebuild_distro_specific_sstate_cross_native_targets(self):
111 targetarch = get_bb_var('TUNE_ARCH')
112 self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + targetarch, 'binutils-native'], temp_sstate_location=True)
113
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500114 @testcase(1372)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500115 def test_rebuild_distro_specific_sstate_cross_target(self):
116 targetarch = get_bb_var('TUNE_ARCH')
117 self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + targetarch], temp_sstate_location=True)
118
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500119 @testcase(1373)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500120 def test_rebuild_distro_specific_sstate_native_target(self):
121 self.run_test_rebuild_distro_specific_sstate(['binutils-native'], temp_sstate_location=True)
122
123
124 # Test the sstate-cache-management script. Each element in the global_config list is used with the corresponding element in the target_config list
125 # 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)
126 def run_test_sstate_cache_management_script(self, target, global_config=[''], target_config=[''], ignore_patterns=[]):
127 self.assertTrue(global_config)
128 self.assertTrue(target_config)
129 self.assertTrue(len(global_config) == len(target_config), msg='Lists global_config and target_config should have the same number of elements')
130 self.config_sstate(temp_sstate_location=True, add_local_mirrors=[self.sstate_path])
131
132 # If buildhistory is enabled, we need to disable version-going-backwards QA checks for this test. It may report errors otherwise.
133 if ('buildhistory' in get_bb_var('USER_CLASSES')) or ('buildhistory' in get_bb_var('INHERIT')):
134 remove_errors_config = 'ERROR_QA_remove = "version-going-backwards"'
135 self.append_config(remove_errors_config)
136
137 # For not this only checks if random sstate tasks are handled correctly as a group.
138 # In the future we should add control over what tasks we check for.
139
140 sstate_archs_list = []
141 expected_remaining_sstate = []
142 for idx in range(len(target_config)):
143 self.append_config(global_config[idx])
144 self.append_recipeinc(target, target_config[idx])
145 sstate_arch = get_bb_var('SSTATE_PKGARCH', target)
146 if not sstate_arch in sstate_archs_list:
147 sstate_archs_list.append(sstate_arch)
148 if target_config[idx] == target_config[-1]:
149 target_sstate_before_build = self.search_sstate(target + '.*?\.tgz$')
150 bitbake("-cclean %s" % target)
151 result = bitbake(target, ignore_status=True)
152 if target_config[idx] == target_config[-1]:
153 target_sstate_after_build = self.search_sstate(target + '.*?\.tgz$')
154 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)]
155 self.remove_config(global_config[idx])
156 self.remove_recipeinc(target, target_config[idx])
157 self.assertEqual(result.status, 0, msg = "build of %s failed with %s" % (target, result.output))
158
159 runCmd("sstate-cache-management.sh -y --cache-dir=%s --remove-duplicated --extra-archs=%s" % (self.sstate_path, ','.join(map(str, sstate_archs_list))))
160 actual_remaining_sstate = [x for x in self.search_sstate(target + '.*?\.tgz$') if not any(pattern in x for pattern in ignore_patterns)]
161
162 actual_not_expected = [x for x in actual_remaining_sstate if x not in expected_remaining_sstate]
163 self.assertFalse(actual_not_expected, msg="Files should have been removed but ware not: %s" % ', '.join(map(str, actual_not_expected)))
164 expected_not_actual = [x for x in expected_remaining_sstate if x not in actual_remaining_sstate]
165 self.assertFalse(expected_not_actual, msg="Extra files ware removed: %s" ', '.join(map(str, expected_not_actual)))
166
167 @testcase(973)
168 def test_sstate_cache_management_script_using_pr_1(self):
169 global_config = []
170 target_config = []
171 global_config.append('')
172 target_config.append('PR = "0"')
173 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
174
175 @testcase(978)
176 def test_sstate_cache_management_script_using_pr_2(self):
177 global_config = []
178 target_config = []
179 global_config.append('')
180 target_config.append('PR = "0"')
181 global_config.append('')
182 target_config.append('PR = "1"')
183 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
184
185 @testcase(979)
186 def test_sstate_cache_management_script_using_pr_3(self):
187 global_config = []
188 target_config = []
189 global_config.append('MACHINE = "qemux86-64"')
190 target_config.append('PR = "0"')
191 global_config.append(global_config[0])
192 target_config.append('PR = "1"')
193 global_config.append('MACHINE = "qemux86"')
194 target_config.append('PR = "1"')
195 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
196
197 @testcase(974)
198 def test_sstate_cache_management_script_using_machine(self):
199 global_config = []
200 target_config = []
201 global_config.append('MACHINE = "qemux86-64"')
202 target_config.append('')
203 global_config.append('MACHINE = "qemux86"')
204 target_config.append('')
205 self.run_test_sstate_cache_management_script('m4', global_config, target_config, ignore_patterns=['populate_lic'])
206
207 @testcase(1270)
208 def test_sstate_32_64_same_hash(self):
209 """
210 The sstate checksums for both native and target should not vary whether
211 they're built on a 32 or 64 bit system. Rather than requiring two different
212 build machines and running a builds, override the variables calling uname()
213 manually and check using bitbake -S.
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500214
215 Also check that SDKMACHINE changing doesn't change any of these stamps.
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500216 """
217
218 topdir = get_bb_var('TOPDIR')
219 targetvendor = get_bb_var('TARGET_VENDOR')
220 self.write_config("""
221TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
222BUILD_ARCH = \"x86_64\"
223BUILD_OS = \"linux\"
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500224SDKMACHINE = \"x86_64\"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500225""")
226 self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
227 bitbake("core-image-sato -S none")
228 self.write_config("""
229TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
230BUILD_ARCH = \"i686\"
231BUILD_OS = \"linux\"
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500232SDKMACHINE = \"i686\"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500233""")
234 self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
235 bitbake("core-image-sato -S none")
236
237 def get_files(d):
238 f = []
239 for root, dirs, files in os.walk(d):
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500240 if "core-image-sato" in root:
241 # SDKMACHINE changing will change do_rootfs/do_testimage/do_build stamps of core-image-sato itself
242 # which is safe to ignore
243 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500244 f.extend(os.path.join(root, name) for name in files)
245 return f
246 files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/")
247 files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/")
248 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash").replace("i686-linux", "x86_64-linux").replace("i686" + targetvendor + "-linux", "x86_64" + targetvendor + "-linux", ) for x in files2]
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500249 self.maxDiff = None
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500250 self.assertItemsEqual(files1, files2)
251
252
253 @testcase(1271)
254 def test_sstate_nativelsbstring_same_hash(self):
255 """
256 The sstate checksums should be independent of whichever NATIVELSBSTRING is
257 detected. Rather than requiring two different build machines and running
258 builds, override the variables manually and check using bitbake -S.
259 """
260
261 topdir = get_bb_var('TOPDIR')
262 self.write_config("""
263TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
264NATIVELSBSTRING = \"DistroA\"
265""")
266 self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
267 bitbake("core-image-sato -S none")
268 self.write_config("""
269TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
270NATIVELSBSTRING = \"DistroB\"
271""")
272 self.track_for_cleanup(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 f.extend(os.path.join(root, name) for name in files)
279 return f
280 files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/")
281 files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/")
282 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500283 self.maxDiff = None
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500284 self.assertItemsEqual(files1, files2)
285
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500286 @testcase(1368)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500287 def test_sstate_allarch_samesigs(self):
288 """
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500289 The sstate checksums of allarch packages should be independent of whichever
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500290 MACHINE is set. Check this using bitbake -S.
Patrick Williamsd7e96312015-09-22 08:09:05 -0500291 Also, rather than duplicate the test, check nativesdk stamps are the same between
292 the two MACHINE values.
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500293 """
294
295 topdir = get_bb_var('TOPDIR')
296 targetos = get_bb_var('TARGET_OS')
297 targetvendor = get_bb_var('TARGET_VENDOR')
298 self.write_config("""
299TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
300MACHINE = \"qemux86\"
301""")
302 self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
Patrick Williamsd7e96312015-09-22 08:09:05 -0500303 bitbake("world meta-toolchain -S none")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500304 self.write_config("""
305TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
306MACHINE = \"qemuarm\"
307""")
308 self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
Patrick Williamsd7e96312015-09-22 08:09:05 -0500309 bitbake("world meta-toolchain -S none")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500310
311 def get_files(d):
312 f = []
313 for root, dirs, files in os.walk(d):
314 for name in files:
Patrick Williamsd7e96312015-09-22 08:09:05 -0500315 if "meta-environment" in root or "cross-canadian" in root:
316 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500317 if "do_build" not in name:
318 f.append(os.path.join(root, name))
319 return f
320 files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/all" + targetvendor + "-" + targetos)
321 files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/all" + targetvendor + "-" + targetos)
322 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
323 self.maxDiff = None
324 self.assertItemsEqual(files1, files2)
Patrick Williamsd7e96312015-09-22 08:09:05 -0500325
326 nativesdkdir = os.path.basename(glob.glob(topdir + "/tmp-sstatesamehash/stamps/*-nativesdk*-linux")[0])
327
328 files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/" + nativesdkdir)
329 files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/" + nativesdkdir)
330 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
331 self.maxDiff = None
332 self.assertItemsEqual(files1, files2)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500333
334 @testcase(1369)
335 def test_sstate_sametune_samesigs(self):
336 """
337 The sstate checksums of two identical machines (using the same tune) should be the
338 same, apart from changes within the machine specific stamps directory. We use the
339 qemux86copy machine to test this. Also include multilibs in the test.
340 """
341
342 topdir = get_bb_var('TOPDIR')
343 targetos = get_bb_var('TARGET_OS')
344 targetvendor = get_bb_var('TARGET_VENDOR')
345 self.write_config("""
346TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
347MACHINE = \"qemux86\"
348require conf/multilib.conf
349MULTILIBS = "multilib:lib32"
350DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
351""")
352 self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
353 bitbake("world meta-toolchain -S none")
354 self.write_config("""
355TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
356MACHINE = \"qemux86copy\"
357require conf/multilib.conf
358MULTILIBS = "multilib:lib32"
359DEFAULTTUNE_virtclass-multilib-lib32 = "x86"
360""")
361 self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
362 bitbake("world meta-toolchain -S none")
363
364 def get_files(d):
365 f = []
366 for root, dirs, files in os.walk(d):
367 for name in files:
368 if "meta-environment" in root or "cross-canadian" in root:
369 continue
370 if "qemux86copy-" in root or "qemux86-" in root:
371 continue
372 if "do_build" not in name and "do_populate_sdk" not in name:
373 f.append(os.path.join(root, name))
374 return f
375 files1 = get_files(topdir + "/tmp-sstatesamehash/stamps")
376 files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps")
377 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
378 self.maxDiff = None
379 self.assertItemsEqual(files1, files2)