1from pyroute2 import NSPopen 2from distutils.spawn import find_executable 3import traceback 4import distutils.version 5 6import logging, os, sys 7 8if 'PYTHON_TEST_LOGFILE' in os.environ: 9 logfile=os.environ['PYTHON_TEST_LOGFILE'] 10 logging.basicConfig(level=logging.ERROR, filename=logfile, filemode='a') 11else: 12 logging.basicConfig(level=logging.ERROR, stream=sys.stderr) 13 14logger = logging.getLogger() 15 16def has_executable(name): 17 path = find_executable(name) 18 if path is None: 19 raise Exception(name + ": command not found") 20 return path 21 22# This is a decorator that will allow for logging tests, but flagging them as 23# "known to fail". These tests legitimately fail and represent actual bugs, but 24# as these are already documented the test status can be "green" without these 25# tests, similar to catch2's [!mayfail] tag. 26# This is done using the existing python unittest concept of an "expected failure", 27# but it is only done after the fact, if the test fails or raises an exception. 28# It gives all tests a chance to succeed, but if they fail it logs them and 29# continues. 30def mayFail(message): 31 def decorator(func): 32 def wrapper(*args, **kwargs): 33 res = None 34 err = None 35 try: 36 res = func(*args, **kwargs) 37 except BaseException as e: 38 logger.critical("WARNING! Test %s failed, but marked as passed because it is decorated with @mayFail." % 39 args[0]) 40 logger.critical("\tThe reason why this mayFail was: %s" % message) 41 logger.critical("\tThe failure was: \"%s\"" % e) 42 logger.critical("\tStacktrace: \"%s\"" % traceback.format_exc()) 43 testcase=args[0] 44 testcase.TestResult().addExpectedFailure(testcase, e) 45 err = e 46 finally: 47 if err != None: 48 raise err 49 else: 50 return res 51 return wrapper 52 return decorator 53 54class NSPopenWithCheck(NSPopen): 55 """ 56 A wrapper for NSPopen that additionally checks if the program 57 to be executed is available from the system path or not. 58 If found, it proceeds with the usual NSPopen() call. 59 Otherwise, it raises an exception. 60 """ 61 62 def __init__(self, nsname, *argv, **kwarg): 63 name = list(argv)[0][0] 64 has_executable(name) 65 super(NSPopenWithCheck, self).__init__(nsname, *argv, **kwarg) 66 67def kernel_version_ge(major, minor): 68 # True if running kernel is >= X.Y 69 version = distutils.version.LooseVersion(os.uname()[2]).version 70 if version[0] > major: 71 return True 72 if version[0] < major: 73 return False 74 if minor and version[1] < minor: 75 return False 76 return True 77