summaryrefslogtreecommitdiff
path: root/lib/spack/spack/test/container/docker.py
blob: 5e0b8c3d4ea1d29e55f17baf2a499c2f8240ee86 (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
137
138
139
140
141
142
143
144
145
146
147
# 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 re

import pytest

import spack.container.writers as writers


def test_manifest(minimal_configuration):
    writer = writers.create(minimal_configuration)
    manifest_str = writer.manifest
    for line in manifest_str.split("\n"):
        assert "echo" in line


def test_build_and_run_images(minimal_configuration):
    writer = writers.create(minimal_configuration)

    # Test the output of run property
    run = writer.run
    assert run.image == "ubuntu:18.04"

    # Test the output of the build property
    build = writer.build
    assert build.image == "spack/ubuntu-bionic:latest"


def test_packages(minimal_configuration):
    # In this minimal configuration we don't have packages
    writer = writers.create(minimal_configuration)
    assert writer.os_packages_build is None
    assert writer.os_packages_final is None

    # If we add them a list should be returned
    pkgs = ["libgomp1"]
    minimal_configuration["spack"]["container"]["os_packages"] = {"final": pkgs}
    writer = writers.create(minimal_configuration)
    p = writer.os_packages_final
    assert p.update
    assert p.install
    assert p.clean
    assert p.list == pkgs


def test_container_os_packages_command(minimal_configuration):
    # In this minimal configuration we don't have packages
    writer = writers.create(minimal_configuration)
    assert writer.os_packages_build is None
    assert writer.os_packages_final is None

    # If we add them a list should be returned
    minimal_configuration["spack"]["container"]["images"] = {
        "build": "custom-build:latest",
        "final": "custom-final:latest",
    }
    minimal_configuration["spack"]["container"]["os_packages"] = {
        "command": "zypper",
        "final": ["libgomp1"],
    }
    writer = writers.create(minimal_configuration)
    p = writer.os_packages_final
    assert "zypper update -y" in p.update
    assert "zypper install -y" in p.install
    assert "zypper clean -a" in p.clean


def test_ensure_render_works(minimal_configuration, default_config):
    # Here we just want to ensure that nothing is raised
    writer = writers.create(minimal_configuration)
    writer()


def test_strip_is_set_from_config(minimal_configuration):
    writer = writers.create(minimal_configuration)
    assert writer.strip is True

    minimal_configuration["spack"]["container"]["strip"] = False
    writer = writers.create(minimal_configuration)
    assert writer.strip is False


def test_custom_base_images(minimal_configuration):
    """Test setting custom base images from configuration file"""
    minimal_configuration["spack"]["container"]["images"] = {
        "build": "custom-build:latest",
        "final": "custom-final:latest",
    }
    writer = writers.create(minimal_configuration)

    assert writer.bootstrap.image is None
    assert writer.build.image == "custom-build:latest"
    assert writer.run.image == "custom-final:latest"


@pytest.mark.parametrize(
    "images_cfg,expected",
    [
        (
            {"os": "amazonlinux:2", "spack": "develop"},
            {
                "bootstrap_image": "amazonlinux:2",
                "build_image": "bootstrap",
                "final_image": "amazonlinux:2",
            },
        )
    ],
)
def test_base_images_with_bootstrap(minimal_configuration, images_cfg, expected):
    """Check that base images are computed correctly when a
    bootstrap phase is present
    """
    minimal_configuration["spack"]["container"]["images"] = images_cfg
    writer = writers.create(minimal_configuration)

    for property_name, value in expected.items():
        assert getattr(writer, property_name) == value


def test_error_message_invalid_os(minimal_configuration):
    minimal_configuration["spack"]["container"]["images"]["os"] = "invalid:1"
    with pytest.raises(ValueError, match="invalid operating system"):
        writers.create(minimal_configuration)


@pytest.mark.regression("34629,18030")
def test_not_stripping_all_symbols(minimal_configuration):
    """Tests that we are not stripping all symbols, so that libraries can still be
    used for linking.
    """
    minimal_configuration["spack"]["container"]["strip"] = True
    content = writers.create(minimal_configuration)()
    assert "xargs strip" in content
    assert "xargs strip -s" not in content


@pytest.mark.regression("22341")
def test_using_single_quotes_in_dockerfiles(minimal_configuration):
    """Tests that Dockerfiles written by Spack use single quotes in manifest, to avoid issues
    with shell substitution. This may happen e.g. when users have "definitions:" they want to
    expand in dockerfiles.
    """
    manifest_in_docker = writers.create(minimal_configuration).manifest
    assert not re.search(r"echo\s*\"", manifest_in_docker, flags=re.MULTILINE)
    assert re.search(r"echo\s*'", manifest_in_docker)