Source code for openstack_dashboard.test.integration_tests.tests.decorators

#    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.
import functools
import inspect

import nose

from openstack_dashboard.test.integration_tests import config


def _is_test_method_name(method):
    return method.startswith('test_')


def _is_test_cls(cls):
    return cls.__name__.startswith('Test')


def _mark_method_skipped(meth, reason):
    """Mark method as skipped by replacing the actual method with wrapper
    that raises the nose.SkipTest exception.
    """

    @functools.wraps(meth)
    def wrapper(*args, **kwargs):
        raise nose.SkipTest(reason)

    return wrapper


def _mark_class_skipped(cls, reason):
    """Mark every test method of the class as skipped."""
    tests = [attr for attr in dir(cls) if _is_test_method_name(attr)]
    for test in tests:
        method = getattr(cls, test)
        if callable(method):
            setattr(cls, test, _mark_method_skipped(method, reason))
    return cls


NOT_TEST_OBJECT_ERROR_MSG = "Decorator can be applied only on test" \
                            " classes and test methods."


[docs]def services_required(*req_services): """Decorator for marking test's service requirements, if requirements are not met in the configuration file test is marked as skipped. Usage: from openstack_dashboard.test.integration_tests.tests import decorators @decorators.services_required("sahara") class TestLogin(helpers.BaseTestCase): . . . from openstack_dashboard.test.integration_tests.tests import decorators class TestLogin(helpers.BaseTestCase): @decorators.services_required("sahara") def test_login(self): login_pg = loginpage.LoginPage(self.driver, self.conf) . . . """ def actual_decoration(obj): # make sure that we can decorate method and classes as well if inspect.isclass(obj): if not _is_test_cls(obj): raise ValueError(NOT_TEST_OBJECT_ERROR_MSG) skip_method = _mark_class_skipped else: if not _is_test_method_name(obj.func_name): raise ValueError(NOT_TEST_OBJECT_ERROR_MSG) skip_method = _mark_method_skipped # get available services from configuration avail_services = config.get_config().service_available for req_service in req_services: if not getattr(avail_services, req_service, False): obj = skip_method(obj, "%s service is required for this test" " to work properly." % req_service) break return obj return actual_decoration