summaryrefslogtreecommitdiff
path: root/lib/spack/spack/test/audit.py
blob: 98e6ad83c85555c72b435d4a101a15542fee8321 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import pytest

import spack.audit
import spack.config


@pytest.mark.parametrize(
    # PKG-PROPERTIES are ubiquitous in mock packages, since they don't use sha256
    # and they don't change the example.com URL very often.
    "packages,expected_errors",
    [
        # A non existing variant is used in a conflict directive
        (["wrong-variant-in-conflicts"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]),
        # The package declares a non-existing dependency
        (["missing-dependency"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]),
        # The package use a non existing variant in a depends_on directive
        (["wrong-variant-in-depends-on"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]),
        # This package has a GitHub patch URL without full_index=1
        (["invalid-github-patch-url"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]),
        # This package has invalid GitLab patch URLs
        (["invalid-gitlab-patch-url"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]),
        # This package has invalid GitLab patch URLs
        (["invalid-selfhosted-gitlab-patch-url"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]),
        # This package has a stand-alone 'test*' method in build-time callbacks
        (["fail-test-audit"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]),
        # This package has no issues
        (["mpileaks"], None),
        # This package has a conflict with a trigger which cannot constrain the constraint
        # Should not raise an error
        (["unconstrainable-conflict"], None),
    ],
)
def test_package_audits(packages, expected_errors, mock_packages):
    reports = spack.audit.run_group("packages", pkgs=packages)

    # Check that errors were reported only for the expected failure
    actual_errors = [check for check, errors in reports if errors]
    msg = [str(e) for _, errors in reports for e in errors]
    if expected_errors:
        assert expected_errors == actual_errors, msg
    else:
        assert not actual_errors, msg


# Data used in the test below to audit the double definition of a compiler
_double_compiler_definition = [
    {
        "compiler": {
            "spec": "gcc@9.0.1",
            "paths": {
                "cc": "/usr/bin/gcc-9",
                "cxx": "/usr/bin/g++-9",
                "f77": "/usr/bin/gfortran-9",
                "fc": "/usr/bin/gfortran-9",
            },
            "flags": {},
            "operating_system": "ubuntu18.04",
            "target": "x86_64",
            "modules": [],
            "environment": {},
            "extra_rpaths": [],
        }
    },
    {
        "compiler": {
            "spec": "gcc@9.0.1",
            "paths": {
                "cc": "/usr/bin/gcc-9",
                "cxx": "/usr/bin/g++-9",
                "f77": "/usr/bin/gfortran-9",
                "fc": "/usr/bin/gfortran-9",
            },
            "flags": {"cflags": "-O3"},
            "operating_system": "ubuntu18.04",
            "target": "x86_64",
            "modules": [],
            "environment": {},
            "extra_rpaths": [],
        }
    },
]


@pytest.mark.parametrize(
    "config_section,data,failing_check",
    [
        # Double compiler definitions in compilers.yaml
        ("compilers", _double_compiler_definition, "CFG-COMPILER"),
        # Multiple definitions of the same external spec in packages.yaml
        (
            "packages",
            {
                "mpileaks": {
                    "externals": [
                        {"spec": "mpileaks@1.0.0", "prefix": "/"},
                        {"spec": "mpileaks@1.0.0", "prefix": "/usr"},
                    ]
                }
            },
            "CFG-PACKAGES",
        ),
    ],
)
def test_config_audits(config_section, data, failing_check):
    with spack.config.override(config_section, data):
        reports = spack.audit.run_group("configs")
        assert any((check == failing_check) and errors for check, errors in reports)