Changed heat_utils#get_stack_by_name to get_stack. 67/38467/1
authorspisarski <s.pisarski@cablelabs.com>
Mon, 31 Jul 2017 18:26:19 +0000 (12:26 -0600)
committerspisarski <s.pisarski@cablelabs.com>
Mon, 31 Jul 2017 18:26:19 +0000 (12:26 -0600)
Added stack_settings parameter to allow for more robust
queries based on the known settings as required.

JIRA: SNAPS-158

Change-Id: I538826f822307365b1afe997b71280b9ea500eab
Signed-off-by: spisarski <s.pisarski@cablelabs.com>
snaps/domain/stack.py
snaps/openstack/create_stack.py
snaps/openstack/utils/heat_utils.py
snaps/openstack/utils/tests/heat_utils_tests.py

index eaa45b3..0302184 100644 (file)
@@ -27,3 +27,7 @@ class Stack:
         """
         self.name = name
         self.id = stack_id
+
+    def __eq__(self, other):
+        return (self.name == other.name and
+                self.id == other.id)
index cb06e8a..41cc725 100644 (file)
@@ -55,8 +55,8 @@ class OpenStackHeatStack:
         :return: The OpenStack Stack object
         """
         self.__heat_cli = heat_utils.heat_client(self.__os_creds)
-        self.__stack = heat_utils.get_stack_by_name(self.__heat_cli,
-                                                    self.stack_settings.name)
+        self.__stack = heat_utils.get_stack(
+            self.__heat_cli, stack_settings=self.stack_settings)
         if self.__stack:
             logger.info('Found stack with name - ' + self.stack_settings.name)
             return self.__stack
@@ -215,6 +215,13 @@ class StackSettings:
         if not self.template and not self.template_path:
             raise StackSettingsError('A Heat template is required')
 
+    def __eq__(self, other):
+        return (self.name == other.name and
+                self.template == other.template and
+                self.template_path == other.template_path and
+                self.env_values == other.env_values and
+                self.stack_create_timeout == other.stack_create_timeout)
+
 
 class StackSettingsError(Exception):
     """
index ae367a0..a91a21c 100644 (file)
@@ -41,19 +41,29 @@ def heat_client(os_creds):
                   region_name=os_creds.region_name)
 
 
-def get_stack_by_name(heat_cli, stack_name):
+def get_stack(heat_cli, stack_settings=None, stack_name=None):
     """
-    Returns a domain Stack object
+    Returns the first domain Stack object found. When stack_setting
+    is not None, the filter created will take the name attribute. When
+    stack_settings is None and stack_name is not, stack_name will be used
+    instead. When both are None, the first stack object received will be
+    returned, else None
     :param heat_cli: the OpenStack heat client
-    :param stack_name: the name of the heat stack
+    :param stack_settings: a StackSettings object
+    :param stack_name: the name of the heat stack to return
     :return: the Stack domain object else None
     """
-    stacks = heat_cli.stacks.list(**{'name': stack_name})
+
+    stack_filter = dict()
+    if stack_settings:
+        stack_filter['stack_name'] = stack_settings.name
+    elif stack_name:
+        stack_filter['stack_name'] = stack_name
+
+    stacks = heat_cli.stacks.list(**stack_filter)
     for stack in stacks:
         return Stack(name=stack.identifier, stack_id=stack.id)
 
-    return None
-
 
 def get_stack_by_id(heat_cli, stack_id):
     """
index dda1111..90cc934 100644 (file)
@@ -34,7 +34,7 @@ logger = logging.getLogger('nova_utils_tests')
 
 class HeatSmokeTests(OSComponentTestCase):
     """
-    Tests to ensure that the nova client can communicate with the cloud
+    Tests to ensure that the heat client can communicate with the cloud
     """
 
     def test_nova_connect_success(self):
@@ -69,16 +69,16 @@ class HeatSmokeTests(OSComponentTestCase):
 
 class HeatUtilsCreateStackTests(OSComponentTestCase):
     """
-    Test basic nova keypair functionality
+    Test basic Heat functionality
     """
 
     def setUp(self):
         """
-        Instantiates the CreateImage object that is responsible for downloading
-        and creating an OS image file within OpenStack
+        Instantiates OpenStack instances that cannot be spawned by Heat
         """
         guid = self.__class__.__name__ + '-' + str(uuid.uuid4())
