Files
cibuildwheel/unit_test/docker_container_test.py
T

203 lines
6.7 KiB
Python
Raw Normal View History

import platform
2020-07-10 12:46:32 +01:00
import random
import shutil
2020-06-26 21:37:02 +01:00
import subprocess
import textwrap
2020-07-10 13:04:50 +01:00
from pathlib import Path, PurePath
2020-06-26 21:37:02 +01:00
2020-06-26 21:41:00 +01:00
import pytest
from cibuildwheel.docker_container import DockerContainer
2021-11-21 15:19:45 -05:00
from cibuildwheel.environment import EnvironmentAssignmentBash
2020-06-26 21:41:00 +01:00
2020-07-08 22:56:33 +01:00
# for these tests we use manylinux2014 images, because they're available on
# multi architectures and include python3.8
pm = platform.machine()
if pm == "x86_64":
2021-05-03 11:45:43 -04:00
DEFAULT_IMAGE = "quay.io/pypa/manylinux2014_x86_64:2020-05-17-2f8ac3b"
elif pm == "aarch64":
2021-05-03 11:45:43 -04:00
DEFAULT_IMAGE = "quay.io/pypa/manylinux2014_aarch64:2020-05-17-2f8ac3b"
elif pm == "ppc64le":
2021-05-03 11:45:43 -04:00
DEFAULT_IMAGE = "quay.io/pypa/manylinux2014_ppc64le:2020-05-17-2f8ac3b"
elif pm == "s390x":
2021-05-03 11:45:43 -04:00
DEFAULT_IMAGE = "quay.io/pypa/manylinux2014_s390x:2020-05-17-2f8ac3b"
2020-06-26 21:37:02 +01:00
2020-06-26 21:41:00 +01:00
@pytest.mark.docker
2020-06-26 21:37:02 +01:00
def test_simple():
2021-10-12 02:05:47 +01:00
with DockerContainer(docker_image=DEFAULT_IMAGE) as container:
2021-05-03 11:45:43 -04:00
assert container.call(["echo", "hello"], capture_output=True) == "hello\n"
2020-06-26 21:37:02 +01:00
2020-06-26 21:41:00 +01:00
@pytest.mark.docker
2020-06-26 21:37:02 +01:00
def test_no_lf():
2021-10-12 02:05:47 +01:00
with DockerContainer(docker_image=DEFAULT_IMAGE) as container:
2021-05-03 11:45:43 -04:00
assert container.call(["printf", "hello"], capture_output=True) == "hello"
2020-06-26 21:37:02 +01:00
2020-06-26 21:41:00 +01:00
@pytest.mark.docker
2020-06-26 21:37:02 +01:00
def test_environment():
2021-10-12 02:05:47 +01:00
with DockerContainer(docker_image=DEFAULT_IMAGE) as container:
2021-04-30 17:56:34 -04:00
assert (
container.call(
2021-05-03 11:45:43 -04:00
["sh", "-c", "echo $TEST_VAR"], env={"TEST_VAR": "1"}, capture_output=True
2021-04-30 17:56:34 -04:00
)
2021-05-03 11:45:43 -04:00
== "1\n"
2021-04-30 17:56:34 -04:00
)
2020-06-26 21:37:02 +01:00
2020-06-26 21:41:00 +01:00
2020-07-20 01:04:26 +02:00
@pytest.mark.docker
def test_cwd():
2021-10-12 02:05:47 +01:00
with DockerContainer(
docker_image=DEFAULT_IMAGE, cwd="/cibuildwheel/working_directory"
) as container:
2021-05-03 11:45:43 -04:00
assert container.call(["pwd"], capture_output=True) == "/cibuildwheel/working_directory\n"
assert container.call(["pwd"], capture_output=True, cwd="/opt") == "/opt\n"
2020-07-20 01:04:26 +02:00
@pytest.mark.docker
2020-06-26 21:37:02 +01:00
def test_container_removed():
2021-10-12 02:05:47 +01:00
with DockerContainer(docker_image=DEFAULT_IMAGE) as container:
2021-04-30 17:56:34 -04:00
docker_containers_listing = subprocess.run(
2021-05-03 11:45:43 -04:00
"docker container ls",
2021-04-30 17:56:34 -04:00
shell=True,
check=True,
stdout=subprocess.PIPE,
universal_newlines=True,
).stdout
2021-06-12 14:02:06 -04:00
assert container.name is not None
2020-06-26 21:37:02 +01:00
assert container.name in docker_containers_listing
old_container_name = container.name
2021-04-30 17:56:34 -04:00
docker_containers_listing = subprocess.run(
2021-05-03 11:45:43 -04:00
"docker container ls",
2021-04-30 17:56:34 -04:00
shell=True,
check=True,
stdout=subprocess.PIPE,
universal_newlines=True,
).stdout
2020-06-26 21:37:02 +01:00
assert old_container_name not in docker_containers_listing
2020-06-26 21:41:00 +01:00
@pytest.mark.docker
2020-06-26 21:37:02 +01:00
def test_large_environment():
# max environment variable size is 128kB
2021-04-30 17:56:34 -04:00
long_env_var_length = 127 * 1024
2020-06-26 21:37:02 +01:00
large_environment = {
2021-05-03 11:45:43 -04:00
"a": "0" * long_env_var_length,
"b": "0" * long_env_var_length,
"c": "0" * long_env_var_length,
"d": "0" * long_env_var_length,
2020-06-26 21:37:02 +01:00
}
2021-10-12 02:05:47 +01:00
with DockerContainer(docker_image=DEFAULT_IMAGE) as container:
2020-06-26 21:37:02 +01:00
# check the length of d
2021-04-30 17:56:34 -04:00
assert (
2021-05-03 11:45:43 -04:00
container.call(["sh", "-c", "echo ${#d}"], env=large_environment, capture_output=True)
== f"{long_env_var_length}\n"
2021-04-30 17:56:34 -04:00
)
2020-06-26 21:37:02 +01:00
2020-06-26 21:41:00 +01:00
@pytest.mark.docker
2020-06-26 21:37:02 +01:00
def test_binary_output():
2021-10-12 02:05:47 +01:00
with DockerContainer(docker_image=DEFAULT_IMAGE) as container:
2020-07-08 22:56:33 +01:00
# note: the below embedded snippets are in python2
2020-06-26 21:37:02 +01:00
# check that we can pass though arbitrary binary data without erroring
2021-04-30 17:56:34 -04:00
container.call(
[
2021-05-03 11:45:43 -04:00
"/usr/bin/python2",
"-c",
2021-04-30 17:56:34 -04:00
textwrap.dedent(
2021-05-03 11:45:43 -04:00
"""
2021-05-02 16:37:38 +02:00
import sys
sys.stdout.write(''.join(chr(n) for n in range(0, 256)))
2021-05-03 11:45:43 -04:00
"""
2021-04-30 17:56:34 -04:00
),
]
)
2020-06-26 21:37:02 +01:00
# check that we can capture arbitrary binary data
2021-04-30 17:56:34 -04:00
output = container.call(
[
2021-05-03 11:45:43 -04:00
"/usr/bin/python2",
"-c",
2021-04-30 17:56:34 -04:00
textwrap.dedent(
2021-05-03 11:45:43 -04:00
"""
2021-05-02 16:37:38 +02:00
import sys
sys.stdout.write(''.join(chr(n % 256) for n in range(0, 512)))
2021-05-03 11:45:43 -04:00
"""
2021-04-30 17:56:34 -04:00
),
],
capture_output=True,
)
2020-06-26 21:37:02 +01:00
2021-05-03 11:45:43 -04:00
data = bytes(output, encoding="utf8", errors="surrogateescape")
2020-06-26 21:37:02 +01:00
for i in range(512):
2020-06-26 21:37:02 +01:00
assert data[i] == i % 256
# check that environment variables can carry binary data, except null characters
# (https://www.gnu.org/software/libc/manual/html_node/Environment-Variables.html)
binary_data = bytes(n for n in range(1, 256))
2021-05-03 11:45:43 -04:00
binary_data_string = str(binary_data, encoding="utf8", errors="surrogateescape")
2020-06-26 21:37:02 +01:00
output = container.call(
2021-05-03 11:45:43 -04:00
["python2", "-c", 'import os, sys; sys.stdout.write(os.environ["TEST_VAR"])'],
env={"TEST_VAR": binary_data_string},
2020-06-26 21:37:02 +01:00
capture_output=True,
)
assert output == binary_data_string
2020-07-08 22:56:33 +01:00
@pytest.mark.docker
def test_file_operations(tmp_path: Path):
2021-10-12 02:05:47 +01:00
with DockerContainer(docker_image=DEFAULT_IMAGE) as container:
2020-07-08 22:56:33 +01:00
# test copying a file in
2020-07-10 12:46:32 +01:00
test_binary_data = bytes(random.randrange(256) for _ in range(1000))
2021-05-03 11:45:43 -04:00
original_test_file = tmp_path / "test.dat"
2020-07-08 22:56:33 +01:00
original_test_file.write_bytes(test_binary_data)
2021-05-03 11:45:43 -04:00
dst_file = PurePath("/tmp/test.dat")
2020-07-08 22:56:33 +01:00
container.copy_into(original_test_file, dst_file)
2021-05-03 11:45:43 -04:00
output = container.call(["cat", dst_file], capture_output=True)
assert test_binary_data == bytes(output, encoding="utf8", errors="surrogateescape")
2020-07-08 22:56:33 +01:00
2020-07-10 13:04:50 +01:00
2020-07-10 12:46:32 +01:00
@pytest.mark.docker
def test_dir_operations(tmp_path: Path):
2021-10-12 02:05:47 +01:00
with DockerContainer(docker_image=DEFAULT_IMAGE) as container:
2020-07-10 12:46:32 +01:00
test_binary_data = bytes(random.randrange(256) for _ in range(1000))
2021-05-03 11:45:43 -04:00
original_test_file = tmp_path / "test.dat"
2020-07-10 12:46:32 +01:00
original_test_file.write_bytes(test_binary_data)
2020-07-08 22:56:33 +01:00
# test copying a dir in
2021-05-03 11:45:43 -04:00
test_dir = tmp_path / "test_dir"
2020-07-10 12:46:32 +01:00
test_dir.mkdir()
2021-05-03 11:45:43 -04:00
test_file = test_dir / "test.dat"
2020-07-10 12:46:32 +01:00
shutil.copyfile(original_test_file, test_file)
2020-07-08 22:56:33 +01:00
2021-05-03 11:45:43 -04:00
dst_dir = PurePath("/tmp/test_dir")
dst_file = dst_dir / "test.dat"
2020-07-10 12:46:32 +01:00
container.copy_into(test_dir, dst_dir)
2021-05-03 11:45:43 -04:00
output = container.call(["cat", dst_file], capture_output=True)
assert test_binary_data == bytes(output, encoding="utf8", errors="surrogateescape")
2020-07-10 12:46:32 +01:00
# test glob
2021-05-03 11:45:43 -04:00
assert container.glob(dst_dir, "*.dat") == [dst_file]
2020-07-10 12:46:32 +01:00
# test copy dir out
2021-05-03 11:45:43 -04:00
new_test_dir = tmp_path / "test_dir_new"
2020-07-10 12:46:32 +01:00
container.copy_out(dst_dir, new_test_dir)
2021-05-03 11:45:43 -04:00
assert test_binary_data == (new_test_dir / "test.dat").read_bytes()
@pytest.mark.docker
def test_environment_executor():
2021-10-12 02:05:47 +01:00
with DockerContainer(docker_image=DEFAULT_IMAGE) as container:
2021-11-21 15:19:45 -05:00
assignment = EnvironmentAssignmentBash("TEST=$(echo 42)")
assert assignment.evaluated_value({}, container.environment_executor) == "42"