1#! /usr/bin/env python3 2# 3# BitBake Toaster Implementation 4# 5# Copyright (C) 2016 Intel Corporation 6# 7# SPDX-License-Identifier: GPL-2.0-only 8# 9# 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 21from tests.builds.buildtest import BuildTest 22 23 24class BuildCoreImageMinimal(BuildTest): 25 """Build core-image-minimal and test the results""" 26 27 def setUp(self): 28 self.completed_build = self.build("core-image-minimal") 29 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): 49 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() 53 54 self.assertEqual(total_task_order, 55 distinct_task_order, 56 msg='Errors task order is not unique') 57 58 # Check task order sequence for one build - tc=825 59 def test_Task_Order_Sequence(self): 60 cnt_err = [] 61 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") 66 67 cnt_tasks = 0 68 for task in tasks: 69 cnt_tasks += 1 70 if (task['order'] != cnt_tasks): 71 cnt_err.append(task['id']) 72 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'], 107 'sstate_result': task['sstate_result']}) 108 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") 374