App Engine Python SDK version 1.9.2
git-svn-id: http://googleappengine.googlecode.com/svn/trunk/python@423 80f5ef21-4148-0410-bacc-cfb02402ada8
diff --git a/lib/docker/tests/test.py b/lib/docker/tests/test.py
new file mode 100644
index 0000000..5ab0031
--- /dev/null
+++ b/lib/docker/tests/test.py
@@ -0,0 +1,1221 @@
+# Copyright 2013 dotCloud inc.
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import base64
+import datetime
+import io
+import json
+import os
+import signal
+import tempfile
+import unittest
+
+import docker
+import requests
+import six
+
+import fake_api
+
+
+try:
+ from unittest import mock
+except ImportError:
+ import mock
+
+
+def response(status_code=200, content='', headers=None, reason=None, elapsed=0,
+ request=None):
+ res = requests.Response()
+ res.status_code = status_code
+ if not isinstance(content, six.string_types):
+ content = json.dumps(content)
+ if six.PY3:
+ content = content.encode('ascii')
+ res._content = content
+ res.headers = requests.structures.CaseInsensitiveDict(headers or {})
+ res.reason = reason
+ res.elapsed = datetime.timedelta(elapsed)
+ res.request = request
+ return res
+
+
+def fake_resp(url, data=None, **kwargs):
+ status_code, content = fake_api.fake_responses[url]()
+ return response(status_code=status_code, content=content)
+
+fake_request = mock.Mock(side_effect=fake_resp)
+url_prefix = 'http+unix://var/run/docker.sock/v{0}/'.format(
+ docker.client.DEFAULT_DOCKER_API_VERSION)
+
+
+@mock.patch.multiple('docker.Client', get=fake_request, post=fake_request,
+ put=fake_request, delete=fake_request)
+class DockerClientTest(unittest.TestCase):
+ def setUp(self):
+ self.client = docker.Client()
+ # Force-clear authconfig to avoid tampering with the tests
+ self.client._cfg = {'Configs': {}}
+
+ #########################
+ ## INFORMATION TESTS ##
+ #########################
+ def test_version(self):
+ try:
+ self.client.version()
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'version',
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_info(self):
+ try:
+ self.client.info()
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'info',
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_search(self):
+ try:
+ self.client.search('busybox')
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/search',
+ params={'term': 'busybox'},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_image_viz(self):
+ try:
+ self.client.images('busybox', viz=True)
+ self.fail('Viz output should not be supported!')
+ except Exception:
+ pass
+
+ ###################
+ ## LISTING TESTS ##
+ ###################
+
+ def test_images(self):
+ try:
+ self.client.images(all=True)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+ fake_request.assert_called_with(
+ url_prefix + 'images/json',
+ params={'filter': None, 'only_ids': 0, 'all': 1},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_images_quiet(self):
+ try:
+ self.client.images(all=True, quiet=True)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+ fake_request.assert_called_with(
+ url_prefix + 'images/json',
+ params={'filter': None, 'only_ids': 1, 'all': 1},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_image_ids(self):
+ try:
+ self.client.images(quiet=True)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/json',
+ params={'filter': None, 'only_ids': 1, 'all': 0},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_list_containers(self):
+ try:
+ self.client.containers(all=True)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/json',
+ params={
+ 'all': 1,
+ 'since': None,
+ 'limit': -1,
+ 'trunc_cmd': 1,
+ 'before': None
+ },
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ #####################
+ ## CONTAINER TESTS ##
+ #####################
+
+ def test_create_container(self):
+ try:
+ self.client.create_container('busybox', 'true')
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(args[0][0],
+ url_prefix + 'containers/create')
+ self.assertEqual(json.loads(args[1]['data']),
+ json.loads('''
+ {"Tty": false, "Image": "busybox", "Cmd": ["true"],
+ "AttachStdin": false, "Memory": 0,
+ "AttachStderr": true, "AttachStdout": true,
+ "StdinOnce": false,
+ "OpenStdin": false, "NetworkDisabled": false}'''))
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+
+ def test_create_container_with_binds(self):
+ mount_dest = '/mnt'
+ #mount_origin = '/tmp'
+
+ try:
+ self.client.create_container('busybox', ['ls', mount_dest],
+ volumes=[mount_dest])
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(args[0][0],
+ url_prefix + 'containers/create')
+ self.assertEqual(json.loads(args[1]['data']),
+ json.loads('''
+ {"Tty": false, "Image": "busybox",
+ "Cmd": ["ls", "/mnt"], "AttachStdin": false,
+ "Volumes": {"/mnt": {}}, "Memory": 0,
+ "AttachStderr": true,
+ "AttachStdout": true, "OpenStdin": false,
+ "StdinOnce": false,
+ "NetworkDisabled": false}'''))
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+
+ def test_create_container_with_ports(self):
+ try:
+ self.client.create_container('busybox', 'ls',
+ ports=[1111, (2222, 'udp'), (3333,)])
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(args[0][0],
+ url_prefix + 'containers/create')
+ self.assertEqual(json.loads(args[1]['data']),
+ json.loads('''
+ {"Tty": false, "Image": "busybox",
+ "Cmd": ["ls"], "AttachStdin": false,
+ "Memory": 0, "ExposedPorts": {
+ "1111/tcp": {},
+ "2222/udp": {},
+ "3333/tcp": {}
+ },
+ "AttachStderr": true,
+ "AttachStdout": true, "OpenStdin": false,
+ "StdinOnce": false,
+ "NetworkDisabled": false}'''))
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+
+ def test_create_container_with_entrypoint(self):
+ try:
+ self.client.create_container('busybox', 'hello',
+ entrypoint='cowsay')
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(args[0][0],
+ url_prefix + 'containers/create')
+ self.assertEqual(json.loads(args[1]['data']),
+ json.loads('''
+ {"Tty": false, "Image": "busybox",
+ "Cmd": ["hello"], "AttachStdin": false,
+ "Memory": 0,
+ "AttachStderr": true,
+ "AttachStdout": true, "OpenStdin": false,
+ "StdinOnce": false,
+ "NetworkDisabled": false,
+ "Entrypoint": "cowsay"}'''))
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+
+ def test_create_container_with_cpu_shares(self):
+ try:
+ self.client.create_container('busybox', 'ls',
+ cpu_shares=5)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(args[0][0],
+ url_prefix + 'containers/create')
+ self.assertEqual(json.loads(args[1]['data']),
+ json.loads('''
+ {"Tty": false, "Image": "busybox",
+ "Cmd": ["ls"], "AttachStdin": false,
+ "Memory": 0,
+ "AttachStderr": true,
+ "AttachStdout": true, "OpenStdin": false,
+ "StdinOnce": false,
+ "NetworkDisabled": false,
+ "CpuShares": 5}'''))
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+
+ def test_create_container_with_working_dir(self):
+ try:
+ self.client.create_container('busybox', 'ls',
+ working_dir='/root')
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(args[0][0],
+ url_prefix + 'containers/create')
+ self.assertEqual(json.loads(args[1]['data']),
+ json.loads('''
+ {"Tty": false, "Image": "busybox",
+ "Cmd": ["ls"], "AttachStdin": false,
+ "Memory": 0,
+ "AttachStderr": true,
+ "AttachStdout": true, "OpenStdin": false,
+ "StdinOnce": false,
+ "NetworkDisabled": false,
+ "WorkingDir": "/root"}'''))
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+
+ def test_create_container_with_stdin_open(self):
+ try:
+ self.client.create_container('busybox', 'true', stdin_open=True)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(args[0][0],
+ url_prefix + 'containers/create')
+ self.assertEqual(json.loads(args[1]['data']),
+ json.loads('''
+ {"Tty": false, "Image": "busybox", "Cmd": ["true"],
+ "AttachStdin": true, "Memory": 0,
+ "AttachStderr": true, "AttachStdout": true,
+ "StdinOnce": true,
+ "OpenStdin": true, "NetworkDisabled": false}'''))
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+
+ def test_create_named_container(self):
+ try:
+ self.client.create_container('busybox', 'true',
+ name='marisa-kirisame')
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(args[0][0],
+ url_prefix + 'containers/create')
+ self.assertEqual(json.loads(args[1]['data']),
+ json.loads('''
+ {"Tty": false, "Image": "busybox", "Cmd": ["true"],
+ "AttachStdin": false, "Memory": 0,
+ "AttachStderr": true, "AttachStdout": true,
+ "StdinOnce": false,
+ "OpenStdin": false, "NetworkDisabled": false}'''))
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+ self.assertEqual(args[1]['params'], {'name': 'marisa-kirisame'})
+
+ def test_start_container(self):
+ try:
+ self.client.start(fake_api.FAKE_CONTAINER_ID)
+ except Exception as e:
+ raise e
+ self.fail('Command should not raise exception: {0}'.format(e))
+ args = fake_request.call_args
+ self.assertEqual(
+ args[0][0],
+ url_prefix + 'containers/3cc2351ab11b/start'
+ )
+ self.assertEqual(
+ json.loads(args[1]['data']),
+ {"PublishAllPorts": False, "Privileged": False}
+ )
+ self.assertEqual(
+ args[1]['headers'],
+ {'Content-Type': 'application/json'}
+ )
+ self.assertEqual(
+ args[1]['timeout'],
+ docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_start_container_with_lxc_conf(self):
+ try:
+ self.client.start(
+ fake_api.FAKE_CONTAINER_ID,
+ lxc_conf={'lxc.conf.k': 'lxc.conf.value'}
+ )
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+ args = fake_request.call_args
+ self.assertEqual(
+ args[0][0],
+ url_prefix + 'containers/3cc2351ab11b/start'
+ )
+ self.assertEqual(
+ json.loads(args[1]['data']),
+ {"LxcConf": [{"Value": "lxc.conf.value", "Key": "lxc.conf.k"}],
+ "PublishAllPorts": False, "Privileged": False}
+ )
+ self.assertEqual(
+ args[1]['headers'],
+ {'Content-Type': 'application/json'}
+ )
+ self.assertEqual(
+ args[1]['timeout'],
+ docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_start_container_with_lxc_conf_compat(self):
+ try:
+ self.client.start(
+ fake_api.FAKE_CONTAINER_ID,
+ lxc_conf=[{'Key': 'lxc.conf.k', 'Value': 'lxc.conf.value'}]
+ )
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(args[0][0], url_prefix +
+ 'containers/3cc2351ab11b/start')
+ self.assertEqual(
+ json.loads(args[1]['data']),
+ {
+ "LxcConf": [{"Key": "lxc.conf.k", "Value": "lxc.conf.value"}],
+ "PublishAllPorts": False,
+ "Privileged": False,
+ }
+ )
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+ self.assertEqual(
+ args[1]['timeout'],
+ docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_start_container_with_binds(self):
+ try:
+ mount_dest = '/mnt'
+ mount_origin = '/tmp'
+ self.client.start(fake_api.FAKE_CONTAINER_ID,
+ binds={mount_origin: mount_dest})
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(args[0][0], url_prefix +
+ 'containers/3cc2351ab11b/start')
+ self.assertEqual(json.loads(args[1]['data']),
+ {"Binds": ["/tmp:/mnt"],
+ "PublishAllPorts": False,
+ "Privileged": False})
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+ self.assertEqual(
+ args[1]['timeout'],
+ docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_start_container_with_port_binds(self):
+ self.maxDiff = None
+ try:
+ self.client.start(fake_api.FAKE_CONTAINER_ID, port_bindings={
+ 1111: None,
+ 2222: 2222,
+ '3333/udp': (3333,),
+ 4444: ('127.0.0.1',),
+ 5555: ('127.0.0.1', 5555),
+ 6666: [('127.0.0.1',), ('192.168.0.1',)]
+ })
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(args[0][0], url_prefix +
+ 'containers/3cc2351ab11b/start')
+ data = json.loads(args[1]['data'])
+ self.assertEqual(data['PublishAllPorts'], False)
+ self.assertTrue('1111/tcp' in data['PortBindings'])
+ self.assertTrue('2222/tcp' in data['PortBindings'])
+ self.assertTrue('3333/udp' in data['PortBindings'])
+ self.assertTrue('4444/tcp' in data['PortBindings'])
+ self.assertTrue('5555/tcp' in data['PortBindings'])
+ self.assertTrue('6666/tcp' in data['PortBindings'])
+ self.assertEqual(
+ [{"HostPort": "", "HostIp": ""}],
+ data['PortBindings']['1111/tcp']
+ )
+ self.assertEqual(
+ [{"HostPort": "2222", "HostIp": ""}],
+ data['PortBindings']['2222/tcp']
+ )
+ self.assertEqual(
+ [{"HostPort": "3333", "HostIp": ""}],
+ data['PortBindings']['3333/udp']
+ )
+ self.assertEqual(
+ [{"HostPort": "", "HostIp": "127.0.0.1"}],
+ data['PortBindings']['4444/tcp']
+ )
+ self.assertEqual(
+ [{"HostPort": "5555", "HostIp": "127.0.0.1"}],
+ data['PortBindings']['5555/tcp']
+ )
+ self.assertEqual(len(data['PortBindings']['6666/tcp']), 2)
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+ self.assertEqual(
+ args[1]['timeout'],
+ docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_start_container_with_links(self):
+ # one link
+ try:
+ link_path = 'path'
+ alias = 'alias'
+ self.client.start(fake_api.FAKE_CONTAINER_ID,
+ links={link_path: alias})
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(
+ args[0][0],
+ url_prefix + 'containers/3cc2351ab11b/start'
+ )
+ self.assertEqual(
+ json.loads(args[1]['data']),
+ {"PublishAllPorts": False, "Privileged": False,
+ "Links": ["path:alias"]}
+ )
+ self.assertEqual(
+ args[1]['headers'],
+ {'Content-Type': 'application/json'}
+ )
+
+ def test_start_container_with_multiple_links(self):
+ try:
+ link_path = 'path'
+ alias = 'alias'
+ self.client.start(
+ fake_api.FAKE_CONTAINER_ID,
+ links={
+ link_path + '1': alias + '1',
+ link_path + '2': alias + '2'
+ }
+ )
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(
+ args[0][0],
+ url_prefix + 'containers/3cc2351ab11b/start'
+ )
+ self.assertEqual(
+ json.loads(args[1]['data']),
+ {
+ "PublishAllPorts": False,
+ "Privileged": False,
+ "Links": ["path1:alias1", "path2:alias2"]
+ }
+ )
+ self.assertEqual(
+ args[1]['headers'],
+ {'Content-Type': 'application/json'}
+ )
+
+ def test_start_container_with_links_as_list_of_tuples(self):
+ # one link
+ try:
+ link_path = 'path'
+ alias = 'alias'
+ self.client.start(fake_api.FAKE_CONTAINER_ID,
+ links=[(link_path, alias)])
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(
+ args[0][0],
+ url_prefix + 'containers/3cc2351ab11b/start'
+ )
+ self.assertEqual(
+ json.loads(args[1]['data']),
+ {"PublishAllPorts": False, "Privileged": False,
+ "Links": ["path:alias"]}
+ )
+ self.assertEqual(
+ args[1]['headers'],
+ {'Content-Type': 'application/json'}
+ )
+
+ def test_start_container_privileged(self):
+ try:
+ self.client.start(fake_api.FAKE_CONTAINER_ID, privileged=True)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(
+ args[0][0],
+ url_prefix + 'containers/3cc2351ab11b/start'
+ )
+ self.assertEqual(json.loads(args[1]['data']),
+ {"PublishAllPorts": False, "Privileged": True})
+ self.assertEqual(args[1]['headers'],
+ {'Content-Type': 'application/json'})
+ self.assertEqual(
+ args[1]['timeout'],
+ docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_start_container_with_dict_instead_of_id(self):
+ try:
+ self.client.start({'Id': fake_api.FAKE_CONTAINER_ID})
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+ args = fake_request.call_args
+ self.assertEqual(
+ args[0][0],
+ url_prefix + 'containers/3cc2351ab11b/start'
+ )
+ self.assertEqual(
+ json.loads(args[1]['data']),
+ {"PublishAllPorts": False, "Privileged": False}
+ )
+ self.assertEqual(
+ args[1]['headers'],
+ {'Content-Type': 'application/json'}
+ )
+ self.assertEqual(
+ args[1]['timeout'],
+ docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_wait(self):
+ try:
+ self.client.wait(fake_api.FAKE_CONTAINER_ID)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/wait',
+ timeout=None
+ )
+
+ def test_wait_with_dict_instead_of_id(self):
+ try:
+ self.client.wait({'Id': fake_api.FAKE_CONTAINER_ID})
+ except Exception as e:
+ raise e
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/wait',
+ timeout=None
+ )
+
+ def test_url_compatibility_unix(self):
+ c = docker.Client(base_url="unix://socket")
+
+ assert c.base_url == "http+unix://socket"
+
+ def test_url_compatibility_unix_triple_slash(self):
+ c = docker.Client(base_url="unix:///socket")
+
+ assert c.base_url == "http+unix://socket"
+
+ def test_url_compatibility_http_unix_triple_slash(self):
+ c = docker.Client(base_url="http+unix:///socket")
+
+ assert c.base_url == "http+unix://socket"
+
+ def test_url_compatibility_http(self):
+ c = docker.Client(base_url="http://hostname")
+
+ assert c.base_url == "http://hostname"
+
+ def test_url_compatibility_tcp(self):
+ c = docker.Client(base_url="tcp://hostname")
+
+ assert c.base_url == "http://hostname"
+
+ def test_logs(self):
+ try:
+ self.client.logs(fake_api.FAKE_CONTAINER_ID)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/attach',
+ params={'stream': 0, 'logs': 1, 'stderr': 1, 'stdout': 1},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS,
+ stream=False
+ )
+
+ def test_logs_with_dict_instead_of_id(self):
+ try:
+ self.client.logs({'Id': fake_api.FAKE_CONTAINER_ID})
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/attach',
+ params={'stream': 0, 'logs': 1, 'stderr': 1, 'stdout': 1},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS,
+ stream=False
+ )
+
+ def test_log_streaming(self):
+ try:
+ self.client.logs(fake_api.FAKE_CONTAINER_ID, stream=True)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/attach',
+ params={'stream': 1, 'logs': 1, 'stderr': 1, 'stdout': 1},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS,
+ stream=True
+ )
+
+ def test_diff(self):
+ try:
+ self.client.diff(fake_api.FAKE_CONTAINER_ID)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/changes',
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_diff_with_dict_instead_of_id(self):
+ try:
+ self.client.diff({'Id': fake_api.FAKE_CONTAINER_ID})
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/changes',
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_port(self):
+ try:
+ self.client.port({'Id': fake_api.FAKE_CONTAINER_ID}, 1111)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/json',
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_stop_container(self):
+ try:
+ self.client.stop(fake_api.FAKE_CONTAINER_ID, timeout=2)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/stop',
+ params={'t': 2},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_stop_container_with_dict_instead_of_id(self):
+ try:
+ self.client.stop({'Id': fake_api.FAKE_CONTAINER_ID}, timeout=2)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/stop',
+ params={'t': 2},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_kill_container(self):
+ try:
+ self.client.kill(fake_api.FAKE_CONTAINER_ID)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/kill',
+ params={},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_kill_container_with_dict_instead_of_id(self):
+ try:
+ self.client.kill({'Id': fake_api.FAKE_CONTAINER_ID})
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/kill',
+ params={},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_kill_container_with_signal(self):
+ try:
+ self.client.kill(fake_api.FAKE_CONTAINER_ID, signal=signal.SIGTERM)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/kill',
+ params={'signal': signal.SIGTERM},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_restart_container(self):
+ try:
+ self.client.restart(fake_api.FAKE_CONTAINER_ID, timeout=2)
+ except Exception as e:
+ self.fail('Command should not raise exception : {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/restart',
+ params={'t': 2},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_restart_container_with_dict_instead_of_id(self):
+ try:
+ self.client.restart({'Id': fake_api.FAKE_CONTAINER_ID}, timeout=2)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/restart',
+ params={'t': 2},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_remove_container(self):
+ try:
+ self.client.remove_container(fake_api.FAKE_CONTAINER_ID)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b',
+ params={'v': False, 'link': False},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_remove_container_with_dict_instead_of_id(self):
+ try:
+ self.client.remove_container({'Id': fake_api.FAKE_CONTAINER_ID})
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b',
+ params={'v': False, 'link': False},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_remove_link(self):
+ try:
+ self.client.remove_container(fake_api.FAKE_CONTAINER_ID, link=True)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b',
+ params={'v': False, 'link': True},
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_export(self):
+ try:
+ self.client.export(fake_api.FAKE_CONTAINER_ID)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/export',
+ stream=True,
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_export_with_dict_instead_of_id(self):
+ try:
+ self.client.export({'Id': fake_api.FAKE_CONTAINER_ID})
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/export',
+ stream=True,
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_inspect_container(self):
+ try:
+ self.client.inspect_container(fake_api.FAKE_CONTAINER_ID)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'containers/3cc2351ab11b/json',
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ ##################
+ ## IMAGES TESTS ##
+ ##################
+
+ def test_pull(self):
+ try:
+ self.client.pull('joffrey/test001')
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(
+ args[0][0],
+ url_prefix + 'images/create'
+ )
+ self.assertEqual(
+ args[1]['params'],
+ {'tag': None, 'fromImage': 'joffrey/test001'}
+ )
+ self.assertFalse(args[1]['stream'])
+
+ def test_pull_stream(self):
+ try:
+ self.client.pull('joffrey/test001', stream=True)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ args = fake_request.call_args
+ self.assertEqual(
+ args[0][0],
+ url_prefix + 'images/create'
+ )
+ self.assertEqual(
+ args[1]['params'],
+ {'tag': None, 'fromImage': 'joffrey/test001'}
+ )
+ self.assertTrue(args[1]['stream'])
+
+ def test_commit(self):
+ try:
+ self.client.commit(fake_api.FAKE_CONTAINER_ID)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'commit',
+ data='{}',
+ headers={'Content-Type': 'application/json'},
+ params={
+ 'repo': None,
+ 'comment': None,
+ 'tag': None,
+ 'container': '3cc2351ab11b',
+ 'author': None
+ },
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_remove_image(self):
+ try:
+ self.client.remove_image(fake_api.FAKE_IMAGE_ID)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/e9aa60c60128',
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_image_history(self):
+ try:
+ self.client.history(fake_api.FAKE_IMAGE_NAME)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/test_image/history',
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_import_image(self):
+ try:
+ self.client.import_image(
+ fake_api.FAKE_TARBALL_PATH,
+ repository=fake_api.FAKE_REPO_NAME,
+ tag=fake_api.FAKE_TAG_NAME
+ )
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/create',
+ params={
+ 'repo': fake_api.FAKE_REPO_NAME,
+ 'tag': fake_api.FAKE_TAG_NAME,
+ 'fromSrc': fake_api.FAKE_TARBALL_PATH
+ },
+ data=None,
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_import_image_from_file(self):
+ buf = tempfile.NamedTemporaryFile(delete=False)
+ try:
+ # pretent the buffer is a file
+ self.client.import_image(
+ buf.name,
+ repository=fake_api.FAKE_REPO_NAME,
+ tag=fake_api.FAKE_TAG_NAME
+ )
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/create',
+ params={
+ 'repo': fake_api.FAKE_REPO_NAME,
+ 'tag': fake_api.FAKE_TAG_NAME,
+ 'fromSrc': '-'
+ },
+ data='',
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+ buf.close()
+ os.remove(buf.name)
+
+ def test_import_image_from_image(self):
+ try:
+ self.client.import_image(
+ image=fake_api.FAKE_IMAGE_NAME,
+ repository=fake_api.FAKE_REPO_NAME,
+ tag=fake_api.FAKE_TAG_NAME
+ )
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/create',
+ params={
+ 'repo': fake_api.FAKE_REPO_NAME,
+ 'tag': fake_api.FAKE_TAG_NAME,
+ 'fromImage': fake_api.FAKE_IMAGE_NAME
+ },
+ data=None,
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_inspect_image(self):
+ try:
+ self.client.inspect_image(fake_api.FAKE_IMAGE_NAME)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/test_image/json',
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_insert_image(self):
+ try:
+ self.client.insert(fake_api.FAKE_IMAGE_NAME,
+ fake_api.FAKE_URL, fake_api.FAKE_PATH)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/test_image/insert',
+ params={
+ 'url': fake_api.FAKE_URL,
+ 'path': fake_api.FAKE_PATH
+ },
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_push_image(self):
+ try:
+ self.client.push(fake_api.FAKE_IMAGE_NAME)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/test_image/push',
+ data='{}',
+ headers={'Content-Type': 'application/json'},
+ stream=False,
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_push_image_stream(self):
+ try:
+ self.client.push(fake_api.FAKE_IMAGE_NAME, stream=True)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/test_image/push',
+ data='{}',
+ headers={'Content-Type': 'application/json'},
+ stream=True,
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_tag_image(self):
+ try:
+ self.client.tag(fake_api.FAKE_IMAGE_ID, fake_api.FAKE_REPO_NAME)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/e9aa60c60128/tag',
+ params={
+ 'tag': None,
+ 'repo': 'repo',
+ 'force': 0
+ },
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_tag_image_tag(self):
+ try:
+ self.client.tag(
+ fake_api.FAKE_IMAGE_ID,
+ fake_api.FAKE_REPO_NAME,
+ tag=fake_api.FAKE_TAG_NAME
+ )
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/e9aa60c60128/tag',
+ params={
+ 'tag': 'tag',
+ 'repo': 'repo',
+ 'force': 0
+ },
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ def test_tag_image_force(self):
+ try:
+ self.client.tag(
+ fake_api.FAKE_IMAGE_ID, fake_api.FAKE_REPO_NAME, force=True)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ fake_request.assert_called_with(
+ url_prefix + 'images/e9aa60c60128/tag',
+ params={
+ 'tag': None,
+ 'repo': 'repo',
+ 'force': 1
+ },
+ timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
+ )
+
+ #################
+ # BUILDER TESTS #
+ #################
+
+ def test_build_container(self):
+ script = io.BytesIO('\n'.join([
+ 'FROM busybox',
+ 'MAINTAINER docker-py',
+ 'RUN mkdir -p /tmp/test',
+ 'EXPOSE 8080',
+ 'ADD https://dl.dropboxusercontent.com/u/20637798/silence.tar.gz'
+ ' /tmp/silence.tar.gz'
+ ]).encode('ascii'))
+ try:
+ self.client.build(fileobj=script)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ def test_build_container_stream(self):
+ script = io.BytesIO('\n'.join([
+ 'FROM busybox',
+ 'MAINTAINER docker-py',
+ 'RUN mkdir -p /tmp/test',
+ 'EXPOSE 8080',
+ 'ADD https://dl.dropboxusercontent.com/u/20637798/silence.tar.gz'
+ ' /tmp/silence.tar.gz'
+ ]).encode('ascii'))
+ try:
+ self.client.build(fileobj=script, stream=True)
+ except Exception as e:
+ self.fail('Command should not raise exception: {0}'.format(e))
+
+ #######################
+ ## PY SPECIFIC TESTS ##
+ #######################
+
+ def test_load_config_no_file(self):
+ folder = tempfile.mkdtemp()
+ cfg = docker.auth.load_config(folder)
+ self.assertTrue(cfg is not None)
+
+ def test_load_config(self):
+ folder = tempfile.mkdtemp()
+ f = open(os.path.join(folder, '.dockercfg'), 'w')
+ auth_ = base64.b64encode(b'sakuya:izayoi').decode('ascii')
+ f.write('auth = {0}\n'.format(auth_))
+ f.write('email = sakuya@scarlet.net')
+ f.close()
+ cfg = docker.auth.load_config(folder)
+ self.assertTrue(docker.auth.INDEX_URL in cfg)
+ self.assertNotEqual(cfg[docker.auth.INDEX_URL], None)
+ cfg = cfg[docker.auth.INDEX_URL]
+ self.assertEqual(cfg['username'], 'sakuya')
+ self.assertEqual(cfg['password'], 'izayoi')
+ self.assertEqual(cfg['email'], 'sakuya@scarlet.net')
+ self.assertEqual(cfg.get('auth'), None)
+
+
+if __name__ == '__main__':
+ unittest.main()