11from __future__ import annotations
22
3+ import errno
34import os
45import sys
56
67import pytest
78
9+ from virtualenv .info import IMPLEMENTATION
810from virtualenv .run import cli_run
911
1012
@@ -16,24 +18,34 @@ def test_too_many_open_files(tmp_path):
1618 import resource # noqa: PLC0415
1719
1820 soft_limit , hard_limit = resource .getrlimit (resource .RLIMIT_NOFILE )
19- if soft_limit > 1024 :
20- pytest .skip ("soft limit for open files is too high to reliably trigger the error" )
2121
2222 # Lower the soft limit to a small number to trigger the error
2323 try :
2424 resource .setrlimit (resource .RLIMIT_NOFILE , (32 , hard_limit ))
2525 except ValueError :
2626 pytest .skip ("could not lower the soft limit for open files" )
27+ except AttributeError as exc : # pypy, graalpy
28+ if "module 'resource' has no attribute 'setrlimit'" in str (exc ):
29+ pytest .skip (f"{ IMPLEMENTATION } does not support resource.setrlimit" )
2730
2831 # Keep some file descriptors open to make it easier to trigger the error
2932 fds = []
3033 try :
31- fds .extend (os .open (os .devnull , os .O_RDONLY ) for _ in range (20 ))
32-
33- with pytest .raises (SystemExit ) as excinfo :
34+ # JIT implementations use more file descriptors up front so we can run out early
35+ try :
36+ fds .extend (os .open (os .devnull , os .O_RDONLY ) for _ in range (20 ))
37+ except OSError as jit_exceptions : # pypy, graalpy
38+ assert jit_exceptions .errno == errno .EMFILE # noqa: PT017
39+ assert "Too many open files" in str (jit_exceptions ) # noqa: PT017
40+
41+ expected_exceptions = SystemExit , OSError , RuntimeError
42+ with pytest .raises (expected_exceptions ) as too_many_open_files_exc :
3443 cli_run ([str (tmp_path / "venv" )])
3544
36- assert excinfo .value .code != 0
45+ if isinstance (too_many_open_files_exc , SystemExit ):
46+ assert too_many_open_files_exc .code != 0
47+ else :
48+ assert "Too many open files" in str (too_many_open_files_exc .value )
3749
3850 finally :
3951 for fd in fds :
0 commit comments