blob: c4efc47fe496dd30c28c276a7c362659d7168541 [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
37 @testcase(975)
38 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
46 @testcase(976)
47 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
73 @testcase(977)
74 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
77 @testcase(977)
78 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
114 @testcase(175)
115 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
119 @testcase(175)
120 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.
214 """
215
216 topdir = get_bb_var('TOPDIR')
217 targetvendor = get_bb_var('TARGET_VENDOR')
218 self.write_config("""
219TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
220BUILD_ARCH = \"x86_64\"
221BUILD_OS = \"linux\"
222""")
223 self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
224 bitbake("core-image-sato -S none")
225 self.write_config("""
226TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
227BUILD_ARCH = \"i686\"
228BUILD_OS = \"linux\"
229""")
230 self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
231 bitbake("core-image-sato -S none")
232
233 def get_files(d):
234 f = []
235 for root, dirs, files in os.walk(d):
236 f.extend(os.path.join(root, name) for name in files)
237 return f
238 files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/")
239 files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/")
240 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]
241 self.assertItemsEqual(files1, files2)
242
243
244 @testcase(1271)
245 def test_sstate_nativelsbstring_same_hash(self):
246 """
247 The sstate checksums should be independent of whichever NATIVELSBSTRING is
248 detected. Rather than requiring two different build machines and running
249 builds, override the variables manually and check using bitbake -S.
250 """
251
252 topdir = get_bb_var('TOPDIR')
253 self.write_config("""
254TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
255NATIVELSBSTRING = \"DistroA\"
256""")
257 self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
258 bitbake("core-image-sato -S none")
259 self.write_config("""
260TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
261NATIVELSBSTRING = \"DistroB\"
262""")
263 self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
264 bitbake("core-image-sato -S none")
265
266 def get_files(d):
267 f = []
268 for root, dirs, files in os.walk(d):
269 f.extend(os.path.join(root, name) for name in files)
270 return f
271 files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/")
272 files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/")
273 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
274 self.assertItemsEqual(files1, files2)
275
276 def test_sstate_allarch_samesigs(self):
277 """
278 The sstate checksums off allarch packages should be independent of whichever
279 MACHINE is set. Check this using bitbake -S.
Patrick Williamsd7e96312015-09-22 08:09:05 -0500280 Also, rather than duplicate the test, check nativesdk stamps are the same between
281 the two MACHINE values.
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500282 """
283
284 topdir = get_bb_var('TOPDIR')
285 targetos = get_bb_var('TARGET_OS')
286 targetvendor = get_bb_var('TARGET_VENDOR')
287 self.write_config("""
288TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
289MACHINE = \"qemux86\"
290""")
291 self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
Patrick Williamsd7e96312015-09-22 08:09:05 -0500292 bitbake("world meta-toolchain -S none")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500293 self.write_config("""
294TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
295MACHINE = \"qemuarm\"
296""")
297 self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
Patrick Williamsd7e96312015-09-22 08:09:05 -0500298 bitbake("world meta-toolchain -S none")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500299
300 def get_files(d):
301 f = []
302 for root, dirs, files in os.walk(d):
303 for name in files:
Patrick Williamsd7e96312015-09-22 08:09:05 -0500304 if "meta-environment" in root or "cross-canadian" in root:
305 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500306 if "do_build" not in name:
307 f.append(os.path.join(root, name))
308 return f
309 files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/all" + targetvendor + "-" + targetos)
310 files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/all" + targetvendor + "-" + targetos)
311 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
312 self.maxDiff = None
313 self.assertItemsEqual(files1, files2)
Patrick Williamsd7e96312015-09-22 08:09:05 -0500314
315 nativesdkdir = os.path.basename(glob.glob(topdir + "/tmp-sstatesamehash/stamps/*-nativesdk*-linux")[0])
316
317 files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/" + nativesdkdir)
318 files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/" + nativesdkdir)
319 files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
320 self.maxDiff = None
321 self.assertItemsEqual(files1, files2)
322