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