summaryrefslogtreecommitdiff
path: root/tests/integration/api_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/integration/api_test.py')
-rw-r--r--tests/integration/api_test.py292
1 files changed, 292 insertions, 0 deletions
diff --git a/tests/integration/api_test.py b/tests/integration/api_test.py
new file mode 100644
index 0000000..1b33728
--- /dev/null
+++ b/tests/integration/api_test.py
@@ -0,0 +1,292 @@
+import base64
+import json
+import os
+import shutil
+import tempfile
+import time
+import unittest
+import warnings
+
+import docker
+import six
+
+BUSYBOX = 'busybox:buildroot-2014.02'
+EXEC_DRIVER = []
+
+
+def exec_driver_is_native():
+ global EXEC_DRIVER
+ if not EXEC_DRIVER:
+ c = docker_client()
+ EXEC_DRIVER = c.info()['ExecutionDriver']
+ c.close()
+ return EXEC_DRIVER.startswith('native')
+
+
+def docker_client(**kwargs):
+ return docker.Client(**docker_client_kwargs(**kwargs))
+
+
+def docker_client_kwargs(**kwargs):
+ client_kwargs = docker.utils.kwargs_from_env(assert_hostname=False)
+ client_kwargs.update(kwargs)
+ return client_kwargs
+
+
+def setup_module():
+ warnings.simplefilter('error')
+ c = docker_client()
+ try:
+ c.inspect_image(BUSYBOX)
+ except docker.errors.NotFound:
+ os.write(2, "\npulling busybox\n".encode('utf-8'))
+ for data in c.pull(BUSYBOX, stream=True):
+ data = json.loads(data.decode('utf-8'))
+ os.write(2, ("%c[2K\r" % 27).encode('utf-8'))
+ status = data.get("status")
+ progress = data.get("progress")
+ detail = "{0} - {1}".format(status, progress).encode('utf-8')
+ os.write(2, detail)
+ os.write(2, "\npulled busybox\n".encode('utf-8'))
+
+ # Double make sure we now have busybox
+ c.inspect_image(BUSYBOX)
+ c.close()
+
+
+class BaseTestCase(unittest.TestCase):
+ tmp_imgs = []
+ tmp_containers = []
+ tmp_folders = []
+ tmp_volumes = []
+
+ def setUp(self):
+ if six.PY2:
+ self.assertRegex = self.assertRegexpMatches
+ self.assertCountEqual = self.assertItemsEqual
+ self.client = docker_client(timeout=60)
+ self.tmp_imgs = []
+ self.tmp_containers = []
+ self.tmp_folders = []
+ self.tmp_volumes = []
+ self.tmp_networks = []
+
+ def tearDown(self):
+ for img in self.tmp_imgs:
+ try:
+ self.client.remove_image(img)
+ except docker.errors.APIError:
+ pass
+ for container in self.tmp_containers:
+ try:
+ self.client.stop(container, timeout=1)
+ self.client.remove_container(container)
+ except docker.errors.APIError:
+ pass
+ for network in self.tmp_networks:
+ try:
+ self.client.remove_network(network)
+ except docker.errors.APIError:
+ pass
+ for folder in self.tmp_folders:
+ shutil.rmtree(folder)
+
+ for volume in self.tmp_volumes:
+ try:
+ self.client.remove_volume(volume)
+ except docker.errors.APIError:
+ pass
+
+ self.client.close()
+
+ def run_container(self, *args, **kwargs):
+ container = self.client.create_container(*args, **kwargs)
+ self.tmp_containers.append(container)
+ self.client.start(container)
+ exitcode = self.client.wait(container)
+
+ if exitcode != 0:
+ output = self.client.logs(container)
+ raise Exception(
+ "Container exited with code {}:\n{}"
+ .format(exitcode, output))
+
+ return container
+
+
+#########################
+# INFORMATION TESTS #
+#########################
+
+
+class InformationTest(BaseTestCase):
+ def test_version(self):
+ res = self.client.version()
+ self.assertIn('GoVersion', res)
+ self.assertIn('Version', res)
+ self.assertEqual(len(res['Version'].split('.')), 3)
+
+ def test_info(self):
+ res = self.client.info()
+ self.assertIn('Containers', res)
+ self.assertIn('Images', res)
+ self.assertIn('Debug', res)
+
+ def test_search(self):
+ self.client = docker_client(timeout=10)
+ res = self.client.search('busybox')
+ self.assertTrue(len(res) >= 1)
+ base_img = [x for x in res if x['name'] == 'busybox']
+ self.assertEqual(len(base_img), 1)
+ self.assertIn('description', base_img[0])
+
+
+#################
+# LINKS TESTS #
+#################
+
+
+class LinkTest(BaseTestCase):
+ def test_remove_link(self):
+ # Create containers
+ container1 = self.client.create_container(
+ BUSYBOX, 'cat', detach=True, stdin_open=True
+ )
+ container1_id = container1['Id']
+ self.tmp_containers.append(container1_id)
+ self.client.start(container1_id)
+
+ # Create Link
+ # we don't want the first /
+ link_path = self.client.inspect_container(container1_id)['Name'][1:]
+ link_alias = 'mylink'
+
+ container2 = self.client.create_container(
+ BUSYBOX, 'cat', host_config=self.client.create_host_config(
+ links={link_path: link_alias}, network_mode='none'
+ )
+ )
+ container2_id = container2['Id']
+ self.tmp_containers.append(container2_id)
+ self.client.start(container2_id)
+
+ # Remove link
+ linked_name = self.client.inspect_container(container2_id)['Name'][1:]
+ link_name = '%s/%s' % (linked_name, link_alias)
+ self.client.remove_container(link_name, link=True)
+
+ # Link is gone
+ containers = self.client.containers(all=True)
+ retrieved = [x for x in containers if link_name in x['Names']]
+ self.assertEqual(len(retrieved), 0)
+
+ # Containers are still there
+ retrieved = [
+ x for x in containers if x['Id'].startswith(container1_id) or
+ x['Id'].startswith(container2_id)
+ ]
+ self.assertEqual(len(retrieved), 2)
+
+
+#######################
+# PY SPECIFIC TESTS #
+#######################
+
+class LoadConfigTest(BaseTestCase):
+ def test_load_legacy_config(self):
+ folder = tempfile.mkdtemp()
+ self.tmp_folders.append(folder)
+ cfg_path = os.path.join(folder, '.dockercfg')
+ f = open(cfg_path, '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(cfg_path)
+ self.assertNotEqual(cfg[docker.auth.INDEX_NAME], None)
+ cfg = cfg[docker.auth.INDEX_NAME]
+ self.assertEqual(cfg['username'], 'sakuya')
+ self.assertEqual(cfg['password'], 'izayoi')
+ self.assertEqual(cfg['email'], 'sakuya@scarlet.net')
+ self.assertEqual(cfg.get('Auth'), None)
+
+ def test_load_json_config(self):
+ folder = tempfile.mkdtemp()
+ self.tmp_folders.append(folder)
+ cfg_path = os.path.join(folder, '.dockercfg')
+ f = open(os.path.join(folder, '.dockercfg'), 'w')
+ auth_ = base64.b64encode(b'sakuya:izayoi').decode('ascii')
+ email_ = 'sakuya@scarlet.net'
+ f.write('{{"{0}": {{"auth": "{1}", "email": "{2}"}}}}\n'.format(
+ docker.auth.INDEX_URL, auth_, email_))
+ f.close()
+ cfg = docker.auth.load_config(cfg_path)
+ 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)
+
+
+class AutoDetectVersionTest(unittest.TestCase):
+ def test_client_init(self):
+ client = docker_client(version='auto')
+ client_version = client._version
+ api_version = client.version(api_version=False)['ApiVersion']
+ self.assertEqual(client_version, api_version)
+ api_version_2 = client.version()['ApiVersion']
+ self.assertEqual(client_version, api_version_2)
+ client.close()
+
+ def test_auto_client(self):
+ client = docker.AutoVersionClient(**docker_client_kwargs())
+ client_version = client._version
+ api_version = client.version(api_version=False)['ApiVersion']
+ self.assertEqual(client_version, api_version)
+ api_version_2 = client.version()['ApiVersion']
+ self.assertEqual(client_version, api_version_2)
+ client.close()
+ with self.assertRaises(docker.errors.DockerException):
+ docker.AutoVersionClient(**docker_client_kwargs(version='1.11'))
+
+
+class ConnectionTimeoutTest(unittest.TestCase):
+ def setUp(self):
+ self.timeout = 0.5
+ self.client = docker.client.Client(base_url='http://192.168.10.2:4243',
+ timeout=self.timeout)
+
+ def test_timeout(self):
+ start = time.time()
+ res = None
+ # This call isn't supposed to complete, and it should fail fast.
+ try:
+ res = self.client.inspect_container('id')
+ except:
+ pass
+ end = time.time()
+ self.assertTrue(res is None)
+ self.assertTrue(end - start < 2 * self.timeout)
+
+
+class UnixconnTest(unittest.TestCase):
+ """
+ Test UNIX socket connection adapter.
+ """
+
+ def test_resource_warnings(self):
+ """
+ Test no warnings are produced when using the client.
+ """
+
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter('always')
+
+ client = docker_client()
+ client.images()
+ client.close()
+ del client
+
+ assert len(w) == 0, \
+ "No warnings produced: {0}".format(w[0].message)