Title: [276512] trunk/Tools
Revision
276512
Author
gsnedd...@apple.com
Date
2021-04-23 12:34:35 -0700 (Fri, 23 Apr 2021)

Log Message

Add a conftest.py to run existing webkitpy tests in pytest
https://bugs.webkit.org/show_bug.cgi?id=224687

Reviewed by Jonathan Bedard.

* Scripts/webkitpy/common/system/executive_unittest.py:
(ExecutiveTest.serial_test_run_in_parallel): Deal with the fact that pytest
running the tests might be not be the same version as the autoinstalled version,
and not API compatible.
* Scripts/webkitpy/conftest.py: Added.
(pytest_configure): Define the markers the plugins in conftest use
(pytest_addoption): Add --run-integration to allow them to be disabled by default.
(pytest_pycollect_makeitem): Rename serial/integration tests so pytest finds them.
(pytest_collection_modifyitems): Mark tests as skipped when needed per the above.
* Scripts/webkitpy/pytest.ini: Added.
* Scripts/webkitpy/test/main_unittest.py:
(TestStubs): Stop these from being picked up by pytest as tests.
* Scripts/webkitpy/test/markers.py: Fix this so pytest is technically optional,
even though it is always present because of the autoinstalled copy.

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (276511 => 276512)


--- trunk/Tools/ChangeLog	2021-04-23 19:21:24 UTC (rev 276511)
+++ trunk/Tools/ChangeLog	2021-04-23 19:34:35 UTC (rev 276512)
@@ -1,3 +1,25 @@
+2021-04-23  Sam Sneddon  <gsnedd...@apple.com>
+
+        Add a conftest.py to run existing webkitpy tests in pytest
+        https://bugs.webkit.org/show_bug.cgi?id=224687
+
+        Reviewed by Jonathan Bedard.
+
+        * Scripts/webkitpy/common/system/executive_unittest.py:
+        (ExecutiveTest.serial_test_run_in_parallel): Deal with the fact that pytest
+        running the tests might be not be the same version as the autoinstalled version,
+        and not API compatible.
+        * Scripts/webkitpy/conftest.py: Added.
+        (pytest_configure): Define the markers the plugins in conftest use
+        (pytest_addoption): Add --run-integration to allow them to be disabled by default.
+        (pytest_pycollect_makeitem): Rename serial/integration tests so pytest finds them.
+        (pytest_collection_modifyitems): Mark tests as skipped when needed per the above.
+        * Scripts/webkitpy/pytest.ini: Added.
+        * Scripts/webkitpy/test/main_unittest.py:
+        (TestStubs): Stop these from being picked up by pytest as tests.
+        * Scripts/webkitpy/test/markers.py: Fix this so pytest is technically optional,
+        even though it is always present because of the autoinstalled copy.
+
 2021-04-23  Aakash Jain  <aakash_j...@apple.com>
 
         Make report-non-inclusive-language ignore .db files

Modified: trunk/Tools/Scripts/webkitpy/common/system/executive_unittest.py (276511 => 276512)


--- trunk/Tools/Scripts/webkitpy/common/system/executive_unittest.py	2021-04-23 19:21:24 UTC (rev 276511)
+++ trunk/Tools/Scripts/webkitpy/common/system/executive_unittest.py	2021-04-23 19:34:35 UTC (rev 276512)
@@ -250,9 +250,19 @@
         cmd_line = [sys.executable, '-c', 'import time; time.sleep(%f); print("hello")' % DELAY_SECS]
         cwd = os.getcwd()
         commands = [tuple([cmd_line, cwd])] * NUM_PROCESSES
-        start = time.time()
-        command_outputs = Executive().run_in_parallel(commands, processes=NUM_PROCESSES)
-        done = time.time()
+
+        try:
+            # we overwrite __main__ to be this to avoid any issues with
+            # multiprocessing's spawning caused by multiple versions of pytest on
+            # sys.path
+            old_main = sys.modules["__main__"]
+            sys.modules["__main__"] = sys.modules[__name__]
+            start = time.time()
+            command_outputs = Executive().run_in_parallel(commands, processes=NUM_PROCESSES)
+            done = time.time()
+        finally:
+            sys.modules["__main__"] = old_main
+
         self.assertTrue(done - start < NUM_PROCESSES * DELAY_SECS)
         self.assertEqual([output[1] for output in command_outputs], [b'hello\n'] * NUM_PROCESSES)
         self.assertEqual([],  multiprocessing.active_children())

Added: trunk/Tools/Scripts/webkitpy/conftest.py (0 => 276512)


--- trunk/Tools/Scripts/webkitpy/conftest.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/conftest.py	2021-04-23 19:34:35 UTC (rev 276512)
@@ -0,0 +1,110 @@
+# 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")
+
+
+def pytest_addoption(parser):
+    parser.addoption(
+        "--run-integration",
+        action=""
+        default=False,
+        help="run integration 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-integration"):
+        skip_integration = pytest.mark.skip(
+            reason="need --run-integration option to run"
+        )
+        for item in items:
+            if "integration" in item.keywords:
+                item.add_marker(skip_integration)

Added: trunk/Tools/Scripts/webkitpy/pytest.ini (0 => 276512)


--- trunk/Tools/Scripts/webkitpy/pytest.ini	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/pytest.ini	2021-04-23 19:34:35 UTC (rev 276512)
@@ -0,0 +1,14 @@
+[pytest]
+python_files=*_unittest.py *_integrationtest.py
+xfail_strict=true
+addopts = -rfEX --strict-markers -k 'not scm_unittest'
+
+filterwarnings =
+    ignore:invalid escape sequence.*:DeprecationWarning
+    ignore:Please use assert.* instead.:DeprecationWarning
+    ignore:The 'warn' method is deprecated, use 'warning' instead:DeprecationWarning
+    ignore:cannot collect test class 'Test[^']*' because it has a __init__ constructor:pytest.PytestCollectionWarning
+    ignore:the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses:DeprecationWarning
+    ignore:Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3, and in 3.[0-9]+ it will stop working:DeprecationWarning
+    ignore:The readPlist function is deprecated, use load\(\) instead:DeprecationWarning
+    ignore:inspect.getargspec\(\) is deprecated since Python 3.0, use inspect.signature\(\) or inspect.getfullargspec\(\):DeprecationWarning

Modified: trunk/Tools/Scripts/webkitpy/test/main_unittest.py (276511 => 276512)


--- trunk/Tools/Scripts/webkitpy/test/main_unittest.py	2021-04-23 19:21:24 UTC (rev 276511)
+++ trunk/Tools/Scripts/webkitpy/test/main_unittest.py	2021-04-23 19:34:35 UTC (rev 276512)
@@ -38,6 +38,8 @@
 
 
 class TestStubs(unittest.TestCase):
+    __pytest_no_rewrite__ = True
+
     def test_empty(self):
         pass
 

Modified: trunk/Tools/Scripts/webkitpy/test/markers.py (276511 => 276512)


--- trunk/Tools/Scripts/webkitpy/test/markers.py	2021-04-23 19:21:24 UTC (rev 276511)
+++ trunk/Tools/Scripts/webkitpy/test/markers.py	2021-04-23 19:34:35 UTC (rev 276512)
@@ -22,7 +22,12 @@
 
 import unittest
 
+try:
+    import pytest
+except ImportError:
+    pass
 
+
 def xfail(*args, **kwargs):
     """a pytest.mark.xfail-like wrapper for unittest.expectedFailure
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to