mirror of
git://git.yoctoproject.org/poky
synced 2026-09-06 02:27:22 +00:00
In order to make the test skipping decorators independent of the oeTest object we rely on the unittest result object to construct skip, fail and error lists used by these decorators. Created a new object getResults that analyses upper frames and retrieves the unittest result object instance, then return a list of failed, skipped and error tests. Also removed the oetest import from decorators.py because it was no longer required. (From OE-Core rev: 4d2d201158236bd4c72546cf8db88681ff921b11) Signed-off-by: Lucian Musat <georgex.l.musat@intel.com> Signed-off-by: Saul Wold <sgw@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
145 lines
4.9 KiB
Python
145 lines
4.9 KiB
Python
# Copyright (C) 2013 Intel Corporation
|
|
#
|
|
# Released under the MIT license (see COPYING.MIT)
|
|
|
|
# Some custom decorators that can be used by unittests
|
|
# Most useful is skipUnlessPassed which can be used for
|
|
# creating dependecies between two test methods.
|
|
|
|
import logging
|
|
import sys
|
|
import unittest
|
|
|
|
#get the "result" object from one of the upper frames provided that one of these upper frames is a unittest.case frame
|
|
class getResults(object):
|
|
def __init__(self):
|
|
#dynamically determine the unittest.case frame and use it to get the name of the test method
|
|
upperf = sys._current_frames().values()[0]
|
|
while (upperf.f_globals['__name__'] != 'unittest.case'):
|
|
upperf = upperf.f_back
|
|
self.faillist = [ seq[0]._testMethodName for seq in upperf.f_locals['result'].failures ]
|
|
self.errorlist = [ seq[0]._testMethodName for seq in upperf.f_locals['result'].errors ]
|
|
#ignore the _ErrorHolder objects from the skipped tests list
|
|
self.skiplist = []
|
|
for seq in upperf.f_locals['result'].skipped:
|
|
try:
|
|
self.skiplist.append(seq[0]._testMethodName)
|
|
except: pass
|
|
|
|
def getFailList(self):
|
|
return self.faillist
|
|
|
|
def getErrorList(self):
|
|
return self.errorlist
|
|
|
|
def getSkipList(self):
|
|
return self.skiplist
|
|
|
|
class skipIfFailure(object):
|
|
|
|
def __init__(self,testcase):
|
|
self.testcase = testcase
|
|
|
|
def __call__(self,f):
|
|
def wrapped_f(*args):
|
|
res = getResults()
|
|
if self.testcase in (res.getFailList() or res.getErrorList()):
|
|
raise unittest.SkipTest("Testcase dependency not met: %s" % self.testcase)
|
|
return f(*args)
|
|
wrapped_f.__name__ = f.__name__
|
|
return wrapped_f
|
|
|
|
class skipIfSkipped(object):
|
|
|
|
def __init__(self,testcase):
|
|
self.testcase = testcase
|
|
|
|
def __call__(self,f):
|
|
def wrapped_f(*args):
|
|
res = getResults()
|
|
if self.testcase in res.getSkipList():
|
|
raise unittest.SkipTest("Testcase dependency not met: %s" % self.testcase)
|
|
return f(*args)
|
|
wrapped_f.__name__ = f.__name__
|
|
return wrapped_f
|
|
|
|
class skipUnlessPassed(object):
|
|
|
|
def __init__(self,testcase):
|
|
self.testcase = testcase
|
|
|
|
def __call__(self,f):
|
|
def wrapped_f(*args):
|
|
res = getResults()
|
|
if self.testcase in res.getSkipList() or \
|
|
self.testcase in res.getFailList() or \
|
|
self.testcase in res.getErrorList():
|
|
raise unittest.SkipTest("Testcase dependency not met: %s" % self.testcase)
|
|
return f(*args)
|
|
wrapped_f.__name__ = f.__name__
|
|
return wrapped_f
|
|
|
|
class testcase(object):
|
|
|
|
def __init__(self, test_case):
|
|
self.test_case = test_case
|
|
|
|
def __call__(self, func):
|
|
def wrapped_f(*args):
|
|
return func(*args)
|
|
wrapped_f.test_case = self.test_case
|
|
return wrapped_f
|
|
|
|
def LogResults(original_class):
|
|
orig_method = original_class.run
|
|
|
|
#rewrite the run method of unittest.TestCase to add testcase logging
|
|
def run(self, result, *args, **kws):
|
|
orig_method(self, result, *args, **kws)
|
|
passed = True
|
|
testMethod = getattr(self, self._testMethodName)
|
|
|
|
#if test case is decorated then use it's number, else use it's name
|
|
try:
|
|
test_case = testMethod.test_case
|
|
except AttributeError:
|
|
test_case = self._testMethodName
|
|
|
|
#create custom logging level for filtering.
|
|
custom_log_level = 100
|
|
logging.addLevelName(custom_log_level, 'RESULTS')
|
|
caller = os.path.basename(sys.argv[0])
|
|
|
|
def results(self, message, *args, **kws):
|
|
if self.isEnabledFor(custom_log_level):
|
|
self.log(custom_log_level, message, *args, **kws)
|
|
logging.Logger.results = results
|
|
|
|
logging.basicConfig(filename=os.path.join(os.getcwd(),'results-'+caller+'.log'),
|
|
filemode='w',
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
datefmt='%H:%M:%S',
|
|
level=custom_log_level)
|
|
local_log = logging.getLogger(caller)
|
|
|
|
#check status of tests and record it
|
|
for (name, msg) in result.errors:
|
|
if self._testMethodName == str(name).split(' ')[0]:
|
|
local_log.results("Testcase "+str(test_case)+": ERROR")
|
|
local_log.results("Testcase "+str(test_case)+":\n"+msg)
|
|
passed = False
|
|
for (name, msg) in result.failures:
|
|
if self._testMethodName == str(name).split(' ')[0]:
|
|
local_log.results("Testcase "+str(test_case)+": FAILED")
|
|
local_log.results("Testcase "+str(test_case)+":\n"+msg)
|
|
passed = False
|
|
for (name, msg) in result.skipped:
|
|
if self._testMethodName == str(name).split(' ')[0]:
|
|
local_log.results("Testcase "+str(test_case)+": SKIPPED")
|
|
passed = False
|
|
if passed:
|
|
local_log.results("Testcase "+str(test_case)+": PASSED")
|
|
|
|
original_class.run = run
|
|
return original_class
|