mirror of https://github.com/docker/docker-py.git
				
				
				
			
		
			
				
	
	
		
			2308 lines
		
	
	
		
			83 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			2308 lines
		
	
	
		
			83 KiB
		
	
	
	
		
			Python
		
	
	
	
| # 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 gzip
 | |
| import io
 | |
| import json
 | |
| import os
 | |
| import re
 | |
| import shutil
 | |
| import signal
 | |
| import socket
 | |
| import sys
 | |
| import tarfile
 | |
| import tempfile
 | |
| import threading
 | |
| import time
 | |
| import unittest
 | |
| import warnings
 | |
| import random
 | |
| 
 | |
| import docker
 | |
| import requests
 | |
| import six
 | |
| 
 | |
| import fake_api
 | |
| 
 | |
| try:
 | |
|     from unittest import mock
 | |
| except ImportError:
 | |
|     import mock
 | |
| 
 | |
| 
 | |
| warnings.simplefilter('error')
 | |
| create_host_config = docker.utils.create_host_config
 | |
| 
 | |
| 
 | |
| 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.binary_type):
 | |
|         content = json.dumps(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_resolve_authconfig(authconfig, registry=None):
 | |
|     return None
 | |
| 
 | |
| 
 | |
| 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)
 | |
| 
 | |
| 
 | |
| class Cleanup(object):
 | |
|     if sys.version_info < (2, 7):
 | |
|         # Provide a basic implementation of addCleanup for Python < 2.7
 | |
|         def __init__(self, *args, **kwargs):
 | |
|             super(Cleanup, self).__init__(*args, **kwargs)
 | |
|             self._cleanups = []
 | |
| 
 | |
|         def tearDown(self):
 | |
|             super(Cleanup, self).tearDown()
 | |
|             ok = True
 | |
|             while self._cleanups:
 | |
|                 fn, args, kwargs = self._cleanups.pop(-1)
 | |
|                 try:
 | |
|                     fn(*args, **kwargs)
 | |
|                 except KeyboardInterrupt:
 | |
|                     raise
 | |
|                 except:
 | |
|                     ok = False
 | |
|             if not ok:
 | |
|                 raise
 | |
| 
 | |
|         def addCleanup(self, function, *args, **kwargs):
 | |
|             self._cleanups.append((function, args, kwargs))
 | |
| 
 | |
| 
 | |
| @mock.patch.multiple('docker.Client', get=fake_request, post=fake_request,
 | |
|                      put=fake_request, delete=fake_request)
 | |
| class DockerClientTest(Cleanup, unittest.TestCase):
 | |
|     def setUp(self):
 | |
|         self.client = docker.Client()
 | |
|         # Force-clear authconfig to avoid tampering with the tests
 | |
|         self.client._cfg = {'Configs': {}}
 | |
| 
 | |
|     def tearDown(self):
 | |
|         self.client.close()
 | |
| 
 | |
|     def base_create_payload(self, img='busybox', cmd=None):
 | |
|         if not cmd:
 | |
|             cmd = ['true']
 | |
|         return {"Tty": False, "Image": img, "Cmd": cmd,
 | |
|                 "AttachStdin": False, "Memory": 0,
 | |
|                 "AttachStderr": True, "AttachStdout": True,
 | |
|                 "StdinOnce": False,
 | |
|                 "OpenStdin": False, "NetworkDisabled": False,
 | |
|                 "MemorySwap": 0
 | |
|                 }
 | |
| 
 | |
|     def test_ctor(self):
 | |
|         try:
 | |
|             docker.Client(version=1.12)
 | |
|         except Exception as e:
 | |
|             self.assertTrue(isinstance(e, docker.errors.DockerException))
 | |
|             if not six.PY3:
 | |
|                 self.assertEqual(
 | |
|                     str(e),
 | |
|                     'version parameter must be a string. Found float'
 | |
|                 )
 | |
| 
 | |
|     #########################
 | |
|     #   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
 | |
| 
 | |
|     def test_events(self):
 | |
|         try:
 | |
|             self.client.events()
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         fake_request.assert_called_with(
 | |
|             url_prefix + 'events',
 | |
|             params={'since': None, 'until': None, 'filters': None},
 | |
|             stream=True
 | |
|         )
 | |
| 
 | |
|     def test_events_with_since_until(self):
 | |
|         ts = 1356048000
 | |
|         now = datetime.datetime.fromtimestamp(ts)
 | |
|         since = now - datetime.timedelta(seconds=10)
 | |
|         until = now + datetime.timedelta(seconds=10)
 | |
|         try:
 | |
|             self.client.events(since=since, until=until)
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         fake_request.assert_called_with(
 | |
|             url_prefix + 'events',
 | |
|             params={
 | |
|                 'since': ts - 10,
 | |
|                 'until': ts + 10,
 | |
|                 'filters': None
 | |
|             },
 | |
|             stream=True
 | |
|         )
 | |
| 
 | |
|     def test_events_with_filters(self):
 | |
|         filters = {'event': ['die', 'stop'],
 | |
|                    'container': fake_api.FAKE_CONTAINER_ID}
 | |
|         try:
 | |
|             self.client.events(filters=filters)
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         expected_filters = docker.utils.convert_filters(filters)
 | |
|         fake_request.assert_called_with(
 | |
|             url_prefix + 'events',
 | |
|             params={
 | |
|                 'since': None,
 | |
|                 'until': None,
 | |
|                 'filters': expected_filters
 | |
|             },
 | |
|             stream=True
 | |
|         )
 | |
