test/cmd/compiler.py: use mock packages (#50362)

Signed-off-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>
Co-authored-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>
This commit is contained in:
Tamara Dahlgren 2025-05-16 02:53:36 -07:00 committed by GitHub
parent e3a7d5763f
commit 9738f1c026
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 69 additions and 10 deletions

View File

@ -15,6 +15,8 @@
compiler = spack.main.SpackCommand("compiler")
pytestmark = [pytest.mark.usefixtures("mock_packages")]
@pytest.fixture
def compilers_dir(mock_executable):
@ -80,7 +82,7 @@ def test_compiler_find_without_paths(no_packages_yaml, working_env, mock_executa
@pytest.mark.regression("37996")
def test_compiler_remove(mutable_config, mock_packages):
def test_compiler_remove(mutable_config):
"""Tests that we can remove a compiler from configuration."""
assert any(
compiler.satisfies("gcc@=9.4.0") for compiler in spack.compilers.config.all_compilers()
@ -93,7 +95,7 @@ def test_compiler_remove(mutable_config, mock_packages):
@pytest.mark.regression("37996")
def test_removing_compilers_from_multiple_scopes(mutable_config, mock_packages):
def test_removing_compilers_from_multiple_scopes(mutable_config):
# Duplicate "site" scope into "user" scope
site_config = spack.config.get("packages", scope="site")
spack.config.set("packages", site_config, scope="user")
@ -189,12 +191,12 @@ def test_compiler_find_path_order(no_packages_yaml, working_env, compilers_dir):
}
def test_compiler_list_empty(no_packages_yaml, working_env, compilers_dir):
def test_compiler_list_empty(no_packages_yaml, compilers_dir, monkeypatch):
"""Spack should not automatically search for compilers when listing them and none are
available. And when stdout is not a tty like in tests, there should be no output and
no error exit code.
"""
os.environ["PATH"] = str(compilers_dir)
monkeypatch.setenv("PATH", str(compilers_dir), prepend=":")
out = compiler("list")
assert not out
assert compiler.returncode == 0

View File

@ -4286,7 +4286,7 @@ def test_env_include_packages_url(
"""Test inclusion of a (GitHub) URL."""
develop_url = "https://github.com/fake/fake/blob/develop/"
default_packages = develop_url + "etc/fake/defaults/packages.yaml"
sha256 = "8b69d9c6e983dfb8bac2ddc3910a86265cffdd9c85f905c716d426ec5b0d9847"
sha256 = "6a1b26c857ca7e5bcd7342092e2f218da43d64b78bd72771f603027ea3c8b4af"
spack_yaml = tmpdir.join("spack.yaml")
with spack_yaml.open("w") as f:
f.write(

View File

@ -759,7 +759,7 @@ def test_virtual_is_fully_expanded_for_mpileaks(self):
@pytest.mark.parametrize(
"spec_str,expected,not_expected",
[
# clang only provides C, and C++ compilers, while gcc has also fortran
# clang (llvm~flang) only provides C, and C++ compilers, while gcc has also fortran
#
# If we ask mpileaks%clang, then %gcc must be used for fortran, and since
# %gcc is preferred to clang in config, it will be used for most nodes

View File

@ -887,6 +887,7 @@ def no_packages_yaml(mutable_config):
compilers_yaml = local_config.get_section_filename("packages")
if os.path.exists(compilers_yaml):
os.remove(compilers_yaml)
mutable_config.clear_caches()
return mutable_config

View File

@ -81,7 +81,7 @@ packages:
fortran: /path/bin/gfortran-10
llvm:
externals:
- spec: "llvm@15.0.0 +clang os={linux_os.name}{linux_os.version} target={target}"
- spec: "llvm@15.0.0 +clang~flang os={linux_os.name}{linux_os.version} target={target}"
prefix: /path
extra_attributes:
compilers:

View File

@ -52,9 +52,9 @@ def test_rfc_remote_local_path_no_dest():
packages_yaml_sha256 = (
"8b69d9c6e983dfb8bac2ddc3910a86265cffdd9c85f905c716d426ec5b0d9847"
"6a1b26c857ca7e5bcd7342092e2f218da43d64b78bd72771f603027ea3c8b4af"
if sys.platform != "win32"
else "182a5cdfdd88f50be23e55607b46285854c664c064e5a9f3f1e0200ebca6a1db"
else "ae3239d769f9e6dc137a998489b0d44c70b03e21de4ecd6a623a3463a1a5c3f4"
)

View File

@ -2,6 +2,7 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import re
from spack.package import *
@ -12,20 +13,75 @@ class Llvm(Package, CompilerPackage):
homepage = "http://www.example.com"
url = "http://www.example.com/gcc-1.0.tar.gz"
tags = ["compiler"]
version("18.1.8", md5="0123456789abcdef0123456789abcdef")
variant(
"clang", default=True, description="Build the LLVM C/C++/Objective-C compiler frontend"
)
variant(
"flang",
default=False,
description="Build the LLVM Fortran compiler frontend "
"(experimental - parser only, needs GCC)",
)
variant("lld", default=True, description="Build the LLVM linker")
provides("c", "cxx", when="+clang")
provides("fortran", when="+flang")
depends_on("c")
compiler_version_argument = "--version"
c_names = ["clang"]
cxx_names = ["clang++"]
fortran_names = ["flang"]
clang_and_friends = "(?:clang|flang|flang-new)"
compiler_version_regex = (
# Normal clang compiler versions are left as-is
rf"{clang_and_friends} version ([^ )\n]+)-svn[~.\w\d-]*|"
# Don't include hyphenated patch numbers in the version
# (see https://github.com/spack/spack/pull/14365 for details)
rf"{clang_and_friends} version ([^ )\n]+?)-[~.\w\d-]*|"
rf"{clang_and_friends} version ([^ )\n]+)|"
# LLDB
r"lldb version ([^ )\n]+)|"
# LLD
r"LLD ([^ )\n]+) \(compatible with GNU linkers\)"
)
fortran_names = ["flang", "flang-new"]
@classmethod
def determine_version(cls, exe):
try:
compiler = Executable(exe)
output = compiler(cls.compiler_version_argument, output=str, error=str)
if "Apple" in output:
return None
if "AMD" in output:
return None
match = re.search(cls.compiler_version_regex, output)
if match:
return match.group(match.lastindex)
except ProcessError:
pass
except Exception as e:
tty.debug(e)
return None
@classmethod
def filter_detected_exes(cls, prefix, exes_in_prefix):
# Executables like lldb-vscode-X are daemon listening on some port and would hang Spack
# during detection. clang-cl, clang-cpp, etc. are dev tools that we don't need to test
reject = re.compile(
r"-(vscode|cpp|cl|ocl|gpu|tidy|rename|scan-deps|format|refactor|offload|"
r"check|query|doc|move|extdef|apply|reorder|change-namespace|"
r"include-fixer|import-test|dap|server|PerfectShuffle)"
)
return [x for x in exes_in_prefix if not reject.search(x)]
def install(self, spec, prefix):
# Create the minimal compiler that will fool `spack compiler find`