Add some UT test cases and fix pep8 errors for spawn_vm 31/16731/2
authorzhifeng.jiang <jiang.zhifeng@zte.com.cn>
Tue, 12 Jul 2016 09:06:58 +0000 (17:06 +0800)
committerzhifeng.jiang <jiang.zhifeng@zte.com.cn>
Tue, 12 Jul 2016 09:20:53 +0000 (17:20 +0800)
JIRA:QTIP-89

Change-Id: I2555a0a7a8ffaf6d19cfad88770cd8e378d154b2
Signed-off-by: zhifeng.jiang <jiang.zhifeng@zte.com.cn>
func/spawn_vm.py
tests/spawn_vm_test.py [new file with mode: 0644]

index 94aa424..ec63230 100644 (file)
-##############################################################################
-# Copyright (c) 2015 Dell Inc  and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-import os
-import sys
-from collections import defaultdict
-from func.env_setup import Env_setup
-from func.fetchimg import FetchImg
-import yaml
-import heatclient.client
-import keystoneclient
-import glanceclient
-from novaclient import client
-import time
-import json
-from func.create_zones import create_zones
-
-class SpawnVM(Env_setup):
-    vm_role_ip_dict = defaultdict(list)
-    installer = ''
-
-    def __init__(self, vm_info):
-        print 'SpawnVM Class initiated'
-        vm_role_ip_dict = vm_info.copy()
-        print 'Generating Heat Template\n'
-        self._keystone_client = None
-        self._heat_client = None
-        self._glance_client = None
-        self._nova_client = None
-        nova =self. _get_nova_client()
-        azoneobj = create_zones()
-        azoneobj.create_agg(vm_info['availability_zone'])
-        installer= self.get_installer_type()
-        self.Heat_template1 = self.HeatTemplate_vm(vm_info,installer)
-        self.create_stack(vm_role_ip_dict, self.Heat_template1)
-
-    def get_installer_type(self):
-        print 'Getting Installer Name'
-        return os.environ['INSTALLER_TYPE']
-
-    def get_public_network(self,installer_detected):
-
-        '''
-        TODO: GET THE NAMES OF THE PUBLIC NETWORKS for OTHER PROJECTS
-        '''
-        print 'Getting Public Network'
-        if installer_detected.lower() == 'fuel':
-            return 'admin_floating_net'
-        if installer_detected.lower() == 'apex':
-            return 'external'
-        if installer_detected.lower() == 'compass':
-            return 'ext-net'
-        if installer_detected.lower() == 'joid':
-            return 'ext-net'
-
-    def HeatTemplate_vm(self, vm_params, installer):
-        try:
-            Heat_Dic=''
-            with open('./heat/SampleHeat.yaml', 'r+') as H_temp:
-                Heat_Dic = yaml.load(H_temp)
-        except yaml.YAMLError as exc:
-            if hasattr(exc, 'problem_mark'):
-                mark = exc.problem_mark
-                print 'Error in qtip/heat/SampleHeat.yaml at: (%s,%s)' % (mark.line + 1, mark.column + 1)
-                print 'EXITING PROGRAM. Correct File and restart'
-                sys.exit(0)
-        fopen = open('./data/QtipKey.pub', 'r')
-        fopenstr = fopen.read()
-        fopenstr = fopenstr.rstrip()
-        scriptcmd = '#!/bin/bash \n echo {0} >>  foo.txt \n echo {1} >> /root/.ssh/authorized_keys'.format(
-            fopenstr, fopenstr)
-
-        netName = self.get_public_network(installer)
-        print netName
-        Heat_Dic['heat_template_version'] = '2014-10-16'
-        Heat_Dic['resources']['KeyPairSavePrivate'] = {
-            'type': 'OS::Nova::KeyPair',
-            'properties': {
-                    'save_private_key': 'true',
-                    'name': 'my_key'
-            }
-        }
-        Heat_Dic['parameters']['public_network'] = {
-            'type': 'string',
-            #'default': vm_params['public_network'][0]
-            'default': netName
-        }
-        for x in range(1, len(vm_params['availability_zone']) + 1):
-            avail_zone = vm_params['availability_zone'][x - 1]
-            img = vm_params['OS_image'][x - 1]
-            flavor = vm_params['flavor'][x - 1]
-
-            Heat_Dic['parameters']['availability_zone_' +str(x)] = {
-                 'description': 'Availability Zone of the instance',
-                 'default': avail_zone,
-                 'type': 'string'
-
-                 }
-
-            Heat_Dic['resources']['public_port_' +str(x)] = {
-                    'type': 'OS::Neutron::Port',
-                    'properties': {
-                        'network': {'get_resource': 'private_network'},
-                        'security_groups': [{ 'get_resource': 'demo1_security_Group'}],
-                        'fixed_ips': [
-                            {'subnet_id': {'get_resource': 'private_subnet'}}]}}
-
-            Heat_Dic['resources']['floating_ip_' + str(x)] = {
-                'type': 'OS::Neutron::FloatingIP',
-                'properties': {
-                    'floating_network': {'get_param': 'public_network'}}}
-
-            Heat_Dic['resources']['floating_ip_assoc_' + str(x)] = {
-                'type': 'OS::Neutron::FloatingIPAssociation',
-                'properties': {
-                    'floatingip_id': {'get_resource': 'floating_ip_' + str(x)},
-                    'port_id': {'get_resource': 'public_port_' + str(x)}}}
-
-            Heat_Dic['resources']['my_instance_' + str(x)] = {
-                'type': 'OS::Nova::Server',
-                'properties': {
-                    'image': img,
-                    'networks':[
-                    {'port': {'get_resource': 'public_port_' + str(x)}}],
-                    'flavor': flavor,
-                    'availability_zone': avail_zone,
-                    'name': 'instance' + str(x),
-                    'key_name': {'get_resource': 'KeyPairSavePrivate'},
-                    'user_data_format': 'RAW',
-                    'user_data': scriptcmd}}
-
-            Heat_Dic['resources']['demo1_security_Group'] = {
-                'type': 'OS::Neutron::SecurityGroup',
-                'properties': {
-                    'name': 'demo1_security_Group',
-                    'rules': [{
-                        'protocol': 'tcp',
-                        'port_range_min': 22,
-                        'port_range_max': 5201},
-                        {'protocol': 'udp',
-                        'port_range_min': 22,
-                        'port_range_max': 5201},
-                        {'protocol': 'icmp'}]}}
-
-            Heat_Dic['outputs']['instance_PIP_' +str(x)] = {
-                'description': 'IP address of the instance',
-                'value': {'get_attr': ['my_instance_' + str(x), 'first_address']}}
-            Heat_Dic['outputs']['instance_ip_' +str(x)] = {
-                'description': 'IP address of the instance',
-                'value': {'get_attr': ['floating_ip_' + str(x), 'floating_ip_address']}}
-
-            Heat_Dic['outputs']['availability_instance_' + str(x)] = {
-                'description': 'Availability Zone of the Instance',
-                'value': { 'get_param': 'availability_zone_'+str(x)}}
-
-
-        Heat_Dic['outputs']['KeyPair_PublicKey'] = {
-            'description': 'Private Key',
-            'value': {'get_attr': ['KeyPairSavePrivate', 'private_key']}
-        }
-        del Heat_Dic['outputs']['description']
-        return Heat_Dic
-
-    def _get_keystone_client(self):
-        '''returns a keystone client instance'''
-
-        if self._keystone_client is None:
-            self._keystone_client = keystoneclient.v2_0.client.Client(
-                auth_url=os.environ.get('OS_AUTH_URL'),
-                username=os.environ.get('OS_USERNAME'),
-                password=os.environ.get('OS_PASSWORD'),
-                tenant_name=os.environ.get('OS_TENANT_NAME'))
-        return self._keystone_client
-
-    def _get_nova_client(self):
-        if self._nova_client is None:
-            keystone = self._get_keystone_client()
-            self._nova_client = client.Client('2', token=keystone.auth_token)
-        return self._nova_client
-
-    def _get_heat_client(self):
-        '''returns a heat client instance'''
-        if self._heat_client is None:
-            keystone = self._get_keystone_client()
-            heat_endpoint = keystone.service_catalog.url_for(
-                service_type='orchestration')
-            self._heat_client = heatclient.client.Client(
-                '1', endpoint=heat_endpoint, token=keystone.auth_token)
-        return self._heat_client
-
-    def _get_glance_client(self):
-        if self._glance_client is None:
-            keystone = self._get_keystone_client()
-            glance_endpoint = keystone.service_catalog.url_for(
-                service_type='image')
-            self._glance_client = glanceclient.Client(
-                '2', glance_endpoint, token=keystone.auth_token)
-        return self._glance_client
-
-    def create_stack(self, vm_role_ip_dict, Heat_template):
-
-        stackname = 'QTIP'
-        heat = self._get_heat_client()
-        glance = self._get_glance_client()
-
-        available_images = []
-        for image_list in glance.images.list():
-
-            available_images.append(image_list.name)
-
-        if 'QTIP_CentOS' in available_images:
-            print 'Image Present'
-
-        elif 'QTIP_CentOS' not in available_images:
-            fetchImage = FetchImg()
-            fetchImage.download()
-            print 'Uploading Image to Glance. Please wait'
-            qtip_image = glance.images.create(
-                name='QTIP_CentOS',
-                visibility='public',
-                disk_format='qcow2',
-                container_format='bare')
-            qtip_image = glance.images.upload(
-                qtip_image.id, open('./Temp_Img/QTIP_CentOS.qcow2'))
-        json_temp = json.dumps(Heat_template)
-
-        for checks in range(3):
-            for prev_stacks in heat.stacks.list():
-
-                if prev_stacks.stack_name == 'QTIP':
-                    print 'QTIP Stacks exists.\nDeleting Existing Stack'
-                    heat.stacks.delete('QTIP')
-                    time.sleep(10)
-
-        print '\nStack Creating Started\n'
-
-        try:
-            heat.stacks.create(stack_name=stackname, template=Heat_template)
-        except:
-            print 'Create Failed :( '
-
-        cluster_detail = heat.stacks.get(stackname)
-        while(cluster_detail.status != 'COMPLETE'):
-            if cluster_detail.status == 'IN_PROGRESS':
-                print 'Stack Creation in Progress'
-            cluster_detail = heat.stacks.get(stackname)
-            time.sleep(10)
-        print 'Stack Created'
-        print 'Getting Public IP(s)'
-        zone = []
-        s=0
-        for vm in range(len(vm_role_ip_dict['OS_image'])):
-
-            for I in cluster_detail.outputs:
-                availabilityKey = 'availability_instance_'+str(vm+1)
-
-                if I['output_key'] == availabilityKey:
-                    zone.insert(s,str(I['output_value']))
-                    s=s+1
-            for i in cluster_detail.outputs:
-                instanceKey = "instance_ip_" + str(vm + 1)
-                privateIPkey = 'instance_PIP_' + str(vm +1)
-                if i['output_key'] == instanceKey:
-                    Env_setup.roles_dict[vm_role_ip_dict['role'][vm]].append(
-                                                        str(i['output_value']))
-                    Env_setup.ip_pw_list.append((str(i['output_value']),''))
-
-                if i['output_key'] == privateIPkey:
-                    Env_setup.ip_pw_dict[vm_role_ip_dict['role'][vm]]=str(i['output_value'])
-                if i['output_key'] == 'KeyPair_PublicKey':
-                    sshkey = str(i['output_value'])
-
-        with open('./data/my_key.pem', 'w') as fopen:
-            fopen.write(sshkey)
-        fopen.close()
-        print Env_setup.ip_pw_list
+##############################################################################\r
+# Copyright (c) 2015 Dell Inc  and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+import os\r
+import sys\r
+from collections import defaultdict\r
+from func.env_setup import Env_setup\r
+from func.fetchimg import FetchImg\r
+import yaml\r
+import heatclient.client\r
+import keystoneclient\r
+import glanceclient\r
+from novaclient import client\r
+import time\r
+from func.create_zones import create_zones\r
+\r
+\r
+class SpawnVM(Env_setup):\r
+    vm_role_ip_dict = defaultdict(list)\r
+    installer = ''\r
+\r
+    def __init__(self, vm_info):\r
+        Env_setup.__init__(self)\r
+        print 'SpawnVM Class initiated'\r
+        vm_role_ip_dict = vm_info.copy()\r
+        print 'Generating Heat Template\n'\r
+        self._keystone_client = None\r
+        self._heat_client = None\r
+        self._glance_client = None\r
+        self._nova_client = None\r
+        self. _get_nova_client()\r
+        azoneobj = create_zones()\r
+        azoneobj.create_agg(vm_info['availability_zone'])\r
+        installer = self.get_installer_type()\r
+        self.Heat_template1 = self.heat_template_vm(vm_info, installer)\r
+        self.create_stack(vm_role_ip_dict, self.Heat_template1)\r
+\r
+    @staticmethod\r
+    def get_installer_type():\r
+        print 'Getting Installer Name'\r
+        return os.environ['INSTALLER_TYPE']\r
+\r
+    @staticmethod\r
+    def get_public_network(installer_detected):\r
+\r
+        """\r
+        TODO: GET THE NAMES OF THE PUBLIC NETWORKS for OTHER PROJECTS\r
+        """\r
+        print 'Getting Public Network'\r
+        if installer_detected.lower() == 'fuel':\r
+            return 'admin_floating_net'\r
+        if installer_detected.lower() == 'apex':\r
+            return 'external'\r
+        if installer_detected.lower() == 'compass':\r
+            return 'ext-net'\r
+        if installer_detected.lower() == 'joid':\r
+            return 'ext-net'\r
+\r
+    def heat_template_vm(self, vm_params, installer):\r
+        Heat_Dic = {}\r
+        try:\r
+            with open('./heat/SampleHeat.yaml', 'r+') as H_temp:\r
+                Heat_Dic = yaml.load(H_temp)\r
+        except yaml.YAMLError as exc:\r
+            if hasattr(exc, 'problem_mark'):\r
+                mark = exc.problem_mark\r
+                print 'Error in qtip/heat/SampleHeat.yaml at: (%s,%s)' % (mark.line + 1, mark.column + 1)\r
+                print 'EXITING PROGRAM. Correct File and restart'\r
+                sys.exit(0)\r
+        fopen = open('./data/QtipKey.pub', 'r')\r
+        fopenstr = fopen.read()\r
+        fopenstr = fopenstr.rstrip()\r
+        scriptcmd = '#!/bin/bash \n echo {0} >>  foo.txt \n echo {1} >> /root/.ssh/authorized_keys'.format(\r
+            fopenstr, fopenstr)\r
+\r
+        netName = self.get_public_network(installer)\r
+        print netName\r
+        Heat_Dic['heat_template_version'] = '2014-10-16'\r
+        Heat_Dic['resources']['KeyPairSavePrivate'] = {\r
+            'type': 'OS::Nova::KeyPair',\r
+            'properties': {\r
+                    'save_private_key': 'true',\r
+                    'name': 'my_key'\r
+            }\r
+        }\r
+        Heat_Dic['parameters']['public_network'] = {\r
+            'type': 'string',\r
+            'default': netName\r
+        }\r
+        for x in range(1, len(vm_params['availability_zone']) + 1):\r
+            avail_zone = vm_params['availability_zone'][x - 1]\r
+            img = vm_params['OS_image'][x - 1]\r
+            flavor = vm_params['flavor'][x - 1]\r
+\r
+            Heat_Dic['parameters']['availability_zone_' + str(x)] = \\r
+                {'description': 'Availability Zone of the instance',\r
+                 'default': avail_zone,\r
+                 'type': 'string'}\r
+\r
+            Heat_Dic['resources']['public_port_' + str(x)] = \\r
+                {'type': 'OS::Neutron::Port',\r
+                 'properties': {'network': {'get_resource': 'private_network'},\r
+                                'security_groups': [{'get_resource': 'demo1_security_Group'}],\r
+                                'fixed_ips': [{'subnet_id':\r
+                                               {'get_resource': 'private_subnet'}}]}}\r
+\r
+            Heat_Dic['resources']['floating_ip_' + str(x)] = {\r
+                'type': 'OS::Neutron::FloatingIP',\r
+                'properties': {\r
+                    'floating_network': {'get_param': 'public_network'}}}\r
+\r
+            Heat_Dic['resources']['floating_ip_assoc_' + str(x)] = {\r
+                'type': 'OS::Neutron::FloatingIPAssociation',\r
+                'properties': {\r
+                    'floatingip_id': {'get_resource': 'floating_ip_' + str(x)},\r
+                    'port_id': {'get_resource': 'public_port_' + str(x)}}}\r
+\r
+            Heat_Dic['resources']['my_instance_' + str(x)] = \\r
+                {'type': 'OS::Nova::Server',\r
+                 'properties': {'image': img,\r
+                                'networks':\r
+                                    [{'port': {'get_resource': 'public_port_' + str(x)}}],\r
+                                'flavor': flavor,\r
+                                'availability_zone': avail_zone,\r
+                                'name': 'instance' + str(x),\r
+                                'key_name': {'get_resource': 'KeyPairSavePrivate'},\r
+                                'user_data_format': 'RAW',\r
+                                'user_data': scriptcmd}}\r
+\r
+            Heat_Dic['resources']['demo1_security_Group'] = {\r
+                'type': 'OS::Neutron::SecurityGroup',\r
+                'properties': {\r
+                    'name': 'demo1_security_Group',\r
+                    'rules': [{\r
+                        'protocol': 'tcp',\r
+                        'port_range_min': 22,\r
+                        'port_range_max': 5201},\r
+                        {'protocol': 'udp',\r
+                         'port_range_min': 22,\r
+                         'port_range_max': 5201},\r
+                        {'protocol': 'icmp'}]}}\r
+\r
+            Heat_Dic['outputs']['instance_PIP_' + str(x)] = {\r
+                'description': 'IP address of the instance',\r
+                'value': {'get_attr': ['my_instance_' + str(x), 'first_address']}}\r
+            Heat_Dic['outputs']['instance_ip_' + str(x)] = {\r
+                'description': 'IP address of the instance',\r
+                'value': {'get_attr': ['floating_ip_' + str(x), 'floating_ip_address']}}\r
+\r
+            Heat_Dic['outputs']['availability_instance_' + str(x)] = {\r
+                'description': 'Availability Zone of the Instance',\r
+                'value': {'get_param': 'availability_zone_' + str(x)}}\r
+\r
+        Heat_Dic['outputs']['KeyPair_PublicKey'] = {\r
+            'description': 'Private Key',\r
+            'value': {'get_attr': ['KeyPairSavePrivate', 'private_key']}\r
+        }\r
+        del Heat_Dic['outputs']['description']\r
+        print Heat_Dic\r
+        return Heat_Dic\r
+\r
+    def _get_keystone_client(self):\r
+        """returns a keystone client instance"""\r
+\r
+        if self._keystone_client is None:\r
+            self._keystone_client = keystoneclient.v2_0.client.Client(\r
+                auth_url=os.environ.get('OS_AUTH_URL'),\r
+                username=os.environ.get('OS_USERNAME'),\r
+                password=os.environ.get('OS_PASSWORD'),\r
+                tenant_name=os.environ.get('OS_TENANT_NAME'))\r
+        return self._keystone_client\r
+\r
+    def _get_nova_client(self):\r
+        if self._nova_client is None:\r
+            keystone = self._get_keystone_client()\r
+            self._nova_client = client.Client('2', token=keystone.auth_token)\r
+        return self._nova_client\r
+\r
+    def _get_heat_client(self):\r
+        """returns a heat client instance"""\r
+        if self._heat_client is None:\r
+            keystone = self._get_keystone_client()\r
+            heat_endpoint = keystone.service_catalog.url_for(\r
+                service_type='orchestration')\r
+            self._heat_client = heatclient.client.Client(\r
+                '1', endpoint=heat_endpoint, token=keystone.auth_token)\r
+        return self._heat_client\r
+\r
+    def _get_glance_client(self):\r
+        if self._glance_client is None:\r
+            keystone = self._get_keystone_client()\r
+            glance_endpoint = keystone.service_catalog.url_for(\r
+                service_type='image')\r
+            self._glance_client = glanceclient.Client(\r
+                '2', glance_endpoint, token=keystone.auth_token)\r
+        return self._glance_client\r
+\r
+    def create_stack(self, vm_role_ip_dict, heat_template):\r
+\r
+        global sshkey\r
+        stackname = 'QTIP'\r
+        heat = self._get_heat_client()\r
+        glance = self._get_glance_client()\r
+\r
+        available_images = []\r
+        for image_list in glance.images.list():\r
+\r
+            available_images.append(image_list.name)\r
+\r
+        if 'QTIP_CentOS' in available_images:\r
+            print 'Image Present'\r
+\r
+        elif 'QTIP_CentOS' not in available_images:\r
+            fetchImage = FetchImg()\r
+            fetchImage.download()\r
+            print 'Uploading Image to Glance. Please wait'\r
+            qtip_image = glance.images.create(\r
+                name='QTIP_CentOS',\r
+                visibility='public',\r
+                disk_format='qcow2',\r
+                container_format='bare')\r
+            glance.images.upload(\r
+                qtip_image.id, open('./Temp_Img/QTIP_CentOS.qcow2'))\r
+        for checks in range(3):\r
+            print "Try to delete heats %s" % checks\r
+            for prev_stacks in heat.stacks.list():\r
+                if prev_stacks.stack_name == 'QTIP':\r
+                    print 'QTIP Stacks exists.\nDeleting Existing Stack'\r
+                    heat.stacks.delete('QTIP')\r
+                    time.sleep(10)\r
+\r
+        print '\nStack Creating Started\n'\r
+\r
+        try:\r
+            heat.stacks.create(stack_name=stackname, template=heat_template)\r
+        except Exception:\r
+            print 'Create Failed :( '\r
+\r
+        cluster_detail = heat.stacks.get(stackname)\r
+        while cluster_detail.status != 'COMPLETE':\r
+            if cluster_detail.status == 'IN_PROGRESS':\r
+                print 'Stack Creation in Progress'\r
+            cluster_detail = heat.stacks.get(stackname)\r
+            time.sleep(10)\r
+        print 'Stack Created'\r
+        print 'Getting Public IP(s)'\r
+        zone = []\r
+        s = 0\r
+        for vm in range(len(vm_role_ip_dict['OS_image'])):\r
+\r
+            for I in cluster_detail.outputs:\r
+                availabilityKey = 'availability_instance_' + str(vm + 1)\r
+\r
+                if I['output_key'] == availabilityKey:\r
+                    zone.insert(s, str(I['output_value']))\r
+                    s = s + 1\r
+            for i in cluster_detail.outputs:\r
+                instanceKey = "instance_ip_" + str(vm + 1)\r
+                privateIPkey = 'instance_PIP_' + str(vm + 1)\r
+                if i['output_key'] == instanceKey:\r
+                    Env_setup.roles_dict[vm_role_ip_dict['role'][vm]] \\r
+                        .append(str(i['output_value']))\r
+                    Env_setup.ip_pw_list.append((str(i['output_value']), ''))\r
+\r
+                if i['output_key'] == privateIPkey:\r
+                    Env_setup.ip_pw_dict[vm_role_ip_dict['role'][vm]] = str(i['output_value'])\r
+                if i['output_key'] == 'KeyPair_PublicKey':\r
+                    sshkey = str(i['output_value'])\r
+\r
+        with open('./data/my_key.pem', 'w') as fopen:\r
+            fopen.write(sshkey)\r
+        fopen.close()\r
+        print Env_setup.ip_pw_list\r
diff --git a/tests/spawn_vm_test.py b/tests/spawn_vm_test.py
new file mode 100644 (file)
index 0000000..eb843ad
--- /dev/null
@@ -0,0 +1,71 @@
+import pytest
+import mock
+from mock import Mock, MagicMock
+import os
+from func.spawn_vm import SpawnVM
+
+
+class KeystoneMock(MagicMock):
+    auth_token = Mock()
+    v2_0 = Mock()
+
+
+class ImageMock(MagicMock):
+    name = 'QTIP_CentOS'
+
+
+class ImagesMock(MagicMock):
+    def list(self):
+        return [ImageMock()]
+
+
+class StackMock(MagicMock):
+    status = 'COMPLETE'
+    outputs = [{'output_key': 'availability_instance_1',
+                'output_value': 'output_value_1'},
+               {'output_key': 'instance_ip_1',
+                "output_value": "172.10.0.154"},
+               {"output_key": "instance_PIP_1",
+                "output_value": "10.10.17.5"},
+               {'output_key': 'KeyPair_PublicKey',
+                "output_value": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpwIBAAKCAQEAqCiHcrLBXtxG0LhnKndU7VIVpYxORmv0d4tvujkWOkYuagiW\nU/MTRk0zhRvFQDVPEs0Jrj/BIecqm6fjjT6dZ/H7JLYGaqJitRkoupKgBsMSIqUz\nrR0ekOlfXZ6N+Ud8k6s+qjc7BO4b1ezz78jHisC5o0GCkUV0ECx64Re1fO+oKs1c\nfL9aaexahJUYN3J48pazQz+imc2x/G9nuqHX3cqEszmxnT4jwv//In1GjHy2AyXw\n1oA5F6wZoQCSrXc2BditU+1tlVhEkPFt5JgiHUpY8T8mYbroT7JH6xjcGSKUN+HG\nN8PXNUTD1VAQfwHpkfsGMfDyzjytCXsoTEOqnwIDAQABAoIBAAEL/4vfQQTuKiKy\ngzHofEbd8/SL4xDdKzBzVca7BEBon3FZjFYJdV1CrcduXNQBgPSFAkJrczBa2BEQ\nAoKmmSREhWO9Hl0blbG67l36+7QPEtXUYXX6cG5Ghal3izq6DzR8JG+62Es3kETM\nrNgZT+S1PnKdvcpZvFc9b6ZnF2InuTbrmNVBZKrhdWOJ5tCwRGKKUl6BHoJH3yu0\nT5hUW277e1LYHx+hZtoZ98ToC+LGe6/M8a8y6VLYpcQlX2AtVXeGDalomunF+p3f\nuY6din6s4lq1gSJz03PTpUbwiuhYCTe8Xkseu74Y+XYYJXPHopFju0Ewd6p0Db9Q\nJzzxCoECggCBAM2ox9zyrDc/Vlc0bb9SciFGUd/nEJF89+UHy98bAkpo22zNZIDg\nfacSgkg/6faZD+KrOU0I5W7m2B5t6w2fNHHik6NYGSLQ1JhgbXELGV7X/qECDL02\nctPaf+8o+dYoZja2LdJNASq2nmEmPI3LSHhzAt4dWY4W+geXiHt4iWVHAoIAgQDR\nUdN09xv4U+stWqNcSfgjtx6boEUE8Ky7pyj+LrZKG0L61Jy9cSDP0x0rCtkW9vVR\n6RjidWM/DHQ5cl6aq+7pPy20/OqtqttFYT4R+C3AoAnRSaNzPD9a80C2gjv7WEz0\nPPFstWkI1gsN71KKRx7e6NIa9CNn5x9iE+SGfjgb6QKCAIBXylzG7LCnRNpOj4rp\nyP//RE1fDvv7nyUTF6jnrFfl+6zvXR4yBaKd10DWJrJxGhW15PGo+Ms39EL9el6E\nihmRI+9yIwFX411dToxpXRuPaRTBFmbpvnx2Ayfpp8w+pzA62rnktApzeVFSl0fy\nH3zoLfBjcJPyG8zPwNf6HRJJsQKCAIAE2S5asTaWo+r4m/bYtmXm/eDZnfa7TI/T\nsOWELbTPNp5wjOgsgyhNaAhu7MtmesXn5cxLwohP94vhoMKMNptMD8iRPqJ471Iw\n4zW62NLGeW6AyIHes3CMPMIs+AtHoR33MkotSG5sY/jRk8+HoGoYo6/qK+l+CJ5z\neR579wR5sQKCAIAvPWq+bvcPTDKUU1Fe/Y/GyWoUA+uSqmCdORBkK38lALFGphxj\nfDz9dXskimqW+A9hOPOS8dm8YcVvi/TLXVE5Vsx9VkOg6z6AZBQpgNXGfOgpju4W\nbjER7bQaASatuWQyCxbA9oNlAUdSeOhGTxeFLkLj7hNMd6tLjfd8w7A/hA==\n-----END RSA PRIVATE KEY-----\n"}]
+
+
+class HeatMock(MagicMock):
+    def list(self):
+        return []
+
+    def get(self, stackname):
+        return StackMock()
+
+    def create(self, stack_name, template):
+        pass
+
+
+class TestClass:
+    @pytest.mark.parametrize("test_input, expected", [
+        ({'availability_zone': ['compute1', 'compute1'],
+          'OS_image': ['QTIP_CentOS', 'QTIP_CentOS'],
+          'public_network': ['admin-floating_net', 'admin-floating_net'],
+          'flavor': ['m1.large', 'm1.large'],
+          'role': ['1-server', '2-host']},
+         [('172.10.0.154', '')]),
+    ])
+    @mock.patch('func.spawn_vm.Env_setup')
+    @mock.patch('func.spawn_vm.FetchImg')
+    @mock.patch('func.spawn_vm.create_zones')
+    @mock.patch('func.spawn_vm.client', autospec=True)
+    @mock.patch('func.spawn_vm.glanceclient', autospec=True)
+    @mock.patch('func.spawn_vm.keystoneclient.v2_0', autospec=True)
+    @mock.patch('func.spawn_vm.heatclient.client', autospec=True)
+    def test_create_zones_success(self, mock_heat, mock_keystone, mock_glance,
+                                  mock_nova_client, mock_zone, mock_fetch,
+                                  mock_setup, test_input, expected):
+        mock_glance.Client.return_value = Mock(images=ImagesMock())
+        mock_nova_client.Client.return_value = Mock()
+        mock_heat.Client.return_value = Mock(stacks=HeatMock())
+        k = mock.patch.dict(os.environ, {'INSTALLER_TYPE': 'fuel'})
+        k.start()
+        SpawnVM(test_input)
+        k.stop()
+        mock_setup.ip_pw_list.append.assert_called_with(expected[0])