| 
 | |
|     ###################
 | |
|     #  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_images_filters(self):
 | |
|         try:
 | |
|             self.client.images(filters={'dangling': 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': 0,
 | |
|                     'filters': '{"dangling": ["true"]}'},
 | |
|             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,
 | |
|                 'size': 0,
 | |
|                 '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,
 | |
|                              "MemorySwap": 0}'''))
 | |
|         self.assertEqual(args[1]['headers'],
 | |
|                          {'Content-Type': 'application/json'})
 | |
| 
 | |
|     def test_create_container_with_binds(self):
 | |
|         mount_dest = '/mnt'
 | |
| 
 | |
|         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,
 | |
|                              "MemorySwap": 0}'''))
 | |
|         self.assertEqual(args[1]['headers'],
 | |
|                          {'Content-Type': 'application/json'})
 | |
| 
 | |
|     def test_create_container_with_volume_string(self):
 | |
|         mount_dest = '/mnt'
 | |
| 
 | |
|         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,
 | |
|                              "MemorySwap": 0}'''))
 | |
|         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,
 | |
|                              "MemorySwap": 0}'''))
 | |
|         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",
 | |
|                              "MemorySwap": 0}'''))
 | |
|         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,
 | |
|                              "MemorySwap": 0}'''))
 | |
|         self.assertEqual(args[1]['headers'],
 | |
|                          {'Content-Type': 'application/json'})
 | |
| 
 | |
|     def test_create_container_with_cpuset(self):
 | |
|         try:
 | |
|             self.client.create_container('busybox', 'ls',
 | |
|                                          cpuset='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/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,
 | |
|                              "Cpuset": "0,1",
 | |
|                              "MemorySwap": 0}'''))
 | |
|         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",
 | |
|                              "MemorySwap": 0}'''))
 | |
|         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,
 | |
|                              "MemorySwap": 0}'''))
 | |
|         self.assertEqual(args[1]['headers'],
 | |
|                          {'Content-Type': 'application/json'})
 | |
| 
 | |
|     def test_create_container_with_volumes_from(self):
 | |
|         vol_names = ['foo', 'bar']
 | |
|         try:
 | |
|             self.client.create_container('busybox', 'true',
 | |
|                                          volumes_from=vol_names)
 | |
|         except docker.errors.DockerException as e:
 | |
|             self.assertTrue(
 | |
|                 docker.utils.compare_version('1.10', self.client._version) >= 0
 | |
|             )
 | |
|             return
 | |
|         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'])['VolumesFrom'],
 | |
|                          ','.join(vol_names))
 | |
|         self.assertEqual(args[1]['headers'],
 | |
|                          {'Content-Type': 'application/json'})
 | |
| 
 | |
|     def test_create_container_empty_volumes_from(self):
 | |
|         try:
 | |
|             self.client.create_container('busybox', 'true', volumes_from=[])
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         args = fake_request.call_args
 | |
|         data = json.loads(args[1]['data'])
 | |
|         self.assertTrue('VolumesFrom' not in data)
 | |
| 
 | |
|     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,
 | |
|                              "MemorySwap": 0}'''))
 | |
|         self.assertEqual(args[1]['headers'],
 | |
|                          {'Content-Type': 'application/json'})
 | |
|         self.assertEqual(args[1]['params'], {'name': 'marisa-kirisame'})
 | |
| 
 | |
|     def test_create_container_with_mem_limit_as_int(self):
 | |
|         try:
 | |
|             self.client.create_container('busybox', 'true',
 | |
|                                          mem_limit=128.0)
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         args = fake_request.call_args
 | |
|         data = json.loads(args[1]['data'])
 | |
|         self.assertEqual(data['Memory'], 128.0)
 | |
| 
 | |
|     def test_create_container_with_mem_limit_as_string(self):
 | |
|         try:
 | |
|             self.client.create_container('busybox', 'true',
 | |
|                                          mem_limit='128')
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         args = fake_request.call_args
 | |
|         data = json.loads(args[1]['data'])
 | |
|         self.assertEqual(data['Memory'], 128.0)
 | |
| 
 | |
|     def test_create_container_with_mem_limit_as_string_with_k_unit(self):
 | |
|         try:
 | |
|             self.client.create_container('busybox', 'true',
 | |
|                                          mem_limit='128k')
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         args = fake_request.call_args
 | |
|         data = json.loads(args[1]['data'])
 | |
|         self.assertEqual(data['Memory'], 128.0 * 1024)
 | |
| 
 | |
|     def test_create_container_with_mem_limit_as_string_with_m_unit(self):
 | |
|         try:
 | |
|             self.client.create_container('busybox', 'true',
 | |
|                                          mem_limit='128m')
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         args = fake_request.call_args
 | |
|         data = json.loads(args[1]['data'])
 | |
|         self.assertEqual(data['Memory'], 128.0 * 1024 * 1024)
 | |
| 
 | |
|     def test_create_container_with_mem_limit_as_string_with_g_unit(self):
 | |
|         try:
 | |
|             self.client.create_container('busybox', 'true',
 | |
|                                          mem_limit='128g')
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         args = fake_request.call_args
 | |
|         data = json.loads(args[1]['data'])
 | |
|         self.assertEqual(data['Memory'], 128.0 * 1024 * 1024 * 1024)
 | |