-        stack_name = self.__class__.__name__ + '-' + str(guid) + '-stack'
+        stack_name1 = self.__class__.__name__ + '-' + str(guid) + '-stack1'
+        stack_name2 = self.__class__.__name__ + '-' + str(guid) + '-stack2'
 
         self.image_creator = OpenStackImage(
             self.os_creds, openstack_tests.cirros_image_settings(
@@ -96,19 +96,29 @@ class HeatUtilsCreateStackTests(OSComponentTestCase):
                       'flavor_name': self.flavor_creator.flavor_settings.name}
         heat_tmplt_path = pkg_resources.resource_filename(
             'snaps.openstack.tests.heat', 'test_heat_template.yaml')
-        self.stack_settings = StackSettings(
-            name=stack_name, template_path=heat_tmplt_path,
+        self.stack_settings1 = StackSettings(
+            name=stack_name1, template_path=heat_tmplt_path,
             env_values=env_values)
-        self.stack = None
+        self.stack_settings2 = StackSettings(
+            name=stack_name2, template_path=heat_tmplt_path,
+            env_values=env_values)
+        self.stack1 = None
+        self.stack2 = None
         self.heat_client = heat_utils.heat_client(self.os_creds)
 
     def tearDown(self):
         """
         Cleans the image and downloaded image file
         """
-        if self.stack:
+        if self.stack1:
             try:
-                heat_utils.delete_stack(self.heat_client, self.stack)
+                heat_utils.delete_stack(self.heat_client, self.stack1)
+            except:
+                pass
+
+        if self.stack2:
+            try:
+                heat_utils.delete_stack(self.heat_client, self.stack2)
             except:
                 pass
 
@@ -125,21 +135,104 @@ class HeatUtilsCreateStackTests(OSComponentTestCase):
                 pass
 
     def test_create_stack(self):
+        """
+        Tests the creation of an OpenStack Heat stack1 that does not exist.
+        """
+        self.stack1 = heat_utils.create_stack(self.heat_client,
+                                              self.stack_settings1)
+
+        stack_query_1 = heat_utils.get_stack(
+            self.heat_client, stack_settings=self.stack_settings1)
+        self.assertEqual(self.stack1, stack_query_1)
+
+        stack_query_2 = heat_utils.get_stack(
+            self.heat_client, stack_name=self.stack_settings1.name)
+        self.assertEqual(self.stack1, stack_query_2)
+
+        stack_query_3 = heat_utils.get_stack_by_id(self.heat_client,
+                                                   self.stack1.id)
+        self.assertEqual(self.stack1, stack_query_3)
+
+        outputs = heat_utils.get_stack_outputs(
+            self.heat_client, self.stack1.id)
+        self.assertIsNotNone(outputs)
+        self.assertEqual(0, len(outputs))
+
+        end_time = time.time() + create_stack.STACK_COMPLETE_TIMEOUT
+
+        is_active = False
+        while time.time() < end_time:
+            status = heat_utils.get_stack_status(self.heat_client,
+                                                 self.stack1.id)
+            if status == create_stack.STATUS_CREATE_COMPLETE:
+                is_active = True
+                break
+            elif status == create_stack.STATUS_CREATE_FAILED:
+                is_active = False
+                break
+
+            time.sleep(3)
+
+        self.assertTrue(is_active)
+
+    def test_create_stack_x2(self):
         """
         Tests the creation of an OpenStack keypair that does not exist.
         """
-        self.stack = heat_utils.create_stack(self.heat_client,
-                                             self.stack_settings)
+        self.stack1 = heat_utils.create_stack(self.heat_client,
+                                              self.stack_settings1)
+
+        stack1_query_1 = heat_utils.get_stack(
+            self.heat_client, stack_settings=self.stack_settings1)
+        self.assertEqual(self.stack1, stack1_query_1)
+
+        stack1_query_2 = heat_utils.get_stack(
+            self.heat_client, stack_name=self.stack_settings1.name)
+        self.assertEqual(self.stack1, stack1_query_2)
+
+        stack1_query_3 = heat_utils.get_stack_by_id(self.heat_client,
+                                                    self.stack1.id)
+        self.assertEqual(self.stack1, stack1_query_3)
+
+        outputs = heat_utils.get_stack_outputs(self.heat_client,
+                                               self.stack1.id)
+        self.assertIsNotNone(outputs)
+        self.assertEqual(0, len(outputs))
+
+        end_time = time.time() + create_stack.STACK_COMPLETE_TIMEOUT
+
+        is_active = False
+        while time.time() < end_time:
+            status = heat_utils.get_stack_status(self.heat_client,
+                                                 self.stack1.id)
+            if status == create_stack.STATUS_CREATE_COMPLETE:
+                is_active = True
+                break
+            elif status == create_stack.STATUS_CREATE_FAILED:
+                is_active = False
+                break
+
+            time.sleep(3)
+
+        self.assertTrue(is_active)
+
+        self.stack2 = heat_utils.create_stack(self.heat_client,
+                                              self.stack_settings2)
+
+        stack2_query_1 = heat_utils.get_stack(
+            self.heat_client, stack_settings=self.stack_settings2)
+        self.assertEqual(self.stack2, stack2_query_1)
 
-        stack_query_1 = heat_utils.get_stack_by_name(self.heat_client,
-                                                     self.stack_settings.name)
-        self.assertEqual(self.stack.id, stack_query_1.id)
+        stack2_query_2 = heat_utils.get_stack(
+            self.heat_client, stack_name=self.stack_settings2.name)
+        self.assertEqual(self.stack2, stack2_query_2)
 
-        stack_query_2 = heat_utils.get_stack_by_id(self.heat_client,
-                                                   self.stack.id)
-        self.assertEqual(self.stack.id, stack_query_2.id)
+        stack2_query_3 = heat_utils.get_stack_by_id(self.heat_client,
+                                                    self.stack2.id)
+        self.assertEqual(self.stack2, stack2_query_3)
 
-        outputs = heat_utils.get_stack_outputs(self.heat_client, self.stack.id)
+        outputs = heat_utils.get_stack_outputs(self.heat_client,
+                                               self.stack2.id)
         self.assertIsNotNone(outputs)
         self.assertEqual(0, len(outputs))
 
@@ -148,7 +241,7 @@ class HeatUtilsCreateStackTests(OSComponentTestCase):
         is_active = False
         while time.time() < end_time:
             status = heat_utils.get_stack_status(self.heat_client,
-                                                 self.stack.id)
+                                                 self.stack2.id)
             if status == create_stack.STATUS_CREATE_COMPLETE:
                 is_active = True
                 break