| 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 |