blob: ba4f5185c757624a837312a10059b952d0ec86cd [file] [log] [blame]
Jay Pipes13b479b2012-06-11 14:52:27 -04001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2012 OpenStack, LLC
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
Jay Pipesf38eaac2012-06-21 13:37:35 -040018import logging
David Kranzcf0040c2012-06-26 09:46:56 -040019import time
Jay Pipesf38eaac2012-06-21 13:37:35 -040020
Jay Pipes13b479b2012-06-11 14:52:27 -040021import unittest2 as unittest
22
Jay Pipesf38eaac2012-06-21 13:37:35 -040023from tempest import config
Daryl Walleckc7251962012-03-12 17:26:54 -050024from tempest import openstack
Rohit Karajgidc300b22012-05-04 08:11:00 -070025from tempest.common.utils.data_utils import rand_name
Jay Pipesf38eaac2012-06-21 13:37:35 -040026from tempest.services.identity.json.admin_client import AdminClient
27
Tiago Melloeda03b52012-08-22 23:47:29 -030028__all__ = ['BaseComputeTest', 'BaseComputeTestJSON', 'BaseComputeTestXML',
29 'BaseComputeAdminTestJSON', 'BaseComputeAdminTestXML']
30
Jay Pipesf38eaac2012-06-21 13:37:35 -040031LOG = logging.getLogger(__name__)
Daryl Walleckc7251962012-03-12 17:26:54 -050032
33
Tiago Melloeda03b52012-08-22 23:47:29 -030034class BaseComputeTest(unittest.TestCase):
Daryl Walleckc7251962012-03-12 17:26:54 -050035
Jay Pipesf38eaac2012-06-21 13:37:35 -040036 """Base test case class for all Compute API tests"""
Daryl Walleckc7251962012-03-12 17:26:54 -050037
Jay Pipesf38eaac2012-06-21 13:37:35 -040038 @classmethod
39 def setUpClass(cls):
40 cls.config = config.TempestConfig()
41 cls.isolated_creds = []
42
43 if cls.config.compute.allow_tenant_isolation:
44 creds = cls._get_isolated_creds()
45 username, tenant_name, password = creds
46 os = openstack.Manager(username=username,
47 password=password,
Dan Smithcf8fab62012-08-14 08:03:48 -070048 tenant_name=tenant_name,
49 interface=cls._interface)
Daryl Walleckc7251962012-03-12 17:26:54 -050050 else:
Dan Smithcf8fab62012-08-14 08:03:48 -070051 os = openstack.Manager(interface=cls._interface)
Daryl Walleckc7251962012-03-12 17:26:54 -050052
Jay Pipesf38eaac2012-06-21 13:37:35 -040053 cls.os = os
54 cls.servers_client = os.servers_client
55 cls.flavors_client = os.flavors_client
56 cls.images_client = os.images_client
57 cls.extensions_client = os.extensions_client
58 cls.floating_ips_client = os.floating_ips_client
59 cls.keypairs_client = os.keypairs_client
Jay Pipesf38eaac2012-06-21 13:37:35 -040060 cls.security_groups_client = os.security_groups_client
61 cls.console_outputs_client = os.console_outputs_client
62 cls.limits_client = os.limits_client
63 cls.volumes_client = os.volumes_client
64 cls.build_interval = cls.config.compute.build_interval
65 cls.build_timeout = cls.config.compute.build_timeout
66 cls.ssh_user = cls.config.compute.ssh_user
67 cls.image_ref = cls.config.compute.image_ref
68 cls.image_ref_alt = cls.config.compute.image_ref_alt
69 cls.flavor_ref = cls.config.compute.flavor_ref
70 cls.flavor_ref_alt = cls.config.compute.flavor_ref_alt
71 cls.servers = []
Daryl Walleckc7251962012-03-12 17:26:54 -050072
Jay Pipesf38eaac2012-06-21 13:37:35 -040073 @classmethod
74 def _get_identity_admin_client(cls):
75 """
76 Returns an instance of the Identity Admin API client
77 """
78 client_args = (cls.config,
79 cls.config.identity_admin.username,
80 cls.config.identity_admin.password,
81 cls.config.identity.auth_url)
82 tenant_name = cls.config.identity_admin.tenant_name
83 admin_client = AdminClient(*client_args, tenant_name=tenant_name)
84 return admin_client
Daryl Walleckc7251962012-03-12 17:26:54 -050085
Jay Pipesf38eaac2012-06-21 13:37:35 -040086 @classmethod
87 def _get_isolated_creds(cls):
88 """
89 Creates a new set of user/tenant/password credentials for a
90 **regular** user of the Compute API so that a test case can
91 operate in an isolated tenant container.
92 """
93 admin_client = cls._get_identity_admin_client()
94 rand_name_root = cls.__name__
95 if cls.isolated_creds:
96 # Main user already created. Create the alt one...
97 rand_name_root += '-alt'
98 username = rand_name_root + "-user"
99 email = rand_name_root + "@example.com"
100 tenant_name = rand_name_root + "-tenant"
101 tenant_desc = tenant_name + "-desc"
102 password = "pass"
103
104 resp, tenant = admin_client.create_tenant(name=tenant_name,
105 description=tenant_desc)
106 resp, user = admin_client.create_user(username,
107 password,
108 tenant['id'],
109 email)
110 # Store the complete creds (including UUID ids...) for later
111 # but return just the username, tenant_name, password tuple
112 # that the various clients will use.
113 cls.isolated_creds.append((user, tenant))
114
115 return username, tenant_name, password
116
117 @classmethod
118 def clear_isolated_creds(cls):
119 if not cls.isolated_creds:
120 pass
121 admin_client = cls._get_identity_admin_client()
122
123 for user, tenant in cls.isolated_creds:
124 admin_client.delete_user(user['id'])
125 admin_client.delete_tenant(tenant['id'])
126
127 @classmethod
Dan Smith74e7bcb2012-08-21 09:18:26 -0700128 def clear_remaining_servers(cls):
129 # NOTE(danms): Only nuke all left-over servers if we're in our
130 # own isolated tenant
131 if not cls.isolated_creds:
132 return
133 resp, servers = cls.servers_client.list_servers()
134 for server in servers['servers']:
135 try:
136 cls.servers_client.delete_server(server['id'])
137 except Exception:
138 pass
139
140 for server in servers['servers']:
141 try:
142 cls.servers_client.wait_for_server_termination(server['id'])
143 except Exception:
144 pass
145
146 @classmethod
Jay Pipesf38eaac2012-06-21 13:37:35 -0400147 def tearDownClass(cls):
Dan Smith74e7bcb2012-08-21 09:18:26 -0700148 cls.clear_remaining_servers()
Jay Pipesf38eaac2012-06-21 13:37:35 -0400149 cls.clear_isolated_creds()
Rohit Karajgidc300b22012-05-04 08:11:00 -0700150
151 def create_server(self, image_id=None):
152 """Wrapper utility that returns a test server"""
Jay Pipesf38eaac2012-06-21 13:37:35 -0400153 server_name = rand_name(self.__class__.__name__ + "-instance")
Rohit Karajgidc300b22012-05-04 08:11:00 -0700154 flavor = self.flavor_ref
155 if not image_id:
156 image_id = self.image_ref
157
158 resp, server = self.servers_client.create_server(
159 server_name, image_id, flavor)
160 self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
161 self.servers.append(server)
162 return server
David Kranzcf0040c2012-06-26 09:46:56 -0400163
164 def wait_for(self, condition):
165 """Repeatedly calls condition() until a timeout"""
166 start_time = int(time.time())
167 while True:
168 try:
169 condition()
170 except:
171 pass
172 else:
173 return
174 if int(time.time()) - start_time >= self.build_timeout:
175 condition()
176 return
177 time.sleep(self.build_interval)
Jay Pipesf38eaac2012-06-21 13:37:35 -0400178
179
Tiago Melloeda03b52012-08-22 23:47:29 -0300180class BaseComputeTestJSON(BaseComputeTest):
Dan Smithcf8fab62012-08-14 08:03:48 -0700181 @classmethod
182 def setUpClass(cls):
183 cls._interface = "json"
184 super(BaseComputeTestJSON, cls).setUpClass()
185
186# NOTE(danms): For transition, keep the old name active as JSON
187BaseComputeTest = BaseComputeTestJSON
188
189
Tiago Melloeda03b52012-08-22 23:47:29 -0300190class BaseComputeTestXML(BaseComputeTest):
Dan Smithcf8fab62012-08-14 08:03:48 -0700191 @classmethod
192 def setUpClass(cls):
193 cls._interface = "xml"
194 super(BaseComputeTestXML, cls).setUpClass()
195
196
Jay Pipesf38eaac2012-06-21 13:37:35 -0400197class BaseComputeAdminTest(unittest.TestCase):
198
199 """Base test case class for all Compute Admin API tests"""
200
201 @classmethod
202 def setUpClass(cls):
203 cls.config = config.TempestConfig()
204 cls.admin_username = cls.config.compute_admin.username
205 cls.admin_password = cls.config.compute_admin.password
206 cls.admin_tenant = cls.config.compute_admin.tenant_name
207
208 if not cls.admin_username and cls.admin_password and cls.admin_tenant:
209 msg = ("Missing Compute Admin API credentials "
210 "in configuration.")
211 raise nose.SkipTest(msg)
212
Tiago Melloeda03b52012-08-22 23:47:29 -0300213 cls.os = openstack.AdminManager(interface=cls._interface)
214
215
216class BaseComputeAdminTestJSON(BaseComputeAdminTest):
217 @classmethod
218 def setUpClass(cls):
219 cls._interface = "json"
220 super(BaseComputeAdminTestJSON, cls).setUpClass()
221
222
223class BaseComputeAdminTestXML(BaseComputeAdminTest):
224 @classmethod
225 def setUpClass(cls):
226 cls._interface = "xml"
227 super(BaseComputeAdminTestXML, cls).setUpClass()