Coverage for tests / integration / test_parallel_execution.py: 100%
56 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Integration tests for parallel tool execution."""
3from __future__ import annotations
5import contextlib
6import os
7import tempfile
8from collections.abc import Iterator
10import pytest
11from assertpy import assert_that
13from lintro.plugins import ToolRegistry
14from lintro.utils.tool_executor import run_lint_tools_simple
17@pytest.fixture(autouse=True)
18def set_lintro_test_mode_env(lintro_test_mode: object) -> Iterator[None]:
19 """Set test mode for all tests in this module.
21 Args:
22 lintro_test_mode: Shared fixture that manages env vars.
24 Yields:
25 None: This fixture is used for its side effect only.
26 """
27 yield
30@pytest.fixture
31def temp_python_files() -> Iterator[list[str]]:
32 """Create multiple temporary Python files for parallel testing.
34 Yields:
35 list[str]: List of paths to temporary Python files.
36 """
37 files: list[str] = []
38 temp_dir = tempfile.mkdtemp()
40 # Create multiple files with various issues
41 file_contents = [
42 (
43 "file1.py",
44 "import sys\nimport os\n\ndef add(a, b):\n return a + b\n",
45 ),
46 (
47 "file2.py",
48 "def greet(name: str) -> str:\n return f'Hello, {name}!'\n",
49 ),
50 (
51 "file3.py",
52 "import json\n\ndata = {'key': 'value'}\n",
53 ),
54 ]
56 for filename, content in file_contents:
57 file_path = os.path.join(temp_dir, filename)
58 with open(file_path, "w") as f:
59 f.write(content)
60 files.append(file_path)
62 yield files
64 # Cleanup
65 for file_path in files:
66 with contextlib.suppress(FileNotFoundError):
67 os.unlink(file_path)
68 with contextlib.suppress(OSError):
69 os.rmdir(temp_dir)
72def test_check_multiple_files(temp_python_files: list[str]) -> None:
73 """Test running check on multiple files.
75 Args:
76 temp_python_files: Pytest fixture providing temp files.
77 """
78 exit_code = run_lint_tools_simple(
79 action="check",
80 paths=temp_python_files,
81 tools="ruff",
82 tool_options=None,
83 exclude=None,
84 include_venv=False,
85 group_by="file",
86 output_format="grid",
87 verbose=False,
88 raw_output=False,
89 )
91 # Should complete without crashing
92 assert_that(exit_code).is_instance_of(int)
95def test_consistent_results_across_runs(temp_python_files: list[str]) -> None:
96 """Test that multiple runs produce consistent results.
98 Args:
99 temp_python_files: Pytest fixture providing temp files.
100 """
101 # Run twice
102 exit_code_1 = run_lint_tools_simple(
103 action="check",
104 paths=temp_python_files,
105 tools="ruff",
106 tool_options=None,
107 exclude=None,
108 include_venv=False,
109 group_by="file",
110 output_format="grid",
111 verbose=False,
112 )
114 exit_code_2 = run_lint_tools_simple(
115 action="check",
116 paths=temp_python_files,
117 tools="ruff",
118 tool_options=None,
119 exclude=None,
120 include_venv=False,
121 group_by="file",
122 output_format="grid",
123 verbose=False,
124 )
126 # Exit codes should match
127 assert_that(exit_code_1).is_equal_to(exit_code_2)
130def test_check_with_single_file(temp_python_files: list[str]) -> None:
131 """Test check with single file.
133 Args:
134 temp_python_files: Pytest fixture providing temp files.
135 """
136 exit_code = run_lint_tools_simple(
137 action="check",
138 paths=[temp_python_files[0]],
139 tools="ruff",
140 tool_options=None,
141 exclude=None,
142 include_venv=False,
143 group_by="file",
144 output_format="grid",
145 verbose=False,
146 )
148 assert_that(exit_code).is_instance_of(int)
151def test_format_action(temp_python_files: list[str]) -> None:
152 """Test format action.
154 Args:
155 temp_python_files: Pytest fixture providing temp files.
156 """
157 exit_code = run_lint_tools_simple(
158 action="fmt",
159 paths=temp_python_files,
160 tools="ruff",
161 tool_options=None,
162 exclude=None,
163 include_venv=False,
164 group_by="file",
165 output_format="grid",
166 verbose=False,
167 )
169 assert_that(exit_code).is_instance_of(int)
172def test_different_output_formats(temp_python_files: list[str]) -> None:
173 """Test different output formats.
175 Args:
176 temp_python_files: Pytest fixture providing temp files.
177 """
178 for fmt in ["grid", "plain", "json"]:
179 exit_code = run_lint_tools_simple(
180 action="check",
181 paths=temp_python_files,
182 tools="ruff",
183 tool_options=None,
184 exclude=None,
185 include_venv=False,
186 group_by="file",
187 output_format=fmt,
188 verbose=False,
189 )
190 assert_that(exit_code).is_instance_of(int)
193def test_tool_definition_exists() -> None:
194 """Test that ruff tool has proper definition."""
195 ruff_tool = ToolRegistry.get("ruff")
197 assert_that(ruff_tool).is_not_none()
198 assert_that(ruff_tool.definition).is_not_none()
199 assert_that(ruff_tool.definition.name).is_equal_to("ruff")
202def test_tool_respects_execution_order(temp_python_files: list[str]) -> None:
203 """Test that tool execution order is predictable.
205 Args:
206 temp_python_files: Pytest fixture providing temp files.
207 """
208 # Run multiple times to verify consistency
209 results = []
210 for _ in range(3):
211 exit_code = run_lint_tools_simple(
212 action="check",
213 paths=temp_python_files,
214 tools="ruff",
215 tool_options=None,
216 exclude=None,
217 include_venv=False,
218 group_by="file",
219 output_format="grid",
220 verbose=False,
221 )
222 results.append(exit_code)
224 # All runs should produce same exit code
225 assert_that(len(set(results))).is_equal_to(1)