blob: 44b6cbec7b602eeae30378db7d9bfc6071ec49bb [file] [log] [blame]
Brad Bishop96ff1982019-08-19 13:50:42 -04001#! /usr/bin/env python3
Patrick Williamsc0f7c042017-02-23 20:41:17 -06002#
3# BitBake Toaster Implementation
4#
5# Copyright (C) 2016 Intel Corporation
6#
Brad Bishopc342db32019-05-15 21:57:59 -04007# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc0f7c042017-02-23 20:41:17 -06008#
Patrick Williamsc0f7c042017-02-23 20:41:17 -06009# Tests were part of openembedded-core oe selftest Authored by: Lucian Musat
10# Ionut Chisanovici, Paul Eggleton and Cristian Iorga
11
12import os
13
14from django.db.models import Q
15
16from orm.models import Target_Image_File, Target_Installed_Package, Task
17from orm.models import Package_Dependency, Recipe_Dependency, Build
18from orm.models import Task_Dependency, Package, Target, Recipe
19from orm.models import CustomImagePackage
20
Brad Bishop6e60e8b2018-02-01 10:27:11 -050021from tests.builds.buildtest import BuildTest
Patrick Williamsc0f7c042017-02-23 20:41:17 -060022
23
24class BuildCoreImageMinimal(BuildTest):
25 """Build core-image-minimal and test the results"""
26
27 def setUp(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050028 self.completed_build = self.build("core-image-minimal")
Patrick Williamsc0f7c042017-02-23 20:41:17 -060029
30 # Check if build name is unique - tc_id=795
31 def test_Build_Unique_Name(self):
32 all_builds = Build.objects.all().count()
33 distinct_builds = Build.objects.values('id').distinct().count()
34 self.assertEqual(distinct_builds,
35 all_builds,
36 msg='Build name is not unique')
37
38 # Check if build cooker log path is unique - tc_id=819
39 def test_Build_Unique_Cooker_Log_Path(self):
40 distinct_path = Build.objects.values(
41 'cooker_log_path').distinct().count()
42 total_builds = Build.objects.values('id').count()
43 self.assertEqual(distinct_path,
44 total_builds,
45 msg='Build cooker log path is not unique')
46
47 # Check if task order is unique for one build - tc=824
48 def test_Task_Unique_Order(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050049 total_task_order = Task.objects.filter(
50 build=self.built).values('order').count()
51 distinct_task_order = Task.objects.filter(
52 build=self.completed_build).values('order').distinct().count()
Patrick Williamsc0f7c042017-02-23 20:41:17 -060053
Brad Bishop6e60e8b2018-02-01 10:27:11 -050054 self.assertEqual(total_task_order,
55 distinct_task_order,
56 msg='Errors task order is not unique')
Patrick Williamsc0f7c042017-02-23 20:41:17 -060057
58 # Check task order sequence for one build - tc=825
59 def test_Task_Order_Sequence(self):
Patrick Williamsc0f7c042017-02-23 20:41:17 -060060 cnt_err = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -050061 tasks = Task.objects.filter(
62 Q(build=self.completed_build),
63 ~Q(order=None),
64 ~Q(task_name__contains='_setscene')
65 ).values('id', 'order').order_by("order")
Patrick Williamsc0f7c042017-02-23 20:41:17 -060066
Brad Bishop6e60e8b2018-02-01 10:27:11 -050067 cnt_tasks = 0
68 for task in tasks:
69 cnt_tasks += 1
70 if (task['order'] != cnt_tasks):
71 cnt_err.append(task['id'])
Patrick Williamsc0f7c042017-02-23 20:41:17 -060072 self.assertEqual(
73 len(cnt_err), 0, msg='Errors for task id: %s' % cnt_err)
74
75 # Check if disk_io matches the difference between EndTimeIO and
76 # StartTimeIO in build stats - tc=828
77 # def test_Task_Disk_IO_TC828(self):
78
79 # Check if outcome = 2 (SSTATE) then sstate_result must be 3 (RESTORED) -
80 # tc=832
81 def test_Task_If_Outcome_2_Sstate_Result_Must_Be_3(self):
82 tasks = Task.objects.filter(outcome=2).values('id', 'sstate_result')
83 cnt_err = []
84 for task in tasks:
85 if (task['sstate_result'] != 3):
86 cnt_err.append(task['id'])
87
88 self.assertEqual(len(cnt_err),
89 0,
90 msg='Errors for task id: %s' % cnt_err)
91
92 # Check if outcome = 1 (COVERED) or 3 (EXISTING) then sstate_result must
93 # be 0 (SSTATE_NA) - tc=833
94 def test_Task_If_Outcome_1_3_Sstate_Result_Must_Be_0(self):
95 tasks = Task.objects.filter(
96 outcome__in=(Task.OUTCOME_COVERED,
97 Task.OUTCOME_PREBUILT)).values('id',
98 'task_name',
99 'sstate_result')
100 cnt_err = []
101
102 for task in tasks:
103 if (task['sstate_result'] != Task.SSTATE_NA and
104 task['sstate_result'] != Task.SSTATE_MISS):
105 cnt_err.append({'id': task['id'],
106 'name': task['task_name'],
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500107 'sstate_result': task['sstate_result']})
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600108
109 self.assertEqual(len(cnt_err),
110 0,
111 msg='Errors for task id: %s' % cnt_err)
112
113 # Check if outcome is 0 (SUCCESS) or 4 (FAILED) then sstate_result must be
114 # 0 (NA), 1 (MISS) or 2 (FAILED) - tc=834
115 def test_Task_If_Outcome_0_4_Sstate_Result_Must_Be_0_1_2(self):
116 tasks = Task.objects.filter(
117 outcome__in=(0, 4)).values('id', 'sstate_result')
118 cnt_err = []
119
120 for task in tasks:
121 if (task['sstate_result'] not in [0, 1, 2]):
122 cnt_err.append(task['id'])
123
124 self.assertEqual(len(cnt_err),
125 0,
126 msg='Errors for task id: %s' % cnt_err)
127
128 # Check if task_executed = TRUE (1), script_type must be 0 (CODING_NA), 2
129 # (CODING_PYTHON), 3 (CODING_SHELL) - tc=891
130 def test_Task_If_Task_Executed_True_Script_Type_0_2_3(self):
131 tasks = Task.objects.filter(
132 task_executed=1).values('id', 'script_type')
133 cnt_err = []
134
135 for task in tasks:
136 if (task['script_type'] not in [0, 2, 3]):
137 cnt_err.append(task['id'])
138 self.assertEqual(len(cnt_err),
139 0,
140 msg='Errors for task id: %s' % cnt_err)
141
142 # Check if task_executed = TRUE (1), outcome must be 0 (SUCCESS) or 4
143 # (FAILED) - tc=836
144 def test_Task_If_Task_Executed_True_Outcome_0_4(self):
145 tasks = Task.objects.filter(task_executed=1).values('id', 'outcome')
146 cnt_err = []
147
148 for task in tasks:
149 if (task['outcome'] not in [0, 4]):
150 cnt_err.append(task['id'])
151
152 self.assertEqual(len(cnt_err),
153 0,
154 msg='Errors for task id: %s' % cnt_err)
155
156 # Check if task_executed = FALSE (0), script_type must be 0 - tc=890
157 def test_Task_If_Task_Executed_False_Script_Type_0(self):
158 tasks = Task.objects.filter(
159 task_executed=0).values('id', 'script_type')
160 cnt_err = []
161
162 for task in tasks:
163 if (task['script_type'] != 0):
164 cnt_err.append(task['id'])
165
166 self.assertEqual(len(cnt_err),
167 0,
168 msg='Errors for task id: %s' % cnt_err)
169
170 # Check if task_executed = FALSE (0) and build outcome = SUCCEEDED (0),
171 # task outcome must be 1 (COVERED), 2 (CACHED), 3 (PREBUILT), 5 (EMPTY) -
172 # tc=837
173 def test_Task_If_Task_Executed_False_Outcome_1_2_3_5(self):
174 builds = Build.objects.filter(outcome=0).values('id')
175 cnt_err = []
176 for build in builds:
177 tasks = Task.objects.filter(
178 build=build['id'], task_executed=0).values('id', 'outcome')
179 for task in tasks:
180 if (task['outcome'] not in [1, 2, 3, 5]):
181 cnt_err.append(task['id'])
182
183 self.assertEqual(len(cnt_err),
184 0,
185 msg='Errors for task id: %s' % cnt_err)
186
187 # Key verification - tc=888
188 def test_Target_Installed_Package(self):
189 rows = Target_Installed_Package.objects.values('id',
190 'target_id',
191 'package_id')
192 cnt_err = []
193
194 for row in rows:
195 target = Target.objects.filter(id=row['target_id']).values('id')
196 package = Package.objects.filter(id=row['package_id']).values('id')
197 if (not target or not package):
198 cnt_err.append(row['id'])
199 self.assertEqual(len(cnt_err),
200 0,
201 msg='Errors for target installed package id: %s' %
202 cnt_err)
203
204 # Key verification - tc=889
205 def test_Task_Dependency(self):
206 rows = Task_Dependency.objects.values('id',
207 'task_id',
208 'depends_on_id')
209 cnt_err = []
210 for row in rows:
211 task_id = Task.objects.filter(id=row['task_id']).values('id')
212 depends_on_id = Task.objects.filter(
213 id=row['depends_on_id']).values('id')
214 if (not task_id or not depends_on_id):
215 cnt_err.append(row['id'])
216 self.assertEqual(len(cnt_err),
217 0,
218 msg='Errors for task dependency id: %s' % cnt_err)
219
220 # Check if build target file_name is populated only if is_image=true AND
221 # orm_build.outcome=0 then if the file exists and its size matches
222 # the file_size value. Need to add the tc in the test run
223 def test_Target_File_Name_Populated(self):
224 builds = Build.objects.filter(outcome=0).values('id')
225 for build in builds:
226 targets = Target.objects.filter(
227 build_id=build['id'], is_image=1).values('id')
228 for target in targets:
229 target_files = Target_Image_File.objects.filter(
230 target_id=target['id']).values('id',
231 'file_name',
232 'file_size')
233 cnt_err = []
234 for file_info in target_files:
235 target_id = file_info['id']
236 target_file_name = file_info['file_name']
237 target_file_size = file_info['file_size']
238 if (not target_file_name or not target_file_size):
239 cnt_err.append(target_id)
240 else:
241 if (not os.path.exists(target_file_name)):
242 cnt_err.append(target_id)
243 else:
244 if (os.path.getsize(target_file_name) !=
245 target_file_size):
246 cnt_err.append(target_id)
247 self.assertEqual(len(cnt_err), 0,
248 msg='Errors for target image file id: %s' %
249 cnt_err)
250
251 # Key verification - tc=884
252 def test_Package_Dependency(self):
253 cnt_err = []
254 deps = Package_Dependency.objects.values(
255 'id', 'package_id', 'depends_on_id')
256 for dep in deps:
257 if (dep['package_id'] == dep['depends_on_id']):
258 cnt_err.append(dep['id'])
259 self.assertEqual(len(cnt_err), 0,
260 msg='Errors for package dependency id: %s' % cnt_err)
261
262 # Recipe key verification, recipe name does not depends on a recipe having
263 # the same name - tc=883
264 def test_Recipe_Dependency(self):
265 deps = Recipe_Dependency.objects.values(
266 'id', 'recipe_id', 'depends_on_id')
267 cnt_err = []
268 for dep in deps:
269 if (not dep['recipe_id'] or not dep['depends_on_id']):
270 cnt_err.append(dep['id'])
271 else:
272 name = Recipe.objects.filter(
273 id=dep['recipe_id']).values('name')
274 dep_name = Recipe.objects.filter(
275 id=dep['depends_on_id']).values('name')
276 if (name == dep_name):
277 cnt_err.append(dep['id'])
278 self.assertEqual(len(cnt_err), 0,
279 msg='Errors for recipe dependency id: %s' % cnt_err)
280
281 # Check if package name does not start with a number (0-9) - tc=846
282 def test_Package_Name_For_Number(self):
283 packages = Package.objects.filter(~Q(size=-1)).values('id', 'name')
284 cnt_err = []
285 for package in packages:
286 if (package['name'][0].isdigit() is True):
287 cnt_err.append(package['id'])
288 self.assertEqual(
289 len(cnt_err), 0, msg='Errors for package id: %s' % cnt_err)
290
291 # Check if package version starts with a number (0-9) - tc=847
292 def test_Package_Version_Starts_With_Number(self):
293 packages = Package.objects.filter(
294 ~Q(size=-1)).values('id', 'version')
295 cnt_err = []
296 for package in packages:
297 if (package['version'][0].isdigit() is False):
298 cnt_err.append(package['id'])
299 self.assertEqual(
300 len(cnt_err), 0, msg='Errors for package id: %s' % cnt_err)
301
302 # Check if package revision starts with 'r' - tc=848
303 def test_Package_Revision_Starts_With_r(self):
304 packages = Package.objects.filter(
305 ~Q(size=-1)).values('id', 'revision')
306 cnt_err = []
307 for package in packages:
308 if (package['revision'][0].startswith("r") is False):
309 cnt_err.append(package['id'])
310 self.assertEqual(
311 len(cnt_err), 0, msg='Errors for package id: %s' % cnt_err)
312
313 # Check the validity of the package build_id
314 # TC must be added in test run
315 def test_Package_Build_Id(self):
316 packages = Package.objects.filter(
317 ~Q(size=-1)).values('id', 'build_id')
318 cnt_err = []
319 for package in packages:
320 build_id = Build.objects.filter(
321 id=package['build_id']).values('id')
322 if (not build_id):
323 # They have no build_id but if they are
324 # CustomImagePackage that's expected
325 try:
326 CustomImagePackage.objects.get(pk=package['id'])
327 except CustomImagePackage.DoesNotExist:
328 cnt_err.append(package['id'])
329
330 self.assertEqual(len(cnt_err),
331 0,
332 msg="Errors for package id: %s they have no build"
333 "associated with them" % cnt_err)
334
335 # Check the validity of package recipe_id
336 # TC must be added in test run
337 def test_Package_Recipe_Id(self):
338 packages = Package.objects.filter(
339 ~Q(size=-1)).values('id', 'recipe_id')
340 cnt_err = []
341 for package in packages:
342 recipe_id = Recipe.objects.filter(
343 id=package['recipe_id']).values('id')
344 if (not recipe_id):
345 cnt_err.append(package['id'])
346 self.assertEqual(
347 len(cnt_err), 0, msg='Errors for package id: %s' % cnt_err)
348
349 # Check if package installed_size field is not null
350 # TC must be aded in test run
351 def test_Package_Installed_Size_Not_NULL(self):
352 packages = Package.objects.filter(
353 installed_size__isnull=True).values('id')
354 cnt_err = []
355 for package in packages:
356 cnt_err.append(package['id'])
357 self.assertEqual(
358 len(cnt_err), 0, msg='Errors for package id: %s' % cnt_err)
359
360 def test_custom_packages_generated(self):
361 """Test if there is a corresponding generated CustomImagePackage"""
362 """ for each of the packages generated"""
363 missing_packages = []
364
365 for package in Package.objects.all():
366 try:
367 CustomImagePackage.objects.get(name=package.name)
368 except CustomImagePackage.DoesNotExist:
369 missing_packages.append(package.name)
370
371 self.assertEqual(len(missing_packages), 0,
372 "Some package were created from the build but their"
373 " corresponding CustomImagePackage was not found")