blob: e4a49b3a8f94ff704a14a8a16ef13b4da9528d10 [file] [log] [blame]
# Copyright (C) 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function, absolute_import
import functools
import warnings
import inspect
class skip_conditional(object):
'''
Test method decorator that marks a test method as ignorable if the given
arguments evaluate as Truthy. If the argument is callable, then it is called
and the return value is used as the predicate.
>>> class MyTestClass(TestBase):
... def test_something(self):
... pass
...
... @skip_conditional(not sys.platform.startswith("linux"))
... def test_some_linux_behaviour(self):
... assert "vmlinuz" in open("/proc/cmdline").read()
...
... @skip_conditional(lambda : True):
... def test_that_never_runs(self):
... pass
'''
def __init__(self, skip_condition, message="skipped"):
self._skip_condition = skip_condition
self._message = message
def __call__(self, func):
@functools.wraps(func)
def inner(*args, **kwargs):
skip_condition = self._skip_condition
if callable(skip_condition):
# args[0] is ``self``
skip_condition = skip_condition(args[0])
if skip_condition:
print("skipping %r - %s" % (func, self._message))
return True
return func(args[0])
return inner
class skip_test(skip_conditional):
''''
Unconditionally skip a test
'''
def __init__(self, skip_condition, *args, **kwargs):
super(skip_test, self).__init__(True, *args, **kwargs)
java_only_test = lambda: skip_conditional(lambda self: not self.app_type == 'java')
cpp_only_test = lambda: skip_conditional(lambda self: not self.app_type == 'cpp')
jni_only_test = lambda: skip_conditional(lambda self: not self.app_type == 'jni')
def wimpy(func):
'''
Mark a test as 'wimpy' that is - a function specifically known to be quick-running.
This implementation simply adds the `.wimpy` attribute to the decorated function
and returns it, otherwise unmodified
'''
func.wimpy = True
return func
class ordered_test(object):
'''Set the ordered attribute on function'''
def __init__(self, order):
self._order = order
def __call__(self, func):
func.test_order = self._order
return func
class deprecated(object):
"""
method or function decorator used to warn of pending feature removal:
>>> @deprecated()
... def myfunc():
... return 'hello'
...
>>> myfunc()
DeprecationWarning: `__main__.myfunc()` is deprecated and will be removed soon.
'hello'
>>> class MyClass(object):
... @deprecated(alternative_feature='print')
... def myprint(self, *args, **kwargs):
... print(*args, **kwargs)
...
>>> obj = MyClass()
>>> obj.myprint("hello")
DeprecationWarning: `__main__.MyClass.myfunc()` is deprecated and will be removed soon. Use 'print' instead.
hello
"""
def __init__(
self,
alternative_feature=None,
removal_date='soon',
exception=UserWarning
):
self.alternative_feature_message = (
alternative_feature and 'use %r instead' % alternative_feature or ''
)
self.exception = exception
self.removal_date = removal_date
def __call__(self, func):
class_name = ''
if getattr(func, 'im_class', None):
class_name = '%s.' % func.im_class.__name__
if getattr(func, 'im_func', None):
func_name = func.im_func.func_name
else:
func_name = func.func_name
module_name = getattr(func, '__module__')
warning = "`%s.%s%s()` is deprecated and will be removed %s. %s" % (
module_name,
class_name,
func_name,
self.removal_date,
self.alternative_feature_message
)
@functools.wraps(func)
def inner(*args, **kwargs):
if not getattr(func, 'deprecation_warned', False):
warnings.warn(warning, self.exception, 2)
func.deprecation_warned = True
return func(*args, **kwargs)
return inner