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
6 changes: 6 additions & 0 deletions Tests/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,12 @@
pytest.fail(msg + ": " + repr(actuals) + " != " + repr(targets))


def timeout_unless_slower_valgrind(timeout: float) -> pytest.MarkDecorator:
if "PILLOW_VALGRIND_TEST" in os.environ:
return pytest.mark.pil_noop_mark()

Check warning on line 166 in Tests/helper.py

View check run for this annotation

Codecov / codecov/patch

Tests/helper.py#L166

Added line #L166 was not covered by tests
return pytest.mark.timeout(timeout)


def skip_unless_feature(feature: str) -> pytest.MarkDecorator:
reason = f"{feature} not available"
return pytest.mark.skipif(not features.check(feature), reason=reason)
Expand Down
3 changes: 2 additions & 1 deletion Tests/test_file_eps.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
is_win32,
mark_if_feature_version,
skip_unless_feature,
timeout_unless_slower_valgrind,
)

HAS_GHOSTSCRIPT = EpsImagePlugin.has_ghostscript()
Expand Down Expand Up @@ -398,7 +399,7 @@ def test_emptyline() -> None:
assert image.format == "EPS"


@pytest.mark.timeout(timeout=5)
@timeout_unless_slower_valgrind(5)
@pytest.mark.parametrize(
"test_file",
["Tests/images/eps/timeout-d675703545fee17acab56e5fec644c19979175de.eps"],
Expand Down
9 changes: 7 additions & 2 deletions Tests/test_file_fli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@

from PIL import FliImagePlugin, Image, ImageFile

from .helper import assert_image_equal, assert_image_equal_tofile, is_pypy
from .helper import (
assert_image_equal,
assert_image_equal_tofile,
is_pypy,
timeout_unless_slower_valgrind,
)

# created as an export of a palette image from Gimp2.6
# save as...-> hopper.fli, default options.
Expand Down Expand Up @@ -189,7 +194,7 @@ def test_seek() -> None:
"Tests/images/timeout-bff0a9dc7243a8e6ede2408d2ffa6a9964698b87.fli",
],
)
@pytest.mark.timeout(timeout=3)
@timeout_unless_slower_valgrind(3)
def test_timeouts(test_file: str) -> None:
with open(test_file, "rb") as f:
with Image.open(f) as im:
Expand Down
3 changes: 2 additions & 1 deletion Tests/test_file_jpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
is_win32,
mark_if_feature_version,
skip_unless_feature,
timeout_unless_slower_valgrind,
)

ElementTree: ModuleType | None
Expand Down Expand Up @@ -1033,7 +1034,7 @@ def test_save_xmp(self, tmp_path: Path) -> None:
with pytest.raises(ValueError):
im.save(f, xmp=b"1" * 65505)

@pytest.mark.timeout(timeout=1)
@timeout_unless_slower_valgrind(1)
def test_eof(self, monkeypatch: pytest.MonkeyPatch) -> None:
# Even though this decoder never says that it is finished
# the image should still end when there is no new data
Expand Down
10 changes: 7 additions & 3 deletions Tests/test_file_pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@

from PIL import Image, PdfParser, features

from .helper import hopper, mark_if_feature_version, skip_unless_feature
from .helper import (
hopper,
mark_if_feature_version,
skip_unless_feature,
timeout_unless_slower_valgrind,
)


def helper_save_as_pdf(tmp_path: Path, mode: str, **kwargs: Any) -> str:
Expand Down Expand Up @@ -339,8 +344,7 @@ def test_pdf_append_to_bytesio() -> None:
assert len(f.getvalue()) > initial_size


@pytest.mark.timeout(1)
@pytest.mark.skipif("PILLOW_VALGRIND_TEST" in os.environ, reason="Valgrind is slower")
@timeout_unless_slower_valgrind(1)
@pytest.mark.parametrize("newline", (b"\r", b"\n"))
def test_redos(newline: bytes) -> None:
malicious = b" trailer<<>>" + newline * 3456
Expand Down
5 changes: 3 additions & 2 deletions Tests/test_file_tiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
hopper,
is_pypy,
is_win32,
timeout_unless_slower_valgrind,
)

ElementTree: ModuleType | None
Expand Down Expand Up @@ -988,7 +989,7 @@ def test_string_dimension(self) -> None:
with pytest.raises(OSError):
im.load()

@pytest.mark.timeout(6)
@timeout_unless_slower_valgrind(6)
@pytest.mark.filterwarnings("ignore:Truncated File Read")
def test_timeout(self, monkeypatch: pytest.MonkeyPatch) -> None:
with Image.open("Tests/images/timeout-6646305047838720") as im:
Expand All @@ -1001,7 +1002,7 @@ def test_timeout(self, monkeypatch: pytest.MonkeyPatch) -> None:
"Tests/images/oom-225817ca0f8c663be7ab4b9e717b02c661e66834.tif",
],
)
@pytest.mark.timeout(2)
@timeout_unless_slower_valgrind(2)
def test_oom(self, test_file: str) -> None:
with pytest.raises(UnidentifiedImageError):
with pytest.warns(UserWarning):
Expand Down
6 changes: 2 additions & 4 deletions Tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
is_win32,
mark_if_feature_version,
skip_unless_feature,
timeout_unless_slower_valgrind,
)

ElementTree: ModuleType | None
Expand Down Expand Up @@ -572,10 +573,7 @@ def test_check_size(self) -> None:
i = Image.new("RGB", [1, 1])
assert isinstance(i.size, tuple)

@pytest.mark.timeout(0.75)
@pytest.mark.skipif(
"PILLOW_VALGRIND_TEST" in os.environ, reason="Valgrind is slower"
)
@timeout_unless_slower_valgrind(0.75)
@pytest.mark.parametrize("size", ((0, 100000000), (100000000, 0)))
def test_empty_image(self, size: tuple[int, int]) -> None:
Image.new("RGB", size)
Expand Down
4 changes: 2 additions & 2 deletions Tests/test_imagefontpil.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from PIL import Image, ImageDraw, ImageFont, _util, features

from .helper import assert_image_equal_tofile
from .helper import assert_image_equal_tofile, timeout_unless_slower_valgrind

fonts = [ImageFont.load_default_imagefont()]
if not features.check_module("freetype2"):
Expand Down Expand Up @@ -72,7 +72,7 @@ def test_decompression_bomb() -> None:
font.getmask("A" * 1_000_000)


@pytest.mark.timeout(4)
@timeout_unless_slower_valgrind(4)
def test_oom() -> None:
glyph = struct.pack(
">hhhhhhhhhh", 1, 0, -32767, -32767, 32767, 32767, -32767, -32767, 32767, 32767
Expand Down
Loading