Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/language_tool_python/download_lt.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,9 @@ def download(self) -> None:
return

if self not in self.get_installed_versions():
with ( # pragma: no cover # integration: HTTP download + extraction
# In test env, LT is probably already installed, so this branch is not
# taken, but the ZIP extraction code is tested in unit and property tests
with ( # pragma: no cover
tempfile.TemporaryDirectory(dir=download_folder) as temp_dir,
tempfile.NamedTemporaryFile(
suffix=".zip",
Expand Down
3 changes: 2 additions & 1 deletion src/language_tool_python/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
from .utils import correct

_startupinfo: object | None = None
if sys.platform == "win32":
# Windows-specific code, coverage is measured on Linux
if sys.platform == "win32": # pragma: no cover
_startupinfo = subprocess.STARTUPINFO()
_startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

Expand Down
53 changes: 17 additions & 36 deletions tests/integration/test_config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""Integration tests for LanguageTool configuration options (require a local server)."""

import re
import time

import pytest

Expand Down Expand Up @@ -131,47 +130,29 @@ def test_config_text_length() -> None:


def test_config_caching() -> None:
"""Test the caching configuration parameters.

This test verifies that LanguageTool's caching mechanism (cacheSize and
pipelineCaching) significantly improves performance when checking the same text
multiple times. The test measures the time difference between an uncached and a
cached check to ensure caching provides a substantial speedup.

This is inherently a timing-sensitive test and could still be flaky under heavy
machine load, so it: (1) performs a warm-up check on unrelated text before
timing, to exclude one-off JIT/connection-setup costs from the measurement
without pre-populating the cache for the text under test, and (2) repeats the
timed comparison up to ``_ATTEMPTS`` times, succeeding as soon as one attempt
shows the expected speedup, instead of requiring every attempt to pass.

:raises AssertionError: If caching does not provide the expected performance
improvement in any attempt.
"""
speedup_factor = 5.0
attempts = 3
"""Test that the caching configuration parameters are accepted by the server.

This test verifies that LanguageTool starts successfully and correctly checks
text when configured with ``cacheSize`` and ``pipelineCaching``, including when
the same sentence is checked twice in a row (the second call takes the cache
hit code path server-side).

The actual speedup these options provide is a wall-clock measurement, which is
too noisy on shared CI runners to gate pass/fail on: it belongs in the
``perf``-marked benchmark suite (see ``test_bench_check_with_pipeline_cache`` in
``tests/benchmarks/test_bench_check.py``), which is opt-in and does not affect
CI results.

:raises AssertionError: If the tool fails to produce matches under this config.
"""
with language_tool_python.LanguageTool(
"en-US",
config={"cacheSize": 1000, "pipelineCaching": True},
) as tool:
tool.check("warm-up text unrelated to the cached sentence below")

s = "hello darkness my old frend"
for _ in range(attempts):
t1 = time.time()
tool.check(s)
t2 = time.time()
tool.check(s)
t3 = time.time()

# In practice, speedups of around 250x (6.76s to 0.028s) have been observed.
if (t2 - t1) / speedup_factor > (t3 - t2):
return

pytest.fail(
f"Caching did not provide the expected speedup in {attempts} attempts."
)
assert len(tool.check(s)) > 0
# Second check of the same sentence exercises the cache-hit path.
assert len(tool.check(s)) > 0


def test_inexistent_language() -> None:
Expand Down
Loading