blob: 95d3bf72fc0ee32436d0ca4a4f20140057db462d [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001# Copyright (C) 2013 Intel Corporation
2#
3# Released under the MIT license (see COPYING.MIT)
4
5# Main unittest module used by testimage.bbclass
6# This provides the oeRuntimeTest base class which is inherited by all tests in meta/lib/oeqa/runtime.
7
8# It also has some helper functions and it's responsible for actually starting the tests
9
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050010import os, re, mmap, sys
Patrick Williamsc124f4f2015-09-15 14:41:29 -050011import unittest
12import inspect
13import subprocess
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050014import signal
Patrick Williamsc0f7c042017-02-23 20:41:17 -060015import shutil
16import functools
Patrick Williamsf1e5d692016-03-30 15:21:19 -050017try:
18 import bb
19except ImportError:
20 pass
21import logging
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050022
23import oeqa.runtime
24# Exported test doesn't require sdkext
25try:
26 import oeqa.sdkext
27except ImportError:
28 pass
Patrick Williamsf1e5d692016-03-30 15:21:19 -050029from oeqa.utils.decorators import LogResults, gettag, getResults
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050030from oeqa.utils import avoid_paths_in_environ
Patrick Williamsf1e5d692016-03-30 15:21:19 -050031
32logger = logging.getLogger("BitBake")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050033
34def getVar(obj):
35 #extend form dict, if a variable didn't exists, need find it in testcase
36 class VarDict(dict):
37 def __getitem__(self, key):
38 return gettag(obj, key)
39 return VarDict()
40
41def checkTags(tc, tagexp):
42 return eval(tagexp, None, getVar(tc))
43
Patrick Williamsc124f4f2015-09-15 14:41:29 -050044def filterByTagExp(testsuite, tagexp):
45 if not tagexp:
46 return testsuite
47 caseList = []
48 for each in testsuite:
49 if not isinstance(each, unittest.BaseTestSuite):
50 if checkTags(each, tagexp):
51 caseList.append(each)
52 else:
53 caseList.append(filterByTagExp(each, tagexp))
54 return testsuite.__class__(caseList)
55
Patrick Williamsc124f4f2015-09-15 14:41:29 -050056@LogResults
57class oeTest(unittest.TestCase):
58
Patrick Williamsc0f7c042017-02-23 20:41:17 -060059 pscmd = "ps"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050060 longMessage = True
61
62 @classmethod
63 def hasPackage(self, pkg):
Patrick Williamsc0f7c042017-02-23 20:41:17 -060064 """
65 True if the full package name exists in the manifest, False otherwise.
66 """
67 return pkg in oeTest.tc.pkgmanifest
68
69 @classmethod
70 def hasPackageMatch(self, match):
71 """
72 True if match exists in the manifest as a regular expression substring,
73 False otherwise.
74 """
75 for s in oeTest.tc.pkgmanifest:
76 if re.match(match, s):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050077 return True
78 return False
79
80 @classmethod
81 def hasFeature(self,feature):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050082 if feature in oeTest.tc.imagefeatures or \
83 feature in oeTest.tc.distrofeatures:
84 return True
85 else:
86 return False
87
88class oeRuntimeTest(oeTest):
89 def __init__(self, methodName='runTest'):
90 self.target = oeRuntimeTest.tc.target
91 super(oeRuntimeTest, self).__init__(methodName)
92
93 def setUp(self):
Patrick Williamsc0f7c042017-02-23 20:41:17 -060094 # Install packages in the DUT
95 self.tc.install_uninstall_packages(self.id())
96
Patrick Williamsc124f4f2015-09-15 14:41:29 -050097 # Check if test needs to run
98 if self.tc.sigterm:
99 self.fail("Got SIGTERM")
100 elif (type(self.target).__name__ == "QemuTarget"):
101 self.assertTrue(self.target.check(), msg = "Qemu not running?")
102
Patrick Williamsd7e96312015-09-22 08:09:05 -0500103 self.setUpLocal()
104
105 # a setup method before tests but after the class instantiation
106 def setUpLocal(self):
107 pass
108
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500109 def tearDown(self):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600110 # Unistall packages in the DUT
111 self.tc.install_uninstall_packages(self.id(), False)
112
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500113 res = getResults()
114 # If a test fails or there is an exception dump
115 # for QemuTarget only
116 if (type(self.target).__name__ == "QemuTarget" and
117 (self.id() in res.getErrorList() or
118 self.id() in res.getFailList())):
119 self.tc.host_dumper.create_dir(self._testMethodName)
120 self.tc.host_dumper.dump_host()
121 self.target.target_dumper.dump_target(
122 self.tc.host_dumper.dump_dir)
123 print ("%s dump data stored in %s" % (self._testMethodName,
124 self.tc.host_dumper.dump_dir))
125
126 self.tearDownLocal()
127
128 # Method to be run after tearDown and implemented by child classes
129 def tearDownLocal(self):
130 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500131
132 #TODO: use package_manager.py to install packages on any type of image
133 def install_packages(self, packagelist):
134 for package in packagelist:
135 (status, result) = self.target.run("smart install -y "+package)
136 if status != 0:
137 return status
138
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600139class OETestCalledProcessError(subprocess.CalledProcessError):
140 def __str__(self):
141 if hasattr(self, "stderr"):
142 return "Command '%s' returned non-zero exit status %d with output %s and stderr %s" % (self.cmd, self.returncode, self.output, self.stderr)
143 else:
144 return "Command '%s' returned non-zero exit status %d with output %s" % (self.cmd, self.returncode, self.output)
145
146subprocess.CalledProcessError = OETestCalledProcessError
147
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500148class oeSDKTest(oeTest):
149 def __init__(self, methodName='runTest'):
150 self.sdktestdir = oeSDKTest.tc.sdktestdir
151 super(oeSDKTest, self).__init__(methodName)
152
153 @classmethod
154 def hasHostPackage(self, pkg):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500155 if re.search(pkg, oeTest.tc.hostpkgmanifest):
156 return True
157 return False
158
159 def _run(self, cmd):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600160 return subprocess.check_output(". %s > /dev/null; %s;" % (self.tc.sdkenv, cmd), shell=True, stderr=subprocess.STDOUT).decode("utf-8")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500161
162class oeSDKExtTest(oeSDKTest):
163 def _run(self, cmd):
164 # extensible sdk shows a warning if found bitbake in the path
165 # because can cause contamination, i.e. use devtool from
166 # poky/scripts instead of eSDK one.
167 env = os.environ.copy()
168 paths_to_avoid = ['bitbake/bin', 'poky/scripts']
169 env['PATH'] = avoid_paths_in_environ(paths_to_avoid)
170
171 return subprocess.check_output(". %s > /dev/null;"\
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600172 " %s;" % (self.tc.sdkenv, cmd), stderr=subprocess.STDOUT, shell=True, env=env).decode("utf-8")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500173
174def getmodule(pos=2):
175 # stack returns a list of tuples containg frame information
176 # First element of the list the is current frame, caller is 1
177 frameinfo = inspect.stack()[pos]
178 modname = inspect.getmodulename(frameinfo[1])
179 #modname = inspect.getmodule(frameinfo[0]).__name__
180 return modname
181
182def skipModule(reason, pos=2):
183 modname = getmodule(pos)
184 if modname not in oeTest.tc.testsrequired:
185 raise unittest.SkipTest("%s: %s" % (modname, reason))
186 else:
187 raise Exception("\nTest %s wants to be skipped.\nReason is: %s" \
188 "\nTest was required in TEST_SUITES, so either the condition for skipping is wrong" \
189 "\nor the image really doesn't have the required feature/package when it should." % (modname, reason))
190
191def skipModuleIf(cond, reason):
192
193 if cond:
194 skipModule(reason, 3)
195
196def skipModuleUnless(cond, reason):
197
198 if not cond:
199 skipModule(reason, 3)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500200
201_buffer_logger = ""
202def custom_verbose(msg, *args, **kwargs):
203 global _buffer_logger
204 if msg[-1] != "\n":
205 _buffer_logger += msg
206 else:
207 _buffer_logger += msg
208 try:
209 bb.plain(_buffer_logger.rstrip("\n"), *args, **kwargs)
210 except NameError:
211 logger.info(_buffer_logger.rstrip("\n"), *args, **kwargs)
212 _buffer_logger = ""
213
214class TestContext(object):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600215 def __init__(self, d, exported=False):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500216 self.d = d
217
218 self.testsuites = self._get_test_suites()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600219
220 if exported:
221 path = [os.path.dirname(os.path.abspath(__file__))]
222 extrapath = ""
223 else:
224 path = d.getVar("BBPATH", True).split(':')
225 extrapath = "lib/oeqa"
226
227 self.testslist = self._get_tests_list(path, extrapath)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500228 self.testsrequired = self._get_test_suites_required()
229
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600230 self.filesdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "runtime/files")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500231 self.imagefeatures = d.getVar("IMAGE_FEATURES", True).split()
232 self.distrofeatures = d.getVar("DISTRO_FEATURES", True).split()
233
234 # get testcase list from specified file
235 # if path is a relative path, then relative to build/conf/
236 def _read_testlist(self, fpath, builddir):
237 if not os.path.isabs(fpath):
238 fpath = os.path.join(builddir, "conf", fpath)
239 if not os.path.exists(fpath):
240 bb.fatal("No such manifest file: ", fpath)
241 tcs = []
242 for line in open(fpath).readlines():
243 line = line.strip()
244 if line and not line.startswith("#"):
245 tcs.append(line)
246 return " ".join(tcs)
247
248 # return test list by type also filter if TEST_SUITES is specified
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600249 def _get_tests_list(self, bbpath, extrapath):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500250 testslist = []
251
252 type = self._get_test_namespace()
253
254 # This relies on lib/ under each directory in BBPATH being added to sys.path
255 # (as done by default in base.bbclass)
256 for testname in self.testsuites:
257 if testname != "auto":
258 if testname.startswith("oeqa."):
259 testslist.append(testname)
260 continue
261 found = False
262 for p in bbpath:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600263 if os.path.exists(os.path.join(p, extrapath, type, testname + ".py")):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500264 testslist.append("oeqa." + type + "." + testname)
265 found = True
266 break
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600267 elif os.path.exists(os.path.join(p, extrapath, type, testname.split(".")[0] + ".py")):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500268 testslist.append("oeqa." + type + "." + testname)
269 found = True
270 break
271 if not found:
272 bb.fatal('Test %s specified in TEST_SUITES could not be found in lib/oeqa/runtime under BBPATH' % testname)
273
274 if "auto" in self.testsuites:
275 def add_auto_list(path):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500276 files = sorted([f for f in os.listdir(path) if f.endswith('.py') and not f.startswith('_')])
277 for f in files:
278 module = 'oeqa.' + type + '.' + f[:-3]
279 if module not in testslist:
280 testslist.append(module)
281
282 for p in bbpath:
283 testpath = os.path.join(p, 'lib', 'oeqa', type)
284 bb.debug(2, 'Searching for tests in %s' % testpath)
285 if os.path.exists(testpath):
286 add_auto_list(testpath)
287
288 return testslist
289
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600290 def getTestModules(self):
291 """
292 Returns all the test modules in the testlist.
293 """
294
295 import pkgutil
296
297 modules = []
298 for test in self.testslist:
299 if re.search("\w+\.\w+\.test_\S+", test):
300 test = '.'.join(t.split('.')[:3])
301 module = pkgutil.get_loader(test)
302 modules.append(module)
303
304 return modules
305
306 def getModulefromID(self, test_id):
307 """
308 Returns the test module based on a test id.
309 """
310
311 module_name = ".".join(test_id.split(".")[:3])
312 modules = self.getTestModules()
313 for module in modules:
314 if module.name == module_name:
315 return module
316
317 return None
318
319 def getTests(self, test):
320 '''Return all individual tests executed when running the suite.'''
321 # Unfortunately unittest does not have an API for this, so we have
322 # to rely on implementation details. This only needs to work
323 # for TestSuite containing TestCase.
324 method = getattr(test, '_testMethodName', None)
325 if method:
326 # leaf case: a TestCase
327 yield test
328 else:
329 # Look into TestSuite.
330 tests = getattr(test, '_tests', [])
331 for t1 in tests:
332 for t2 in self.getTests(t1):
333 yield t2
334
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500335 def loadTests(self):
336 setattr(oeTest, "tc", self)
337
338 testloader = unittest.TestLoader()
339 testloader.sortTestMethodsUsing = None
340 suites = [testloader.loadTestsFromName(name) for name in self.testslist]
341 suites = filterByTagExp(suites, getattr(self, "tagexp", None))
342
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500343 # Determine dependencies between suites by looking for @skipUnlessPassed
344 # method annotations. Suite A depends on suite B if any method in A
345 # depends on a method on B.
346 for suite in suites:
347 suite.dependencies = []
348 suite.depth = 0
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600349 for test in self.getTests(suite):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500350 methodname = getattr(test, '_testMethodName', None)
351 if methodname:
352 method = getattr(test, methodname)
353 depends_on = getattr(method, '_depends_on', None)
354 if depends_on:
355 for dep_suite in suites:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600356 if depends_on in [getattr(t, '_testMethodName', None) for t in self.getTests(dep_suite)]:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500357 if dep_suite not in suite.dependencies and \
358 dep_suite is not suite:
359 suite.dependencies.append(dep_suite)
360 break
361 else:
362 logger.warning("Test %s was declared as @skipUnlessPassed('%s') but that test is either not defined or not active. Will run the test anyway." %
363 (test, depends_on))
364
365 # Use brute-force topological sort to determine ordering. Sort by
366 # depth (higher depth = must run later), with original ordering to
367 # break ties.
368 def set_suite_depth(suite):
369 for dep in suite.dependencies:
370 new_depth = set_suite_depth(dep) + 1
371 if new_depth > suite.depth:
372 suite.depth = new_depth
373 return suite.depth
374
375 for index, suite in enumerate(suites):
376 set_suite_depth(suite)
377 suite.index = index
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600378
379 def cmp(a, b):
380 return (a > b) - (a < b)
381
382 def cmpfunc(a, b):
383 return cmp((a.depth, a.index), (b.depth, b.index))
384
385 suites.sort(key=functools.cmp_to_key(cmpfunc))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500386
387 self.suite = testloader.suiteClass(suites)
388
389 return self.suite
390
391 def runTests(self):
392 logger.info("Test modules %s" % self.testslist)
393 if hasattr(self, "tagexp") and self.tagexp:
394 logger.info("Filter test cases by tags: %s" % self.tagexp)
395 logger.info("Found %s tests" % self.suite.countTestCases())
396 runner = unittest.TextTestRunner(verbosity=2)
397 if 'bb' in sys.modules:
398 runner.stream.write = custom_verbose
399
400 return runner.run(self.suite)
401
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600402class RuntimeTestContext(TestContext):
403 def __init__(self, d, target, exported=False):
404 super(RuntimeTestContext, self).__init__(d, exported)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500405
406 self.target = target
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500407
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600408 self.pkgmanifest = {}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500409 manifest = os.path.join(d.getVar("DEPLOY_DIR_IMAGE", True),
410 d.getVar("IMAGE_LINK_NAME", True) + ".manifest")
411 nomanifest = d.getVar("IMAGE_NO_MANIFEST", True)
412 if nomanifest is None or nomanifest != "1":
413 try:
414 with open(manifest) as f:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600415 for line in f:
416 (pkg, arch, version) = line.strip().split()
417 self.pkgmanifest[pkg] = (version, arch)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500418 except IOError as e:
419 bb.fatal("No package manifest file found. Did you build the image?\n%s" % e)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500420
421 def _get_test_namespace(self):
422 return "runtime"
423
424 def _get_test_suites(self):
425 testsuites = []
426
427 manifests = (self.d.getVar("TEST_SUITES_MANIFEST", True) or '').split()
428 if manifests:
429 for manifest in manifests:
430 testsuites.extend(self._read_testlist(manifest,
431 self.d.getVar("TOPDIR", True)).split())
432
433 else:
434 testsuites = self.d.getVar("TEST_SUITES", True).split()
435
436 return testsuites
437
438 def _get_test_suites_required(self):
439 return [t for t in self.d.getVar("TEST_SUITES", True).split() if t != "auto"]
440
441 def loadTests(self):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600442 super(RuntimeTestContext, self).loadTests()
443 if oeTest.hasPackage("procps"):
444 oeRuntimeTest.pscmd = "ps -ef"
445
446 def extract_packages(self):
447 """
448 Find packages that will be needed during runtime.
449 """
450
451 modules = self.getTestModules()
452 bbpaths = self.d.getVar("BBPATH", True).split(":")
453
454 shutil.rmtree(self.d.getVar("TEST_EXTRACTED_DIR", True))
455 shutil.rmtree(self.d.getVar("TEST_PACKAGED_DIR", True))
456 for module in modules:
457 json_file = self._getJsonFile(module)
458 if json_file:
459 needed_packages = self._getNeededPackages(json_file)
460 self._perform_package_extraction(needed_packages)
461
462 def _perform_package_extraction(self, needed_packages):
463 """
464 Extract packages that will be needed during runtime.
465 """
466
467 import oe.path
468
469 extracted_path = self.d.getVar("TEST_EXTRACTED_DIR", True)
470 packaged_path = self.d.getVar("TEST_PACKAGED_DIR", True)
471
472 for key,value in needed_packages.items():
473 packages = ()
474 if isinstance(value, dict):
475 packages = (value, )
476 elif isinstance(value, list):
477 packages = value
478 else:
479 bb.fatal("Failed to process needed packages for %s; "
480 "Value must be a dict or list" % key)
481
482 for package in packages:
483 pkg = package["pkg"]
484 rm = package.get("rm", False)
485 extract = package.get("extract", True)
486 if extract:
487 dst_dir = os.path.join(extracted_path, pkg)
488 else:
489 dst_dir = os.path.join(packaged_path)
490
491 # Extract package and copy it to TEST_EXTRACTED_DIR
492 pkg_dir = self._extract_in_tmpdir(pkg)
493 if extract:
494
495 # Same package used for more than one test,
496 # don't need to extract again.
497 if os.path.exists(dst_dir):
498 continue
499 oe.path.copytree(pkg_dir, dst_dir)
500 shutil.rmtree(pkg_dir)
501
502 # Copy package to TEST_PACKAGED_DIR
503 else:
504 self._copy_package(pkg)
505
506 def _getJsonFile(self, module):
507 """
508 Returns the path of the JSON file for a module, empty if doesn't exitst.
509 """
510
511 module_file = module.path
512 json_file = "%s.json" % module_file.rsplit(".", 1)[0]
513 if os.path.isfile(module_file) and os.path.isfile(json_file):
514 return json_file
515 else:
516 return ""
517
518 def _getNeededPackages(self, json_file, test=None):
519 """
520 Returns a dict with needed packages based on a JSON file.
521
522
523 If a test is specified it will return the dict just for that test.
524 """
525
526 import json
527
528 needed_packages = {}
529
530 with open(json_file) as f:
531 test_packages = json.load(f)
532 for key,value in test_packages.items():
533 needed_packages[key] = value
534
535 if test:
536 if test in needed_packages:
537 needed_packages = needed_packages[test]
538 else:
539 needed_packages = {}
540
541 return needed_packages
542
543 def _extract_in_tmpdir(self, pkg):
544 """"
545 Returns path to a temp directory where the package was
546 extracted without dependencies.
547 """
548
549 from oeqa.utils.package_manager import get_package_manager
550
551 pkg_path = os.path.join(self.d.getVar("TEST_INSTALL_TMP_DIR", True), pkg)
552 pm = get_package_manager(self.d, pkg_path)
553 extract_dir = pm.extract(pkg)
554 shutil.rmtree(pkg_path)
555
556 return extract_dir
557
558 def _copy_package(self, pkg):
559 """
560 Copy the RPM, DEB or IPK package to dst_dir
561 """
562
563 from oeqa.utils.package_manager import get_package_manager
564
565 pkg_path = os.path.join(self.d.getVar("TEST_INSTALL_TMP_DIR", True), pkg)
566 dst_dir = self.d.getVar("TEST_PACKAGED_DIR", True)
567 pm = get_package_manager(self.d, pkg_path)
568 pkg_info = pm.package_info(pkg)
569 file_path = pkg_info[pkg]["filepath"]
570 shutil.copy2(file_path, dst_dir)
571 shutil.rmtree(pkg_path)
572
573 def install_uninstall_packages(self, test_id, pkg_dir, install):
574 """
575 Check if the test requires a package and Install/Unistall it in the DUT
576 """
577
578 test = test_id.split(".")[4]
579 module = self.getModulefromID(test_id)
580 json = self._getJsonFile(module)
581 if json:
582 needed_packages = self._getNeededPackages(json, test)
583 if needed_packages:
584 self._install_uninstall_packages(needed_packages, pkg_dir, install)
585
586 def _install_uninstall_packages(self, needed_packages, pkg_dir, install=True):
587 """
588 Install/Unistall packages in the DUT without using a package manager
589 """
590
591 if isinstance(needed_packages, dict):
592 packages = [needed_packages]
593 elif isinstance(needed_packages, list):
594 packages = needed_packages
595
596 for package in packages:
597 pkg = package["pkg"]
598 rm = package.get("rm", False)
599 extract = package.get("extract", True)
600 src_dir = os.path.join(pkg_dir, pkg)
601
602 # Install package
603 if install and extract:
604 self.target.connection.copy_dir_to(src_dir, "/")
605
606 # Unistall package
607 elif not install and rm:
608 self.target.connection.delete_dir_structure(src_dir, "/")
609
610class ImageTestContext(RuntimeTestContext):
611 def __init__(self, d, target, host_dumper):
612 super(ImageTestContext, self).__init__(d, target)
613
614 self.tagexp = d.getVar("TEST_SUITES_TAGS", True)
615
616 self.host_dumper = host_dumper
617
618 self.sigterm = False
619 self.origsigtermhandler = signal.getsignal(signal.SIGTERM)
620 signal.signal(signal.SIGTERM, self._sigterm_exception)
621
622 def _sigterm_exception(self, signum, stackframe):
623 bb.warn("TestImage received SIGTERM, shutting down...")
624 self.sigterm = True
625 self.target.stop()
626
627 def install_uninstall_packages(self, test_id, install=True):
628 """
629 Check if the test requires a package and Install/Unistall it in the DUT
630 """
631
632 pkg_dir = self.d.getVar("TEST_EXTRACTED_DIR", True)
633 super(ImageTestContext, self).install_uninstall_packages(test_id, pkg_dir, install)
634
635class ExportTestContext(RuntimeTestContext):
636 def __init__(self, d, target, exported=False, parsedArgs={}):
637 """
638 This class is used when exporting tests and when are executed outside OE environment.
639
640 parsedArgs can contain the following:
641 - tag: Filter test by tag.
642 """
643 super(ExportTestContext, self).__init__(d, target, exported)
644
645 tag = parsedArgs.get("tag", None)
646 self.tagexp = tag if tag != None else d.getVar("TEST_SUITES_TAGS", True)
647
648 self.sigterm = None
649
650 def install_uninstall_packages(self, test_id, install=True):
651 """
652 Check if the test requires a package and Install/Unistall it in the DUT
653 """
654
655 export_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
656 extracted_dir = self.d.getVar("TEST_EXPORT_EXTRACTED_DIR", True)
657 pkg_dir = os.path.join(export_dir, extracted_dir)
658 super(ExportTestContext, self).install_uninstall_packages(test_id, pkg_dir, install)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500659
660class SDKTestContext(TestContext):
661 def __init__(self, d, sdktestdir, sdkenv, tcname, *args):
662 super(SDKTestContext, self).__init__(d)
663
664 self.sdktestdir = sdktestdir
665 self.sdkenv = sdkenv
666 self.tcname = tcname
667
668 if not hasattr(self, 'target_manifest'):
669 self.target_manifest = d.getVar("SDK_TARGET_MANIFEST", True)
670 try:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600671 self.pkgmanifest = {}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500672 with open(self.target_manifest) as f:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600673 for line in f:
674 (pkg, arch, version) = line.strip().split()
675 self.pkgmanifest[pkg] = (version, arch)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500676 except IOError as e:
677 bb.fatal("No package manifest file found. Did you build the sdk image?\n%s" % e)
678
679 if not hasattr(self, 'host_manifest'):
680 self.host_manifest = d.getVar("SDK_HOST_MANIFEST", True)
681 try:
682 with open(self.host_manifest) as f:
683 self.hostpkgmanifest = f.read()
684 except IOError as e:
685 bb.fatal("No host package manifest file found. Did you build the sdk image?\n%s" % e)
686
687 def _get_test_namespace(self):
688 return "sdk"
689
690 def _get_test_suites(self):
691 return (self.d.getVar("TEST_SUITES_SDK", True) or "auto").split()
692
693 def _get_test_suites_required(self):
694 return [t for t in (self.d.getVar("TEST_SUITES_SDK", True) or \
695 "auto").split() if t != "auto"]
696
697class SDKExtTestContext(SDKTestContext):
698 def __init__(self, d, sdktestdir, sdkenv, tcname, *args):
699 self.target_manifest = d.getVar("SDK_EXT_TARGET_MANIFEST", True)
700 self.host_manifest = d.getVar("SDK_EXT_HOST_MANIFEST", True)
701 if args:
702 self.cm = args[0] # Compatibility mode for run SDK tests
703 else:
704 self.cm = False
705
706 super(SDKExtTestContext, self).__init__(d, sdktestdir, sdkenv, tcname)
707
708 self.sdkextfilesdir = os.path.join(os.path.dirname(os.path.abspath(
709 oeqa.sdkext.__file__)), "files")
710
711 def _get_test_namespace(self):
712 if self.cm:
713 return "sdk"
714 else:
715 return "sdkext"
716
717 def _get_test_suites(self):
718 return (self.d.getVar("TEST_SUITES_SDK_EXT", True) or "auto").split()
719
720 def _get_test_suites_required(self):
721 return [t for t in (self.d.getVar("TEST_SUITES_SDK_EXT", True) or \
722 "auto").split() if t != "auto"]