summaryrefslogtreecommitdiffstats
path: root/meta/classes
diff options
context:
space:
mode:
authorJoshua Watt <jpewhacker@gmail.com>2018-11-19 12:11:13 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2019-02-06 16:38:30 +0000
commit676046bc36b450f25e213a35000be20e68e7f19e (patch)
tree53625ddf1cf73b7447e392ba16ffb948cb7ab0db /meta/classes
parentf54aac732b70730b6ed393ae8cbacb1a0feab327 (diff)
downloadpoky-676046bc36b450f25e213a35000be20e68e7f19e.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) (From OE-Core rev: d0828522fc3a4bd3f86488edcedcce10833c18dc) Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/classes')
-rw-r--r--meta/classes/testsdk.bbclass217
1 files changed, 15 insertions, 202 deletions
diff --git a/meta/classes/testsdk.bbclass b/meta/classes/testsdk.bbclass
index 458c3f40b0..758a23ac55 100644
--- a/meta/classes/testsdk.bbclass
+++ b/meta/classes/testsdk.bbclass
@@ -14,218 +14,31 @@
14# 14#
15# where "<image-name>" is an image like core-image-sato. 15# where "<image-name>" is an image like core-image-sato.
16 16
17def get_sdk_configuration(d, test_type): 17TESTSDK_CLASS_NAME ?= "oeqa.sdk.testsdk.TestSDK"
18 import platform 18TESTSDKEXT_CLASS_NAME ?= "oeqa.sdkext.testsdk.TestSDKExt"
19 from oeqa.utils.metadata import get_layers
20 configuration = {'TEST_TYPE': test_type,
21 'MACHINE': d.getVar("MACHINE"),
22 'SDKMACHINE': d.getVar("SDKMACHINE"),
23 'IMAGE_BASENAME': d.getVar("IMAGE_BASENAME"),
24 'IMAGE_PKGTYPE': d.getVar("IMAGE_PKGTYPE"),
25 'STARTTIME': d.getVar("DATETIME"),
26 'HOST_DISTRO': oe.lsb.distro_identifier().replace(' ', '-'),
27 'LAYERS': get_layers(d.getVar("BBLAYERS"))}
28 return configuration
29get_sdk_configuration[vardepsexclude] = "DATETIME"
30 19
31def get_sdk_json_result_dir(d): 20def import_and_run(name, d):
32 json_result_dir = os.path.join(d.getVar("LOG_DIR"), 'oeqa') 21 import importlib
33 custom_json_result_dir = d.getVar("OEQA_JSON_RESULT_DIR")
34 if custom_json_result_dir:
35 json_result_dir = custom_json_result_dir
36 return json_result_dir
37 22
38def get_sdk_result_id(configuration): 23 class_name = d.getVar(name)
39 return '%s_%s_%s_%s_%s' % (configuration['TEST_TYPE'], configuration['IMAGE_BASENAME'], configuration['SDKMACHINE'], configuration['MACHINE'], configuration['STARTTIME']) 24 if class_name:
25 module, cls = class_name.rsplit('.', 1)
26 m = importlib.import_module(module)
27 c = getattr(m, cls)()
28 c.run(d)
29 else:
30 bb.warn('No tests were run because %s did not define a class' % name)
40 31
41def testsdk_main(d): 32import_and_run[vardepsexclude] = "DATETIME BB_ORIGENV"
42 import os
43 import subprocess
44 import json
45 import logging
46
47 from bb.utils import export_proxies
48 from oeqa.sdk.context import OESDKTestContext, OESDKTestContextExecutor
49 from oeqa.utils import make_logger_bitbake_compatible
50
51 pn = d.getVar("PN")
52 logger = make_logger_bitbake_compatible(logging.getLogger("BitBake"))
53
54 # sdk use network for download projects for build
55 export_proxies(d)
56
57 tcname = d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.sh")
58 if not os.path.exists(tcname):
59 bb.fatal("The toolchain %s is not built. Build it before running the tests: 'bitbake <image> -c populate_sdk' ." % tcname)
60
61 tdname = d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.testdata.json")
62 test_data = json.load(open(tdname, "r"))
63
64 target_pkg_manifest = OESDKTestContextExecutor._load_manifest(
65 d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.target.manifest"))
66 host_pkg_manifest = OESDKTestContextExecutor._load_manifest(
67 d.expand("${SDK_DEPLOY}/${TOOLCHAIN_OUTPUTNAME}.host.manifest"))
68
69 processes = d.getVar("TESTIMAGE_NUMBER_THREADS") or d.getVar("BB_NUMBER_THREADS")
70 if processes:
71 try:
72 import testtools, subunit
73 except ImportError:
74 bb.warn("Failed to import testtools or subunit, the testcases will run serially")
75 processes = None
76
77 sdk_dir = d.expand("${WORKDIR}/testimage-sdk/")
78 bb.utils.remove(sdk_dir, True)
79 bb.utils.mkdirhier(sdk_dir)
80 try:
81 subprocess.check_output("cd %s; %s <<EOF\n./\nY\nEOF" % (sdk_dir, tcname), shell=True)
82 except subprocess.CalledProcessError as e:
83 bb.fatal("Couldn't install the SDK:\n%s" % e.output.decode("utf-8"))
84
85 fail = False
86 sdk_envs = OESDKTestContextExecutor._get_sdk_environs(sdk_dir)
87 for s in sdk_envs:
88 sdk_env = sdk_envs[s]
89 bb.plain("SDK testing environment: %s" % s)
90 tc = OESDKTestContext(td=test_data, logger=logger, sdk_dir=sdk_dir,
91 sdk_env=sdk_env, target_pkg_manifest=target_pkg_manifest,
92 host_pkg_manifest=host_pkg_manifest)
93
94 try:
95 tc.loadTests(OESDKTestContextExecutor.default_cases)
96 except Exception as e:
97 import traceback
98 bb.fatal("Loading tests failed:\n%s" % traceback.format_exc())
99
100 if processes:
101 result = tc.runTests(processes=int(processes))
102 else:
103 result = tc.runTests()
104
105 component = "%s %s" % (pn, OESDKTestContextExecutor.name)
106 context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env))
107 configuration = get_sdk_configuration(d, 'sdk')
108 result.logDetails(get_sdk_json_result_dir(d),
109 configuration,
110 get_sdk_result_id(configuration))
111 result.logSummary(component, context_msg)
112
113 if not result.wasSuccessful():
114 fail = True
115
116 if fail:
117 bb.fatal("%s - FAILED - check the task log and the commands log" % pn)
118
119testsdk_main[vardepsexclude] =+ "BB_ORIGENV"
120 33
121python do_testsdk() { 34python do_testsdk() {
122 testsdk_main(d) 35 import_and_run('TESTSDK_CLASS_NAME', d)
123} 36}
124addtask testsdk 37addtask testsdk
125do_testsdk[nostamp] = "1" 38do_testsdk[nostamp] = "1"
126 39
127def testsdkext_main(d):
128 import os
129 import json
130 import subprocess
131 import logging
132
133 from bb.utils import export_proxies
134 from oeqa.utils import avoid_paths_in_environ, make_logger_bitbake_compatible, subprocesstweak
135 from oeqa.sdkext.context import OESDKExtTestContext, OESDKExtTestContextExecutor
136
137 pn = d.getVar("PN")
138 logger = make_logger_bitbake_compatible(logging.getLogger("BitBake"))
139
140 # extensible sdk use network
141 export_proxies(d)
142
143 subprocesstweak.errors_have_output()
144
145 # extensible sdk can be contaminated if native programs are
146 # in PATH, i.e. use perl-native instead of eSDK one.
147 paths_to_avoid = [d.getVar('STAGING_DIR'),
148 d.getVar('BASE_WORKDIR')]
149 os.environ['PATH'] = avoid_paths_in_environ(paths_to_avoid)
150
151 tcname = d.expand("${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.sh")
152 if not os.path.exists(tcname):
153 bb.fatal("The toolchain ext %s is not built. Build it before running the" \
154 " tests: 'bitbake <image> -c populate_sdk_ext' ." % tcname)
155
156 tdname = d.expand("${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.testdata.json")
157 test_data = json.load(open(tdname, "r"))
158
159 target_pkg_manifest = OESDKExtTestContextExecutor._load_manifest(
160 d.expand("${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.target.manifest"))
161 host_pkg_manifest = OESDKExtTestContextExecutor._load_manifest(
162 d.expand("${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.host.manifest"))
163
164 sdk_dir = d.expand("${WORKDIR}/testsdkext/")
165 bb.utils.remove(sdk_dir, True)
166 bb.utils.mkdirhier(sdk_dir)
167 try:
168 subprocess.check_output("%s -y -d %s" % (tcname, sdk_dir), shell=True)
169 except subprocess.CalledProcessError as e:
170 msg = "Couldn't install the extensible SDK:\n%s" % e.output.decode("utf-8")
171 logfn = os.path.join(sdk_dir, 'preparing_build_system.log')
172 if os.path.exists(logfn):
173 msg += '\n\nContents of preparing_build_system.log:\n'
174 with open(logfn, 'r') as f:
175 for line in f:
176 msg += line
177 bb.fatal(msg)
178
179 fail = False
180 sdk_envs = OESDKExtTestContextExecutor._get_sdk_environs(sdk_dir)
181 for s in sdk_envs:
182 bb.plain("Extensible SDK testing environment: %s" % s)
183
184 sdk_env = sdk_envs[s]
185
186 # Use our own SSTATE_DIR and DL_DIR so that updates to the eSDK come from our sstate cache
187 # and we don't spend hours downloading kernels for the kernel module test
188 # Abuse auto.conf since local.conf would be overwritten by the SDK
189 with open(os.path.join(sdk_dir, 'conf', 'auto.conf'), 'a+') as f:
190 f.write('SSTATE_MIRRORS += " \\n file://.* file://%s/PATH"\n' % test_data.get('SSTATE_DIR'))
191 f.write('SOURCE_MIRROR_URL = "file://%s"\n' % test_data.get('DL_DIR'))
192 f.write('INHERIT += "own-mirrors"\n')
193 f.write('PREMIRRORS_prepend = " git://git.yoctoproject.org/.* git://%s/git2/git.yoctoproject.org.BASENAME \\n "\n' % test_data.get('DL_DIR'))
194
195 # We need to do this in case we have a minimal SDK
196 subprocess.check_output(". %s > /dev/null; devtool sdk-install meta-extsdk-toolchain" % \
197 sdk_env, cwd=sdk_dir, shell=True, stderr=subprocess.STDOUT)
198
199 tc = OESDKExtTestContext(td=test_data, logger=logger, sdk_dir=sdk_dir,
200 sdk_env=sdk_env, target_pkg_manifest=target_pkg_manifest,
201 host_pkg_manifest=host_pkg_manifest)
202
203 try:
204 tc.loadTests(OESDKExtTestContextExecutor.default_cases)
205 except Exception as e:
206 import traceback
207 bb.fatal("Loading tests failed:\n%s" % traceback.format_exc())
208
209 result = tc.runTests()
210
211 component = "%s %s" % (pn, OESDKExtTestContextExecutor.name)
212 context_msg = "%s:%s" % (os.path.basename(tcname), os.path.basename(sdk_env))
213 configuration = get_sdk_configuration(d, 'sdkext')
214 result.logDetails(get_sdk_json_result_dir(d),
215 configuration,
216 get_sdk_result_id(configuration))
217 result.logSummary(component, context_msg)
218
219 if not result.wasSuccessful():
220 fail = True
221
222 if fail:
223 bb.fatal("%s - FAILED - check the task log and the commands log" % pn)
224
225testsdkext_main[vardepsexclude] =+ "BB_ORIGENV"
226
227python do_testsdkext() { 40python do_testsdkext() {
228 testsdkext_main(d) 41 import_and_run('TESTSDKEXT_CLASS_NAME', d)
229} 42}
230addtask testsdkext 43addtask testsdkext
231do_testsdkext[nostamp] = "1" 44do_testsdkext[nostamp] = "1"