import gzip import io import shutil import pytest import docker from docker import auth, errors from docker.api.build import process_dockerfile from ..helpers import make_tree from .api_test import BaseAPIClientTest, fake_request, url_prefix class BuildTest(BaseAPIClientTest): def test_build_container(self): script = io.BytesIO( "\n".join( [ "FROM busybox", "RUN mkdir -p /tmp/test", "EXPOSE 8080", "ADD https://dl.dropboxusercontent.com/u/20637798/silence.tar.gz" " /tmp/silence.tar.gz", ] ).encode("ascii") ) self.client.build(fileobj=script) def test_build_container_pull(self): script = io.BytesIO( "\n".join( [ "FROM busybox", "RUN mkdir -p /tmp/test", "EXPOSE 8080", "ADD https://dl.dropboxusercontent.com/u/20637798/silence.tar.gz" " /tmp/silence.tar.gz", ] ).encode("ascii") ) self.client.build(fileobj=script, pull=True) def test_build_container_custom_context(self): script = io.BytesIO( "\n".join( [ "FROM busybox", "RUN mkdir -p /tmp/test", "EXPOSE 8080", "ADD https://dl.dropboxusercontent.com/u/20637798/silence.tar.gz" " /tmp/silence.tar.gz", ] ).encode("ascii") ) context = docker.utils.mkbuildcontext(script) self.client.build(fileobj=context, custom_context=True) def test_build_container_custom_context_gzip(self): script = io.BytesIO( "\n".join( [ "FROM busybox", "RUN mkdir -p /tmp/test", "EXPOSE 8080", "ADD https://dl.dropboxusercontent.com/u/20637798/silence.tar.gz" " /tmp/silence.tar.gz", ] ).encode("ascii") ) context = docker.utils.mkbuildcontext(script) gz_context = gzip.GzipFile(fileobj=context) self.client.build(fileobj=gz_context, custom_context=True, encoding="gzip") def test_build_remote_with_registry_auth(self): self.client._auth_configs = auth.AuthConfig( { "auths": { "https://example.com": { "user": "example", "password": "example", "email": "example@example.com", } } } ) expected_params = { "t": None, "q": False, "dockerfile": None, "rm": False, "nocache": False, "pull": False, "forcerm": False, "remote": "https://github.com/docker-library/mongo", } expected_headers = { "X-Registry-Config": auth.encode_header(self.client._auth_configs.auths) } self.client.build(path="https://github.com/docker-library/mongo") fake_request.assert_called_with( "POST", f"{url_prefix}build", stream=True, data=None, headers=expected_headers, params=expected_params, timeout=None, ) def test_build_container_with_named_dockerfile(self): self.client.build(".", dockerfile="nameddockerfile") def test_build_with_invalid_tag(self): with pytest.raises(errors.DockerException): self.client.build(".", tag="https://example.com") def test_build_container_with_container_limits(self): self.client.build( ".", container_limits={ "memory": 1024 * 1024, "cpusetcpus": 1, "cpushares": 1000, "memswap": 1024 * 1024 * 8, }, ) def test_build_container_invalid_container_limits(self): with pytest.raises(docker.errors.DockerException): self.client.build(".", container_limits={"foo": "bar"}) def test_set_auth_headers_with_empty_dict_and_auth_configs(self): self.client._auth_configs = auth.AuthConfig( { "auths": { "https://example.com": { "user": "example", "password": "example", "email": "example@example.com", } } } ) headers = {} expected_headers = { "X-Registry-Config": auth.encode_header(self.client._auth_configs.auths) } self.client._set_auth_headers(headers) assert headers == expected_headers def test_set_auth_headers_with_dict_and_auth_configs(self): self.client._auth_configs = auth.AuthConfig( { "auths": { "https://example.com": { "user": "example", "password": "example", "email": "example@example.com", } } } ) headers = {"foo": "bar"} expected_headers = { "X-Registry-Config": auth.encode_header(self.client._auth_configs.auths), "foo": "bar", } self.client._set_auth_headers(headers) assert headers == expected_headers def test_set_auth_headers_with_dict_and_no_auth_configs(self): headers = {"foo": "bar"} expected_headers = {"foo": "bar"} self.client._set_auth_headers(headers) assert headers == expected_headers @pytest.mark.skipif( not docker.constants.IS_WINDOWS_PLATFORM, reason="Windows-specific syntax" ) def test_process_dockerfile_win_longpath_prefix(self): dirs = [ "foo", "foo/bar", "baz", ] files = [ "Dockerfile", "foo/Dockerfile.foo", "foo/bar/Dockerfile.bar", "baz/Dockerfile.baz", ] base = make_tree(dirs, files) self.addCleanup(shutil.rmtree, base) def pre(path): return docker.constants.WINDOWS_LONGPATH_PREFIX + path assert process_dockerfile(None, pre(base)) == (None, None) assert process_dockerfile("Dockerfile", pre(base)) == ("Dockerfile", None) assert process_dockerfile("foo/Dockerfile.foo", pre(base)) == ( "foo/Dockerfile.foo", None, ) assert process_dockerfile("../Dockerfile", pre(f"{base}\\foo"))[1] is not None assert process_dockerfile("../baz/Dockerfile.baz", pre(f"{base}/baz")) == ( "../baz/Dockerfile.baz", None, ) def test_process_dockerfile(self): dirs = [ "foo", "foo/bar", "baz", ] files = [ "Dockerfile", "foo/Dockerfile.foo", "foo/bar/Dockerfile.bar", "baz/Dockerfile.baz", ] base = make_tree(dirs, files) self.addCleanup(shutil.rmtree, base) assert process_dockerfile(None, base) == (None, None) assert process_dockerfile("Dockerfile", base) == ("Dockerfile", None) assert process_dockerfile("foo/Dockerfile.foo", base) == ( "foo/Dockerfile.foo", None, ) assert process_dockerfile("../Dockerfile", f"{base}/foo")[1] is not None assert process_dockerfile("../baz/Dockerfile.baz", f"{base}/baz") == ( "../baz/Dockerfile.baz", None, )