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