]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: RestClient can't handle ProtocolError exceptions 23347/head
authorVolker Theile <vtheile@suse.com>
Tue, 31 Jul 2018 08:43:06 +0000 (10:43 +0200)
committerVolker Theile <vtheile@suse.com>
Thu, 2 Aug 2018 10:13:35 +0000 (12:13 +0200)
Fixes: https://tracker.ceph.com/issues/25190
Signed-off-by: Volker Theile <vtheile@suse.com>
src/pybind/mgr/dashboard/rest_client.py
src/pybind/mgr/dashboard/tests/test_rest_client.py

index 6099fe945254fae52ddbd4d902877191487110da..a8ac9f8ea6f8ca4ea2e88b0580147b9a25eaf693 100644 (file)
@@ -439,8 +439,11 @@ class RestClient(object):
                     logger.error("%s REST API failed %s, SSL error.",
                                  self.client_name, method.upper())
                 else:
-                    match = re.match(r'.*: \[Errno (-?\d+)\] (.+)',
-                                     ex.args[0].reason.args[0])
+                    try:
+                        match = re.match(r'.*: \[Errno (-?\d+)\] (.+)',
+                                         ex.args[0].reason.args[0])
+                    except AttributeError:
+                        match = False
                     if match:
                         errno = match.group(1)
                         strerror = match.group(2)
index 7a15319ff9eceb5f1fd23065f738c0e5a5aac72b..f1f0267abd545514dccf25296aa5b86696978094 100644 (file)
@@ -1,9 +1,11 @@
 # -*- coding: utf-8 -*-
 import unittest
+import requests.exceptions
 
 from mock import patch
+from urllib3.exceptions import MaxRetryError, ProtocolError
 from .. import mgr
-from ..rest_client import RestClient
+from ..rest_client import RequestException, RestClient
 
 
 class RestClientTest(unittest.TestCase):
@@ -42,3 +44,51 @@ class RestClientTest(unittest.TestCase):
             mock_request.assert_called_with(
                 'GET', '/test', None, None, None, None,
                 None, None, 40)
+
+
+class RestClientDoRequestTest(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        cls.mock_requests = patch('requests.Session').start()
+        cls.rest_client = RestClient('localhost', 8000, 'UnitTest')
+
+    def test_do_request_exception_no_args(self):
+        self.mock_requests().get.side_effect = requests.exceptions.ConnectionError()
+        with self.assertRaises(RequestException) as context:
+            self.rest_client.do_request('GET', '/test')
+            self.assertEqual('UnitTest REST API cannot be reached. Please '
+                             'check your configuration and that the API '
+                             'endpoint is accessible',
+                             context.exception.message)
+
+    def test_do_request_exception_args_1(self):
+        self.mock_requests().post.side_effect = requests.exceptions.ConnectionError(
+            MaxRetryError('Abc', 'http://xxx.yyy', 'too many redirects'))
+        with self.assertRaises(RequestException) as context:
+            self.rest_client.do_request('POST', '/test')
+            self.assertEqual('UnitTest REST API cannot be reached. Please '
+                             'check your configuration and that the API '
+                             'endpoint is accessible',
+                             context.exception.message)
+
+    def test_do_request_exception_args_2(self):
+        self.mock_requests().put.side_effect = requests.exceptions.ConnectionError(
+            ProtocolError('Connection broken: xyz'))
+        with self.assertRaises(RequestException) as context:
+            self.rest_client.do_request('PUT', '/test')
+            self.assertEqual('UnitTest REST API cannot be reached. Please '
+                             'check your configuration and that the API '
+                             'endpoint is accessible',
+                             context.exception.message)
+
+    def test_do_request_exception_nested_args(self):
+        self.mock_requests().delete.side_effect = requests.exceptions.ConnectionError(
+            MaxRetryError('Xyz', 'https://foo.bar',
+                          Exception('Foo: [Errno -42] bla bla bla')))
+        with self.assertRaises(RequestException) as context:
+            self.rest_client.do_request('DELETE', '/test')
+            self.assertEqual('UnitTest REST API cannot be reached: bla '
+                             'bla bla [errno -42]. Please check your '
+                             'configuration and that the API endpoint '
+                             'is accessible',
+                             context.exception.message)