blob: 496883595cfeabbaf0d74c7804a1307c2dc0fc7a [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
Doug Hellmann583ce2c2015-03-11 14:55:46 +000015from oslo_log import log as logging
Masayuki Igawabfa07602015-01-20 18:47:17 +090016from tempest_lib import exceptions as lib_exc
Ghanshyam961ea1a2014-06-09 10:56:00 +090017import yaml
Sean Daguee0a65d12014-03-25 15:59:16 -040018
Fei Long Wangd39431f2015-05-14 11:30:48 +120019from tempest.common.utils import data_utils
Matthew Treinishcb09bbb2014-01-29 18:20:25 +000020from tempest import config
Steve Bakerd2525a92013-05-06 15:29:03 +120021import tempest.test
22
Matthew Treinishcb09bbb2014-01-29 18:20:25 +000023CONF = config.CONF
Steve Bakerd2525a92013-05-06 15:29:03 +120024
25LOG = logging.getLogger(__name__)
26
27
28class BaseOrchestrationTest(tempest.test.BaseTestCase):
29 """Base test case class for all Orchestration API tests."""
30
Andrea Frittolib21de6c2015-02-06 20:12:38 +000031 credentials = ['primary']
32
Steve Bakerd2525a92013-05-06 15:29:03 +120033 @classmethod
Rohan Kanade80b938a2015-02-07 10:58:56 +053034 def skip_checks(cls):
35 super(BaseOrchestrationTest, cls).skip_checks()
Matthew Treinishcb09bbb2014-01-29 18:20:25 +000036 if not CONF.service_available.heat:
Steve Bakerd2525a92013-05-06 15:29:03 +120037 raise cls.skipException("Heat support is required")
38
Rohan Kanade80b938a2015-02-07 10:58:56 +053039 @classmethod
40 def setup_credentials(cls):
41 super(BaseOrchestrationTest, cls).setup_credentials()
Matthew Treinishdb9721d2015-03-18 14:21:28 -040042 stack_owner_role = CONF.orchestration.stack_owner_role
Andrea Frittoli (andreaf)737fac92015-05-12 16:14:35 +010043 cls.os = cls.get_client_manager(roles=[stack_owner_role])
Rohan Kanade80b938a2015-02-07 10:58:56 +053044
45 @classmethod
46 def setup_clients(cls):
47 super(BaseOrchestrationTest, cls).setup_clients()
Sean Daguee0a65d12014-03-25 15:59:16 -040048 cls.orchestration_client = cls.os.orchestration_client
49 cls.client = cls.orchestration_client
50 cls.servers_client = cls.os.servers_client
51 cls.keypairs_client = cls.os.keypairs_client
52 cls.network_client = cls.os.network_client
John Warren94d8faf2015-09-15 12:22:24 -040053 cls.networks_client = cls.os.networks_client
54 cls.volumes_client = cls.os.volumes_client
huangtianhua01cba0a2014-04-30 16:18:03 +080055 cls.images_v2_client = cls.os.image_client_v2
Rohan Kanade80b938a2015-02-07 10:58:56 +053056
Rabi Mishrae42bfe42015-09-29 18:02:13 +053057 if CONF.volume_feature_enabled.api_v2:
58 cls.volumes_client = cls.os.volumes_v2_client
59 else:
60 cls.volumes_client = cls.os.volumes_client
61
Rohan Kanade80b938a2015-02-07 10:58:56 +053062 @classmethod
63 def resource_setup(cls):
64 super(BaseOrchestrationTest, cls).resource_setup()
65 cls.build_timeout = CONF.orchestration.build_timeout
66 cls.build_interval = CONF.orchestration.build_interval
Steve Bakerd2525a92013-05-06 15:29:03 +120067 cls.stacks = []
Steve Bakerb1f67b52013-06-24 14:42:30 +120068 cls.keypairs = []
huangtianhua01cba0a2014-04-30 16:18:03 +080069 cls.images = []
Steve Bakerd2525a92013-05-06 15:29:03 +120070
71 @classmethod
Ghanshyam2a180b82014-06-16 13:54:22 +090072 def create_stack(cls, stack_name, template_data, parameters=None,
Steven Hardy1b25fe02014-05-07 16:21:28 +010073 environment=None, files=None):
Ghanshyam2a180b82014-06-16 13:54:22 +090074 if parameters is None:
75 parameters = {}
David Kranz8ad924b2015-01-16 16:50:18 -050076 body = cls.client.create_stack(
Steve Bakerd2525a92013-05-06 15:29:03 +120077 stack_name,
78 template=template_data,
Steven Hardy00de7582014-05-07 15:18:52 +010079 parameters=parameters,
Steven Hardy1b25fe02014-05-07 16:21:28 +010080 environment=environment,
81 files=files)
David Kranz8ad924b2015-01-16 16:50:18 -050082 stack_id = body.response['location'].split('/')[-1]
Steve Bakerd2525a92013-05-06 15:29:03 +120083 stack_identifier = '%s/%s' % (stack_name, stack_id)
Steve Bakerb7942772013-06-27 10:23:28 +120084 cls.stacks.append(stack_identifier)
Steve Bakerd2525a92013-05-06 15:29:03 +120085 return stack_identifier
86
87 @classmethod
Steven Hardy5be93e82014-04-02 21:24:05 +010088 def _clear_stacks(cls):
Steve Bakerd2525a92013-05-06 15:29:03 +120089 for stack_identifier in cls.stacks:
90 try:
Sean Daguead824912014-03-25 14:56:35 -040091 cls.client.delete_stack(stack_identifier)
Masayuki Igawabfa07602015-01-20 18:47:17 +090092 except lib_exc.NotFound:
Steve Bakerd2525a92013-05-06 15:29:03 +120093 pass
94
95 for stack_identifier in cls.stacks:
Zhi Kun Liu03aec1d2014-08-12 16:57:05 +080096 try:
97 cls.client.wait_for_stack_status(
98 stack_identifier, 'DELETE_COMPLETE')
Masayuki Igawabfa07602015-01-20 18:47:17 +090099 except lib_exc.NotFound:
Zhi Kun Liu03aec1d2014-08-12 16:57:05 +0800100 pass
Steve Bakerd2525a92013-05-06 15:29:03 +1200101
Steve Bakerb7942772013-06-27 10:23:28 +1200102 @classmethod
Bartosz Górskiab33b7e2013-06-27 00:39:47 -0700103 def _create_keypair(cls, name_start='keypair-heat-'):
Masayuki Igawa259c1132013-10-31 17:48:44 +0900104 kp_name = data_utils.rand_name(name_start)
ghanshyamdee01f22015-08-17 11:41:47 +0900105 body = cls.keypairs_client.create_keypair(name=kp_name)['keypair']
Steve Bakerb7942772013-06-27 10:23:28 +1200106 cls.keypairs.append(kp_name)
Steve Bakerd2525a92013-05-06 15:29:03 +1200107 return body
108
109 @classmethod
Steven Hardy5be93e82014-04-02 21:24:05 +0100110 def _clear_keypairs(cls):
Steve Bakerb1f67b52013-06-24 14:42:30 +1200111 for kp_name in cls.keypairs:
112 try:
113 cls.keypairs_client.delete_keypair(kp_name)
114 except Exception:
115 pass
116
117 @classmethod
huangtianhua01cba0a2014-04-30 16:18:03 +0800118 def _create_image(cls, name_start='image-heat-', container_format='bare',
119 disk_format='iso'):
120 image_name = data_utils.rand_name(name_start)
David Kranz34f18782015-01-06 13:43:55 -0500121 body = cls.images_v2_client.create_image(image_name,
122 container_format,
123 disk_format)
huangtianhua01cba0a2014-04-30 16:18:03 +0800124 image_id = body['id']
125 cls.images.append(image_id)
126 return body
127
128 @classmethod
129 def _clear_images(cls):
130 for image_id in cls.images:
131 try:
132 cls.images_v2_client.delete_image(image_id)
Masayuki Igawabfa07602015-01-20 18:47:17 +0900133 except lib_exc.NotFound:
huangtianhua01cba0a2014-04-30 16:18:03 +0800134 pass
135
136 @classmethod
Ghanshyam961ea1a2014-06-09 10:56:00 +0900137 def read_template(cls, name, ext='yaml'):
Qiu Hua Qiaof6368772014-04-01 01:12:39 -0500138 loc = ["stacks", "templates", "%s.%s" % (name, ext)]
139 fullpath = os.path.join(os.path.dirname(__file__), *loc)
Sean Daguee0a65d12014-03-25 15:59:16 -0400140
141 with open(fullpath, "r") as f:
142 content = f.read()
143 return content
144
145 @classmethod
Ghanshyam961ea1a2014-06-09 10:56:00 +0900146 def load_template(cls, name, ext='yaml'):
147 loc = ["stacks", "templates", "%s.%s" % (name, ext)]
148 fullpath = os.path.join(os.path.dirname(__file__), *loc)
149
150 with open(fullpath, "r") as f:
151 return yaml.safe_load(f)
152
153 @classmethod
Andrea Frittoli556f7962014-09-15 13:14:54 +0100154 def resource_cleanup(cls):
Steven Hardy5be93e82014-04-02 21:24:05 +0100155 cls._clear_stacks()
156 cls._clear_keypairs()
huangtianhua01cba0a2014-04-30 16:18:03 +0800157 cls._clear_images()
Andrea Frittoli556f7962014-09-15 13:14:54 +0100158 super(BaseOrchestrationTest, cls).resource_cleanup()
Steve Bakerd2525a92013-05-06 15:29:03 +1200159
Steve Baker38d8f092013-06-12 12:47:16 +1200160 @staticmethod
161 def stack_output(stack, output_key):
Steven Hardy48ec7052014-03-28 14:06:27 +0000162 """Return a stack output value for a given key."""
Steve Baker38d8f092013-06-12 12:47:16 +1200163 return next((o['output_value'] for o in stack['outputs']
164 if o['output_key'] == output_key), None)
Steven Hardye2a74442014-03-25 12:10:52 +0000165
166 def assert_fields_in_dict(self, obj, *fields):
167 for field in fields:
168 self.assertIn(field, obj)
169
170 def list_resources(self, stack_identifier):
171 """Get a dict mapping of resource names to types."""
Anusha Ramineniab6c3a32015-08-18 08:33:09 +0530172 resources = self.client.list_resources(stack_identifier)['resources']
Steven Hardye2a74442014-03-25 12:10:52 +0000173 self.assertIsInstance(resources, list)
174 for res in resources:
175 self.assert_fields_in_dict(res, 'logical_resource_id',
176 'resource_type', 'resource_status',
177 'updated_time')
178
179 return dict((r['resource_name'], r['resource_type'])
180 for r in resources)
Steven Hardy8b54fc52014-03-28 16:15:51 +0000181
182 def get_stack_output(self, stack_identifier, output_key):
Anusha Ramineniab6c3a32015-08-18 08:33:09 +0530183 body = self.client.show_stack(stack_identifier)['stack']
Steven Hardy8b54fc52014-03-28 16:15:51 +0000184 return self.stack_output(body, output_key)