# Copyright (C) 2021 Apple Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import warnings import types import sys import pytest def pytest_configure(config): config.addinivalue_line("markers", "serial: tests that must be run in serial") config.addinivalue_line("markers", "integration: integration tests") config.addinivalue_line("markers", "slow: tests that take a while to run") def pytest_addoption(parser): parser.addoption( "--run-slow", action="store_true", default=False, help="run slow tests" ) @pytest.hookimpl(tryfirst=True) def pytest_pycollect_makeitem(collector, name, obj): try: ut = sys.modules["unittest"] if not issubclass(obj, ut.TestCase): return None except Exception: return None if getattr(obj, "__pytest_no_rewrite__", False): return None for attr_name in set(dir(obj)): serial = False integration = False if attr_name.startswith("serial_integration_test_"): serial = True integration = True elif attr_name.startswith("serial_test_"): serial = True elif attr_name.startswith("integration_test_"): integration = True else: continue method = getattr(obj, attr_name) if not callable(method): continue new_attr_name = "test_" + attr_name existing_attr = getattr(obj, new_attr_name, None) if existing_attr: if method != existing_attr: warnings.warn( "attribute %r already defined on %r; %r might hide %r" % (new_attr_name, obj, method, existing_attr) ) if sys.version_info < (3,) and isinstance(method, types.MethodType): method = method.im_func if serial: method = pytest.mark.serial(method) if integration: method = pytest.mark.integration(method) setattr(obj, new_attr_name, method) return None def pytest_collection_modifyitems(config, items): if hasattr(config, "workerinput"): skip_serial = pytest.mark.skip(reason="cannot run in parallel") for item in items: if "serial" in item.keywords: item.add_marker(skip_serial) if not config.getoption("--run-slow"): skip_slow = pytest.mark.skip(reason="need --run-slow option to run") for item in items: if "slow" in item.keywords: item.add_marker(skip_slow)