| 
 | |
|     def test_create_container_with_mem_limit_as_string_with_wrong_value(self):
 | |
|         self.assertRaises(docker.errors.DockerException,
 | |
|                           self.client.create_container,
 | |
|                           'busybox', 'true', mem_limit='128p')
 | |
| 
 | |
|         self.assertRaises(docker.errors.DockerException,
 | |
|                           self.client.create_container,
 | |
|                           'busybox', 'true', mem_limit='1f28')
 | |
| 
 | |
|     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']), {})
 | |
|         self.assertEqual(
 | |
|             args[1]['headers'], {'Content-Type': 'application/json'}
 | |
|         )
 | |
|         self.assertEqual(
 | |
|             args[1]['timeout'], docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_create_container_with_lxc_conf(self):
 | |
|         try:
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true', host_config=create_host_config(
 | |
|                     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/create'
 | |
|         )
 | |
|         expected_payload = self.base_create_payload()
 | |
|         expected_payload['HostConfig'] = create_host_config()
 | |
|         expected_payload['HostConfig']['LxcConf'] = [
 | |
|             {"Value": "lxc.conf.value", "Key": "lxc.conf.k"}
 | |
|         ]
 | |
| 
 | |
|         self.assertEqual(json.loads(args[1]['data']), expected_payload)
 | |
|         self.assertEqual(
 | |
|             args[1]['headers'],
 | |
|             {'Content-Type': 'application/json'}
 | |
|         )
 | |
