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