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