1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright 2011 Justin Santa Barbara
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
10
# http://www.apache.org/licenses/LICENSE-2.0
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
19
Provides common functionality for integrated unit tests
25
from nova import exception
26
from nova import flags
27
from nova import service
28
from nova import test # For the flags
29
from nova.auth import manager
30
from nova.exception import Error
31
from nova.log import logging
32
from nova.tests.integrated.api import client
37
LOG = logging.getLogger('nova.tests.integrated')
40
def generate_random_alphanumeric(length):
41
"""Creates a random alphanumeric string of specified length"""
42
return ''.join(random.choice(string.ascii_uppercase + string.digits)
43
for _x in range(length))
46
def generate_random_numeric(length):
47
"""Creates a random numeric string of specified length"""
48
return ''.join(random.choice(string.digits)
49
for _x in range(length))
52
def generate_new_element(items, prefix, numeric=False):
53
"""Creates a random string with prefix, that is not in 'items' list"""
56
candidate = prefix + generate_random_numeric(8)
58
candidate = prefix + generate_random_alphanumeric(8)
59
if not candidate in items:
61
print "Random collision on %s" % candidate
64
class TestUser(object):
65
def __init__(self, name, secret, auth_url):
68
self.auth_url = auth_url
71
raise exception.Error("auth_url is required")
72
self.openstack_api = client.TestOpenStackClient(self.name,
77
class IntegratedUnitTestContext(object):
81
self.auth_manager = manager.AuthManager()
83
self.wsgi_server = None
85
self.api_service = None
89
self.project_name = None
94
self._start_services()
96
self._create_test_user()
98
def _create_test_user(self):
99
self.test_user = self._create_unittest_user()
101
# No way to currently pass this through the OpenStack API
102
self.project_name = 'openstack'
103
self._configure_project(self.project_name, self.test_user)
105
def _start_services(self):
106
# WSGI shutdown broken :-(
108
if not self.api_service:
109
self._start_api_service()
112
for service in self.services:
115
# TODO(justinsb): Shutdown WSGI & anything else we startup
117
# WSGI shutdown broken :-(
118
# self.wsgi_server.terminate()
119
# self.wsgi_server = None
120
self.test_user = None
122
def _create_unittest_user(self):
123
users = self.auth_manager.get_users()
124
user_names = [user.name for user in users]
125
auth_name = generate_new_element(user_names, 'unittest_user_')
126
auth_key = generate_random_alphanumeric(16)
128
# Right now there's a bug where auth_name and auth_key are reversed
132
self.auth_manager.create_user(auth_name, auth_name, auth_key, False)
133
return TestUser(auth_name, auth_key, self.auth_url)
135
def _configure_project(self, project_name, user):
136
projects = self.auth_manager.get_projects()
137
project_names = [project.name for project in projects]
138
if not project_name in project_names:
139
project = self.auth_manager.create_project(project_name,
144
self.auth_manager.add_to_project(user.name, project_name)
146
def _start_api_service(self):
147
api_service = service.ApiService.create()
151
raise Exception("API Service was None")
153
# WSGI shutdown broken :-(
154
#self.services.append(volume_service)
155
self.api_service = api_service
157
self.auth_url = 'http://localhost:8774/v1.0'
161
# WSGI shutdown broken :-(
165
# if not IntegratedUnitTestContext.__INSTANCE:
166
# IntegratedUnitTestContext.startup()
167
# #raise Error("Must call IntegratedUnitTestContext::startup")
168
# return IntegratedUnitTestContext.__INSTANCE
172
# Because WSGI shutdown is broken at the moment, we have to recycle
174
if IntegratedUnitTestContext.__INSTANCE:
175
#raise Error("Multiple calls to IntegratedUnitTestContext.startup")
176
IntegratedUnitTestContext.__INSTANCE.setup()
178
IntegratedUnitTestContext.__INSTANCE = IntegratedUnitTestContext()
179
return IntegratedUnitTestContext.__INSTANCE
183
if not IntegratedUnitTestContext.__INSTANCE:
184
raise Error("Must call IntegratedUnitTestContext::startup")
185
IntegratedUnitTestContext.__INSTANCE.cleanup()
186
# WSGI shutdown broken :-(
188
#IntegratedUnitTestContext.__INSTANCE = None