|         self.assertEqual(
 | |
|             args[1]['timeout'],
 | |
|             docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_create_container_with_lxc_conf_compat(self):
 | |
|         try:
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true', host_config=create_host_config(
 | |
|                     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/create')
 | |
|         expected_payload = self.base_create_payload()
 | |
|         expected_payload['HostConfig'] = create_host_config()
 | |
|         expected_payload['HostConfig']['LxcConf'] = [
 | |
|             {"Value": "lxc.conf.value", "Key": "lxc.conf.k"}
 | |
|         ]
 | |
|         self.assertEqual(
 | |
|             json.loads(args[1]['data']), expected_payload)
 | |
|         self.assertEqual(args[1]['headers'],
 | |
|                          {'Content-Type': 'application/json'})
 | |
|         self.assertEqual(
 | |
|             args[1]['timeout'],
 | |
|             docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_create_container_with_binds_ro(self):
 | |
|         try:
 | |
|             mount_dest = '/mnt'
 | |
|             mount_origin = '/tmp'
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true', host_config=create_host_config(
 | |
|                     binds={mount_origin: {
 | |
|                         "bind": mount_dest,
 | |
|                         "ro": 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')
 | |
|         expected_payload = self.base_create_payload()
 | |
|         expected_payload['HostConfig'] = create_host_config()
 | |
|         expected_payload['HostConfig']['Binds'] = ["/tmp:/mnt:ro"]
 | |
|         self.assertEqual(json.loads(args[1]['data']), expected_payload)
 | |
|         self.assertEqual(args[1]['headers'],
 | |
|                          {'Content-Type': 'application/json'})
 | |
|         self.assertEqual(
 | |
|             args[1]['timeout'],
 | |
|             docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_create_container_with_binds_rw(self):
 | |
|         try:
 | |
|             mount_dest = '/mnt'
 | |
|             mount_origin = '/tmp'
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true', host_config=create_host_config(
 | |
|                     binds={mount_origin: {
 | |
|                         "bind": mount_dest,
 | |
|                         "ro": False
 | |
|                     }}
 | |
|                 )
 | |
|             )
 | |
|         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')
 | |
|         expected_payload = self.base_create_payload()
 | |
|         expected_payload['HostConfig'] = create_host_config()
 | |
|         expected_payload['HostConfig']['Binds'] = ["/tmp:/mnt:rw"]
 | |
|         self.assertEqual(json.loads(args[1]['data']), expected_payload)
 | |
|         self.assertEqual(args[1]['headers'],
 | |
|                          {'Content-Type': 'application/json'})
 | |
|         self.assertEqual(
 | |
|             args[1]['timeout'],
 | |
|             docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_create_container_with_port_binds(self):
 | |
|         self.maxDiff = None
 | |
|         try:
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true', host_config=create_host_config(
 | |
|                     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/create')
 | |
|         data = json.loads(args[1]['data'])
 | |
|         port_bindings = data['HostConfig']['PortBindings']
 | |
|         self.assertTrue('1111/tcp' in port_bindings)
 | |
|         self.assertTrue('2222/tcp' in port_bindings)
 | |
|         self.assertTrue('3333/udp' in port_bindings)
 | |
|         self.assertTrue('4444/tcp' in port_bindings)
 | |
|         self.assertTrue('5555/tcp' in port_bindings)
 | |
|         self.assertTrue('6666/tcp' in port_bindings)
 | |
|         self.assertEqual(
 | |
|             [{"HostPort": "", "HostIp": ""}],
 | |
|             port_bindings['1111/tcp']
 | |
|         )
 | |
|         self.assertEqual(
 | |
|             [{"HostPort": "2222", "HostIp": ""}],
 | |
|             port_bindings['2222/tcp']
 | |
|         )
 | |
|         self.assertEqual(
 | |
|             [{"HostPort": "3333", "HostIp": ""}],
 | |
|             port_bindings['3333/udp']
 | |
|         )
 | |
|         self.assertEqual(
 | |
|             [{"HostPort": "", "HostIp": "127.0.0.1"}],
 | |
|             port_bindings['4444/tcp']
 | |
|         )
 | |
|         self.assertEqual(
 | |
|             [{"HostPort": "5555", "HostIp": "127.0.0.1"}],
 | |
|             port_bindings['5555/tcp']
 | |
|         )
 | |
|         self.assertEqual(len(port_bindings['6666/tcp']), 2)
 | |
|         self.assertEqual(args[1]['headers'],
 | |
|                          {'Content-Type': 'application/json'})
 | |
|         self.assertEqual(
 | |
|             args[1]['timeout'],
 | |
|             docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_create_container_with_mac_address(self):
 | |
|         try:
 | |
|             mac_address_expected = "02:42:ac:11:00:0a"
 | |
|             container = self.client.create_container(
 | |
|                 'busybox', ['sleep', '60'], mac_address=mac_address_expected)
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         res = self.client.inspect_container(container['Id'])
 | |
|         self.assertEqual(mac_address_expected,
 | |
|                          res['NetworkSettings']['MacAddress'])
 | |
| 
 | |
|     def test_create_container_with_links(self):
 | |
|         try:
 | |
|             link_path = 'path'
 | |
|             alias = 'alias'
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true', host_config=create_host_config(
 | |
|                     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/create'
 | |
|         )
 | |
|         expected_payload = self.base_create_payload()
 | |
|         expected_payload['HostConfig'] = create_host_config()
 | |
|         expected_payload['HostConfig']['Links'] = ['path:alias']
 | |
| 
 | |
|         self.assertEqual(json.loads(args[1]['data']), expected_payload)
 | |
|         self.assertEqual(
 | |
|             args[1]['headers'], {'Content-Type': 'application/json'}
 | |
|         )
 | |
| 
 | |
|     def test_create_container_with_multiple_links(self):
 | |
|         try:
 | |
|             link_path = 'path'
 | |
|             alias = 'alias'
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true', host_config=create_host_config(
 | |
|                     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/create')
 | |
|         expected_payload = self.base_create_payload()
 | |
|         expected_payload['HostConfig'] = create_host_config()
 | |
|         expected_payload['HostConfig']['Links'] = [
 | |
|             'path1:alias1', 'path2:alias2'
 | |
|         ]
 | |
|         self.assertEqual(json.loads(args[1]['data']), expected_payload)
 | |
|         self.assertEqual(
 | |
|             args[1]['headers'], {'Content-Type': 'application/json'}
 | |
|         )
 | |
| 
 | |
|     def test_create_container_with_links_as_list_of_tuples(self):
 | |
|         try:
 | |
|             link_path = 'path'
 | |
|             alias = 'alias'
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true', host_config=create_host_config(
 | |
|                     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/create')
 | |
|         expected_payload = self.base_create_payload()
 | |
|         expected_payload['HostConfig'] = create_host_config()
 | |
|         expected_payload['HostConfig']['Links'] = ['path:alias']
 | |
| 
 | |
|         self.assertEqual(json.loads(args[1]['data']), expected_payload)
 | |
|         self.assertEqual(
 | |
|             args[1]['headers'], {'Content-Type': 'application/json'}
 | |
|         )
 | |
| 
 | |
|     def test_create_container_privileged(self):
 | |
|         try:
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true',
 | |
|                 host_config=create_host_config(privileged=True)
 | |
|             )
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         expected_payload = self.base_create_payload()
 | |
|         expected_payload['HostConfig'] = create_host_config()
 | |
|         expected_payload['HostConfig']['Privileged'] = True
 | |
|         args = fake_request.call_args
 | |
|         self.assertEqual(args[0][0], url_prefix + 'containers/create')
 | |
|         self.assertEqual(json.loads(args[1]['data']), expected_payload)
 | |
|         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"}]}
 | |
|         )
 | |
|         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"}]}
 | |
|         )
 | |
|         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_ro(self):
 | |
|         try:
 | |
|             mount_dest = '/mnt'
 | |
|             mount_origin = '/tmp'
 | |
|             self.client.start(fake_api.FAKE_CONTAINER_ID,
 | |
|                               binds={mount_origin: {
 | |
|                                   "bind": mount_dest,
 | |
|                                   "ro": 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']), {"Binds": ["/tmp:/mnt:ro"]}
 | |
|         )
 | |
|         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_rw(self):
 | |
|         try:
 | |
|             mount_dest = '/mnt'
 | |
|             mount_origin = '/tmp'
 | |
|             self.client.start(fake_api.FAKE_CONTAINER_ID,
 | |
|                               binds={mount_origin: {
 | |
|                                   "bind": mount_dest, "ro": False}})
 | |
|         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:rw"]}
 | |
|         )
 | |
|         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.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']), {"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']),
 | |
|             {"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']), {"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']), {"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']), {})
 | |
|         self.assertEqual(
 | |
|             args[1]['headers'], {'Content-Type': 'application/json'}
 | |
|         )
 | |
|         self.assertEqual(
 | |
|             args[1]['timeout'], docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_create_container_with_restart_policy(self):
 | |
|         try:
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true', host_config=create_host_config(
 | |
|                     restart_policy={
 | |
|                         "Name": "always",
 | |
|                         "MaximumRetryCount": 0
 | |
|                     }
 | |
|                 )
 | |
