77 lines
2.7 KiB
Python
77 lines
2.7 KiB
Python
from pyroute2 import NSPopen
|
|
from distutils.spawn import find_executable
|
|
import traceback
|
|
import distutils.version
|
|
|
|
import logging, os, sys
|
|
|
|
if 'PYTHON_TEST_LOGFILE' in os.environ:
|
|
logfile=os.environ['PYTHON_TEST_LOGFILE']
|
|
logging.basicConfig(level=logging.ERROR, filename=logfile, filemode='a')
|
|
else:
|
|
logging.basicConfig(level=logging.ERROR, stream=sys.stderr)
|
|
|
|
logger = logging.getLogger()
|
|
|
|
def has_executable(name):
|
|
path = find_executable(name)
|
|
if path is None:
|
|
raise Exception(name + ": command not found")
|
|
return path
|
|
|
|
# This is a decorator that will allow for logging tests, but flagging them as
|
|
# "known to fail". These tests legitimately fail and represent actual bugs, but
|
|
# as these are already documented the test status can be "green" without these
|
|
# tests, similar to catch2's [!mayfail] tag.
|
|
# This is done using the existing python unittest concept of an "expected failure",
|
|
# but it is only done after the fact, if the test fails or raises an exception.
|
|
# It gives all tests a chance to succeed, but if they fail it logs them and
|
|
# continues.
|
|
def mayFail(message):
|
|
def decorator(func):
|
|
def wrapper(*args, **kwargs):
|
|
res = None
|
|
err = None
|
|
try:
|
|
res = func(*args, **kwargs)
|
|
except BaseException as e:
|
|
logger.critical("WARNING! Test %s failed, but marked as passed because it is decorated with @mayFail." %
|
|
args[0])
|
|
logger.critical("\tThe reason why this mayFail was: %s" % message)
|
|
logger.critical("\tThe failure was: \"%s\"" % e)
|
|
logger.critical("\tStacktrace: \"%s\"" % traceback.format_exc())
|
|
testcase=args[0]
|
|
testcase.TestResult().addExpectedFailure(testcase, e)
|
|
err = e
|
|
finally:
|
|
if err != None:
|
|
raise err
|
|
else:
|
|
return res
|
|
return wrapper
|
|
return decorator
|
|
|
|
class NSPopenWithCheck(NSPopen):
|
|
"""
|
|
A wrapper for NSPopen that additionally checks if the program
|
|
to be executed is available from the system path or not.
|
|
If found, it proceeds with the usual NSPopen() call.
|
|
Otherwise, it raises an exception.
|
|
"""
|
|
|
|
def __init__(self, nsname, *argv, **kwarg):
|
|
name = list(argv)[0][0]
|
|
has_executable(name)
|
|
super(NSPopenWithCheck, self).__init__(nsname, *argv, **kwarg)
|
|
|
|
def kernel_version_ge(major, minor):
|
|
# True if running kernel is >= X.Y
|
|
version = distutils.version.LooseVersion(os.uname()[2]).version
|
|
if version[0] > major:
|
|
return True
|
|
if version[0] < major:
|
|
return False
|
|
if minor and version[1] < minor:
|
|
return False
|
|
return True
|