Skip to content

Commit e14cebd

Browse files
Copilotlostmsufilmor
authored
Fix silently-passing subprocess tests and process resource leak (#112)
* Fix PicklingError in subprocess spawn by moving fixtures to conftest.py Co-authored-by: lostmsu <239520+lostmsu@users.noreply.github.com> * Fix silent subprocess failures: assert exitcode and fix test_coreclr_properties kwargs The real reason CI doesn't fail despite Python 3.13 being tested: run_in_subprocess never checked p.exitcode, so any subprocess crash was silently ignored by the parent test. Adding the assert immediately exposes a pre-existing bug: test_coreclr_properties passed properties=dict(...) as a single kwarg, but _do_test_coreclr_autogenerated_runtimeconfig uses **properties to collect individual kwargs. This double-wrapped the dict, causing AttributeError: 'dict' object has no attribute 'encode' in the subprocess — silently swallowed until now. Co-authored-by: lostmsu <239520+lostmsu@users.noreply.github.com> * Fix resource leak: wrap p.exitcode assert in try/finally so p.close() always runs Without try/finally, if `assert p.exitcode == 0` raises AssertionError, `p.close()` is never called. This leaves the Process object unclosed and causes `ResourceWarning: process ... not closed` on Python 3.12+. Co-authored-by: lostmsu <239520+lostmsu@users.noreply.github.com> * Fix format --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lostmsu <239520+lostmsu@users.noreply.github.com> Co-authored-by: Benedikt Reinartz <filmor@gmail.com>
1 parent d3fa8a8 commit e14cebd

File tree

2 files changed

+32
-24
lines changed

2 files changed

+32
-24
lines changed

tests/conftest.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from pathlib import Path
2+
from subprocess import check_call
3+
4+
import pytest
5+
6+
NETCORE_VERSION = "net10.0"
7+
8+
9+
@pytest.fixture(scope="session")
10+
def example_netstandard(tmp_path_factory: pytest.TempPathFactory) -> Path:
11+
return build_example(tmp_path_factory, "netstandard2.0")
12+
13+
14+
@pytest.fixture(scope="session")
15+
def example_netcore(tmp_path_factory: pytest.TempPathFactory) -> Path:
16+
return build_example(tmp_path_factory, NETCORE_VERSION)
17+
18+
19+
def build_example(tmp_path_factory: pytest.TempPathFactory, framework: str) -> Path:
20+
out = tmp_path_factory.mktemp(f"example-{framework}")
21+
proj_path = Path(__file__).parent.parent / "example" / "example.csproj"
22+
23+
_ = check_call(["dotnet", "build", str(proj_path), "-o", str(out), "-f", framework])
24+
25+
return out

tests/test_common.py

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,9 @@
11
import shutil
22
import sys
33
from pathlib import Path
4-
from subprocess import check_call
54

65
import pytest
76

8-
NETCORE_VERSION = "net10.0"
9-
10-
11-
@pytest.fixture(scope="session")
12-
def example_netstandard(tmp_path_factory: pytest.TempPathFactory) -> Path:
13-
return build_example(tmp_path_factory, "netstandard2.0")
14-
15-
16-
@pytest.fixture(scope="session")
17-
def example_netcore(tmp_path_factory: pytest.TempPathFactory) -> Path:
18-
return build_example(tmp_path_factory, NETCORE_VERSION)
19-
20-
21-
def build_example(tmp_path_factory: pytest.TempPathFactory, framework: str) -> Path:
22-
out = tmp_path_factory.mktemp(f"example-{framework}")
23-
proj_path = Path(__file__).parent.parent / "example" / "example.csproj"
24-
25-
_ = check_call(["dotnet", "build", str(proj_path), "-o", str(out), "-f", framework])
26-
27-
return out
28-
297

308
def test_mono(example_netstandard: Path):
319
from clr_loader import get_mono
@@ -112,7 +90,7 @@ def test_coreclr_properties(example_netcore: Path):
11290
run_in_subprocess(
11391
_do_test_coreclr_autogenerated_runtimeconfig,
11492
example_netcore,
115-
properties=dict(APP_CONTEXT_BASE_DIRECTORY=str(example_netcore)),
93+
APP_CONTEXT_BASE_DIRECTORY=str(example_netcore),
11694
)
11795

11896

@@ -177,4 +155,9 @@ def run_in_subprocess(func, *args, **kwargs):
177155
p = get_context("spawn").Process(target=func, args=args, kwargs=kwargs)
178156
p.start()
179157
p.join()
180-
p.close()
158+
try:
159+
assert p.exitcode == 0, (
160+
f"Subprocess {func.__name__!r} failed with exit code {p.exitcode}"
161+
)
162+
finally:
163+
p.close()

0 commit comments

Comments
 (0)