|             )
 | |
|         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')
 | |
| 
 | |
|         expected_payload = self.base_create_payload()
 | |
|         expected_payload['HostConfig'] = create_host_config()
 | |
|         expected_payload['HostConfig']['RestartPolicy'] = {
 | |
|             "MaximumRetryCount": 0, "Name": "always"
 | |
|         }
 | |
|         self.assertEqual(json.loads(args[1]['data']), expected_payload)
 | |
| 
 | |
|         self.assertEqual(
 | |
|             args[1]['headers'], {'Content-Type': 'application/json'}
 | |
|         )
 | |
|         self.assertEqual(
 | |
|             args[1]['timeout'], docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_create_container_with_added_capabilities(self):
 | |
|         try:
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true',
 | |
|                 host_config=create_host_config(cap_add=['MKNOD'])
 | |
|             )
 | |
|         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')
 | |
|         expected_payload = self.base_create_payload()
 | |
|         expected_payload['HostConfig'] = create_host_config()
 | |
|         expected_payload['HostConfig']['CapAdd'] = ['MKNOD']
 | |
|         self.assertEqual(json.loads(args[1]['data']), expected_payload)
 | |
|         self.assertEqual(
 | |
|             args[1]['headers'], {'Content-Type': 'application/json'}
 | |
|         )
 | |
|         self.assertEqual(
 | |
|             args[1]['timeout'], docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_create_container_with_dropped_capabilities(self):
 | |
|         try:
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true',
 | |
|                 host_config=create_host_config(cap_drop=['MKNOD'])
 | |
|             )
 | |
|         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')
 | |
|         expected_payload = self.base_create_payload()
 | |
|         expected_payload['HostConfig'] = create_host_config()
 | |
|         expected_payload['HostConfig']['CapDrop'] = ['MKNOD']
 | |
|         self.assertEqual(json.loads(args[1]['data']), expected_payload)
 | |
|         self.assertEqual(
 | |
|             args[1]['headers'], {'Content-Type': 'application/json'}
 | |
|         )
 | |
|         self.assertEqual(
 | |
|             args[1]['timeout'], docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_create_container_with_devices(self):
 | |
|         try:
 | |
|             self.client.create_container(
 | |
|                 'busybox', 'true', host_config=create_host_config(
 | |
|                     devices=['/dev/sda:/dev/xvda:rwm',
 | |
|                              '/dev/sdb:/dev/xvdb',
 | |
|                              '/dev/sdc']
 | |
|                 )
 | |
|             )
 | |
|         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')
 | |
|         expected_payload = self.base_create_payload()
 | |
|         expected_payload['HostConfig'] = create_host_config()
 | |
|         expected_payload['HostConfig']['Devices'] = [
 | |
|             {'CgroupPermissions': 'rwm',
 | |
|              'PathInContainer': '/dev/xvda',
 | |
|              'PathOnHost': '/dev/sda'},
 | |
|             {'CgroupPermissions': 'rwm',
 | |
|              'PathInContainer': '/dev/xvdb',
 | |
|              'PathOnHost': '/dev/sdb'},
 | |
|             {'CgroupPermissions': 'rwm',
 | |
|              'PathInContainer': '/dev/sdc',
 | |
|              'PathOnHost': '/dev/sdc'}
 | |
|         ]
 | |
|         self.assertEqual(json.loads(args[1]['data']), expected_payload)
 | |
|         self.assertEqual(
 | |
|             args[1]['headers'], {'Content-Type': 'application/json'}
 | |
|         )
 | |
|         self.assertEqual(
 | |
|             args[1]['timeout'], docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_resize_container(self):
 | |
|         try:
 | |
|             self.client.resize(
 | |
|                 {'Id': fake_api.FAKE_CONTAINER_ID},
 | |
|                 height=15,
 | |
|                 width=120
 | |
|             )
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         fake_request.assert_called_with(
 | |
|             url_prefix + 'containers/3cc2351ab11b/resize',
 | |
|             params={'h': 15, 'w': 120},
 | |
|             timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_rename_container(self):
 | |
|         try:
 | |
|             self.client.rename(
 | |
|                 {'Id': fake_api.FAKE_CONTAINER_ID},
 | |
|                 name='foobar'
 | |
|             )
 | |
|         except Exception as e:
 | |
|             self.fail('Command shold not raise exception: {0}'.format(e))
 | |
| 
 | |
|         fake_request.assert_called_with(
 | |
|             url_prefix + 'containers/3cc2351ab11b/rename',
 | |
|             params={'name': 'foobar'},
 | |
|             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:1234")
 | |
| 
 | |
|         assert c.base_url == "http://hostname:1234"
 | |
| 
 | |
|     def test_url_compatibility_tcp(self):
 | |
|         c = docker.Client(base_url="tcp://hostname:1234")
 | |
| 
 | |
|         assert c.base_url == "http://hostname:1234"
 | |
| 
 | |
|     def test_logs(self):
 | |
|         try:
 | |
|             logs = 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/logs',
 | |
|             params={'timestamps': 0, 'follow': 0, 'stderr': 1, 'stdout': 1,
 | |
|                     'tail': 'all'},
 | |
|             timeout=docker.client.DEFAULT_TIMEOUT_SECONDS,
 | |
|             stream=False
 | |
|         )
 | |
| 
 | |
|         self.assertEqual(
 | |
|             logs,
 | |
|             'Flowering Nights\n(Sakuya Iyazoi)\n'.encode('ascii')
 | |
|         )
 | |
| 
 | |
|     def test_logs_with_dict_instead_of_id(self):
 | |
|         try:
 | |
|             logs = 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/logs',
 | |
|             params={'timestamps': 0, 'follow': 0, 'stderr': 1, 'stdout': 1,
 | |
|                     'tail': 'all'},
 | |
|             timeout=docker.client.DEFAULT_TIMEOUT_SECONDS,
 | |
|             stream=False
 | |
|         )
 | |
| 
 | |
|         self.assertEqual(
 | |
|             logs,
 | |
|             'Flowering Nights\n(Sakuya Iyazoi)\n'.encode('ascii')
 | |
|         )
 | |
| 
 | |
|     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/logs',
 | |
|             params={'timestamps': 0, 'follow': 1, 'stderr': 1, 'stdout': 1,
 | |
|                     'tail': 'all'},
 | |
|             timeout=docker.client.DEFAULT_TIMEOUT_SECONDS,
 | |
|             stream=True
 | |
|         )
 | |
| 
 | |
|     def test_log_tail(self):
 | |
|         try:
 | |
|             self.client.logs(fake_api.FAKE_CONTAINER_ID, stream=False, tail=10)
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         fake_request.assert_called_with(
 | |
|             url_prefix + 'containers/3cc2351ab11b/logs',
 | |
|             params={'timestamps': 0, 'follow': 0, 'stderr': 1, 'stdout': 1,
 | |
|                     'tail': 10},
 | |
|             timeout=docker.client.DEFAULT_TIMEOUT_SECONDS,
 | |
|             stream=False
 | |
|         )
 | |
| 
 | |
|     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):
 | |
