summaryrefslogtreecommitdiffstats
path: root/meta/lib
diff options
context:
space:
mode:
authorJoshua Watt <jpewhacker@gmail.com>2018-11-19 12:11:13 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2018-11-21 11:54:14 +0000
commit1554c7c3a69e1996c2d901feb22be37aa85c42a5 (patch)
treea49496be4c1a01a70556fb070d67578e65ad8be8 /meta/lib
parentbdffa0ce10870f70e0a7ab7636ff0d797df43e3a (diff)
downloadpoky-1554c7c3a69e1996c2d901feb22be37aa85c42a5.tar.gz
classes/testsdk: Split implementation into classes
Splits the SDK test implementation into configurable Python classes. The classes used for the normal and extensible SDKs are ${TESTSDK_CLASS_NAME} and ${TESTSDKEXT_CLASS_NAME} respectively. This allows SDK machines to override the classes used to implement the tests. For the traditional SDK, a common "run()" function is provided by the class (oeqa.sdk.testsdk.TestSDK), with several hook member functions that can be overridden in child classes, making it easier to have consistent behavior. The extensible SDK class (oeqa.sdkext.testsdk.TestSDKEXT) also has a common "run()" function, but no hooks have yet been added as there is not currently a known use case for create derived classes. These changes should be purely organizational; no functional changes have been made to either the standard SDK or extensible SDK tests. [YOCTO #13020] (From OE-Core rev: a06d53928b22d5f88276023c4d57b206db2f27f9) Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib')
-rw-r--r--meta/lib/oeqa/sdk/testsdk.py142
-rw-r--r--meta/lib/oeqa/sdkext/testsdk.py104
2 files changed, 246 insertions, 0 deletions
diff --git a/meta/lib/oeqa/sdk/testsdk.py b/meta/lib/oeqa/sdk/testsdk.py
new file mode 100644
index 0000000000..632ac50d0c
--- /dev/null
+++ b/meta/lib/oeqa/sdk/testsdk.py
@@ -0,0 +1,142 @@
1# Copyright 2018 by Garmin Ltd. or its subsidiaries
2# Released under the MIT license (see COPYING.MIT)
3
4from oeqa.sdk.context import OESDKTestContext, OESDKTestContextExecutor
5
6class TestSDKBase(object):
7 @staticmethod
8 def get_sdk_configuration(d, test_type):
9 import platform
10 import oe.lsb
11 from oeqa.utils.metadata import get_layers
12 configuration = {'TEST_TYPE': test_type,
13 'MACHINE': d.getVar("MACHINE"),
14 'SDKMACHINE': d.getVar("SDKMACHINE"),
15 'IMAGE_BASENAME': d.getVar("IMAGE_BASENAME"),
16 'IMAGE_PKGTYPE': d.getVar("IMAGE_PKGTYPE"),
17 'STARTTIME': d.getVar("DATETIME"),
18 'HOST_DISTRO': oe.lsb.distro_identifier().replace(' ', '-'),
19 'LAYERS': get_layers(d.getVar("BBLAYERS"))}
20 return configuration
21
22 @staticmethod
23 def get_sdk_json_result_dir(d):
24 json_result_dir = os.path.join(d.getVar("LOG_DIR"), 'oeqa')
25 custom_json_result_dir = d.getVar("OEQA_JSON_RESULT_DIR")
26 if custom_json_result_dir:
27 json_result_dir = custom_json_result_dir
28 return json_result_dir
29
30 @staticmethod
31 def get_sdk_result_id(configuration):
32 return '%s_%s_%s_%s_%s' % (configuration['TEST_TYPE'], configuration['IMAGE_BASENAME'], configuration['SDKMACHINE'], configuration['MACHINE'], configuration['STARTTIME'])
33
34class TestSDK(TestSDKBase):
35 context_executor_class = OESDKTestContextExecutor
36 context_class = OESDKTestContext
37 test_type = 'sdk'
38
39 def get_tcname(self, d):
40 """
41 Get the name of the SDK file
42 """
43 return d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.sh")
44
45 def extract_sdk(self, tcname, sdk_dir, d):
46 """
47 Extract the SDK to the specified location
48 """
49 import subprocess
50
51 try:
52 subprocess.check_output("cd %s; %s <<EOF\n./\nY\nEOF" % (sdk_dir, tcname), shell=True)
53 except subprocess.CalledProcessError as e:
54 bb.fatal("Couldn't install the SDK:\n%s" % e.output.decode("utf-8"))
55
56 def setup_context(self, d):
57 """
58 Return a dictionary of additional arguments that should be passed to
59 the context_class on construction
60 """
61 return dict()
62
63 def run(self, d):
64
65 import os
66 import subprocess
67 import json
68 import logging
69
70 from bb.utils import export_proxies
71 from oeqa.utils import make_logger_bitbake_compatible
72
73 pn = d.getVar("PN")
74 logger = make_logger_bitbake_compatible(logging.getLogger("BitBake"))
75
76 # sdk use network for download projects for build
77 export_proxies(d)
78
79 tcname = self.get_tcname(d)
80
81 if not os.path.exists(tcname):
82 bb.fatal("The toolchain %s is not built. Build it before running the tests: 'bitbake <image> -c populate_sdk' ." % tcname)
83
84 tdname = d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.testdata.json")
85 test_data = json.load(open(tdname, "r"))
86
87 target_pkg_manifest = self.context_executor_class._load_manifest(
88 d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.target.manifest"))
89 host_pkg_manifest = self.context_executor_class._load_manifest(
90 d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.host.manifest"))
91
92 processes = d.getVar("TESTIMAGE_NUMBER_THREADS") or d.getVar("BB_NUMBER_THREADS")
93 if processes:
94 try:
95 import testtools, subunit
96 except ImportError:
97 bb.warn("Failed to import testtools or subunit, the testcases will run serially")
98 processes = None
99
100 sdk_dir = d.expand("${WORKDIR}/testimage-sdk/")
101 bb.utils.remove(sdk_dir, True)
102 bb.utils.mkdirhier(sdk_dir)
103
104 context_args = self.setup_context(d)
105
106 self.extract_sdk(tcname, sdk_dir, d)
107
108 fail = False
109 sdk_envs = self.context_executor_class._get_sdk_environs(sdk_dir)
110 for s in sdk_envs:
111 sdk_env = sdk_envs[s]
112 bb.plain("SDK testing environment: %s" % s)
113 tc = self.context_class(td=test_data, logger=logger, sdk_dir=sdk_dir,
114 sdk_env=sdk_env, target_pkg_manifest=target_pkg_manifest,
115 host_pkg_manifest=host_pkg_manifest, **context_args)
116
117 try:
118 tc.loadTests(self.context_executor_class.default_cases)
119 except Exception as e:
120 import traceback
121 bb.fatal("Loading tests failed:\n%s" % traceback.format_exc())
122
123 if processes:
124 result = tc.runTests(processes=int(processes))
125 else:
126 result = tc.runTests()
127
128 component = "%s %s" % (pn, self.context_executor_class.name)
129 context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env))
130 configuration = self.get_sdk_configuration(d, self.test_type)
131 result.logDetails(self.get_sdk_json_result_dir(d),
132 configuration,
133 self.get_sdk_result_id(configuration))
134 result.logSummary(component, context_msg)
135
136 if not result.wasSuccessful():
137 fail = True
138
139 if fail:
140 bb.fatal("%s - FAILED - check the task log and the commands log" % pn)
141
142
diff --git a/meta/lib/oeqa/sdkext/testsdk.py b/meta/lib/oeqa/sdkext/testsdk.py
new file mode 100644
index 0000000000..57b2e0e03f
--- /dev/null
+++ b/meta/lib/oeqa/sdkext/testsdk.py
@@ -0,0 +1,104 @@
1# Copyright 2018 by Garmin Ltd. or its subsidiaries
2# Released under the MIT license (see COPYING.MIT)
3
4from oeqa.sdk.testsdk import TestSDKBase
5
6class TestSDKExt(TestSDKBase):
7 def run(self, d):
8 import os
9 import json
10 import subprocess
11 import logging
12
13 from bb.utils import export_proxies
14 from oeqa.utils import avoid_paths_in_environ, make_logger_bitbake_compatible, subprocesstweak
15 from oeqa.sdkext.context import OESDKExtTestContext, OESDKExtTestContextExecutor
16
17 pn = d.getVar("PN")
18 logger = make_logger_bitbake_compatible(logging.getLogger("BitBake"))
19
20 # extensible sdk use network
21 export_proxies(d)
22
23 subprocesstweak.errors_have_output()
24
25 # extensible sdk can be contaminated if native programs are
26 # in PATH, i.e. use perl-native instead of eSDK one.
27 paths_to_avoid = [d.getVar('STAGING_DIR'),
28 d.getVar('BASE_WORKDIR')]
29 os.environ['PATH'] = avoid_paths_in_environ(paths_to_avoid)
30
31 tcname = d.expand("${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.sh")
32 if not os.path.exists(tcname):
33 bb.fatal("The toolchain ext %s is not built. Build it before running the" \
34 " tests: 'bitbake <image> -c populate_sdk_ext' ." % tcname)
35
36 tdname = d.expand("${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.testdata.json")
37 test_data = json.load(open(tdname, "r"))
38
39 target_pkg_manifest = OESDKExtTestContextExecutor._load_manifest(
40 d.expand("${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.target.manifest"))
41 host_pkg_manifest = OESDKExtTestContextExecutor._load_manifest(
42 d.expand("${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.host.manifest"))
43
44 sdk_dir = d.expand("${WORKDIR}/testsdkext/")
45 bb.utils.remove(sdk_dir, True)
46 bb.utils.mkdirhier(sdk_dir)
47 try:
48 subprocess.check_output("%s -y -d %s" % (tcname, sdk_dir), shell=True)
49 except subprocess.CalledProcessError as e:
50 msg = "Couldn't install the extensible SDK:\n%s" % e.output.decode("utf-8")
51 logfn = os.path.join(sdk_dir, 'preparing_build_system.log')
52 if os.path.exists(logfn):
53 msg += '\n\nContents of preparing_build_system.log:\n'
54 with open(logfn, 'r') as f:
55 for line in f:
56 msg += line
57 bb.fatal(msg)
58
59 fail = False
60 sdk_envs = OESDKExtTestContextExecutor._get_sdk_environs(sdk_dir)
61 for s in sdk_envs:
62 bb.plain("Extensible SDK testing environment: %s" % s)
63
64 sdk_env = sdk_envs[s]
65
66 # Use our own SSTATE_DIR and DL_DIR so that updates to the eSDK come from our sstate cache
67 # and we don't spend hours downloading kernels for the kernel module test
68 # Abuse auto.conf since local.conf would be overwritten by the SDK
69 with open(os.path.join(sdk_dir, 'conf', 'auto.conf'), 'a+') as f:
70 f.write('SSTATE_MIRRORS += " \\n file://.* file://%s/PATH"\n' % test_data.get('SSTATE_DIR'))
71 f.write('SOURCE_MIRROR_URL = "file://%s"\n' % test_data.get('DL_DIR'))
72 f.write('INHERIT += "own-mirrors"\n')
73 f.write('PREMIRRORS_prepend = " git://git.yoctoproject.org/.* git://%s/git2/git.yoctoproject.org.BASENAME \\n "\n' % test_data.get('DL_DIR'))
74
75 # We need to do this in case we have a minimal SDK
76 subprocess.check_output(". %s > /dev/null; devtool sdk-install meta-extsdk-toolchain" % \
77 sdk_env, cwd=sdk_dir, shell=True, stderr=subprocess.STDOUT)
78
79 tc = OESDKExtTestContext(td=test_data, logger=logger, sdk_dir=sdk_dir,
80 sdk_env=sdk_env, target_pkg_manifest=target_pkg_manifest,
81 host_pkg_manifest=host_pkg_manifest)
82
83 try:
84 tc.loadTests(OESDKExtTestContextExecutor.default_cases)
85 except Exception as e:
86 import traceback
87 bb.fatal("Loading tests failed:\n%s" % traceback.format_exc())
88
89 result = tc.runTests()
90
91 component = "%s %s" % (pn, OESDKExtTestContextExecutor.name)
92 context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env))
93 configuration = self.get_sdk_configuration(d, 'sdkext')
94 result.logDetails(self.get_sdk_json_result_dir(d),
95 configuration,
96 self.get_sdk_result_id(configuration))
97 result.logSummary(component, context_msg)
98
99 if not result.wasSuccessful():
100 fail = True
101
102 if fail:
103 bb.fatal("%s - FAILED - check the task log and the commands log" % pn)
104