|
4 | 4 | # LICENSE file in the root directory of this source tree. |
5 | 5 | """Pytest fixtures for the GCC CompilerGym environments.""" |
6 | 6 |
|
| 7 | +import shutil |
7 | 8 | import subprocess |
8 | 9 | from functools import lru_cache |
9 | 10 | from typing import Iterable |
|
13 | 14 | from tests.pytest_plugins.common import docker_is_available |
14 | 15 |
|
15 | 16 |
|
16 | | -@lru_cache(maxsize=2) |
17 | | -def system_gcc_is_available() -> bool: |
| 17 | +def system_has_functional_gcc(gcc_path: str) -> bool: |
18 | 18 | """Return whether there is a system GCC available.""" |
19 | 19 | try: |
20 | 20 | stdout = subprocess.check_output( |
21 | | - ["gcc", "--version"], universal_newlines=True, stderr=subprocess.DEVNULL |
| 21 | + [gcc_path, "--version"], |
| 22 | + universal_newlines=True, |
| 23 | + stderr=subprocess.DEVNULL, |
| 24 | + timeout=30, |
22 | 25 | ) |
23 | 26 | # On some systems "gcc" may alias to a different compiler, so check for |
24 | 27 | # the presence of the name "gcc" in the first line of output. |
25 | 28 | return "gcc" in stdout.split("\n")[0].lower() |
26 | | - except (subprocess.CalledProcessError, FileNotFoundError): |
| 29 | + except ( |
| 30 | + subprocess.CalledProcessError, |
| 31 | + FileNotFoundError, |
| 32 | + subprocess.TimeoutExpired, |
| 33 | + ): |
27 | 34 | return False |
28 | 35 |
|
29 | 36 |
|
30 | | -def system_gcc_path() -> str: |
31 | | - """Return the path of the system GCC as a string.""" |
32 | | - return subprocess.check_output( |
33 | | - ["which", "gcc"], universal_newlines=True, stderr=subprocess.DEVNULL |
34 | | - ).strip() |
35 | | - |
36 | | - |
37 | | -def gcc_environment_is_supported() -> bool: |
38 | | - """Return whether the requirements for the GCC environment are met.""" |
39 | | - return docker_is_available() or system_gcc_is_available() |
| 37 | +@lru_cache |
| 38 | +def system_gcc_is_available(): |
| 39 | + return system_has_functional_gcc(shutil.which("gcc")) |
40 | 40 |
|
41 | 41 |
|
| 42 | +@lru_cache |
42 | 43 | def gcc_bins() -> Iterable[str]: |
43 | 44 | """Return a list of available GCCs.""" |
44 | 45 | if docker_is_available(): |
45 | 46 | yield "docker:gcc:11.2.0" |
46 | | - if system_gcc_is_available(): |
47 | | - yield system_gcc_path() |
| 47 | + system_gcc = shutil.which("gcc") |
| 48 | + if system_gcc and system_has_functional_gcc(system_gcc): |
| 49 | + yield system_gcc |
| 50 | + |
| 51 | + |
| 52 | +def gcc_environment_is_supported() -> bool: |
| 53 | + """Return whether the requirements for the GCC environment are met.""" |
| 54 | + return len(list(gcc_bins())) > 0 |
48 | 55 |
|
49 | 56 |
|
50 | 57 | @pytest.fixture(scope="module", params=gcc_bins()) |
|
0 commit comments