You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by qu...@apache.org on 2017/10/10 05:12:55 UTC

[3/4] libcloud git commit: On Azure ARM, fix destroy_node() return value when successfully destroying a node but the NIC failed to be cleaned up. Added missing tests.

On Azure ARM, fix destroy_node() return value when successfully destroying a node but the NIC failed to be cleaned up. Added missing tests.

Signed-off-by: Quentin Pradet <qu...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/cd681104
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/cd681104
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/cd681104

Branch: refs/heads/trunk
Commit: cd6811042d28ff4fd38d117919b6d4abfe61b632
Parents: 12d8e99
Author: Lucas Di Pentima <ld...@veritasgenetics.com>
Authored: Tue Oct 3 20:20:23 2017 -0300
Committer: Quentin Pradet <qu...@apache.org>
Committed: Tue Oct 10 09:01:17 2017 +0400

----------------------------------------------------------------------
 libcloud/compute/drivers/azure_arm.py   |  3 +-
 libcloud/test/compute/test_azure_arm.py | 70 +++++++++++++++++++++++++++-
 2 files changed, 70 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/cd681104/libcloud/compute/drivers/azure_arm.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/azure_arm.py b/libcloud/compute/drivers/azure_arm.py
index a2237bd..913c461 100644
--- a/libcloud/compute/drivers/azure_arm.py
+++ b/libcloud/compute/drivers/azure_arm.py
@@ -744,7 +744,8 @@ class AzureNodeDriver(NodeDriver):
                         if h.code == 400 and inuse:
                             time.sleep(10)
                         else:
-                            return False
+                            # NIC cleanup failed, try cleaning up the VHD.
+                            break
 
         # Optionally clean up OS disk VHD.
         vhd = node.extra["properties"]["storageProfile"]["osDisk"].get("vhd")

http://git-wip-us.apache.org/repos/asf/libcloud/blob/cd681104/libcloud/test/compute/test_azure_arm.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_azure_arm.py b/libcloud/test/compute/test_azure_arm.py
index 984feed..af1776e 100644
--- a/libcloud/test/compute/test_azure_arm.py
+++ b/libcloud/test/compute/test_azure_arm.py
@@ -20,6 +20,7 @@ from datetime import datetime
 
 import mock
 
+from libcloud.common.exceptions import BaseHTTPError
 from libcloud.compute.base import (NodeLocation, NodeSize, VolumeSnapshot,
                                    StorageVolume)
 from libcloud.compute.drivers.azure_arm import AzureImage, NodeAuthPassword
@@ -46,6 +47,9 @@ class AzureNodeDriverTests(LibcloudTestCase):
         self.driver = Azure(self.TENANT_ID, self.SUBSCRIPTION_ID,
                             self.APPLICATION_ID, self.APPLICATION_PASS)
 
+    def tearDown(self):
+        AzureMockHttp.responses = []
+
     def test_get_image(self):
         # Default storage suffix
         image = self.driver.get_image(image_id='http://www.example.com/foo/image_name')
@@ -129,6 +133,61 @@ class AzureNodeDriverTests(LibcloudTestCase):
             'version': image.version
         })
 
+    @mock.patch('time.sleep', return_value=None)
+    def test_destroy_node(self, time_sleep_mock):
+        def error(e, **kwargs):
+            raise e(**kwargs)
+        node = self.driver.list_nodes()[0]
+        AzureMockHttp.responses = [
+            # OK to the DELETE request
+            lambda f: (httplib.OK, None, {}, 'OK'),
+            # 404 means node destroyed successfully
+            lambda f: error(BaseHTTPError, code=404, message='Not found'),
+        ]
+        ret = self.driver.destroy_node(node)
+        self.assertTrue(ret)
+
+    @mock.patch('time.sleep', return_value=None)
+    def test_destroy_node__async(self, time_sleep_mock):
+        def error(e, **kwargs):
+            raise e(**kwargs)
+        node = self.driver.list_nodes()[0]
+        AzureMockHttp.responses = [
+            # 202 - The delete will happen asynchronously
+            lambda f: error(BaseHTTPError, code=202, message='Deleting'),
+            # 404 means node destroyed successfully
+            lambda f: error(BaseHTTPError, code=404, message='Not found'),
+        ]
+        ret = self.driver.destroy_node(node)
+        self.assertTrue(ret)
+
+    @mock.patch('time.sleep', return_value=None)
+    def test_destroy_node__nic_not_cleaned_up(self, time_sleep_mock):
+        def error(e, **kwargs):
+            raise e(**kwargs)
+        node = self.driver.list_nodes()[0]
+        AzureMockHttp.responses = [
+            # OK to the DELETE request
+            lambda f: (httplib.OK, None, {}, 'OK'),
+            # 404 means node destroyed successfully
+            lambda f: error(BaseHTTPError, code=404, message='Not found'),
+            # 500 - transient error when trying to clean up the NIC
+            lambda f: error(BaseHTTPError, code=500, message="Cloud weather")
+        ]
+        ret = self.driver.destroy_node(node)
+        self.assertTrue(ret)
+
+    def test_destroy_node__failed(self):
+        def error(e, **kwargs):
+            raise e(**kwargs)
+        node = self.driver.list_nodes()[0]
+        AzureMockHttp.responses = [
+            # 403 - There was some problem with your request
+            lambda f: error(BaseHTTPError, code=403, message='Forbidden'),
+        ]
+        ret = self.driver.destroy_node(node)
+        self.assertFalse(ret)
+
     def test_list_nodes(self):
         nodes = self.driver.list_nodes()
 
@@ -400,6 +459,9 @@ class AzureNodeDriverTests(LibcloudTestCase):
 
 class AzureMockHttp(MockHttp):
     fixtures = ComputeFileFixtures('azure_arm')
+    # List of callables to be run in order as responses. Fixture
+    # passed as argument.
+    responses = []
 
     def _update(self, fixture, body):
         for key, value in body.items():
@@ -425,8 +487,12 @@ class AzureMockHttp(MockHttp):
                     fixture = json.dumps(fixture_tmp)
                 except ValueError:
                     pass
-            return (httplib.OK, fixture, headers,
-                    httplib.responses[httplib.OK])
+            if (not n.endswith('_oauth2_token')) and len(self.responses) > 0:
+                f = self.responses.pop(0)
+                return f(fixture)
+            else:
+                return (httplib.OK, fixture, headers,
+                        httplib.responses[httplib.OK])
         return fn