def needs_reflink_fs(test): def no_support(*args): raise SkipTest("btrfs not supported") def not_reflink_fs(*args): raise SkipTest("testdir is not on reflink-capable filesystem") if not has_feature('btrfs-support'): return make_decorator(test)(no_support) elif not is_on_reflink_fs(TESTDIR_NAME): return make_decorator(test)(not_reflink_fs) else: return test
def search_related(test): def skip_test(*args): raise SkipTest("Search not supported") if not is_search_supported(): return make_decorator(test)(skip_test) return test
def decorate(func): def newfunc(*arg, **kw): port = random.randint(8000, 8500) # TODO: ATM we are relying on path being local so we could # start HTTP server in the same directory. FIX IT! SocketServer.TCPServer.allow_reuse_address = True httpd = SocketServer.TCPServer(("", port), SilentHTTPHandler) server_thread = Thread(target=httpd.serve_forever) arg, path = arg[:-1], arg[-1] # There is a problem with Haskell on wheezy trying to # fetch via IPv6 whenever there is a ::1 localhost entry in # /etc/hosts. Apparently fixing that docker image reliably # is not that straightforward, although see # http://jasonincode.com/customizing-hosts-file-in-docker/ # so we just force to use 127.0.0.1 while on wheezy hostname = '127.0.0.1' if on_debian_wheezy else 'localhost' url = 'http://%s:%d/%s/' % (hostname, port, path) lgr.debug("HTTP: serving %s under %s", path, url) server_thread.start() #time.sleep(1) # just give it few ticks try: func(*(arg + (path, url,)), **kw) finally: lgr.debug("HTTP: stopping server") httpd.shutdown() server_thread.join() newfunc = make_decorator(func)(newfunc) return newfunc
def decorate(func): def newfunc(*arg, **kwargs): mvpa2.seed(mvpa2._random_seed) return func(*arg, **kwargs) newfunc = make_decorator(func)(newfunc) return newfunc
def decorate(func): def newfunc(*arg, **kwargs): if __debug__: from mvpa2.base import debug # store a copy old_active = debug.active[:] if entries is None: # turn them all off debug.active = [] else: for e in entries: if e in debug.active: debug.active.remove(e) try: res = func(*arg, **kwargs) return res finally: # we should return the debug states to the original # state regardless either test passes or not! if __debug__: # turn debug targets back on debug.active = old_active newfunc = make_decorator(func)(newfunc) return newfunc
def decorate(func): def newfunc(*arg, **kwargs): timer = Timer(limit, handler) try: log.debug('starting timer in %s for %s', str(datetime.datetime.now()), str(limit)) timer.start() ret = func(*arg, **kwargs) except KeyboardInterrupt: if timer.isAlive: timer.cancel() raise except: if timer.isAlive(): timer.cancel() log.debug('canceled timer in %s because of failure', str(datetime.datetime.now())) raise else: raise TimeExpired, 'Time expired ( and test raised: ' \ + str(sys.exc_info()) + ')', sys.exc_info()[2] if timer.isAlive(): timer.cancel() log.debug('canceled timer in %s', str(datetime.datetime.now())) else: log.debug('timer has expired', str(datetime.datetime.now())) raise TimeExpired("time limit exceeded") return ret newfunc = make_decorator(func)(newfunc) return newfunc
def hash_setup(test): def hash_test(): sys.stdout = output = io.BytesIO() test_hash = test() output.seek(0) test_hash = hashlib.md5(output.read()).hexdigest() output.close() # Get the true hash try: true_hash_file = open(test.__name__ + '.hash', 'r') except IOError: # File doesn't exist because it's a new test and there's no # true hash file true_hash_file = open(test.__name__ + '.hash', 'w') true_hash_file.write(test_hash + '\n') true_hash_file.close() true_hash_file = open(test.__name__ + '.hash', 'r') raise NewTestError("New test found. Run again.") true_hash = true_hash_file.read().strip() true_hash_file.close() assert true_hash == test_hash, 'Test "{}" failed with hash {}'.format( test.__name__, test_hash) return make_decorator(test)(hash_test)
def skip(f): """ Decorator to indicate a test should be skipped. """ def g(*args, **kw): raise SkipTest() return make_decorator(f)(g)
def deprecated(f): """ Decorator to indicate a test is deprecated. """ def g(*args, **kw): raise DeprecatedTest() return make_decorator(f)(g)
def dec(in_func): if cond: def wrapper(): raise nose.SkipTest(msg) return make_decorator(in_func)(wrapper) else: return in_func
def decorator(func): def timed_out(_signum, frame): raise TestTimedOut(time_limit, frame) def newfunc(*args, **kwargs): try: # Will only work on unix systems orig_handler = signal.signal(signal.SIGALRM, timed_out) signal.alarm(time_limit) except AttributeError: pass try: rc = func(*args, **kwargs) finally: try: # Will only work on unix systems signal.alarm(0) signal.signal(signal.SIGALRM, orig_handler) except AttributeError: pass return rc newfunc = make_decorator(func)(newfunc) return newfunc
def regex_related(test): def skip_test(*args): raise SkipTest("Regex not supported") if not is_regex_supported(): return make_decorator(test)(skip_test) return test
def transplant_func(func, module): """ Make a function imported from module A appear as if it is located in module B. >>> from pprint import pprint >>> pprint.__module__ 'pprint' >>> pp = transplant_func(pprint, __name__) >>> pp.__module__ 'nose.util' The original function is not modified. >>> pprint.__module__ 'pprint' Calling the transplanted function calls the original. >>> pp([1, 2]) [1, 2] >>> pprint([1,2]) [1, 2] """ from nose.tools import make_decorator def newfunc(*arg, **kw): return func(*arg, **kw) newfunc = make_decorator(func)(newfunc) newfunc.__module__ = module return newfunc
def snapshot(f): "Takes an MD5 snapshot of video for test acceptance" @wraps(f) def wrapper(*args, **kwargs): filename = f(*args, **kwargs) snapshot_name = f.func_name print "snapshot:", snapshot_name snapshot_filename = os.path.join(snapshot_dir, snapshot_name) snapshot_md5_filename = snapshot_filename + '.md5' snapshot_mov_filename = snapshot_filename + '.mov' # Do we have an existing snapshot in snapshots directory? if not os.path.exists(snapshot_md5_filename): prompt_compare(snapshot_mov_filename, snapshot_md5_filename, filename) else: # otherwise we have a snapshot sample_md5 = md5sum(filename) snapshot_md5 = file(snapshot_md5_filename).read() if sample_md5 == snapshot_md5: print "snapshot: success, they are the same!" else: prompt_compare(snapshot_mov_filename, snapshot_md5_filename, filename) if os.path.exists(filename): print "snapshot: removing", filename os.remove(filename) wrapper = make_decorator(f)(wrapper) return wrapper
def decorate(func): def newfunc(*arg, **kwargs): nfailed, i = 0, 0 # define i just in case for i in range(niter): try: ret = func(*arg, **kwargs) if i + 1 - nfailed >= niter - nfailures: # so we know already that we wouldn't go over # nfailures break except AssertionError as e: nfailed += 1 if __debug__: debug('TEST', "Upon %i-th run, test %s failed with %s", (i, func.__name__, e)) if nfailed > nfailures: if __debug__: debug( 'TEST', "Ran %s %i times. Got %d failures, " "while was allowed %d " "-- re-throwing the last failure %s", (func.__name__, i + 1, nfailed, nfailures, e)) exc_info = sys.exc_info() raise exc_info[1].with_traceback(exc_info[2]) if __debug__: debug('TEST', "Ran %s %i times. Got %d failures.", (func.__name__, i + 1, nfailed)) return ret newfunc = make_decorator(func)(newfunc) return newfunc
def decorate(func): def newfunc(*arg, **kw): port = random.randint(8000, 8500) # TODO: ATM we are relying on path being local so we could # start HTTP server in the same directory. FIX IT! SocketServer.TCPServer.allow_reuse_address = True httpd = SocketServer.TCPServer(("", port), SilentHTTPHandler) server_thread = Thread(target=httpd.serve_forever) arg, path = arg[:-1], arg[-1] # There is a problem with Haskell on wheezy trying to # fetch via IPv6 whenever there is a ::1 localhost entry in # /etc/hosts. Apparently fixing that docker image reliably # is not that straightforward, although see # http://jasonincode.com/customizing-hosts-file-in-docker/ # so we just force to use 127.0.0.1 while on wheezy hostname = '127.0.0.1' if on_debian_wheezy else 'localhost' url = 'http://%s:%d/%s/' % (hostname, port, path) lgr.debug("HTTP: serving %s under %s", path, url) server_thread.start() #time.sleep(1) # just give it few ticks try: func(*(arg + ( path, url, )), **kw) finally: lgr.debug("HTTP: stopping server") httpd.shutdown() server_thread.join() newfunc = make_decorator(func)(newfunc) return newfunc
def dec(in_func): # make the wrapper function # if the condition is True if cond: def inner_wrap(): # try the test anywoy try: in_func() # when in fails, raises KnownFailureTest # which is registered with nose and it will be marked # as K in the results except Exception: raise KnownFailureTest() # if it does not fail, raise KnownFailureDidNotFailTest which # is a normal exception. This may seem counter-intuitive # but knowing when tests that _should_ fail don't can be useful else: raise KnownFailureDidNotFailTest() # use `make_decorator` from nose to make sure that the meta-data on # the function is forwarded properly (name, teardown, setup, etc) return make_decorator(in_func)(inner_wrap) # if the condition is false, don't make a wrapper function # this is effectively a no-op else: return in_func
def decorator(func): # Wrap the test function to call, but with a timeout def wrapper(*args, **kwargs): # First, install the SIGALRM signal handler prev_hndlr = signal.signal(signal.SIGALRM, handler) try: # Set up the alarm signal.alarm(timeout) # Run the test function result = func(*args, **kwargs) finally: # Stop the alarm signal.alarm(0) # Restore the signal handler signal.signal(signal.SIGALRM, prev_hndlr) # Return the result return result # Replace func with wrapper wrapper = tools.make_decorator(func)(wrapper) return wrapper
def use_tdb(func): def new_func(*a, **kw): connect_to_test_db() flush_mongo() func(*a, **kw) flush_mongo() return make_decorator(func)(new_func)
def needs_uge(func): def inner(*args, **kwargs): from drmaa2 import Drmaa2Exception if not os.environ.get('SGE_ROOT'): raise Drmaa2Exception('SGE_ROOT is not defined.') return func(*args, **kwargs) return make_decorator(func)(inner)
def needs_uge(func): def inner(*args, **kwargs): from uge.exceptions.configuration_error import ConfigurationError if 'SGE_ROOT' not in os.environ: raise ConfigurationError('SGE_ROOT is not defined.') return func(*args, **kwargs) return make_decorator(func)(inner)
def requires_login(fn): def __requires_login(*args, **kwargs): cls = args[0] cls.relogin() fn(*args, **kwargs) __requires_login = make_decorator(fn)(__requires_login) return __requires_login
def python3only(func): name = func.__name__ def newfunc(*arg, **kw): if sys.version_info[0] == 3: func(*arg, **kw) newfunc = make_decorator(func)(newfunc) return newfunc
def need_python_27(func): def inner(*args, **kwargs): from sys import version_info as v if v[0] <= 2 and v[1] < 7: raise SkipTest("At least Python 2.7 required") return func(*args, **kwargs) return make_decorator(func)(inner)
def decorator(func): def new_func(*args, **kwargs): with assert_raises(exception, glob=glob, regex=regex, match_case=match_case): return func(*args, **kwargs) return tools.make_decorator(func)(new_func)
def decorate(func): def newfunc(*arg, **kw): import time start = time.time() ret = func(*arg, **kw) end = time.time() sys.stderr.write('%s took %2fs\n' % (func.__name__, end - start)) return ret newfunc = make_decorator(func)(newfunc) return newfunc
def elapsed(func): """ Useful decorator to print out the elapsed time for a unit test. """ def call_elapsed(*args, **kwargs): start_time = time.time() func(*args, **kwargs) sys.__stdout__.write('Time elapsed: %s' % (time.time() - start_time, )) return make_decorator(func)(call_elapsed)
def elapsed(func): """ Useful decorator to print out the elapsed time for a unit test. """ def call_elapsed(*args, **kwargs): start_time = time.time() func(*args, **kwargs) sys.__stdout__.write('Time elapsed: %s' % (time.time() - start_time,)) return make_decorator(func)(call_elapsed)
def compare_images_decorator(func): import inspect _file = inspect.getfile(func) def decorated(): func() for fignum, baseline in zip(plt.get_fignums(), baseline_images): figure = plt.figure(fignum) _assert_same_figure_images(figure, baseline, _file, tol=tol) # also use the cleanup decorator! return make_decorator(cleanup(func))(decorated)
def needs_config(func): def inner(*args, **kwargs): try: create_config_manager() except Exception as ex: print(ex) raise SkipTest("Config manager instance could not be created.") return func(*args, **kwargs) return make_decorator(func)(inner)
def with_script(func): def wrapper(*args, **kwargs): with script.context() as ctx: prepare_databases(ctx.db) ctx.db.session.commit() with script.context() as ctx: func(script, *args, **kwargs) wrapper = make_decorator(func)(wrapper) return wrapper
def decorate(func): def newfunc(*args, **kwargs): with patch( 'remo.base.decorators.messages.warning') as messages_mock: with patch('remo.base.decorators.HttpResponseRedirect', wraps=HttpResponseRedirect) as redirect_mock: func(*args, **kwargs) ok_(messages_mock.called, 'messages.warning() was not called.') ok_(redirect_mock.called) newfunc = make_decorator(func)(newfunc) return newfunc
def decorate(func): def newfunc(*args, **kwargs): with nested( patch('remo.base.decorators.messages.error'), patch('remo.base.decorators.redirect', wraps=redirect)) as (messages_mock, redirect_mock): func(*args, **kwargs) ok_(messages_mock.called, 'messages.error() was not called.') redirect_mock.assert_called_with('main') newfunc = make_decorator(func)(newfunc) return newfunc
def with_database(func): def wrapper(*args, **kwargs): with closing(engine.connect()) as conn: prepare_sequences(conn) trans = conn.begin() try: func(conn, *args, **kwargs) finally: trans.rollback() wrapper = make_decorator(func)(wrapper) return wrapper
def _requires_game_page(fn): fn.__requires_game_page = gid or 0 def __requires_game_page(*args, **kwargs): cls = args[0] cls.goto(urlparse.urljoin(cls.get_root_url(), '/game?gid=%i#board' % fn.__requires_game_page)) fn(*args, **kwargs) __requires_game_page = make_decorator(fn)(__requires_game_page) return __requires_game_page
def _requires_url(fn): fn.__requires_url = url def __requires_url(*args, **kwargs): cls = args[0] cls.goto(urlparse.urljoin(cls.get_root_url(), fn.__requires_url)) fn(*args, **kwargs) __requires_url = make_decorator(fn)(__requires_url) return __requires_url
def _requires_game(fn): fn.__requires_game_creator = creator def __requires_game(*args, **kwargs): cls = args[0] cls._appserver.execute_in_db(fn.__requires_game_creator) fn(*args, **kwargs) __requires_game_page = make_decorator(fn)(__requires_game) return __requires_game
def decorate(func): def newfunc(*args, **kwargs): with nested( patch('mozillians.common.middleware.messages.warning'), patch('mozillians.common.middleware.login_required', wraps=login_required)) as (messages_mock, login_mock): func(*args, **kwargs) ok_(messages_mock.called, 'messages.warning() was not called.') ok_(login_mock.called, 'login_required() was not called.') newfunc = make_decorator(func)(newfunc) return newfunc
def decorate(func): def newfunc(*args, **kwargs): with nested( patch('mozillians.common.middleware.messages.error'), patch('mozillians.common.middleware.redirect', wraps=redirect)) as (messages_mock, redirect_mock): func(*args, **kwargs) ok_(messages_mock.called, 'messages.warning() was not called.') redirect_mock.assert_called_with('phonebook:home') newfunc = make_decorator(func)(newfunc) return newfunc
def decorate(func): def newfunc(*args, **kwargs): with nested( patch('mozillians.common.middleware.messages.error'), patch('mozillians.common.middleware.redirect', wraps=redirect)) as (messages_mock, redirect_mock): func(*args, **kwargs) ok_(messages_mock.called, 'messages.warning() was not called.') redirect_mock.assert_called_with('home') newfunc = make_decorator(func)(newfunc) return newfunc
def labile(niter=3, nfailures=1): """Decorator for labile tests -- runs multiple times Let's reduce probability of random failures but re-running the test multiple times allowing to fail few in a row. Makes sense only for tests which run on random data, so usually decorated with reseed_rng. Otherwise it is unlikely that result would change if algorithms are deterministic and operate on the same data Similar in idea to https://pypi.python.org/pypi/flaky . Parameters ---------- niter: int, optional How many iterations to run maximum nfailures: int, optional How many failures to allow """ def decorate(func): def newfunc(*arg, **kwargs): nfailed, i = 0, 0 # define i just in case for i in xrange(niter): try: ret = func(*arg, **kwargs) if i + 1 - nfailed >= niter - nfailures: # so we know already that we wouldn't go over # nfailures break except AssertionError, e: nfailed += 1 if __debug__: debug('TEST', "Upon %i-th run, test %s failed with %s", (i, func.__name__, e)) if nfailed > nfailures: if __debug__: debug('TEST', "Ran %s %i times. Got %d failures, " "while was allowed %d " "-- re-throwing the last failure %s", (func.__name__, i + 1, nfailed, nfailures, e)) exc_info = sys.exc_info() raise exc_info[1], None, exc_info[2] if __debug__: debug('TEST', "Ran %s %i times. Got %d failures.", (func.__name__, i + 1, nfailed)) return ret newfunc = make_decorator(func)(newfunc) return newfunc
def with_database(func): def wrapper(*args, **kwargs): with closing(script.engine.connect()) as conn: prepare_sequences(conn) trans = conn.begin() try: func(conn, *args, **kwargs) finally: trans.rollback() wrapper = make_decorator(func)(wrapper) return wrapper