From bbad864d899c199fbe8372af16e750e448d98e76 Mon Sep 17 00:00:00 2001 From: alex-dr Date: Wed, 22 Mar 2017 00:41:32 -0400 Subject: [PATCH 1/4] Fix APIError status_code property for client/server errors requests.Response objects evaluate as falsy when the status_code attribute is in the 400-500 range. Therefore we are assured that prior to this change, APIError would show `is_server_error() == False` when generated with a 500-level response and `is_client_error() == False` when generated with a 400-level response. This is not desirable. Added some seemingly dry (not DRY) unit tests to ensure nothing silly slips back in here. Signed-off-by: alex-dr --- docker/errors.py | 2 +- tests/unit/errors_test.py | 65 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/docker/errors.py b/docker/errors.py index d9b197d1a3..03b89c11e3 100644 --- a/docker/errors.py +++ b/docker/errors.py @@ -59,7 +59,7 @@ def __str__(self): @property def status_code(self): - if self.response: + if self.response is not None: return self.response.status_code def is_client_error(self): diff --git a/tests/unit/errors_test.py b/tests/unit/errors_test.py index 876ede3b5f..b78af4e109 100644 --- a/tests/unit/errors_test.py +++ b/tests/unit/errors_test.py @@ -1,5 +1,7 @@ import unittest +import requests + from docker.errors import (APIError, DockerException, create_unexpected_kwargs_error) @@ -11,6 +13,69 @@ def test_api_error_is_caught_by_dockerexception(self): except DockerException: pass + def test_status_code_200(self): + """The status_code property is present with 200 response.""" + resp = requests.Response() + resp.status_code = 200 + err = APIError('', response=resp) + assert err.status_code == 200 + + def test_status_code_400(self): + """The status_code property is present with 400 response.""" + resp = requests.Response() + resp.status_code = 400 + err = APIError('', response=resp) + assert err.status_code == 400 + + def test_status_code_500(self): + """The status_code property is present with 500 response.""" + resp = requests.Response() + resp.status_code = 500 + err = APIError('', response=resp) + assert err.status_code == 500 + + def test_is_server_error_200(self): + """Report not server error on 200 response.""" + resp = requests.Response() + resp.status_code = 200 + err = APIError('', response=resp) + assert err.is_server_error() is False + + def test_is_server_error_300(self): + """Report not server error on 300 response.""" + resp = requests.Response() + resp.status_code = 300 + err = APIError('', response=resp) + assert err.is_server_error() is False + + def test_is_server_error_400(self): + """Report not server error on 400 response.""" + resp = requests.Response() + resp.status_code = 400 + err = APIError('', response=resp) + assert err.is_server_error() is False + + def test_is_server_error_500(self): + """Report server error on 500 response.""" + resp = requests.Response() + resp.status_code = 500 + err = APIError('', response=resp) + assert err.is_server_error() is True + + def test_is_client_error_500(self): + """Report not client error on 500 response.""" + resp = requests.Response() + resp.status_code = 500 + err = APIError('', response=resp) + assert err.is_client_error() is False + + def test_is_client_error_400(self): + """Report client error on 400 response.""" + resp = requests.Response() + resp.status_code = 400 + err = APIError('', response=resp) + assert err.is_client_error() is True + class CreateUnexpectedKwargsErrorTest(unittest.TestCase): def test_create_unexpected_kwargs_error_single(self): From a89faa454ae41647fd1810b3a69efc82e748f681 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Wed, 22 Mar 2017 16:13:33 -0700 Subject: [PATCH 2/4] Set infinite timeout for the `events` method Signed-off-by: Joffrey F --- docker/api/daemon.py | 3 ++- tests/integration/api_service_test.py | 4 ++-- tests/unit/api_test.py | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docker/api/daemon.py b/docker/api/daemon.py index 00367bc309..91c777f092 100644 --- a/docker/api/daemon.py +++ b/docker/api/daemon.py @@ -68,9 +68,10 @@ def events(self, since=None, until=None, filters=None, decode=None): 'until': until, 'filters': filters } + url = self._url('/events') return self._stream_helper( - self._get(self._url('/events'), params=params, stream=True), + self._get(url, params=params, stream=True, timeout=None), decode=decode ) diff --git a/tests/integration/api_service_test.py b/tests/integration/api_service_test.py index 3bfabe91dd..6858ad0e54 100644 --- a/tests/integration/api_service_test.py +++ b/tests/integration/api_service_test.py @@ -363,7 +363,7 @@ def test_create_service_with_secret(self): self.tmp_secrets.append(secret_id) secret_ref = docker.types.SecretReference(secret_id, secret_name) container_spec = docker.types.ContainerSpec( - 'busybox', ['top'], secrets=[secret_ref] + 'busybox', ['sleep', '999'], secrets=[secret_ref] ) task_tmpl = docker.types.TaskTemplate(container_spec) name = self.get_service_name() @@ -388,7 +388,7 @@ def test_create_service_with_unicode_secret(self): self.tmp_secrets.append(secret_id) secret_ref = docker.types.SecretReference(secret_id, secret_name) container_spec = docker.types.ContainerSpec( - 'busybox', ['top'], secrets=[secret_ref] + 'busybox', ['sleep', '999'], secrets=[secret_ref] ) task_tmpl = docker.types.TaskTemplate(container_spec) name = self.get_service_name() diff --git a/tests/unit/api_test.py b/tests/unit/api_test.py index b632d209be..83848c524a 100644 --- a/tests/unit/api_test.py +++ b/tests/unit/api_test.py @@ -229,7 +229,7 @@ def test_events(self): url_prefix + 'events', params={'since': None, 'until': None, 'filters': None}, stream=True, - timeout=DEFAULT_TIMEOUT_SECONDS + timeout=None ) def test_events_with_since_until(self): @@ -249,7 +249,7 @@ def test_events_with_since_until(self): 'filters': None }, stream=True, - timeout=DEFAULT_TIMEOUT_SECONDS + timeout=None ) def test_events_with_filters(self): @@ -268,7 +268,7 @@ def test_events_with_filters(self): 'filters': expected_filters }, stream=True, - timeout=DEFAULT_TIMEOUT_SECONDS + timeout=None ) def _socket_path_for_client_session(self, client): From ae65be045a5a1d69b8d5a193b3bfaf37bf13e7c6 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Tue, 28 Mar 2017 15:00:42 -0700 Subject: [PATCH 3/4] Bump version 2.2.1 ; update changelog Signed-off-by: Joffrey F --- docker/version.py | 2 +- docs/change-log.md | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docker/version.py b/docker/version.py index b2474bd739..08c792b6f6 100644 --- a/docker/version.py +++ b/docker/version.py @@ -1,2 +1,2 @@ -version = "2.2.0" +version = "2.2.1" version_info = tuple([int(d) for d in version.split("-")[0].split(".")]) diff --git a/docs/change-log.md b/docs/change-log.md index c04cd4be8f..5a8d788e6e 100644 --- a/docs/change-log.md +++ b/docs/change-log.md @@ -1,6 +1,18 @@ Change log ========== +2.2.1 +----- + +[List of PRs / issues for this release](https://github.com/docker/docker-py/milestone/31?closed=1) + +### Bugfixes + +* Fixed a bug where the `status_code` attribute of `APIError` exceptions would + not reflect the expected value. +* Fixed an issue where the `events` method would time out unexpectedly if no + data was sent by the engine for a given amount of time. + 2.2.0 ----- From 4a51e787318ad81331815c99e1a575892cf36e4b Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Tue, 28 Mar 2017 15:04:05 -0700 Subject: [PATCH 4/4] Add reload() in docs for Container and Secret classes Signed-off-by: Joffrey F --- docs/change-log.md | 2 +- docs/containers.rst | 1 + docs/secrets.rst | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/change-log.md b/docs/change-log.md index 5a8d788e6e..a6f5c57e9a 100644 --- a/docs/change-log.md +++ b/docs/change-log.md @@ -4,7 +4,7 @@ Change log 2.2.1 ----- -[List of PRs / issues for this release](https://github.com/docker/docker-py/milestone/31?closed=1) +[List of PRs / issues for this release](https://github.com/docker/docker-py/milestone/32?closed=1) ### Bugfixes diff --git a/docs/containers.rst b/docs/containers.rst index 9b27a306b8..20529b0eff 100644 --- a/docs/containers.rst +++ b/docs/containers.rst @@ -40,6 +40,7 @@ Container objects .. automethod:: logs .. automethod:: pause .. automethod:: put_archive + .. automethod:: reload .. automethod:: remove .. automethod:: rename .. automethod:: resize diff --git a/docs/secrets.rst b/docs/secrets.rst index 49e149847d..d1c39f1a16 100644 --- a/docs/secrets.rst +++ b/docs/secrets.rst @@ -26,4 +26,5 @@ Secret objects The raw representation of this object from the server. + .. automethod:: reload .. automethod:: remove