Ver Fonte

Decode APIError explanation to unicode before usage

Signed-off-by: Ulysses Souza <[email protected]>
Ulysses Souza há 5 anos atrás
pai
commit
37eb7a509b
2 ficheiros alterados com 35 adições e 3 exclusões
  1. 5 3
      compose/service.py
  2. 30 0
      tests/unit/service_test.py

+ 5 - 3
compose/service.py

@@ -60,6 +60,7 @@ from .utils import parse_bytes
 from .utils import parse_seconds_float
 from .utils import truncate_id
 from .utils import unique_everseen
+from compose.cli.utils import binarystr_to_unicode
 
 if six.PY2:
     import subprocess32 as subprocess
@@ -343,7 +344,7 @@ class Service(object):
             return Container.create(self.client, **container_options)
         except APIError as ex:
             raise OperationFailedError("Cannot create container for service %s: %s" %
-                                       (self.name, ex.explanation))
+                                       (self.name, binarystr_to_unicode(ex.explanation)))
 
     def ensure_image_exists(self, do_build=BuildAction.none, silent=False, cli=False):
         if self.can_be_built() and do_build == BuildAction.force:
@@ -624,9 +625,10 @@ class Service(object):
         try:
             container.start()
         except APIError as ex:
-            if "driver failed programming external connectivity" in ex.explanation:
+            expl = binarystr_to_unicode(ex.explanation)
+            if "driver failed programming external connectivity" in expl:
                 log.warn("Host is already in use by another container")
-            raise OperationFailedError("Cannot start service %s: %s" % (self.name, ex.explanation))
+            raise OperationFailedError("Cannot start service %s: %s" % (self.name, expl))
         return container
 
     @property

+ 30 - 0
tests/unit/service_test.py

@@ -523,6 +523,36 @@ class ServiceTest(unittest.TestCase):
         assert self.mock_client.build.call_count == 1
         assert self.mock_client.build.call_args[1]['tag'] == 'default_foo'
 
+    def test_create_container_binary_string_error(self):
+        service = Service('foo', client=self.mock_client, build={'context': '.'})
+        service.image = lambda: {'Id': 'abc123'}
+
+        self.mock_client.create_container.side_effect = APIError(None,
+                                                                 None,
+                                                                 b"Test binary string explanation")
+        with pytest.raises(OperationFailedError) as ex:
+            service.create_container()
+
+        assert ex.value.msg == "Cannot create container for service foo: Test binary string explanation"
+
+    def test_start_binary_string_error(self):
+        service = Service('foo', client=self.mock_client)
+        container = Container(self.mock_client, {'Id': 'abc123'})
+
+        self.mock_client.start.side_effect = APIError(None,
+                                                      None,
+                                                      b"Test binary string explanation with "
+                                                      b"driver failed programming external "
+                                                      b"connectivity")
+        with mock.patch('compose.service.log', autospec=True) as mock_log:
+            with pytest.raises(OperationFailedError) as ex:
+                service.start_container(container)
+
+        assert ex.value.msg == "Cannot start service foo: " \
+                               "Test binary string explanation " \
+                               "with driver failed programming external connectivity"
+        mock_log.warn.assert_called_once_with("Host is already in use by another container")
+
     def test_ensure_image_exists_no_build(self):
         service = Service('foo', client=self.mock_client, build={'context': '.'})
         self.mock_client.inspect_image.return_value = {'Id': 'abc123'}