blob: 4e17c3daa2e7520f7a8ecea3a7471dcd8e70ab42 [file] [log] [blame]
Steve Bakerd2525a92013-05-06 15:29:03 +12001# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
Sean Daguee0a65d12014-03-25 15:59:16 -040013import os.path
Matthew Treinish96e9e882014-06-09 18:37:19 -040014
Ghanshyam961ea1a2014-06-09 10:56:00 +090015import yaml
Sean Daguee0a65d12014-03-25 15:59:16 -040016
Matthew Treinishcb09bbb2014-01-29 18:20:25 +000017from tempest import config
Ken'ichi Ohmichi60680a82017-03-10 11:03:16 -080018from tempest.lib.common.utils import data_utils
Jordan Pittier9e227c52016-02-09 14:35:18 +010019from tempest.lib.common.utils import test_utils
Steve Bakerd2525a92013-05-06 15:29:03 +120020import tempest.test
21
Matthew Treinishcb09bbb2014-01-29 18:20:25 +000022CONF = config.CONF
Steve Bakerd2525a92013-05-06 15:29:03 +120023
Steve Bakerd2525a92013-05-06 15:29:03 +120024
25class BaseOrchestrationTest(tempest.test.BaseTestCase):
26 """Base test case class for all Orchestration API tests."""
27
Andrea Frittolib21de6c2015-02-06 20:12:38 +000028 credentials = ['primary']
29
Steve Bakerd2525a92013-05-06 15:29:03 +120030 @classmethod
Rohan Kanade80b938a2015-02-07 10:58:56 +053031 def skip_checks(cls):
32 super(BaseOrchestrationTest, cls).skip_checks()
Matthew Treinishcb09bbb2014-01-29 18:20:25 +000033 if not CONF.service_available.heat:
Steve Bakerd2525a92013-05-06 15:29:03 +120034 raise cls.skipException("Heat support is required")
35
Rohan Kanade80b938a2015-02-07 10:58:56 +053036 @classmethod
Emilien Macchie7740ea2016-02-09 20:13:13 +000037 def setup_credentials(cls):
38 super(BaseOrchestrationTest, cls).setup_credentials()
39 stack_owner_role = CONF.orchestration.stack_owner_role
40 cls.os = cls.get_client_manager(roles=[stack_owner_role])
41
42 @classmethod
Rohan Kanade80b938a2015-02-07 10:58:56 +053043 def setup_clients(cls):
44 super(BaseOrchestrationTest, cls).setup_clients()
Sean Daguee0a65d12014-03-25 15:59:16 -040045 cls.orchestration_client = cls.os.orchestration_client
46 cls.client = cls.orchestration_client
47 cls.servers_client = cls.os.servers_client
48 cls.keypairs_client = cls.os.keypairs_client
John Warren94d8faf2015-09-15 12:22:24 -040049 cls.networks_client = cls.os.networks_client
50 cls.volumes_client = cls.os.volumes_client
huangtianhua01cba0a2014-04-30 16:18:03 +080051 cls.images_v2_client = cls.os.image_client_v2
Rohan Kanade80b938a2015-02-07 10:58:56 +053052
Rabi Mishrae42bfe42015-09-29 18:02:13 +053053 if CONF.volume_feature_enabled.api_v2:
54 cls.volumes_client = cls.os.volumes_v2_client
55 else:
56 cls.volumes_client = cls.os.volumes_client
57
Rohan Kanade80b938a2015-02-07 10:58:56 +053058 @classmethod
59 def resource_setup(cls):
60 super(BaseOrchestrationTest, cls).resource_setup()
61 cls.build_timeout = CONF.orchestration.build_timeout
62 cls.build_interval = CONF.orchestration.build_interval
Steve Bakerd2525a92013-05-06 15:29:03 +120063 cls.stacks = []
Steve Bakerb1f67b52013-06-24 14:42:30 +120064 cls.keypairs = []
huangtianhua01cba0a2014-04-30 16:18:03 +080065 cls.images = []
Steve Bakerd2525a92013-05-06 15:29:03 +120066
67 @classmethod
Ghanshyam2a180b82014-06-16 13:54:22 +090068 def create_stack(cls, stack_name, template_data, parameters=None,
Steven Hardy1b25fe02014-05-07 16:21:28 +010069 environment=None, files=None):
Ghanshyam2a180b82014-06-16 13:54:22 +090070 if parameters is None:
71 parameters = {}
David Kranz8ad924b2015-01-16 16:50:18 -050072 body = cls.client.create_stack(
Steve Bakerd2525a92013-05-06 15:29:03 +120073 stack_name,
74 template=template_data,
Steven Hardy00de7582014-05-07 15:18:52 +010075 parameters=parameters,
Steven Hardy1b25fe02014-05-07 16:21:28 +010076 environment=environment,
77 files=files)
David Kranz8ad924b2015-01-16 16:50:18 -050078 stack_id = body.response['location'].split('/')[-1]
Steve Bakerd2525a92013-05-06 15:29:03 +120079 stack_identifier = '%s/%s' % (stack_name, stack_id)
Steve Bakerb7942772013-06-27 10:23:28 +120080 cls.stacks.append(stack_identifier)
Steve Bakerd2525a92013-05-06 15:29:03 +120081 return stack_identifier
82
83 @classmethod
Steven Hardy5be93e82014-04-02 21:24:05 +010084 def _clear_stacks(cls):
Steve Bakerd2525a92013-05-06 15:29:03 +120085 for stack_identifier in cls.stacks:
Jordan Pittier9e227c52016-02-09 14:35:18 +010086 test_utils.call_and_ignore_notfound_exc(
87 cls.client.delete_stack, stack_identifier)
Steve Bakerd2525a92013-05-06 15:29:03 +120088
89 for stack_identifier in cls.stacks:
Jordan Pittier9e227c52016-02-09 14:35:18 +010090 test_utils.call_and_ignore_notfound_exc(
91 cls.client.wait_for_stack_status, stack_identifier,
92 'DELETE_COMPLETE')
Steve Bakerd2525a92013-05-06 15:29:03 +120093
Steve Bakerb7942772013-06-27 10:23:28 +120094 @classmethod
Bartosz Górskiab33b7e2013-06-27 00:39:47 -070095 def _create_keypair(cls, name_start='keypair-heat-'):
Masayuki Igawa259c1132013-10-31 17:48:44 +090096 kp_name = data_utils.rand_name(name_start)
ghanshyamdee01f22015-08-17 11:41:47 +090097 body = cls.keypairs_client.create_keypair(name=kp_name)['keypair']
Steve Bakerb7942772013-06-27 10:23:28 +120098 cls.keypairs.append(kp_name)
Steve Bakerd2525a92013-05-06 15:29:03 +120099 return body
100
101 @classmethod
Steven Hardy5be93e82014-04-02 21:24:05 +0100102 def _clear_keypairs(cls):
Steve Bakerb1f67b52013-06-24 14:42:30 +1200103 for kp_name in cls.keypairs:
104 try:
105 cls.keypairs_client.delete_keypair(kp_name)
106 except Exception:
107 pass
108
109 @classmethod
huangtianhua01cba0a2014-04-30 16:18:03 +0800110 def _create_image(cls, name_start='image-heat-', container_format='bare',
111 disk_format='iso'):
112 image_name = data_utils.rand_name(name_start)
David Kranz34f18782015-01-06 13:43:55 -0500113 body = cls.images_v2_client.create_image(image_name,
114 container_format,
115 disk_format)
huangtianhua01cba0a2014-04-30 16:18:03 +0800116 image_id = body['id']
117 cls.images.append(image_id)
118 return body
119
120 @classmethod
121 def _clear_images(cls):
122 for image_id in cls.images:
Jordan Pittier9e227c52016-02-09 14:35:18 +0100123 test_utils.call_and_ignore_notfound_exc(
124 cls.images_v2_client.delete_image, image_id)
huangtianhua01cba0a2014-04-30 16:18:03 +0800125
126 @classmethod
Ghanshyam961ea1a2014-06-09 10:56:00 +0900127 def read_template(cls, name, ext='yaml'):
Qiu Hua Qiaof6368772014-04-01 01:12:39 -0500128 loc = ["stacks", "templates", "%s.%s" % (name, ext)]
129 fullpath = os.path.join(os.path.dirname(__file__), *loc)
Sean Daguee0a65d12014-03-25 15:59:16 -0400130
131 with open(fullpath, "r") as f:
132 content = f.read()
133 return content
134
135 @classmethod
Ghanshyam961ea1a2014-06-09 10:56:00 +0900136 def load_template(cls, name, ext='yaml'):
137 loc = ["stacks", "templates", "%s.%s" % (name, ext)]
138 fullpath = os.path.join(os.path.dirname(__file__), *loc)
139
140 with open(fullpath, "r") as f:
141 return yaml.safe_load(f)
142
143 @classmethod
Andrea Frittoli556f7962014-09-15 13:14:54 +0100144 def resource_cleanup(cls):
Steven Hardy5be93e82014-04-02 21:24:05 +0100145 cls._clear_stacks()
146 cls._clear_keypairs()
huangtianhua01cba0a2014-04-30 16:18:03 +0800147 cls._clear_images()
Andrea Frittoli556f7962014-09-15 13:14:54 +0100148 super(BaseOrchestrationTest, cls).resource_cleanup()
Steve Bakerd2525a92013-05-06 15:29:03 +1200149
Steve Baker38d8f092013-06-12 12:47:16 +1200150 @staticmethod
151 def stack_output(stack, output_key):
Steven Hardy48ec7052014-03-28 14:06:27 +0000152 """Return a stack output value for a given key."""
Steve Baker38d8f092013-06-12 12:47:16 +1200153 return next((o['output_value'] for o in stack['outputs']
154 if o['output_key'] == output_key), None)
Steven Hardye2a74442014-03-25 12:10:52 +0000155
156 def assert_fields_in_dict(self, obj, *fields):
157 for field in fields:
158 self.assertIn(field, obj)
159
160 def list_resources(self, stack_identifier):
161 """Get a dict mapping of resource names to types."""
Anusha Ramineniab6c3a32015-08-18 08:33:09 +0530162 resources = self.client.list_resources(stack_identifier)['resources']
Steven Hardye2a74442014-03-25 12:10:52 +0000163 self.assertIsInstance(resources, list)
164 for res in resources:
165 self.assert_fields_in_dict(res, 'logical_resource_id',
166 'resource_type', 'resource_status',
167 'updated_time')
168
169 return dict((r['resource_name'], r['resource_type'])
170 for r in resources)
Steven Hardy8b54fc52014-03-28 16:15:51 +0000171
172 def get_stack_output(self, stack_identifier, output_key):
Anusha Ramineniab6c3a32015-08-18 08:33:09 +0530173 body = self.client.show_stack(stack_identifier)['stack']
Steven Hardy8b54fc52014-03-28 16:15:51 +0000174 return self.stack_output(body, output_key)