11
from keystoneclient.v3 import client
14
def parameterize(ref):
15
"""Rewrites attributes to match the kwarg naming convention in client.
17
>>> paramterize({'project_id': 0})
24
params.setdefault(key[:-3], params.pop(key))
28
class TestClient(client.Client):
30
def serialize(self, entity):
31
return json.dumps(entity, sort_keys=True)
34
class TestCase(testtools.TestCase):
35
TEST_TENANT_NAME = 'aTenant'
38
TEST_ROOT_URL = 'http://127.0.0.1:5000/'
39
TEST_URL = '%s%s' % (TEST_ROOT_URL, 'v3')
40
TEST_ROOT_ADMIN_URL = 'http://127.0.0.1:35357/'
41
TEST_ADMIN_URL = '%s%s' % (TEST_ROOT_ADMIN_URL, 'v3')
43
'config': {'danger_mode': False},
48
super(TestCase, self).setUp()
50
self._original_time = time.time
51
time.time = lambda: 1234
52
requests.request = self.mox.CreateMockAnything()
53
self.client = TestClient(username=self.TEST_USER,
54
token=self.TEST_TOKEN,
55
tenant_name=self.TEST_TENANT_NAME,
56
auth_url=self.TEST_URL,
57
endpoint=self.TEST_URL)
60
time.time = self._original_time
63
super(TestCase, self).tearDown()
66
class UnauthenticatedTestCase(testtools.TestCase):
67
""" Class used as base for unauthenticated calls """
68
TEST_ROOT_URL = 'http://127.0.0.1:5000/'
69
TEST_URL = '%s%s' % (TEST_ROOT_URL, 'v3')
70
TEST_ROOT_ADMIN_URL = 'http://127.0.0.1:35357/'
71
TEST_ADMIN_URL = '%s%s' % (TEST_ROOT_ADMIN_URL, 'v3')
73
'config': {'danger_mode': False},
78
super(UnauthenticatedTestCase, self).setUp()
80
self._original_time = time.time
81
time.time = lambda: 1234
82
requests.request = self.mox.CreateMockAnything()
85
time.time = self._original_time
88
super(UnauthenticatedTestCase, self).tearDown()
91
class CrudTests(testtools.TestCase):
97
def new_ref(self, **kwargs):
98
kwargs.setdefault('id', uuid.uuid4().hex)
101
def additionalSetUp(self):
104
'X-Auth-Token': 'aToken',
105
'User-Agent': 'python-keystoneclient',
109
self.headers['HEAD'] = self.headers['GET'].copy()
110
self.headers['DELETE'] = self.headers['GET'].copy()
111
self.headers['PUT'] = self.headers['GET'].copy()
112
self.headers['POST'] = self.headers['GET'].copy()
113
self.headers['POST']['Content-Type'] = 'application/json'
114
self.headers['PATCH'] = self.headers['POST'].copy()
116
def serialize(self, entity):
117
if isinstance(entity, dict):
118
return json.dumps({self.key: entity}, sort_keys=True)
119
if isinstance(entity, list):
120
return json.dumps({self.collection_key: entity}, sort_keys=True)
121
raise NotImplementedError('Are you sure you want to serialize that?')
123
def test_create(self, ref=None):
124
ref = ref or self.new_ref()
125
resp = TestResponse({
127
"text": self.serialize(ref),
133
kwargs = copy.copy(self.TEST_REQUEST_BASE)
134
kwargs['headers'] = self.headers[method]
135
kwargs['data'] = self.serialize(req_ref)
140
'v3/%s' % self.collection_key),
141
**kwargs).AndReturn((resp))
144
returned = self.manager.create(**parameterize(req_ref))
145
self.assertTrue(isinstance(returned, self.model))
148
getattr(returned, attr),
150
'Expected different %s' % attr)
152
def test_get(self, ref=None):
153
ref = ref or self.new_ref()
154
resp = TestResponse({
156
"text": self.serialize(ref),
160
kwargs = copy.copy(self.TEST_REQUEST_BASE)
161
kwargs['headers'] = self.headers[method]
166
'v3/%s/%s' % (self.collection_key, ref['id'])),
167
**kwargs).AndReturn((resp))
170
returned = self.manager.get(ref['id'])
171
self.assertTrue(isinstance(returned, self.model))
174
getattr(returned, attr),
176
'Expected different %s' % attr)
178
def test_list(self, ref_list=None, expected_path=None, **filter_kwargs):
179
ref_list = ref_list or [self.new_ref(), self.new_ref()]
180
resp = TestResponse({
182
"text": self.serialize(ref_list),
186
kwargs = copy.copy(self.TEST_REQUEST_BASE)
187
kwargs['headers'] = self.headers[method]
192
expected_path or 'v3/%s' % self.collection_key),
193
**kwargs).AndReturn((resp))
196
returned_list = self.manager.list(**filter_kwargs)
197
self.assertTrue(len(returned_list))
198
[self.assertTrue(isinstance(r, self.model)) for r in returned_list]
200
def test_update(self, ref=None):
201
ref = ref or self.new_ref()
204
resp = TestResponse({
206
"text": self.serialize(ref),
210
kwargs = copy.copy(self.TEST_REQUEST_BASE)
211
kwargs['headers'] = self.headers[method]
212
kwargs['data'] = self.serialize(req_ref)
217
'v3/%s/%s' % (self.collection_key, ref['id'])),
218
**kwargs).AndReturn((resp))
221
returned = self.manager.update(ref['id'], **parameterize(req_ref))
222
self.assertTrue(isinstance(returned, self.model))
225
getattr(returned, attr),
227
'Expected different %s' % attr)
229
def test_delete(self, ref=None):
230
ref = ref or self.new_ref()
231
resp = TestResponse({
237
kwargs = copy.copy(self.TEST_REQUEST_BASE)
238
kwargs['headers'] = self.headers[method]
243
'v3/%s/%s' % (self.collection_key, ref['id'])),
244
**kwargs).AndReturn((resp))
247
self.manager.delete(ref['id'])
250
class TestResponse(requests.Response):
251
""" Class used to wrap requests.Response and provide some
252
convenience to initialize with a dict """
254
def __init__(self, data):
256
super(TestResponse, self)
257
if isinstance(data, dict):
258
self.status_code = data.get('status_code', None)
259
self.headers = data.get('headers', None)
260
# Fake the text attribute to streamline Response creation
261
self._text = data.get('text', None)
263
self.status_code = data
265
def __eq__(self, other):
266
return self.__dict__ == other.__dict__