|         timeout = 2
 | |
|         try:
 | |
|             self.client.stop(fake_api.FAKE_CONTAINER_ID, timeout=timeout)
 | |
|         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': timeout},
 | |
|             timeout=(docker.client.DEFAULT_TIMEOUT_SECONDS + timeout)
 | |
|         )
 | |
| 
 | |
|     def test_stop_container_with_dict_instead_of_id(self):
 | |
|         timeout = 2
 | |
|         try:
 | |
|             self.client.stop({'Id': fake_api.FAKE_CONTAINER_ID},
 | |
|                              timeout=timeout)
 | |
|         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': timeout},
 | |
|             timeout=(docker.client.DEFAULT_TIMEOUT_SECONDS + timeout)
 | |
|         )
 | |
| 
 | |
|     def test_execute_command(self):
 | |
|         try:
 | |
|             self.client.execute(fake_api.FAKE_CONTAINER_ID, ['ls', '-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 + 'exec/3cc2351ab11b/start')
 | |
| 
 | |
|         self.assertEqual(json.loads(args[1]['data']),
 | |
|                          json.loads('''{
 | |
|                             "Tty": false,
 | |
|                             "AttachStderr": true,
 | |
|                             "Container": "3cc2351ab11b",
 | |
|                             "Cmd": ["ls", "-1"],
 | |
|                             "AttachStdin": false,
 | |
|                             "User": "",
 | |
|                             "Detach": false,
 | |
|                             "Privileged": false,
 | |
|                             "AttachStdout": true}'''))
 | |
| 
 | |
|         self.assertEqual(args[1]['headers'],
 | |
|                          {'Content-Type': 'application/json'})
 | |
| 
 | |
|     def test_pause_container(self):
 | |
|         try:
 | |
|             self.client.pause(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/pause',
 | |
|             timeout=(docker.client.DEFAULT_TIMEOUT_SECONDS)
 | |
|         )
 | |
| 
 | |
|     def test_unpause_container(self):
 | |
|         try:
 | |
|             self.client.unpause(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/unpause',
 | |
|             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, 'force': 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, 'force': 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, 'force': False},
 | |
|             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
 | |
|         )
 | |
| 
 | |
|     def test_container_stats(self):
 | |
|         try:
 | |
|             self.client.stats(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/stats',
 | |
|             timeout=60,
 | |
|             stream=True
 | |
|         )
 | |
| 
 | |
|     ##################
 | |
|     #  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',
 | |
|             params={'force': False, 'noprune': False},
 | |
|             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 docker.errors.DeprecatedMethod as e:
 | |
|             self.assertTrue(
 | |
|                 docker.utils.compare_version('1.12', self.client._version) >= 0
 | |
|             )
 | |
|             return
 | |
|         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:
 | |
|             with mock.patch('docker.auth.auth.resolve_authconfig',
 | |
|                             fake_resolve_authconfig):
 | |
|                 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',
 | |
|             params={
 | |
|                 'tag': None
 | |
|             },
 | |
|             data='{}',
 | |
|             headers={'Content-Type': 'application/json'},
 | |
|             stream=False,
 | |
|             timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_push_image_with_tag(self):
 | |
|         try:
 | |
|             with mock.patch('docker.auth.auth.resolve_authconfig',
 | |
|                             fake_resolve_authconfig):
 | |
|                 self.client.push(
 | |
|                     fake_api.FAKE_IMAGE_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/test_image/push',
 | |
|             params={
 | |
|                 'tag': fake_api.FAKE_TAG_NAME,
 | |
|             },
 | |
|             data='{}',
 | |
|             headers={'Content-Type': 'application/json'},
 | |
|             stream=False,
 | |
|             timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_push_image_stream(self):
 | |
|         try:
 | |
|             with mock.patch('docker.auth.auth.resolve_authconfig',
 | |
|                             fake_resolve_authconfig):
 | |
|                 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',
 | |
|             params={
 | |
|                 'tag': None
 | |
|             },
 | |
|             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
 | |
|         )
 | |
| 
 | |
|     def test_get_image(self):
 | |
|         try:
 | |
|             self.client.get_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/get',
 | |
|             stream=True,
 | |
|             timeout=docker.client.DEFAULT_TIMEOUT_SECONDS
 | |
|         )
 | |
