1# 2# Copyright 2018 by Garmin Ltd. or its subsidiaries 3# 4# SPDX-License-Identifier: MIT 5# 6 7from oeqa.sdk.context import OESDKTestContext, OESDKTestContextExecutor 8 9class TestSDKBase(object): 10 @staticmethod 11 def get_sdk_configuration(d, test_type): 12 import platform 13 import oe.lsb 14 from oeqa.utils.metadata import get_layers 15 configuration = {'TEST_TYPE': test_type, 16 'MACHINE': d.getVar("MACHINE"), 17 'SDKMACHINE': d.getVar("SDKMACHINE"), 18 'IMAGE_BASENAME': d.getVar("IMAGE_BASENAME"), 19 'IMAGE_PKGTYPE': d.getVar("IMAGE_PKGTYPE"), 20 'STARTTIME': d.getVar("DATETIME"), 21 'HOST_DISTRO': oe.lsb.distro_identifier().replace(' ', '-'), 22 'LAYERS': get_layers(d.getVar("BBLAYERS"))} 23 return configuration 24 25 @staticmethod 26 def get_sdk_json_result_dir(d): 27 json_result_dir = os.path.join(d.getVar("LOG_DIR"), 'oeqa') 28 custom_json_result_dir = d.getVar("OEQA_JSON_RESULT_DIR") 29 if custom_json_result_dir: 30 json_result_dir = custom_json_result_dir 31 return json_result_dir 32 33 @staticmethod 34 def get_sdk_result_id(configuration): 35 return '%s_%s_%s_%s_%s' % (configuration['TEST_TYPE'], configuration['IMAGE_BASENAME'], configuration['SDKMACHINE'], configuration['MACHINE'], configuration['STARTTIME']) 36 37class TestSDK(TestSDKBase): 38 context_executor_class = OESDKTestContextExecutor 39 context_class = OESDKTestContext 40 test_type = 'sdk' 41 42 def get_tcname(self, d): 43 """ 44 Get the name of the SDK file 45 """ 46 return d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.sh") 47 48 def extract_sdk(self, tcname, sdk_dir, d): 49 """ 50 Extract the SDK to the specified location 51 """ 52 import subprocess 53 54 try: 55 subprocess.check_output("cd %s; %s <<EOF\n./\nY\nEOF" % (sdk_dir, tcname), shell=True) 56 except subprocess.CalledProcessError as e: 57 bb.fatal("Couldn't install the SDK:\n%s" % e.output.decode("utf-8")) 58 59 def setup_context(self, d): 60 """ 61 Return a dictionary of additional arguments that should be passed to 62 the context_class on construction 63 """ 64 return dict() 65 66 def run(self, d): 67 68 import os 69 import subprocess 70 import json 71 import logging 72 73 from bb.utils import export_proxies 74 from oeqa.utils import make_logger_bitbake_compatible 75 76 pn = d.getVar("PN") 77 logger = make_logger_bitbake_compatible(logging.getLogger("BitBake")) 78 79 # sdk use network for download projects for build 80 export_proxies(d) 81 82 tcname = self.get_tcname(d) 83 84 if not os.path.exists(tcname): 85 bb.fatal("The toolchain %s is not built. Build it before running the tests: 'bitbake <image> -c populate_sdk' ." % tcname) 86 87 tdname = d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.testdata.json") 88 test_data = json.load(open(tdname, "r")) 89 90 target_pkg_manifest = self.context_executor_class._load_manifest( 91 d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.target.manifest")) 92 host_pkg_manifest = self.context_executor_class._load_manifest( 93 d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.host.manifest")) 94 95 processes = d.getVar("TESTIMAGE_NUMBER_THREADS") or d.getVar("BB_NUMBER_THREADS") 96 if processes: 97 try: 98 import testtools, subunit 99 except ImportError: 100 bb.warn("Failed to import testtools or subunit, the testcases will run serially") 101 processes = None 102 103 sdk_dir = d.expand("${WORKDIR}/testimage-sdk/") 104 bb.utils.remove(sdk_dir, True) 105 bb.utils.mkdirhier(sdk_dir) 106 107 context_args = self.setup_context(d) 108 109 self.extract_sdk(tcname, sdk_dir, d) 110 111 fail = False 112 sdk_envs = self.context_executor_class._get_sdk_environs(sdk_dir) 113 for s in sdk_envs: 114 sdk_env = sdk_envs[s] 115 bb.plain("SDK testing environment: %s" % s) 116 tc = self.context_class(td=test_data, logger=logger, sdk_dir=sdk_dir, 117 sdk_env=sdk_env, target_pkg_manifest=target_pkg_manifest, 118 host_pkg_manifest=host_pkg_manifest, **context_args) 119 120 try: 121 tc.loadTests(self.context_executor_class.default_cases) 122 except Exception as e: 123 import traceback 124 bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) 125 126 if processes: 127 result = tc.runTests(processes=int(processes)) 128 else: 129 result = tc.runTests() 130 131 component = "%s %s" % (pn, self.context_executor_class.name) 132 context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env)) 133 configuration = self.get_sdk_configuration(d, self.test_type) 134 result.logDetails(self.get_sdk_json_result_dir(d), 135 configuration, 136 self.get_sdk_result_id(configuration)) 137 result.logSummary(component, context_msg) 138 139 if not result.wasSuccessful(): 140 fail = True 141 142 if fail: 143 bb.fatal("%s - FAILED - check the task log and the commands log" % pn) 144 145 146