summaryrefslogtreecommitdiff
path: root/lib/spack/spack/test/cmd/stage.py
blob: cdf5ca9fb4c5125112be045335934e01186a0db6 (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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# Copyright 2013-2023 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 os

import pytest

import spack.config
import spack.environment as ev
import spack.package_base
import spack.repo
import spack.stage
import spack.traverse
from spack.main import SpackCommand, SpackCommandError
from spack.version import Version

stage = SpackCommand("stage")
env = SpackCommand("env")

pytestmark = pytest.mark.usefixtures("install_mockery", "mock_packages")


@pytest.mark.not_on_windows("not implemented on windows")
@pytest.mark.disable_clean_stage_check
def test_stage_spec(monkeypatch):
    """Verify that staging specs works."""

    expected = set(["trivial-install-test-package", "mpileaks"])

    def fake_stage(pkg, mirror_only=False):
        expected.remove(pkg.name)

    monkeypatch.setattr(spack.package_base.PackageBase, "do_stage", fake_stage)

    stage("trivial-install-test-package", "mpileaks")

    assert len(expected) == 0


@pytest.fixture(scope="function")
def check_stage_path(monkeypatch, tmpdir):
    expected_path = os.path.join(str(tmpdir), "x")

    def fake_stage(pkg, mirror_only=False):
        assert pkg.path == expected_path

    monkeypatch.setattr(spack.package_base.PackageBase, "do_stage", fake_stage)

    return expected_path


@pytest.mark.not_on_windows("PermissionError")
def test_stage_path(check_stage_path):
    """Verify that --path only works with single specs."""
    stage("--path={0}".format(check_stage_path), "trivial-install-test-package")


def test_stage_path_errors_multiple_specs(check_stage_path):
    """Verify that --path only works with single specs."""
    with pytest.raises(SpackCommandError):
        stage(f"--path={check_stage_path}", "trivial-install-test-package", "mpileaks")


@pytest.mark.not_on_windows("not implemented on windows")
@pytest.mark.disable_clean_stage_check
def test_stage_with_env_outside_env(mutable_mock_env_path, monkeypatch):
    """Verify that stage concretizes specs not in environment instead of erroring."""

    def fake_stage(pkg, mirror_only=False):
        assert pkg.name == "trivial-install-test-package"
        assert pkg.path is None

    monkeypatch.setattr(spack.package_base.PackageBase, "do_stage", fake_stage)

    e = ev.create("test")
    e.add("mpileaks")
    e.concretize()

    with e:
        stage("trivial-install-test-package")


@pytest.mark.not_on_windows("not implemented on windows")
@pytest.mark.disable_clean_stage_check
def test_stage_with_env_inside_env(mutable_mock_env_path, monkeypatch):
    """Verify that stage filters specs in environment instead of reconcretizing."""

    def fake_stage(pkg, mirror_only=False):
        assert pkg.name == "mpileaks"
        assert pkg.version == Version("100.100")

    monkeypatch.setattr(spack.package_base.PackageBase, "do_stage", fake_stage)

    e = ev.create("test")
    e.add("mpileaks@=100.100")
    e.concretize()

    with e:
        stage("mpileaks")


@pytest.mark.not_on_windows("not implemented on windows")
@pytest.mark.disable_clean_stage_check
def test_stage_full_env(mutable_mock_env_path, monkeypatch):
    """Verify that stage filters specs in environment."""

    e = ev.create("test")
    e.add("mpileaks@=100.100")
    e.concretize()

    # list all the package names that should be staged
    expected = set(dep.name for dep in spack.traverse.traverse_nodes(e.concrete_roots()))

    # pop the package name from the list instead of actually staging
    def fake_stage(pkg, mirror_only=False):
        expected.remove(pkg.name)

    monkeypatch.setattr(spack.package_base.PackageBase, "do_stage", fake_stage)

    with e:
        stage()

    # assert that all were staged
    assert len(expected) == 0


@pytest.mark.disable_clean_stage_check
def test_concretizer_arguments(mock_packages, mock_fetch):
    """Make sure stage also has --reuse and --fresh flags."""
    stage("--reuse", "trivial-install-test-package")
    assert spack.config.get("concretizer:reuse", None) is True

    stage("--fresh", "trivial-install-test-package")
    assert spack.config.get("concretizer:reuse", None) is False