| 
 | |
|     def test_load_image(self):
 | |
|         try:
 | |
|             self.client.load_image('Byte Stream....')
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|         fake_request.assert_called_with(
 | |
|             url_prefix + 'images/load',
 | |
|             data='Byte Stream....',
 | |
|             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_pull(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, pull=True)
 | |
|         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))
 | |
| 
 | |
|     def test_build_container_custom_context(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'))
 | |
|         context = docker.utils.mkbuildcontext(script)
 | |
|         try:
 | |
|             self.client.build(fileobj=context, custom_context=True)
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|     def test_build_container_custom_context_gzip(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'))
 | |
|         context = docker.utils.mkbuildcontext(script)
 | |
|         gz_context = gzip.GzipFile(fileobj=context)
 | |
|         try:
 | |
|             self.client.build(
 | |
|                 fileobj=gz_context,
 | |
|                 custom_context=True,
 | |
|                 encoding="gzip"
 | |
|             )
 | |
|         except Exception as e:
 | |
|             self.fail('Command should not raise exception: {0}'.format(e))
 | |
| 
 | |
|     def test_build_remote_with_registry_auth(self):
 | |
|         try:
 | |
|             self.client._auth_configs = {
 | |
|                 'https://example.com': {
 | |
|                     'user': 'example',
 | |
|                     'password': 'example',
 | |
|                     'email': 'example@example.com'
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             self.client.build(path='https://github.com/docker-library/mongo')
 | |
|         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()
 | |
|         self.addCleanup(shutil.rmtree, folder)
 | |
|         cfg = docker.auth.load_config(folder)
 | |
|         self.assertTrue(cfg is not None)
 | |
| 
 | |
|     def test_load_config(self):
 | |
|         folder = tempfile.mkdtemp()
 | |
|         self.addCleanup(shutil.rmtree, folder)
 | |
|         dockercfg_path = os.path.join(folder, '.dockercfg')
 | |
|         f = open(dockercfg_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(dockercfg_path)
 | |
|         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)
 | |
| 
 | |
|     def test_load_config_with_random_name(self):
 | |
|         folder = tempfile.mkdtemp()
 | |
|         self.addCleanup(shutil.rmtree, folder)
 | |
| 
 | |
|         dockercfg_path = os.path.join(folder,
 | |
|                                       '.{0}.dockercfg'.format(
 | |
|                                           random.randrange(100000)))
 | |
|         registry = 'https://your.private.registry.io'
 | |
|         auth_ = base64.b64encode(b'sakuya:izayoi').decode('ascii')
 | |
|         config = {
 | |
|             registry: {
 | |
|                 'auth': '{0}'.format(auth_),
 | |
|                 'email': 'sakuya@scarlet.net'
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         with open(dockercfg_path, 'w') as f:
 | |
|             f.write(json.dumps(config))
 | |
| 
 | |
|         cfg = docker.auth.load_config(dockercfg_path)
 | |
|         self.assertTrue(registry in cfg)
 | |
|         self.assertNotEqual(cfg[registry], None)
 | |
|         cfg = cfg[registry]
 | |
|         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_tar_with_excludes(self):
 | |
|         base = tempfile.mkdtemp()
 | |
|         self.addCleanup(shutil.rmtree, base)
 | |
|         for d in ['test/foo', 'bar']:
 | |
|             os.makedirs(os.path.join(base, d))
 | |
|             for f in ['a.txt', 'b.py', 'other.png']:
 | |
|                 with open(os.path.join(base, d, f), 'w') as f:
 | |
|                     f.write("content")
 | |
| 
 | |
|         for exclude, names in (
 | |
|                 (['*.py'], ['bar', 'bar/a.txt', 'bar/other.png',
 | |
|                             'test', 'test/foo', 'test/foo/a.txt',
 | |
|                             'test/foo/other.png']),
 | |
|                 (['*.png', 'bar'], ['test', 'test/foo', 'test/foo/a.txt',
 | |
|                                     'test/foo/b.py']),
 | |
|                 (['test/foo', 'a.txt'], ['bar', 'bar/a.txt', 'bar/b.py',
 | |
|                                          'bar/other.png', 'test']),
 | |
|         ):
 | |
|             archive = docker.utils.tar(base, exclude=exclude)
 | |
|             tar = tarfile.open(fileobj=archive)
 | |
|             self.assertEqual(sorted(tar.getnames()), names)
 | |
| 
 | |
|     def test_tar_with_empty_directory(self):
 | |
|         base = tempfile.mkdtemp()
 | |
|         self.addCleanup(shutil.rmtree, base)
 | |
|         for d in ['foo', 'bar']:
 | |
|             os.makedirs(os.path.join(base, d))
 | |
|         archive = docker.utils.tar(base)
 | |
|         tar = tarfile.open(fileobj=archive)
 | |
|         self.assertEqual(sorted(tar.getnames()), ['bar', 'foo'])
 | |
| 
 | |
|     def test_tar_with_file_symlinks(self):
 | |
|         base = tempfile.mkdtemp()
 | |
|         self.addCleanup(shutil.rmtree, base)
 | |
|         with open(os.path.join(base, 'foo'), 'w') as f:
 | |
|             f.write("content")
 | |
|         os.makedirs(os.path.join(base, 'bar'))
 | |
|         os.symlink('../foo', os.path.join(base, 'bar/foo'))
 | |
|         archive = docker.utils.tar(base)
 | |
|         tar = tarfile.open(fileobj=archive)
 | |
|         self.assertEqual(sorted(tar.getnames()), ['bar', 'bar/foo', 'foo'])
 | |
| 
 | |
|     def test_tar_with_directory_symlinks(self):
 | |
|         base = tempfile.mkdtemp()
 | |
|         self.addCleanup(shutil.rmtree, base)
 | |
|         for d in ['foo', 'bar']:
 | |
|             os.makedirs(os.path.join(base, d))
 | |
|         os.symlink('../foo', os.path.join(base, 'bar/foo'))
 | |
|         archive = docker.utils.tar(base)
 | |
|         tar = tarfile.open(fileobj=archive)
 | |
|         self.assertEqual(sorted(tar.getnames()), ['bar', 'bar/foo', 'foo'])
 | |
| 
 | |
| 
 | |
| class StreamTest(Cleanup, unittest.TestCase):
 | |
| 
 | |
|     def setUp(self):
 | |
|         socket_dir = tempfile.mkdtemp()
 | |
|         self.build_context = tempfile.mkdtemp()
 | |
|         self.addCleanup(shutil.rmtree, socket_dir)
 | |
|         self.addCleanup(shutil.rmtree, self.build_context)
 | |
|         self.socket_file = os.path.join(socket_dir, 'test_sock.sock')
 | |
|         self.server_socket = self._setup_socket()
 | |
|         self.stop_server = False
 | |
|         server_thread = threading.Thread(target=self.run_server)
 | |
|         server_thread.setDaemon(True)
 | |
|         server_thread.start()
 | |
|         self.response = None
 | |
|         self.request_handler = None
 | |
|         self.addCleanup(server_thread.join)
 | |
|         self.addCleanup(self.stop)
 | |
| 
 | |
|     def stop(self):
 | |
|         self.stop_server = True
 | |
| 
 | |
|     def _setup_socket(self):
 | |
|         server_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
 | |
|         server_sock.bind(self.socket_file)
 | |
|         # Non-blocking mode so that we can shut the test down easily
 | |
|         server_sock.setblocking(0)
 | |
|         server_sock.listen(5)
 | |
|         return server_sock
 | |
| 
 | |
|     def run_server(self):
 | |
|         try:
 | |
|             while not self.stop_server:
 | |
|                 try:
 | |
|                     connection, client_address = self.server_socket.accept()
 | |
|                 except socket.error:
 | |
|                     # Probably no connection to accept yet
 | |
|                     time.sleep(0.01)
 | |
|                     continue
 | |
| 
 | |
|                 connection.setblocking(1)
 | |
|                 try:
 | |
|                     self.request_handler(connection)
 | |
|                 finally:
 | |
|                     connection.close()
 | |
|         finally:
 | |
|             self.server_socket.close()
 | |
| 
 | |
|     def early_response_sending_handler(self, connection):
 | |
|         data = b''
 | |
|         headers = None
 | |
| 
 | |
|         connection.sendall(self.response)
 | |
|         while not headers:
 | |
|             data += connection.recv(2048)
 | |
|             parts = data.split(b'\r\n\r\n', 1)
 | |
|             if len(parts) == 2:
 | |
|                 headers, data = parts
 | |
| 
 | |
|         mo = re.search(r'Content-Length: ([0-9]+)', headers.decode())
 | |
|         assert mo
 | |
|         content_length = int(mo.group(1))
 | |
| 
 | |
|         while True:
 | |
|             if len(data) >= content_length:
 | |
|                 break
 | |
| 
 | |
|             data += connection.recv(2048)
 | |
| 
 | |
|     def test_early_stream_response(self):
 | |
|         self.request_handler = self.early_response_sending_handler
 | |
|         lines = []
 | |
|         for i in range(0, 50):
 | |
|             line = str(i).encode()
 | |
|             lines += [('%x' % len(line)).encode(), line]
 | |
|         lines.append(b'0')
 | |
|         lines.append(b'')
 | |
| 
 | |
|         self.response = (
 | |
|             b'HTTP/1.1 200 OK\r\n'
 | |
|             b'Transfer-Encoding: chunked\r\n'
 | |
|             b'\r\n'
 | |
|         ) + b'\r\n'.join(lines)
 | |
| 
 | |
|         client = docker.Client(base_url="http+unix://" + self.socket_file)
 | |
|         for i in range(5):
 | |
|             try:
 | |
|                 stream = client.build(
 | |
|                     path=self.build_context,
 | |
|                     stream=True
 | |
|                 )
 | |
|                 break
 | |
|             except requests.ConnectionError as e:
 | |
|                 if i == 4:
 | |
|                     raise e
 | |
| 
 | |
|         self.assertEqual(list(stream), [
 | |
|             str(i).encode() for i in range(50)])
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     unittest.main()
 |