From f5924c386384dec09c69c34f08bba4dd08736109 Mon Sep 17 00:00:00 2001 From: Ulises Reyes Date: Sat, 14 Dec 2013 22:00:08 -0500 Subject: [PATCH] Updated the port function in order to parse the new NetworkSettings Port dict (fixes #88) --- docker/client.py | 12 +++---- tests/fake_api.py | 66 +++++++++++++++++++++++++++++++++++++++ tests/integration_test.py | 16 ++++++++++ tests/test.py | 16 +++++++--- 4 files changed, 99 insertions(+), 11 deletions(-) diff --git a/docker/client.py b/docker/client.py index fd4c9e19..68088d89 100644 --- a/docker/client.py +++ b/docker/client.py @@ -540,13 +540,13 @@ class Client(requests.Session): self._raise_for_status(res) json_ = res.json() s_port = str(private_port) - f_port = None - if s_port in json_['NetworkSettings']['PortMapping']['Udp']: - f_port = json_['NetworkSettings']['PortMapping']['Udp'][s_port] - elif s_port in json_['NetworkSettings']['PortMapping']['Tcp']: - f_port = json_['NetworkSettings']['PortMapping']['Tcp'][s_port] + host_port_bindings = None - return f_port + host_port_bindings = json_['NetworkSettings']['Ports'].get(s_port +'/udp') + if host_port_bindings is None: + host_port_bindings = json_['NetworkSettings']['Ports'].get(s_port + '/tcp') + + return host_port_bindings def pull(self, repository, tag=None, stream=False): registry, repo_name = auth.resolve_repository_name(repository) diff --git a/tests/fake_api.py b/tests/fake_api.py index 3d5a1605..ce89dc94 100644 --- a/tests/fake_api.py +++ b/tests/fake_api.py @@ -156,6 +156,70 @@ def get_fake_inspect_image(): } return status_code, response +def get_fake_port(): + status_code = 200 + response = {'Args': [], + 'Config': {'AttachStderr': True, + 'AttachStdin': False, + 'AttachStdout': True, + 'Cmd': ['yes'], + 'CpuShares': 0, + 'Dns': None, + 'Domainname': '', + 'Entrypoint': None, + 'Env': None, + 'ExposedPorts': {'1111': {}, '2222': {}}, + 'Hostname': 'a398832bc87e', + 'Image': 'ubuntu', + 'Memory': 0, + 'MemorySwap': 0, + 'NetworkDisabled': False, + 'OpenStdin': False, + 'PortSpecs': None, + 'StdinOnce': False, + 'Tty': False, + 'User': '', + 'Volumes': None, + 'VolumesFrom': '', + 'WorkingDir': ''}, + 'Created': '2013-12-14T17:41:13.976760086Z', + 'Driver': 'aufs', + 'HostConfig': {'Binds': None, + 'ContainerIDFile': '', + 'Links': None, + 'LxcConf': None, + 'PortBindings': {'1111': None, + '1111/tcp': [{'HostIp': '127.0.0.1', 'HostPort': '4567'}], + '2222': None}, + 'Privileged': False, + 'PublishAllPorts': False}, + 'HostnamePath': '/var/lib/docker/containers/a398832bc87e15b220d710a98386493559df2448480fc9243e86ee5544eea767/hostname', + 'HostsPath': '/var/lib/docker/containers/a398832bc87e15b220d710a98386493559df2448480fc9243e86ee5544eea767/hosts', + 'ID': 'a398832bc87e15b220d710a98386493559df2448480fc9243e86ee5544eea767', + 'Image': '8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c', + 'Name': '/sad_tesla7', + 'NetworkSettings': {'Bridge': 'docker0', + 'Gateway': '172.17.42.1', + 'IPAddress': '172.17.0.19', + 'IPPrefixLen': 16, + 'PortMapping': None, + 'Ports': {'1111': None, + '1111/tcp': [{'HostIp': '127.0.0.1', 'HostPort': '4567'}], + '2222': None}}, + 'Path': 'yes', + 'ResolvConfPath': '/var/lib/docker/containers/a398832bc87e15b220d710a98386493559df2448480fc9243e86ee5544eea767/resolv.conf', + 'State': {'ExitCode': 0, + 'FinishedAt': '0001-01-01T00:00:00Z', + 'Ghost': False, + 'Pid': 11703, + 'Running': True, + 'StartedAt': '2013-12-14T17:41:27.844076587Z'}, + 'SysInitPath': '/usr/bin/docker', + 'Volumes': {}, + 'VolumesRW': {}} + + + return status_code, response def get_fake_insert_image(): status_code = 200 @@ -282,6 +346,8 @@ fake_responses = { post_fake_stop_container, '{1}/{0}/containers/3cc2351ab11b/kill'.format(CURRENT_VERSION, prefix): post_fake_kill_container, + '{1}/{0}/containers/3cc2351ab11b/json'.format(CURRENT_VERSION, prefix): + get_fake_port, '{1}/{0}/containers/3cc2351ab11b/restart'.format(CURRENT_VERSION, prefix): post_fake_restart_container, '{1}/{0}/containers/3cc2351ab11b'.format(CURRENT_VERSION, prefix): diff --git a/tests/integration_test.py b/tests/integration_test.py index c81cbaa2..8461483a 100644 --- a/tests/integration_test.py +++ b/tests/integration_test.py @@ -402,6 +402,22 @@ class TestKillWithSignal(BaseTestCase): self.assertIn('Running', state) self.assertEqual(state['Running'], False, state) +class TestPort(BaseTestCase): + def runTest(self): + container = self.client.create_container('busybox', ['sleep', '9999'], ports=[1111, 2222]) + id = container['Id'] + self.client.start(container, port_bindings={1111: ('127.0.0.1', 4567)}) + port_bindings = self.client.port(container, 1111) + self.assertIsInstance(port_bindings, list) + self.assertEqual(len(port_bindings), 1) + + port_binding = port_bindings.pop() + self.assertIn('HostPort', port_binding) + self.assertIn('HostIp', port_binding) + + self.assertTrue(port_binding['HostPort']) + + self.client.kill(id) class TestRestart(BaseTestCase): def runTest(self): diff --git a/tests/test.py b/tests/test.py index 5d0ce38d..a6625718 100644 --- a/tests/test.py +++ b/tests/test.py @@ -33,11 +33,6 @@ try: except ImportError: import mock - -# FIXME: missing tests for -# port; - - def response(status_code=200, content='', headers=None, reason=None, elapsed=0, request=None): res = requests.Response() @@ -587,6 +582,17 @@ class DockerClientTest(unittest.TestCase): 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( + 'unix://var/run/docker.sock/v1.6/containers/3cc2351ab11b/json', + timeout=docker.client.DEFAULT_TIMEOUT_SECONDS + ) + def test_stop_container(self): try: self.client.stop(fake_api.FAKE_CONTAINER_ID, timeout=2)