Skip to content

Commit e23f327

Browse files
HartornBotLocker
andauthored
[GSK-2159] Using a subprocess for pytest (#1640)
* Using a subprocess for pytest * Regenerating pdm.lock * Handle skip * Fix the skip evaluation * Change the hook * Regenerating pdm.lock --------- Co-authored-by: BotLocker <[email protected]>
1 parent ef802a2 commit e23f327

File tree

4 files changed

+360
-321
lines changed

4 files changed

+360
-321
lines changed

.github/workflows/build-python.yml

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -155,22 +155,6 @@ jobs:
155155
pdm run pip freeze | grep '^pandas'
156156
pdm run pip freeze | grep -q '^pandas==${{ matrix.pandas_v1 && '1' || '2' }}\.'
157157
158-
- name: Test code (RAM expensive in tests/models, tests/testing, tests/test_metamorphic_invariance.py)
159-
if: ${{ startsWith(matrix.os, 'windows') }}
160-
run: pdm test-ram tests/models tests/testing tests/test_metamorphic_invariance.py
161-
162-
- name: Test code (RAM expensive, /tests/models and /tests/testing)
163-
if: ${{ !startsWith(matrix.os, 'windows') }}
164-
run: pdm test-ram --memray tests/models tests/testing tests/test_metamorphic_invariance.py
165-
166-
- name: Test code (RAM expensive, others)
167-
if: ${{ startsWith(matrix.os, 'windows') }}
168-
run: pdm test-ram tests/ --ignore=tests/models --ignore=tests/testing --ignore=tests/test_metamorphic_invariance.py
169-
170-
- name: Test code (RAM expensive, others)
171-
if: ${{ !startsWith(matrix.os, 'windows') }}
172-
run: pdm test-ram --memray tests/ --ignore=tests/models --ignore=tests/testing --ignore=tests/test_metamorphic_invariance.py
173-
174158
- name: Test code (concurrency)
175159
run: pdm test-worker
176160

@@ -199,13 +183,7 @@ jobs:
199183
if: ${{ inputs.run-integration-tests }}
200184
env:
201185
PYTEST_XDIST_AUTO_NUM_WORKERS: 2
202-
run: pdm test-slow tests/integrations
203-
204-
- name: Run integration tests for python
205-
if: ${{ inputs.run-integration-tests }}
206-
env:
207-
PYTEST_XDIST_AUTO_NUM_WORKERS: 2
208-
run: pdm test-slow tests/ --ignore=tests/integrations
186+
run: pdm test-slow tests/
209187

210188
- name: "Memory csv"
211189
if: ${{ always() && matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10' && !matrix.langchain_minimal && !matrix.pandas_v1 && !matrix.pydantic_v1 }}

conftest.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
1+
from typing import List
2+
13
import gc
4+
import json
25
import os
6+
import subprocess
7+
import sys
38
import time
49
from pathlib import Path
10+
from tempfile import NamedTemporaryFile
511

612
import psutil
713
import pytest
14+
from _pytest.config.argparsing import Parser
815
from _pytest.python import Function
16+
from _pytest.reports import TestReport
917

1018

1119
@pytest.hookimpl(hookwrapper=True)
@@ -60,3 +68,43 @@ def pytest_runtest_protocol(item: Function, nextitem: Function):
6068

6169
# Add overall test results
6270
writer.write(f"{item.nodeid},{test_memory_usage:.3f},{full_memory_usage:.3f}\n")
71+
72+
73+
# we know this bit is bad, but we cant help it with the current pytest setup
74+
def pytest_addoption(parser: Parser):
75+
parser.addoption("--use-subprocess", action="store_true", default=False, help="Whether to use subprocess")
76+
77+
78+
def separate_process(item: Function) -> List[TestReport]:
79+
with NamedTemporaryFile(delete=False) as fp:
80+
proc = subprocess.run(
81+
shell=True,
82+
check=False,
83+
stdout=sys.stdout,
84+
stderr=sys.stderr,
85+
args=f"{sys.executable} -m pytest {item.nodeid} -vvv --tb=long --report-log={fp.name} --no-header --no-summary",
86+
cwd=Path(__file__).parent,
87+
)
88+
89+
reports = []
90+
try:
91+
for line in Path(fp.name).read_text().splitlines():
92+
report_dict = json.loads(line)
93+
if report_dict["$report_type"] == "TestReport":
94+
reports.append(TestReport._from_json(report_dict))
95+
return reports
96+
finally:
97+
# Force deletion of the temp file
98+
Path(fp.name).unlink(missing_ok=True)
99+
100+
101+
# https://docs.pytest.org/en/7.1.x/reference/reference.html#pytest.hookspec.pytest_runtest_protocol
102+
@pytest.hookimpl(tryfirst=True)
103+
def pytest_runtest_call(item: Function):
104+
mark = item.get_closest_marker("skip")
105+
skip = mark is not None
106+
mark = item.get_closest_marker("skipif")
107+
skip |= mark is not None and ((len(mark.args) == 1 and mark.args[0]) or mark.kwargs.get("condition", False))
108+
if not skip and item.get_closest_marker("memory_expensive") and item.config.getoption("--use-subprocess"):
109+
reports = separate_process(item)
110+
return reports

0 commit comments

Comments
 (0)