diff options
Diffstat (limited to 'tests/integration/api_container_test.py')
-rw-r--r-- | tests/integration/api_container_test.py | 272 |
1 files changed, 141 insertions, 131 deletions
diff --git a/tests/integration/api_container_test.py b/tests/integration/api_container_test.py index ff70148..1ba3eaa 100644 --- a/tests/integration/api_container_test.py +++ b/tests/integration/api_container_test.py @@ -5,28 +5,27 @@ import tempfile import threading from datetime import datetime -import docker -from docker.constants import IS_WINDOWS_PLATFORM -from docker.utils.socket import next_frame_size -from docker.utils.socket import read_exactly - import pytest - import requests import six -from .base import BUSYBOX, BaseAPIIntegrationTest +import docker from .. import helpers -from ..helpers import ( - requires_api_version, ctrl_with, assert_cat_socket_detached_with_keys -) +from ..helpers import assert_cat_socket_detached_with_keys +from ..helpers import ctrl_with +from ..helpers import requires_api_version +from .base import BaseAPIIntegrationTest +from .base import TEST_IMG +from docker.constants import IS_WINDOWS_PLATFORM +from docker.utils.socket import next_frame_header +from docker.utils.socket import read_exactly class ListContainersTest(BaseAPIIntegrationTest): def test_list_containers(self): res0 = self.client.containers(all=True) size = len(res0) - res1 = self.client.create_container(BUSYBOX, 'true') + res1 = self.client.create_container(TEST_IMG, 'true') assert 'Id' in res1 self.client.start(res1['Id']) self.tmp_containers.append(res1['Id']) @@ -38,20 +37,20 @@ class ListContainersTest(BaseAPIIntegrationTest): assert 'Command' in retrieved assert retrieved['Command'] == six.text_type('true') assert 'Image' in retrieved - assert re.search(r'busybox:.*', retrieved['Image']) + assert re.search(r'alpine:.*', retrieved['Image']) assert 'Status' in retrieved class CreateContainerTest(BaseAPIIntegrationTest): def test_create(self): - res = self.client.create_container(BUSYBOX, 'true') + res = self.client.create_container(TEST_IMG, 'true') assert 'Id' in res self.tmp_containers.append(res['Id']) def test_create_with_host_pid_mode(self): ctnr = self.client.create_container( - BUSYBOX, 'true', host_config=self.client.create_host_config( + TEST_IMG, 'true', host_config=self.client.create_host_config( pid_mode='host', network_mode='none' ) ) @@ -66,7 +65,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): def test_create_with_links(self): res0 = self.client.create_container( - BUSYBOX, 'cat', + TEST_IMG, 'cat', detach=True, stdin_open=True, environment={'FOO': '1'}) @@ -76,7 +75,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): self.client.start(container1_id) res1 = self.client.create_container( - BUSYBOX, 'cat', + TEST_IMG, 'cat', detach=True, stdin_open=True, environment={'FOO': '1'}) @@ -95,7 +94,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): link_env_prefix2 = link_alias2.upper() res2 = self.client.create_container( - BUSYBOX, 'env', host_config=self.client.create_host_config( + TEST_IMG, 'env', host_config=self.client.create_host_config( links={link_path1: link_alias1, link_path2: link_alias2}, network_mode='bridge' ) @@ -115,7 +114,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): def test_create_with_restart_policy(self): container = self.client.create_container( - BUSYBOX, ['sleep', '2'], + TEST_IMG, ['sleep', '2'], host_config=self.client.create_host_config( restart_policy={"Name": "always", "MaximumRetryCount": 0}, network_mode='none' @@ -134,21 +133,21 @@ class CreateContainerTest(BaseAPIIntegrationTest): vol_names = ['foobar_vol0', 'foobar_vol1'] res0 = self.client.create_container( - BUSYBOX, 'true', name=vol_names[0] + TEST_IMG, 'true', name=vol_names[0] ) container1_id = res0['Id'] self.tmp_containers.append(container1_id) self.client.start(container1_id) res1 = self.client.create_container( - BUSYBOX, 'true', name=vol_names[1] + TEST_IMG, 'true', name=vol_names[1] ) container2_id = res1['Id'] self.tmp_containers.append(container2_id) self.client.start(container2_id) res = self.client.create_container( - BUSYBOX, 'cat', detach=True, stdin_open=True, + TEST_IMG, 'cat', detach=True, stdin_open=True, host_config=self.client.create_host_config( volumes_from=vol_names, network_mode='none' ) @@ -162,7 +161,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): def create_container_readonly_fs(self): ctnr = self.client.create_container( - BUSYBOX, ['mkdir', '/shrine'], + TEST_IMG, ['mkdir', '/shrine'], host_config=self.client.create_host_config( read_only=True, network_mode='none' ) @@ -174,7 +173,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): assert res != 0 def create_container_with_name(self): - res = self.client.create_container(BUSYBOX, 'true', name='foobar') + res = self.client.create_container(TEST_IMG, 'true', name='foobar') assert 'Id' in res self.tmp_containers.append(res['Id']) inspect = self.client.inspect_container(res['Id']) @@ -183,7 +182,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): def create_container_privileged(self): res = self.client.create_container( - BUSYBOX, 'true', host_config=self.client.create_host_config( + TEST_IMG, 'true', host_config=self.client.create_host_config( privileged=True, network_mode='none' ) ) @@ -209,7 +208,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): def test_create_with_mac_address(self): mac_address_expected = "02:42:ac:11:00:0a" container = self.client.create_container( - BUSYBOX, ['sleep', '60'], mac_address=mac_address_expected) + TEST_IMG, ['sleep', '60'], mac_address=mac_address_expected) id = container['Id'] @@ -221,7 +220,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): def test_group_id_ints(self): container = self.client.create_container( - BUSYBOX, 'id -G', + TEST_IMG, 'id -G', host_config=self.client.create_host_config(group_add=[1000, 1001]) ) self.tmp_containers.append(container) @@ -237,7 +236,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): def test_group_id_strings(self): container = self.client.create_container( - BUSYBOX, 'id -G', host_config=self.client.create_host_config( + TEST_IMG, 'id -G', host_config=self.client.create_host_config( group_add=['1000', '1001'] ) ) @@ -260,7 +259,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): ) container = self.client.create_container( - BUSYBOX, ['true'], + TEST_IMG, ['true'], host_config=self.client.create_host_config(log_config=log_config) ) self.tmp_containers.append(container['Id']) @@ -282,7 +281,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): with pytest.raises(docker.errors.APIError) as excinfo: # raises an internal server error 500 container = self.client.create_container( - BUSYBOX, ['true'], host_config=self.client.create_host_config( + TEST_IMG, ['true'], host_config=self.client.create_host_config( log_config=log_config ) ) @@ -297,7 +296,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): ) container = self.client.create_container( - BUSYBOX, ['true'], + TEST_IMG, ['true'], host_config=self.client.create_host_config(log_config=log_config) ) self.tmp_containers.append(container['Id']) @@ -316,7 +315,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): ) container = self.client.create_container( - BUSYBOX, ['true'], + TEST_IMG, ['true'], host_config=self.client.create_host_config(log_config=log_config) ) self.tmp_containers.append(container['Id']) @@ -330,7 +329,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): def test_create_with_memory_constraints_with_str(self): ctnr = self.client.create_container( - BUSYBOX, 'true', + TEST_IMG, 'true', host_config=self.client.create_host_config( memswap_limit='1G', mem_limit='700M' @@ -348,7 +347,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): def test_create_with_memory_constraints_with_int(self): ctnr = self.client.create_container( - BUSYBOX, 'true', + TEST_IMG, 'true', host_config=self.client.create_host_config(mem_swappiness=40) ) assert 'Id' in ctnr @@ -362,16 +361,15 @@ class CreateContainerTest(BaseAPIIntegrationTest): def test_create_with_environment_variable_no_value(self): container = self.client.create_container( - BUSYBOX, + TEST_IMG, ['echo'], environment={'Foo': None, 'Other': 'one', 'Blank': ''}, ) self.tmp_containers.append(container['Id']) config = self.client.inspect_container(container['Id']) - assert ( - sorted(config['Config']['Env']) == - sorted(['Foo', 'Other=one', 'Blank=']) - ) + assert 'Foo' in config['Config']['Env'] + assert 'Other=one' in config['Config']['Env'] + assert 'Blank=' in config['Config']['Env'] @requires_api_version('1.22') def test_create_with_tmpfs(self): @@ -380,7 +378,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): } container = self.client.create_container( - BUSYBOX, + TEST_IMG, ['echo'], host_config=self.client.create_host_config( tmpfs=tmpfs)) @@ -392,7 +390,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): @requires_api_version('1.24') def test_create_with_isolation(self): container = self.client.create_container( - BUSYBOX, ['echo'], host_config=self.client.create_host_config( + TEST_IMG, ['echo'], host_config=self.client.create_host_config( isolation='default' ) ) @@ -406,7 +404,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): auto_remove=True ) container = self.client.create_container( - BUSYBOX, ['echo', 'test'], host_config=host_config + TEST_IMG, ['echo', 'test'], host_config=host_config ) self.tmp_containers.append(container['Id']) config = self.client.inspect_container(container) @@ -415,7 +413,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): @requires_api_version('1.25') def test_create_with_stop_timeout(self): container = self.client.create_container( - BUSYBOX, ['echo', 'test'], stop_timeout=25 + TEST_IMG, ['echo', 'test'], stop_timeout=25 ) self.tmp_containers.append(container['Id']) config = self.client.inspect_container(container) @@ -428,7 +426,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): storage_opt={'size': '120G'} ) container = self.client.create_container( - BUSYBOX, ['echo', 'test'], host_config=host_config + TEST_IMG, ['echo', 'test'], host_config=host_config ) self.tmp_containers.append(container) config = self.client.inspect_container(container) @@ -439,7 +437,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): @requires_api_version('1.25') def test_create_with_init(self): ctnr = self.client.create_container( - BUSYBOX, 'true', + TEST_IMG, 'true', host_config=self.client.create_host_config( init=True ) @@ -448,25 +446,12 @@ class CreateContainerTest(BaseAPIIntegrationTest): config = self.client.inspect_container(ctnr) assert config['HostConfig']['Init'] is True - @pytest.mark.xfail(True, reason='init-path removed in 17.05.0') - @requires_api_version('1.25') - def test_create_with_init_path(self): - ctnr = self.client.create_container( - BUSYBOX, 'true', - host_config=self.client.create_host_config( - init_path="/usr/libexec/docker-init" - ) - ) - self.tmp_containers.append(ctnr['Id']) - config = self.client.inspect_container(ctnr) - assert config['HostConfig']['InitPath'] == "/usr/libexec/docker-init" - @requires_api_version('1.24') @pytest.mark.xfail(not os.path.exists('/sys/fs/cgroup/cpu.rt_runtime_us'), reason='CONFIG_RT_GROUP_SCHED isn\'t enabled') def test_create_with_cpu_rt_options(self): ctnr = self.client.create_container( - BUSYBOX, 'true', host_config=self.client.create_host_config( + TEST_IMG, 'true', host_config=self.client.create_host_config( cpu_rt_period=1000, cpu_rt_runtime=500 ) ) @@ -479,7 +464,7 @@ class CreateContainerTest(BaseAPIIntegrationTest): def test_create_with_device_cgroup_rules(self): rule = 'c 7:128 rwm' ctnr = self.client.create_container( - BUSYBOX, 'cat /sys/fs/cgroup/devices/devices.list', + TEST_IMG, 'cat /sys/fs/cgroup/devices/devices.list', host_config=self.client.create_host_config( device_cgroup_rules=[rule] ) @@ -490,6 +475,16 @@ class CreateContainerTest(BaseAPIIntegrationTest): self.client.start(ctnr) assert rule in self.client.logs(ctnr).decode('utf-8') + def test_create_with_uts_mode(self): + container = self.client.create_container( + TEST_IMG, ['echo'], host_config=self.client.create_host_config( + uts_mode='host' + ) + ) + self.tmp_containers.append(container) + config = self.client.inspect_container(container) + assert config['HostConfig']['UTSMode'] == 'host' + @pytest.mark.xfail( IS_WINDOWS_PLATFORM, reason='Test not designed for Windows platform' @@ -506,7 +501,7 @@ class VolumeBindTest(BaseAPIIntegrationTest): self.run_with_volume( False, - BUSYBOX, + TEST_IMG, ['touch', os.path.join(self.mount_dest, self.filename)], ) @@ -514,7 +509,7 @@ class VolumeBindTest(BaseAPIIntegrationTest): container = self.run_with_volume( False, - BUSYBOX, + TEST_IMG, ['ls', self.mount_dest], ) logs = self.client.logs(container) @@ -528,12 +523,12 @@ class VolumeBindTest(BaseAPIIntegrationTest): def test_create_with_binds_ro(self): self.run_with_volume( False, - BUSYBOX, + TEST_IMG, ['touch', os.path.join(self.mount_dest, self.filename)], ) container = self.run_with_volume( True, - BUSYBOX, + TEST_IMG, ['ls', self.mount_dest], ) logs = self.client.logs(container) @@ -552,7 +547,7 @@ class VolumeBindTest(BaseAPIIntegrationTest): ) host_config = self.client.create_host_config(mounts=[mount]) container = self.run_container( - BUSYBOX, ['ls', self.mount_dest], + TEST_IMG, ['ls', self.mount_dest], host_config=host_config ) assert container @@ -571,7 +566,7 @@ class VolumeBindTest(BaseAPIIntegrationTest): ) host_config = self.client.create_host_config(mounts=[mount]) container = self.run_container( - BUSYBOX, ['ls', self.mount_dest], + TEST_IMG, ['ls', self.mount_dest], host_config=host_config ) assert container @@ -590,7 +585,7 @@ class VolumeBindTest(BaseAPIIntegrationTest): ) host_config = self.client.create_host_config(mounts=[mount]) container = self.client.create_container( - BUSYBOX, ['true'], host_config=host_config, + TEST_IMG, ['true'], host_config=host_config, ) assert container inspect_data = self.client.inspect_container(container) @@ -636,7 +631,7 @@ class ArchiveTest(BaseAPIIntegrationTest): def test_get_file_archive_from_container(self): data = 'The Maid and the Pocket Watch of Blood' ctnr = self.client.create_container( - BUSYBOX, 'sh -c "echo {0} > /vol1/data.txt"'.format(data), + TEST_IMG, 'sh -c "echo {0} > /vol1/data.txt"'.format(data), volumes=['/vol1'] ) self.tmp_containers.append(ctnr) @@ -655,7 +650,7 @@ class ArchiveTest(BaseAPIIntegrationTest): def test_get_file_stat_from_container(self): data = 'The Maid and the Pocket Watch of Blood' ctnr = self.client.create_container( - BUSYBOX, 'sh -c "echo -n {0} > /vol1/data.txt"'.format(data), + TEST_IMG, 'sh -c "echo -n {0} > /vol1/data.txt"'.format(data), volumes=['/vol1'] ) self.tmp_containers.append(ctnr) @@ -673,7 +668,7 @@ class ArchiveTest(BaseAPIIntegrationTest): test_file.write(data) test_file.seek(0) ctnr = self.client.create_container( - BUSYBOX, + TEST_IMG, 'cat {0}'.format( os.path.join('/vol1/', os.path.basename(test_file.name)) ), @@ -695,7 +690,7 @@ class ArchiveTest(BaseAPIIntegrationTest): dirs = ['foo', 'bar'] base = helpers.make_tree(dirs, files) ctnr = self.client.create_container( - BUSYBOX, 'ls -p /vol1', volumes=['/vol1'] + TEST_IMG, 'ls -p /vol1', volumes=['/vol1'] ) self.tmp_containers.append(ctnr) with docker.utils.tar(base) as test_tar: @@ -716,7 +711,7 @@ class RenameContainerTest(BaseAPIIntegrationTest): def test_rename_container(self): version = self.client.version()['Version'] name = 'hong_meiling' - res = self.client.create_container(BUSYBOX, 'true') + res = self.client.create_container(TEST_IMG, 'true') assert 'Id' in res self.tmp_containers.append(res['Id']) self.client.rename(res, name) @@ -730,7 +725,7 @@ class RenameContainerTest(BaseAPIIntegrationTest): class StartContainerTest(BaseAPIIntegrationTest): def test_start_container(self): - res = self.client.create_container(BUSYBOX, 'true') + res = self.client.create_container(TEST_IMG, 'true') assert 'Id' in res self.tmp_containers.append(res['Id']) self.client.start(res['Id']) @@ -746,7 +741,7 @@ class StartContainerTest(BaseAPIIntegrationTest): assert inspect['State']['ExitCode'] == 0 def test_start_container_with_dict_instead_of_id(self): - res = self.client.create_container(BUSYBOX, 'true') + res = self.client.create_container(TEST_IMG, 'true') assert 'Id' in res self.tmp_containers.append(res['Id']) self.client.start(res) @@ -774,7 +769,7 @@ class StartContainerTest(BaseAPIIntegrationTest): 'true && echo "Night of Nights"' ] for cmd in commands: - container = self.client.create_container(BUSYBOX, cmd) + container = self.client.create_container(TEST_IMG, cmd) id = container['Id'] self.client.start(id) self.tmp_containers.append(id) @@ -784,7 +779,7 @@ class StartContainerTest(BaseAPIIntegrationTest): class WaitTest(BaseAPIIntegrationTest): def test_wait(self): - res = self.client.create_container(BUSYBOX, ['sleep', '3']) + res = self.client.create_container(TEST_IMG, ['sleep', '3']) id = res['Id'] self.tmp_containers.append(id) self.client.start(id) @@ -797,7 +792,7 @@ class WaitTest(BaseAPIIntegrationTest): assert inspect['State']['ExitCode'] == exitcode def test_wait_with_dict_instead_of_id(self): - res = self.client.create_container(BUSYBOX, ['sleep', '3']) + res = self.client.create_container(TEST_IMG, ['sleep', '3']) id = res['Id'] self.tmp_containers.append(id) self.client.start(res) @@ -811,13 +806,13 @@ class WaitTest(BaseAPIIntegrationTest): @requires_api_version('1.30') def test_wait_with_condition(self): - ctnr = self.client.create_container(BUSYBOX, 'true') + ctnr = self.client.create_container(TEST_IMG, 'true') self.tmp_containers.append(ctnr) with pytest.raises(requests.exceptions.ConnectionError): self.client.wait(ctnr, condition='removed', timeout=1) ctnr = self.client.create_container( - BUSYBOX, ['sleep', '3'], + TEST_IMG, ['sleep', '3'], host_config=self.client.create_host_config(auto_remove=True) ) self.tmp_containers.append(ctnr) @@ -831,7 +826,7 @@ class LogsTest(BaseAPIIntegrationTest): def test_logs(self): snippet = 'Flowering Nights (Sakuya Iyazoi)' container = self.client.create_container( - BUSYBOX, 'echo {0}'.format(snippet) + TEST_IMG, 'echo {0}'.format(snippet) ) id = container['Id'] self.tmp_containers.append(id) @@ -845,7 +840,7 @@ class LogsTest(BaseAPIIntegrationTest): snippet = '''Line1 Line2''' container = self.client.create_container( - BUSYBOX, 'echo "{0}"'.format(snippet) + TEST_IMG, 'echo "{0}"'.format(snippet) ) id = container['Id'] self.tmp_containers.append(id) @@ -858,7 +853,7 @@ Line2''' def test_logs_streaming_and_follow(self): snippet = 'Flowering Nights (Sakuya Iyazoi)' container = self.client.create_container( - BUSYBOX, 'echo {0}'.format(snippet) + TEST_IMG, 'echo {0}'.format(snippet) ) id = container['Id'] self.tmp_containers.append(id) @@ -873,10 +868,12 @@ Line2''' assert logs == (snippet + '\n').encode(encoding='ascii') @pytest.mark.timeout(5) + @pytest.mark.skipif(os.environ.get('DOCKER_HOST', '').startswith('ssh://'), + reason='No cancellable streams over SSH') def test_logs_streaming_and_follow_and_cancel(self): snippet = 'Flowering Nights (Sakuya Iyazoi)' container = self.client.create_container( - BUSYBOX, 'sh -c "echo \\"{0}\\" && sleep 3"'.format(snippet) + TEST_IMG, 'sh -c "echo \\"{0}\\" && sleep 3"'.format(snippet) ) id = container['Id'] self.tmp_containers.append(id) @@ -894,7 +891,7 @@ Line2''' def test_logs_with_dict_instead_of_id(self): snippet = 'Flowering Nights (Sakuya Iyazoi)' container = self.client.create_container( - BUSYBOX, 'echo {0}'.format(snippet) + TEST_IMG, 'echo {0}'.format(snippet) ) id = container['Id'] self.tmp_containers.append(id) @@ -907,7 +904,7 @@ Line2''' def test_logs_with_tail_0(self): snippet = 'Flowering Nights (Sakuya Iyazoi)' container = self.client.create_container( - BUSYBOX, 'echo "{0}"'.format(snippet) + TEST_IMG, 'echo "{0}"'.format(snippet) ) id = container['Id'] self.tmp_containers.append(id) @@ -921,7 +918,7 @@ Line2''' def test_logs_with_until(self): snippet = 'Shanghai Teahouse (Hong Meiling)' container = self.client.create_container( - BUSYBOX, 'echo "{0}"'.format(snippet) + TEST_IMG, 'echo "{0}"'.format(snippet) ) self.tmp_containers.append(container) @@ -936,7 +933,7 @@ Line2''' class DiffTest(BaseAPIIntegrationTest): def test_diff(self): - container = self.client.create_container(BUSYBOX, ['touch', '/test']) + container = self.client.create_container(TEST_IMG, ['touch', '/test']) id = container['Id'] self.client.start(id) self.tmp_containers.append(id) @@ -949,7 +946,7 @@ class DiffTest(BaseAPIIntegrationTest): assert test_diff[0]['Kind'] == 1 def test_diff_with_dict_instead_of_id(self): - container = self.client.create_container(BUSYBOX, ['touch', '/test']) + container = self.client.create_container(TEST_IMG, ['touch', '/test']) id = container['Id'] self.client.start(id) self.tmp_containers.append(id) @@ -964,7 +961,7 @@ class DiffTest(BaseAPIIntegrationTest): class StopTest(BaseAPIIntegrationTest): def test_stop(self): - container = self.client.create_container(BUSYBOX, ['sleep', '9999']) + container = self.client.create_container(TEST_IMG, ['sleep', '9999']) id = container['Id'] self.client.start(id) self.tmp_containers.append(id) @@ -976,7 +973,7 @@ class StopTest(BaseAPIIntegrationTest): assert state['Running'] is False def test_stop_with_dict_instead_of_id(self): - container = self.client.create_container(BUSYBOX, ['sleep', '9999']) + container = self.client.create_container(TEST_IMG, ['sleep', '9999']) assert 'Id' in container id = container['Id'] self.client.start(container) @@ -991,7 +988,7 @@ class StopTest(BaseAPIIntegrationTest): class KillTest(BaseAPIIntegrationTest): def test_kill(self): - container = self.client.create_container(BUSYBOX, ['sleep', '9999']) + container = self.client.create_container(TEST_IMG, ['sleep', '9999']) id = container['Id'] self.client.start(id) self.tmp_containers.append(id) @@ -1005,7 +1002,7 @@ class KillTest(BaseAPIIntegrationTest): assert state['Running'] is False def test_kill_with_dict_instead_of_id(self): - container = self.client.create_container(BUSYBOX, ['sleep', '9999']) + container = self.client.create_container(TEST_IMG, ['sleep', '9999']) id = container['Id'] self.client.start(id) self.tmp_containers.append(id) @@ -1019,7 +1016,7 @@ class KillTest(BaseAPIIntegrationTest): assert state['Running'] is False def test_kill_with_signal(self): - id = self.client.create_container(BUSYBOX, ['sleep', '60']) + id = self.client.create_container(TEST_IMG, ['sleep', '60']) self.tmp_containers.append(id) self.client.start(id) self.client.kill( @@ -1036,7 +1033,7 @@ class KillTest(BaseAPIIntegrationTest): assert state['Running'] is False, state def test_kill_with_signal_name(self): - id = self.client.create_container(BUSYBOX, ['sleep', '60']) + id = self.client.create_container(TEST_IMG, ['sleep', '60']) self.client.start(id) self.tmp_containers.append(id) self.client.kill(id, signal='SIGKILL') @@ -1051,7 +1048,7 @@ class KillTest(BaseAPIIntegrationTest): assert state['Running'] is False, state def test_kill_with_signal_integer(self): - id = self.client.create_container(BUSYBOX, ['sleep', '60']) + id = self.client.create_container(TEST_IMG, ['sleep', '60']) self.client.start(id) self.tmp_containers.append(id) self.client.kill(id, signal=9) @@ -1068,14 +1065,19 @@ class KillTest(BaseAPIIntegrationTest): class PortTest(BaseAPIIntegrationTest): def test_port(self): - port_bindings = { '1111': ('127.0.0.1', '4567'), - '2222': ('127.0.0.1', '4568') + '2222': ('127.0.0.1', '4568'), + '3333/udp': ('127.0.0.1', '4569'), } + ports = [ + 1111, + 2222, + (3333, 'udp'), + ] container = self.client.create_container( - BUSYBOX, ['sleep', '60'], ports=list(port_bindings.keys()), + TEST_IMG, ['sleep', '60'], ports=ports, host_config=self.client.create_host_config( port_bindings=port_bindings, network_mode='bridge' ) @@ -1086,13 +1088,15 @@ class PortTest(BaseAPIIntegrationTest): # Call the port function on each biding and compare expected vs actual for port in port_bindings: + port, _, protocol = port.partition('/') actual_bindings = self.client.port(container, port) port_binding = actual_bindings.pop() ip, host_port = port_binding['HostIp'], port_binding['HostPort'] - assert ip == port_bindings[port][0] - assert host_port == port_bindings[port][1] + port_binding = port if not protocol else port + "/" + protocol + assert ip == port_bindings[port_binding][0] + assert host_port == port_bindings[port_binding][1] self.client.kill(id) @@ -1100,7 +1104,7 @@ class PortTest(BaseAPIIntegrationTest): class ContainerTopTest(BaseAPIIntegrationTest): def test_top(self): container = self.client.create_container( - BUSYBOX, ['sleep', '60'] + TEST_IMG, ['sleep', '60'] ) self.tmp_containers.append(container) @@ -1120,7 +1124,7 @@ class ContainerTopTest(BaseAPIIntegrationTest): ) def test_top_with_psargs(self): container = self.client.create_container( - BUSYBOX, ['sleep', '60']) + TEST_IMG, ['sleep', '60']) self.tmp_containers.append(container) @@ -1136,7 +1140,7 @@ class ContainerTopTest(BaseAPIIntegrationTest): class RestartContainerTest(BaseAPIIntegrationTest): def test_restart(self): - container = self.client.create_container(BUSYBOX, ['sleep', '9999']) + container = self.client.create_container(TEST_IMG, ['sleep', '9999']) id = container['Id'] self.client.start(id) self.tmp_containers.append(id) @@ -1155,16 +1159,16 @@ class RestartContainerTest(BaseAPIIntegrationTest): self.client.kill(id) def test_restart_with_low_timeout(self): - container = self.client.create_container(BUSYBOX, ['sleep', '9999']) + container = self.client.create_container(TEST_IMG, ['sleep', '9999']) self.client.start(container) - self.client.timeout = 1 - self.client.restart(container, timeout=3) + self.client.timeout = 3 + self.client.restart(container, timeout=1) self.client.timeout = None - self.client.restart(container, timeout=3) + self.client.restart(container, timeout=1) self.client.kill(container) def test_restart_with_dict_instead_of_id(self): - container = self.client.create_container(BUSYBOX, ['sleep', '9999']) + container = self.client.create_container(TEST_IMG, ['sleep', '9999']) assert 'Id' in container id = container['Id'] self.client.start(container) @@ -1186,7 +1190,7 @@ class RestartContainerTest(BaseAPIIntegrationTest): class RemoveContainerTest(BaseAPIIntegrationTest): def test_remove(self): - container = self.client.create_container(BUSYBOX, ['true']) + container = self.client.create_container(TEST_IMG, ['true']) id = container['Id'] self.client.start(id) self.client.wait(id) @@ -1196,7 +1200,7 @@ class RemoveContainerTest(BaseAPIIntegrationTest): assert len(res) == 0 def test_remove_with_dict_instead_of_id(self): - container = self.client.create_container(BUSYBOX, ['true']) + container = self.client.create_container(TEST_IMG, ['true']) id = container['Id'] self.client.start(id) self.client.wait(id) @@ -1208,7 +1212,7 @@ class RemoveContainerTest(BaseAPIIntegrationTest): class AttachContainerTest(BaseAPIIntegrationTest): def test_run_container_streaming(self): - container = self.client.create_container(BUSYBOX, '/bin/sh', + container = self.client.create_container(TEST_IMG, '/bin/sh', detach=True, stdin_open=True) id = container['Id'] self.tmp_containers.append(id) @@ -1220,7 +1224,7 @@ class AttachContainerTest(BaseAPIIntegrationTest): line = 'hi there and stuff and things, words!' # `echo` appends CRLF, `printf` doesn't command = "printf '{0}'".format(line) - container = self.client.create_container(BUSYBOX, command, + container = self.client.create_container(TEST_IMG, command, detach=True, tty=False) self.tmp_containers.append(container) @@ -1230,31 +1234,37 @@ class AttachContainerTest(BaseAPIIntegrationTest): self.client.start(container) - next_size = next_frame_size(pty_stdout) + (stream, next_size) = next_frame_header(pty_stdout) + assert stream == 1 # correspond to stdout assert next_size == len(line) data = read_exactly(pty_stdout, next_size) assert data.decode('utf-8') == line def test_attach_no_stream(self): container = self.client.create_container( - BUSYBOX, 'echo hello' + TEST_IMG, 'echo hello' ) self.tmp_containers.append(container) self.client.start(container) output = self.client.attach(container, stream=False, logs=True) assert output == 'hello\n'.encode(encoding='ascii') - @pytest.mark.timeout(5) + @pytest.mark.timeout(10) + @pytest.mark.skipif(os.environ.get('DOCKER_HOST', '').startswith('ssh://'), + reason='No cancellable streams over SSH') + @pytest.mark.xfail(condition=os.environ.get('DOCKER_TLS_VERIFY') or + os.environ.get('DOCKER_CERT_PATH'), + reason='Flaky test on TLS') def test_attach_stream_and_cancel(self): container = self.client.create_container( - BUSYBOX, 'sh -c "echo hello && sleep 60"', + TEST_IMG, 'sh -c "sleep 2 && echo hello && sleep 60"', tty=True ) self.tmp_containers.append(container) self.client.start(container) output = self.client.attach(container, stream=True, logs=True) - threading.Timer(1, output.close).start() + threading.Timer(3, output.close).start() lines = [] for line in output: @@ -1265,7 +1275,7 @@ class AttachContainerTest(BaseAPIIntegrationTest): def test_detach_with_default(self): container = self.client.create_container( - BUSYBOX, 'cat', + TEST_IMG, 'cat', detach=True, stdin_open=True, tty=True ) self.tmp_containers.append(container) @@ -1284,7 +1294,7 @@ class AttachContainerTest(BaseAPIIntegrationTest): self.client._general_configs['detachKeys'] = 'ctrl-p' container = self.client.create_container( - BUSYBOX, 'cat', + TEST_IMG, 'cat', detach=True, stdin_open=True, tty=True ) self.tmp_containers.append(container) @@ -1301,7 +1311,7 @@ class AttachContainerTest(BaseAPIIntegrationTest): self.client._general_configs['detachKeys'] = 'ctrl-p' container = self.client.create_container( - BUSYBOX, 'cat', + TEST_IMG, 'cat', detach=True, stdin_open=True, tty=True ) self.tmp_containers.append(container) @@ -1317,7 +1327,7 @@ class AttachContainerTest(BaseAPIIntegrationTest): class PauseTest(BaseAPIIntegrationTest): def test_pause_unpause(self): - container = self.client.create_container(BUSYBOX, ['sleep', '9999']) + container = self.client.create_container(TEST_IMG, ['sleep', '9999']) id = container['Id'] self.tmp_containers.append(id) self.client.start(container) @@ -1348,9 +1358,9 @@ class PruneTest(BaseAPIIntegrationTest): @requires_api_version('1.25') def test_prune_containers(self): container1 = self.client.create_container( - BUSYBOX, ['sh', '-c', 'echo hello > /data.txt'] + TEST_IMG, ['sh', '-c', 'echo hello > /data.txt'] ) - container2 = self.client.create_container(BUSYBOX, ['sleep', '9999']) + container2 = self.client.create_container(TEST_IMG, ['sleep', '9999']) self.client.start(container1) self.client.start(container2) self.client.wait(container1) @@ -1363,7 +1373,7 @@ class PruneTest(BaseAPIIntegrationTest): class GetContainerStatsTest(BaseAPIIntegrationTest): def test_get_container_stats_no_stream(self): container = self.client.create_container( - BUSYBOX, ['sleep', '60'], + TEST_IMG, ['sleep', '60'], ) self.tmp_containers.append(container) self.client.start(container) @@ -1377,7 +1387,7 @@ class GetContainerStatsTest(BaseAPIIntegrationTest): def test_get_container_stats_stream(self): container = self.client.create_container( - BUSYBOX, ['sleep', '60'], + TEST_IMG, ['sleep', '60'], ) self.tmp_containers.append(container) self.client.start(container) @@ -1395,7 +1405,7 @@ class ContainerUpdateTest(BaseAPIIntegrationTest): old_mem_limit = 400 * 1024 * 1024 new_mem_limit = 300 * 1024 * 1024 container = self.client.create_container( - BUSYBOX, 'top', host_config=self.client.create_host_config( + TEST_IMG, 'top', host_config=self.client.create_host_config( mem_limit=old_mem_limit ) ) @@ -1416,7 +1426,7 @@ class ContainerUpdateTest(BaseAPIIntegrationTest): 'Name': 'on-failure' } container = self.client.create_container( - BUSYBOX, ['sleep', '60'], + TEST_IMG, ['sleep', '60'], host_config=self.client.create_host_config( restart_policy=old_restart_policy ) @@ -1440,7 +1450,7 @@ class ContainerCPUTest(BaseAPIIntegrationTest): def test_container_cpu_shares(self): cpu_shares = 512 container = self.client.create_container( - BUSYBOX, 'ls', host_config=self.client.create_host_config( + TEST_IMG, 'ls', host_config=self.client.create_host_config( cpu_shares=cpu_shares ) ) @@ -1452,7 +1462,7 @@ class ContainerCPUTest(BaseAPIIntegrationTest): def test_container_cpuset(self): cpuset_cpus = "0,1" container = self.client.create_container( - BUSYBOX, 'ls', host_config=self.client.create_host_config( + TEST_IMG, 'ls', host_config=self.client.create_host_config( cpuset_cpus=cpuset_cpus ) ) @@ -1464,7 +1474,7 @@ class ContainerCPUTest(BaseAPIIntegrationTest): @requires_api_version('1.25') def test_create_with_runtime(self): container = self.client.create_container( - BUSYBOX, ['echo', 'test'], runtime='runc' + TEST_IMG, ['echo', 'test'], runtime='runc' ) self.tmp_containers.append(container['Id']) config = self.client.inspect_container(container) @@ -1475,7 +1485,7 @@ class LinkTest(BaseAPIIntegrationTest): def test_remove_link(self): # Create containers container1 = self.client.create_container( - BUSYBOX, 'cat', detach=True, stdin_open=True + TEST_IMG, 'cat', detach=True, stdin_open=True ) container1_id = container1['Id'] self.tmp_containers.append(container1_id) @@ -1487,7 +1497,7 @@ class LinkTest(BaseAPIIntegrationTest): link_alias = 'mylink' container2 = self.client.create_container( - BUSYBOX, 'cat', host_config=self.client.create_host_config( + TEST_IMG, 'cat', host_config=self.client.create_host_config( links={link_path: link_alias} ) ) |