From 1c417604f4a2077841f29ee3cb599f5d5d782737 Mon Sep 17 00:00:00 2001 From: eleanorjboyd Date: Wed, 20 Nov 2024 12:00:53 -0800 Subject: [PATCH 1/2] support pytest-forked plugin --- .../tests/pytestadapter/.data/test_forked.py | 17 ++++++++ python_files/vscode_pytest/__init__.py | 39 ++++++++++++++++--- .../vscode_pytest/run_pytest_script.py | 1 + 3 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 python_files/tests/pytestadapter/.data/test_forked.py diff --git a/python_files/tests/pytestadapter/.data/test_forked.py b/python_files/tests/pytestadapter/.data/test_forked.py new file mode 100644 index 000000000000..00b7b849a90e --- /dev/null +++ b/python_files/tests/pytestadapter/.data/test_forked.py @@ -0,0 +1,17 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +import pytest +import os + + +@pytest.mark.forked +def test_forked_process_p(): + pid = os.getpid() + print(f"Running in process with PID: {pid}") + assert True +@pytest.mark.forked +def test_forked_process_f(): + pid = os.getpid() + print(f"Running in process with PID: {pid}") + assert False diff --git a/python_files/vscode_pytest/__init__.py b/python_files/vscode_pytest/__init__.py index 59a1b75e9688..8d5bab7dd5e1 100644 --- a/python_files/vscode_pytest/__init__.py +++ b/python_files/vscode_pytest/__init__.py @@ -68,6 +68,8 @@ def __init__(self, message): collected_tests_so_far = [] TEST_RUN_PIPE = os.getenv("TEST_RUN_PIPE") SYMLINK_PATH = None +# Get variable set in the `run_pytest_script.py` for the parent process to check if its forked +ROOT_PROCESS_PID: int = os.getenv("PROCESS_ID") def pytest_load_initial_conftests(early_config, parser, args): # noqa: ARG001 @@ -92,6 +94,24 @@ def pytest_load_initial_conftests(early_config, parser, args): # noqa: ARG001 global IS_DISCOVERY IS_DISCOVERY = True + global ROOT_PROCESS_PID + print(early_config.pluginmanager.list_name_plugin()) + if early_config.pluginmanager.has_plugin("pytest_forked"): + if ROOT_PROCESS_PID and int(os.getpid()) == int(ROOT_PROCESS_PID): + print( + "Plugin info[vscode-pytest]: Forked plugin detected but NOT running in forked process." + ) + elif ROOT_PROCESS_PID: + print( + f"Plugin info[vscode-pytest]: Forked plugin detected and running in forked process. Root PID: {ROOT_PROCESS_PID}, Current PID: {os.getpid()}" + ) + else: + print("Plugin info[vscode-pytest]: No root PID defined, setting to 0.") + ROOT_PROCESS_PID = 0 + else: + # If the plugin is not detected, then the root process is the current process. + ROOT_PROCESS_PID = 0 + # check if --rootdir is in the args for arg in args: if "--rootdir=" in arg: @@ -858,12 +878,19 @@ def send_execution_message( status (Literal["success", "error"]): Execution status indicating success or error. tests (Union[testRunResultDict, None]): Test run results, if available. """ - payload: ExecutionPayloadDict = ExecutionPayloadDict( - cwd=cwd, status=status, result=tests, not_found=None, error=None - ) - if ERRORS: - payload["error"] = ERRORS - send_message(payload) + current_pid = os.getpid() + # if ROOT_PROCESS_PID is 0 then forked plugin is not enabled + if ROOT_PROCESS_PID != 0 and int(current_pid) != int(ROOT_PROCESS_PID): + print("PID NOT equal to the root proccess, no return", current_pid, ROOT_PROCESS_PID) + return + else: + print("PID equal to the root of forked proccess", current_pid, ROOT_PROCESS_PID) + payload: ExecutionPayloadDict = ExecutionPayloadDict( + cwd=cwd, status=status, result=tests, not_found=None, error=None + ) + if ERRORS: + payload["error"] = ERRORS + send_message(payload) def send_discovery_message(cwd: str, session_node: TestNode) -> None: diff --git a/python_files/vscode_pytest/run_pytest_script.py b/python_files/vscode_pytest/run_pytest_script.py index 1abfb8b27004..f373cf6b0667 100644 --- a/python_files/vscode_pytest/run_pytest_script.py +++ b/python_files/vscode_pytest/run_pytest_script.py @@ -28,6 +28,7 @@ def run_pytest(args): # args through sys.argv. It then runs pytest.main() with the args and test_ids. if __name__ == "__main__": + os.environ["PROCESS_ID"] = str(os.getpid()) # Add the root directory to the path so that we can import the plugin. directory_path = pathlib.Path(__file__).parent.parent sys.path.append(os.fspath(directory_path)) From beb4d8c5e4687245fe6d73207505e991ee32d618 Mon Sep 17 00:00:00 2001 From: eleanorjboyd Date: Thu, 21 Nov 2024 11:29:26 -0800 Subject: [PATCH 2/2] remove failing tests, update typing --- .../tests/pytestadapter/.data/test_forked.py | 17 ----------------- python_files/vscode_pytest/__init__.py | 3 ++- 2 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 python_files/tests/pytestadapter/.data/test_forked.py diff --git a/python_files/tests/pytestadapter/.data/test_forked.py b/python_files/tests/pytestadapter/.data/test_forked.py deleted file mode 100644 index 00b7b849a90e..000000000000 --- a/python_files/tests/pytestadapter/.data/test_forked.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -import pytest -import os - - -@pytest.mark.forked -def test_forked_process_p(): - pid = os.getpid() - print(f"Running in process with PID: {pid}") - assert True -@pytest.mark.forked -def test_forked_process_f(): - pid = os.getpid() - print(f"Running in process with PID: {pid}") - assert False diff --git a/python_files/vscode_pytest/__init__.py b/python_files/vscode_pytest/__init__.py index 8d5bab7dd5e1..94fde93143a1 100644 --- a/python_files/vscode_pytest/__init__.py +++ b/python_files/vscode_pytest/__init__.py @@ -69,7 +69,8 @@ def __init__(self, message): TEST_RUN_PIPE = os.getenv("TEST_RUN_PIPE") SYMLINK_PATH = None # Get variable set in the `run_pytest_script.py` for the parent process to check if its forked -ROOT_PROCESS_PID: int = os.getenv("PROCESS_ID") +process_id_envvar = os.getenv("PROCESS_ID") +ROOT_PROCESS_PID: int = int(process_id_envvar) if process_id_envvar else 0 def pytest_load_initial_conftests(early_config, parser, args): # noqa: ARG001