You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2020/04/04 20:45:06 UTC

[libcloud] 04/21: Add a test case which verifies deploy_node() correctly propagates fatal errors instead of retrying.

This is an automated email from the ASF dual-hosted git repository.

tomaz pushed a commit to branch 2.8.x
in repository https://gitbox.apache.org/repos/asf/libcloud.git

commit 0e8af0e919befab151426cee5246045e1169c002
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Tue Mar 31 23:18:44 2020 +0200

    Add a test case which verifies deploy_node() correctly propagates fatal
    errors instead of retrying.
---
 libcloud/compute/base.py                 |  3 ++-
 libcloud/test/compute/test_deployment.py | 26 ++++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/libcloud/compute/base.py b/libcloud/compute/base.py
index 4529844..0f555fc 100644
--- a/libcloud/compute/base.py
+++ b/libcloud/compute/base.py
@@ -1726,13 +1726,14 @@ class NodeDriver(BaseDriver):
                 ssh_client.connect()
             except SSH_TIMEOUT_EXCEPTION_CLASSES as e:
                 # Errors which represent fatal invalid key files which should
-                # be propagated to the user
+                # be propagated to the user without us retrying
                 message = str(e).lower()
                 invalid_key_msgs = [
                     'no such file or directory',
                     'invalid key',
                     'not a valid ',
                     'invalid or unsupported key type',
+                    'private file is encrypted',
                     'private key file is encrypted'
                 ]
 
diff --git a/libcloud/test/compute/test_deployment.py b/libcloud/test/compute/test_deployment.py
index dd25310..e7aa9e0 100644
--- a/libcloud/test/compute/test_deployment.py
+++ b/libcloud/test/compute/test_deployment.py
@@ -24,6 +24,7 @@ import unittest
 from libcloud.utils.py3 import httplib
 from libcloud.utils.py3 import u
 from libcloud.utils.py3 import PY3
+from libcloud.utils.py3 import assertRaisesRegex
 
 from libcloud.compute.deployment import MultiStepDeployment, Deployment
 from libcloud.compute.deployment import SSHKeyDeployment, ScriptDeployment
@@ -32,6 +33,7 @@ from libcloud.compute.base import Node
 from libcloud.compute.base import NodeAuthPassword
 from libcloud.compute.types import NodeState, DeploymentError, LibcloudError
 from libcloud.compute.ssh import BaseSSHClient
+from libcloud.compute.ssh import have_paramiko
 from libcloud.compute.drivers.rackspace import RackspaceFirstGenNodeDriver as Rackspace
 
 from libcloud.test import MockHttp, XML_HEADERS
@@ -356,6 +358,30 @@ class DeploymentTests(unittest.TestCase):
         else:
             self.fail('Exception was not thrown')
 
+    @unittest.skipIf(not have_paramiko, 'Skipping because paramiko is not available')
+    def test_ssh_client_connect_immediately_throws_on_fatal_execption(self):
+        # Verify that fatal exceptions are immediately propagated and ensure
+        # we don't try to retry on them
+        from paramiko.ssh_exception import SSHException
+        from paramiko.ssh_exception import PasswordRequiredException
+
+        mock_ssh_client = Mock()
+        mock_ssh_client.connect = Mock()
+        mock_ssh_client.connect.side_effect = IOError('bam')
+
+        mock_exceptions = [
+            SSHException('Invalid or unsupported key type'),
+            PasswordRequiredException('private key file is encrypted')
+        ]
+
+        for mock_exception in mock_exceptions:
+            mock_ssh_client.connect = Mock(side_effect=mock_exception)
+            assertRaisesRegex(self, mock_exception.__class__, str(mock_exception),
+                              self.driver._ssh_client_connect,
+                              ssh_client=mock_ssh_client,
+                              wait_period=0.1,
+                              timeout=0.2)
+
     def test_run_deployment_script_success(self):
         task = Mock()
         ssh_client = Mock()