root / kamaki / clients / compute / test.py @ b773795c
History | View | Annotate | Download (31.5 kB)
1 |
# Copyright 2013 GRNET S.A. All rights reserved.
|
---|---|
2 |
#
|
3 |
# Redistribution and use in source and binary forms, with or
|
4 |
# without modification, are permitted provided that the following
|
5 |
# conditions are met:
|
6 |
#
|
7 |
# 1. Redistributions of source code must retain the above
|
8 |
# copyright notice, this list of conditions and the following
|
9 |
# disclaimer.
|
10 |
#
|
11 |
# 2. Redistributions in binary form must reproduce the above
|
12 |
# copyright notice, this list of conditions and the following
|
13 |
# disclaimer in the documentation and/or other materials
|
14 |
# provided with the distribution.
|
15 |
#
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 |
# POSSIBILITY OF SUCH DAMAGE.
|
28 |
#
|
29 |
# The views and conclusions contained in the software and
|
30 |
# documentation are those of the authors and should not be
|
31 |
# interpreted as representing official policies, either expressed
|
32 |
# or implied, of GRNET S.A.
|
33 |
|
34 |
from mock import patch, call |
35 |
from unittest import TestCase |
36 |
from itertools import product |
37 |
from json import dumps |
38 |
from sys import stdout |
39 |
import json |
40 |
|
41 |
from kamaki.clients import ClientError, compute |
42 |
|
43 |
|
44 |
rest_pkg = 'kamaki.clients.compute.rest_api.ComputeRestClient'
|
45 |
compute_pkg = 'kamaki.clients.compute.ComputeClient'
|
46 |
|
47 |
img_ref = "1m4g3-r3f3r3nc3"
|
48 |
vm_name = "my new VM"
|
49 |
fid = 42
|
50 |
vm_send = dict(server=dict( |
51 |
flavorRef=fid, |
52 |
name=vm_name, |
53 |
imageRef=img_ref, |
54 |
metadata=dict(os="debian", users="root"))) |
55 |
vm_recv = dict(server=dict( |
56 |
status="BUILD",
|
57 |
updated="2013-03-01T10:04:00.637152+00:00",
|
58 |
hostId="",
|
59 |
name=vm_name, |
60 |
imageRef=img_ref, |
61 |
created="2013-03-01T10:04:00.087324+00:00",
|
62 |
flavorRef=fid, |
63 |
adminPass="n0n3sh@11p@55",
|
64 |
suspended=False,
|
65 |
progress=0,
|
66 |
id=31173,
|
67 |
metadata=dict(os="debian", users="root"))) |
68 |
img_recv = dict(image=dict( |
69 |
status="ACTIVE",
|
70 |
updated="2013-02-26T11:10:14+00:00",
|
71 |
name="Debian Base",
|
72 |
created="2013-02-26T11:03:29+00:00",
|
73 |
progress=100,
|
74 |
id=img_ref, |
75 |
metadata=dict(
|
76 |
partition_table="msdos",
|
77 |
kernel="2.6.32",
|
78 |
osfamily="linux",
|
79 |
users="root",
|
80 |
gui="No GUI",
|
81 |
sortorder="1",
|
82 |
os="debian",
|
83 |
root_partition="1",
|
84 |
description="Debian 6.0.7 (Squeeze) Base System")))
|
85 |
vm_list = dict(servers=[
|
86 |
dict(name='n1', id=1), |
87 |
dict(name='n2', id=2)]) |
88 |
flavor_list = dict(flavors=[
|
89 |
dict(id=41, name="C1R1024D20"), |
90 |
dict(id=42, name="C1R1024D40"), |
91 |
dict(id=43, name="C1R1028D20")]) |
92 |
img_list = dict(images=[
|
93 |
dict(name="maelstrom", id="0fb03e45-7d5a-4515-bd4e-e6bbf6457f06"), |
94 |
dict(name="edx_saas", id="1357163d-5fd8-488e-a117-48734c526206"), |
95 |
dict(name="Debian_Wheezy_Base", id="1f8454f0-8e3e-4b6c-ab8e-5236b728dffe"), |
96 |
dict(name="CentOS", id="21894b48-c805-4568-ac8b-7d4bb8eb533d"), |
97 |
dict(name="Ubuntu Desktop", id="37bc522c-c479-4085-bfb9-464f9b9e2e31"), |
98 |
dict(name="Ubuntu 12.10", id="3a24fef9-1a8c-47d1-8f11-e07bd5e544fd"), |
99 |
dict(name="Debian Base", id="40ace203-6254-4e17-a5cb-518d55418a7d"), |
100 |
dict(name="ubuntu_bundled", id="5336e265-5c7c-4127-95cb-2bf832a79903")]) |
101 |
|
102 |
|
103 |
class FR(object): |
104 |
"""FR stands for Fake Response"""
|
105 |
json = vm_recv |
106 |
headers = {} |
107 |
content = json |
108 |
status = None
|
109 |
status_code = 200
|
110 |
|
111 |
|
112 |
def print_iterations(old, new): |
113 |
if new:
|
114 |
if new % 1000: |
115 |
return old
|
116 |
stdout.write('\b' * len('%s' % old)) |
117 |
stdout.write('%s' % new)
|
118 |
else:
|
119 |
stdout.write('# of loops: ')
|
120 |
stdout.flush() |
121 |
return new
|
122 |
|
123 |
|
124 |
class ComputeRestClient(TestCase): |
125 |
|
126 |
"""Set up a ComputesRest thorough test"""
|
127 |
def setUp(self): |
128 |
self.url = 'http://cyclades.example.com' |
129 |
self.token = 'cyc14d3s70k3n' |
130 |
self.client = compute.ComputeRestClient(self.url, self.token) |
131 |
|
132 |
def tearDown(self): |
133 |
FR.json = vm_recv |
134 |
|
135 |
@patch('%s.set_param' % rest_pkg) |
136 |
@patch('%s.get' % rest_pkg, return_value=FR()) |
137 |
def _test_get(self, service, params, get, set_param): |
138 |
method = getattr(self.client, '%s_get' % service) |
139 |
param_args = [({}, {k: k}, {k: v[1]}) for k, v in params.items()] |
140 |
num_of_its = 0
|
141 |
for i, args in enumerate(product( |
142 |
('', '%s_id' % service), |
143 |
(None, False, True), |
144 |
(200, 204), |
145 |
({}, {'k': 'v'}), |
146 |
*param_args)): |
147 |
(srv_id, detail, success, kwargs) = args[:4]
|
148 |
kwargs['success'] = success
|
149 |
srv_kwargs = dict()
|
150 |
for param in args[4:]: |
151 |
srv_kwargs.update(param) |
152 |
srv_kwargs.update(kwargs) |
153 |
method(*args[:2], **srv_kwargs)
|
154 |
srv_str = '/detail' if detail else ( |
155 |
'/%s' % srv_id) if srv_id else '' |
156 |
self.assertEqual(
|
157 |
get.mock_calls[-1],
|
158 |
call('/%s%s' % (service, srv_str), **kwargs))
|
159 |
param_calls = [] |
160 |
for k, v in params.items(): |
161 |
real_v = srv_kwargs.get(k, v[1]) if not srv_id else v[1] |
162 |
param_calls.append(call(v[0], real_v, iff=real_v))
|
163 |
actual = set_param.mock_calls[- len(param_calls):]
|
164 |
self.assertEqual(sorted(actual), sorted(param_calls)) |
165 |
|
166 |
num_of_its = print_iterations(num_of_its, i) |
167 |
print ('\b' * len('%s' % num_of_its)) + ('%s' % i) |
168 |
|
169 |
@patch('%s.set_param' % rest_pkg) |
170 |
@patch('%s.get' % rest_pkg, return_value=FR()) |
171 |
def _test_srv_cmd_get(self, srv, cmd, params, get, set_param): |
172 |
method = getattr(self.client, '%s_%s_get' % (srv, cmd)) |
173 |
param_args = [({}, {k: k}, {k: v[1]}) for k, v in params.items()] |
174 |
num_of_its = 0
|
175 |
for i, args in enumerate(product( |
176 |
('some_server_id', 'other_server_id'), |
177 |
(None, 'xtra_id'), |
178 |
((304, 200), (1000)), |
179 |
({}, {'k': 'v'}), |
180 |
*param_args)): |
181 |
srv_id, xtra_id, success, kwargs = args[:4]
|
182 |
kwargs = dict(kwargs)
|
183 |
kwargs['success'] = success
|
184 |
srv_kwargs = dict()
|
185 |
for param in args[4:]: |
186 |
srv_kwargs.update(param) |
187 |
srv_kwargs.update(kwargs) |
188 |
method(*args[:2], **srv_kwargs)
|
189 |
srv_str = '/%s/%s/%s' % (srv, srv_id, cmd)
|
190 |
srv_str += ('/%s' % xtra_id) if xtra_id else '' |
191 |
self.assertEqual(get.mock_calls[-1], call(srv_str, **kwargs)) |
192 |
param_calls = [] |
193 |
for k, v in params.items(): |
194 |
real_v = srv_kwargs.get(k, v[1])
|
195 |
param_calls.append(call(v[0], real_v, iff=real_v))
|
196 |
actual = set_param.mock_calls[- len(param_calls):]
|
197 |
self.assertEqual(sorted(actual), sorted(param_calls)) |
198 |
|
199 |
num_of_its = print_iterations(num_of_its, i) |
200 |
print ('\b' * len('%s' % num_of_its)) + ('%s' % i) |
201 |
|
202 |
@patch('%s.set_header' % rest_pkg) |
203 |
@patch('%s.set_param' % rest_pkg) |
204 |
@patch('%s.post' % rest_pkg, return_value=FR()) |
205 |
def _test_post(self, srv, cmd, params, post, set_param, set_header): |
206 |
method = getattr(
|
207 |
self.client, '%s_%spost' % (srv, ('%s_' % cmd) if cmd else '')) |
208 |
param_args = [({}, {k: k}, {k: v[1]}) for k, v in params.items()] |
209 |
num_of_its = 0
|
210 |
for i, args in enumerate(product( |
211 |
('%s_id' % srv, 'some_value'), |
212 |
( |
213 |
None,
|
214 |
{'some': {'data': 'in json'}}, |
215 |
['k1', {'k2': 'v2', 'k3': 'v3'}, 'k4']), |
216 |
(202, 1453), |
217 |
({}, {'k': 'v'}), |
218 |
*param_args)): |
219 |
srv_id, json_data, success, kwargs = args[:4]
|
220 |
kwargs = dict(kwargs)
|
221 |
cmd_args = (srv_id, ) if cmd else () |
222 |
kwargs['success'] = success
|
223 |
srv_kwargs = dict()
|
224 |
for param in args[4:]: |
225 |
srv_kwargs.update(param) |
226 |
srv_kwargs.update(kwargs) |
227 |
srv_kwargs['json_data'] = json_data
|
228 |
method(*cmd_args, **srv_kwargs) |
229 |
srv_str = '/%s%s' % (
|
230 |
srv, (('/%s/%s' % (srv_id, cmd)) if cmd else '')) |
231 |
kwargs['data'] = json.dumps(json_data) if json_data else None |
232 |
self.assertEqual(post.mock_calls[-1], call(srv_str, **kwargs)) |
233 |
|
234 |
param_calls = [] |
235 |
for k, v in params.items(): |
236 |
real_v = srv_kwargs.get(k, v[1])
|
237 |
param_calls.append(call(v[0], real_v, iff=real_v))
|
238 |
actual = set_param.mock_calls[- len(param_calls):]
|
239 |
self.assertEqual(sorted(actual), sorted(param_calls)) |
240 |
|
241 |
if json_data:
|
242 |
self.assertEqual(set_header.mock_calls[-2:], [ |
243 |
call('Content-Type', 'application/json'), |
244 |
call('Content-Length', len(kwargs['data']))]) |
245 |
|
246 |
num_of_its = print_iterations(num_of_its, i) |
247 |
print ('\b' * len('%s' % num_of_its)) + ('%s' % i) |
248 |
|
249 |
@patch('%s.set_header' % rest_pkg) |
250 |
@patch('%s.set_param' % rest_pkg) |
251 |
@patch('%s.put' % rest_pkg, return_value=FR()) |
252 |
def _test_put(self, srv, cmd, params, put, set_param, set_headers): |
253 |
method = getattr(self.client, '%s_%sput' % ( |
254 |
srv, ('%s_' % cmd) if cmd else '')) |
255 |
param_args = [({}, {k: k}, {k: v[1]}) for k, v in params.items()] |
256 |
num_of_its = 0
|
257 |
for i, args in enumerate(product( |
258 |
('some_value', '%s_id' % srv), |
259 |
(None, [dict(json="data"), dict(data="json")]), |
260 |
(204, 504), |
261 |
({}, {'k': 'v'}), |
262 |
*param_args)): |
263 |
srv_id, json_data, success, kwargs = args[:4]
|
264 |
kwargs = dict(kwargs)
|
265 |
kwargs['success'] = success
|
266 |
srv_kwargs = dict()
|
267 |
for param in args[4:]: |
268 |
srv_kwargs.update(param) |
269 |
srv_kwargs.update(kwargs) |
270 |
srv_kwargs['json_data'] = json_data
|
271 |
method(srv_id, **srv_kwargs) |
272 |
srv_str = '/%s/%s%s' % (srv, srv_id, ('/%s' % cmd if cmd else '')) |
273 |
|
274 |
if json_data:
|
275 |
json_data = dumps(json_data) |
276 |
self.assertEqual(set_headers.mock_calls[-2:], [ |
277 |
call('Content-Type', 'application/json'), |
278 |
call('Content-Length', len(json_data))]) |
279 |
self.assertEqual(
|
280 |
put.mock_calls[-1],
|
281 |
call(srv_str, data=json_data, **kwargs)) |
282 |
|
283 |
param_calls = [] |
284 |
for k, v in params.items(): |
285 |
real_v = srv_kwargs.get(k, v[1])
|
286 |
param_calls.append(call(v[0], real_v, iff=real_v))
|
287 |
actual = set_param.mock_calls[- len(param_calls):]
|
288 |
self.assertEqual(sorted(actual), sorted(param_calls)) |
289 |
|
290 |
num_of_its = print_iterations(num_of_its, i) |
291 |
print ('\b' * len('%s' % num_of_its)) + ('%s' % i) |
292 |
|
293 |
@patch('%s.delete' % rest_pkg, return_value=FR()) |
294 |
def _test_delete(self, srv, cmd, delete): |
295 |
method = getattr(
|
296 |
self.client, '%s_%sdelete' % (srv, ('%s_' % cmd) if cmd else '')) |
297 |
cmd_params = ('some_cmd_value', 'some_other_value') if cmd else () |
298 |
num_of_its = 0
|
299 |
for i, args in enumerate(product( |
300 |
('%s_id' % srv, 'some_value'), |
301 |
(204, 208), |
302 |
({}, {'k': 'v'}), |
303 |
*cmd_params)): |
304 |
(srv_id, success, kwargs) = args[:3]
|
305 |
kwargs = dict(kwargs)
|
306 |
kwargs['success'] = success
|
307 |
cmd_value = args[-1] if cmd else '' |
308 |
method_args = (srv_id, cmd_value) if cmd else (srv_id, ) |
309 |
method(*method_args, **kwargs) |
310 |
srv_str = '/%s/%s' % (srv, srv_id)
|
311 |
cmd_str = ('/%s/%s' % (cmd, cmd_value)) if cmd else '' |
312 |
self.assertEqual(
|
313 |
delete.mock_calls[-1],
|
314 |
call('%s%s' % (srv_str, cmd_str), **kwargs))
|
315 |
num_of_its = print_iterations(num_of_its, i) |
316 |
print ('\b' * len('%s' % num_of_its)) + ('%s' % i) |
317 |
|
318 |
@patch('%s.get' % rest_pkg, return_value=FR()) |
319 |
def test_limits_get(self, get): |
320 |
self.client.limits_get(success='some_val') |
321 |
get.assert_called_once_with('/limits', success='some_val') |
322 |
|
323 |
def test_servers_get(self): |
324 |
params = dict(
|
325 |
changes_since=('changes-since', None), |
326 |
image=('image', None), |
327 |
flavor=('flavor', None), |
328 |
name=('name', None), |
329 |
marker=('marker', None), |
330 |
limit=('limit', None), |
331 |
status=('status', None), |
332 |
host=('host', None)) |
333 |
self._test_get('servers', params) |
334 |
|
335 |
def test_servers_post(self): |
336 |
params = dict(
|
337 |
security_group=('security_group', None), |
338 |
user_data=('user_data', None), |
339 |
availability_zone=('availability_zone', None)) |
340 |
self._test_post('servers', None, params) |
341 |
|
342 |
def test_servers_put(self): |
343 |
self._test_put('servers', None, dict(server_name=('server', None))) |
344 |
|
345 |
def test_servers_delete(self): |
346 |
self._test_delete('servers', None) |
347 |
|
348 |
def test_servers_metadata_get(self): |
349 |
self._test_srv_cmd_get('servers', 'metadata', {}) |
350 |
|
351 |
def test_servers_metadata_post(self): |
352 |
self._test_post('servers', 'metadata', {}) |
353 |
|
354 |
def test_servers_metadata_put(self): |
355 |
self._test_put('servers', 'metadata', {}) |
356 |
|
357 |
def test_images_metadata_delete(self): |
358 |
self._test_delete('images', 'metadata') |
359 |
|
360 |
def test_servers_action_post(self): |
361 |
self._test_post('servers', 'action', {}) |
362 |
|
363 |
def test_servers_ips_get(self): |
364 |
params = dict(changes_since=('changes-since', None)) |
365 |
self._test_srv_cmd_get('servers', 'ips', params) |
366 |
|
367 |
def test_images_get(self): |
368 |
param = dict(
|
369 |
changes_since=('changes-since', None), |
370 |
server_name=('server', None), |
371 |
name=('name', None), |
372 |
status=('status', None), |
373 |
marker=('marker', None), |
374 |
limit=('limit', None), |
375 |
type=('type', None)) |
376 |
self._test_get('images', param) |
377 |
|
378 |
def test_images_delete(self): |
379 |
self._test_delete('images', None) |
380 |
|
381 |
def test_images_metadata_get(self): |
382 |
self._test_srv_cmd_get('images', 'metadata', {}) |
383 |
|
384 |
def test_images_metadata_post(self): |
385 |
self._test_post('images', 'metadata', {}) |
386 |
|
387 |
def test_images_metadata_put(self): |
388 |
self._test_put('images', 'metadata', {}) |
389 |
|
390 |
def test_servers_metadata_delete(self): |
391 |
self._test_delete('servers', 'metadata') |
392 |
|
393 |
def test_flavors_get(self): |
394 |
params = dict(
|
395 |
changes_since=('changes-since', None), |
396 |
minDisk=('minDisk', None), |
397 |
minRam=('minRam', None), |
398 |
marker=('marker', None), |
399 |
limit=('limit', None)) |
400 |
self._test_get('flavors', params) |
401 |
|
402 |
@patch('%s.get' % rest_pkg, return_value=FR()) |
403 |
def test_floating_ip_pools_get(self, get): |
404 |
for args in product( |
405 |
(200, 204), |
406 |
({}, {'k': 'v'})): |
407 |
success, kwargs = args |
408 |
r = self.client.floating_ip_pools_get(success, **kwargs)
|
409 |
self.assertTrue(isinstance(r, FR)) |
410 |
self.assertEqual(get.mock_calls[-1], call( |
411 |
'/os-floating-ip-pools', success=success, **kwargs))
|
412 |
|
413 |
@patch('%s.get' % rest_pkg, return_value=FR()) |
414 |
def test_floating_ips_get(self, get): |
415 |
for args in product( |
416 |
('', '192.193.194.195'), |
417 |
(200, 204), |
418 |
({}, {'k': 'v'})): |
419 |
ip, success, kwargs = args |
420 |
r = self.client.floating_ips_get(*args[:2], **kwargs) |
421 |
self.assertTrue(isinstance(r, FR)) |
422 |
expected = '' if not ip else '/%s' % ip |
423 |
self.assertEqual(get.mock_calls[-1], call( |
424 |
'/os-floating-ips%s' % expected, success=success, **kwargs))
|
425 |
|
426 |
@patch('%s.set_header' % rest_pkg) |
427 |
@patch('%s.post' % rest_pkg, return_value=FR()) |
428 |
def test_floating_ips_post(self, post, SH): |
429 |
for args in product( |
430 |
(None, [dict(json="data"), dict(data="json")]), |
431 |
('', '192.193.194.195'), |
432 |
(202, 204), |
433 |
({}, {'k': 'v'})): |
434 |
json_data, ip, success, kwargs = args |
435 |
self.client.floating_ips_post(*args[:3], **kwargs) |
436 |
if json_data:
|
437 |
json_data = dumps(json_data) |
438 |
self.assertEqual(SH.mock_calls[-2:], [ |
439 |
call('Content-Type', 'application/json'), |
440 |
call('Content-Length', len(json_data))]) |
441 |
expected = '' if not ip else '/%s' % ip |
442 |
self.assertEqual(post.mock_calls[-1], call( |
443 |
'/os-floating-ips%s' % expected,
|
444 |
data=json_data, success=success, |
445 |
**kwargs)) |
446 |
|
447 |
@patch('%s.delete' % rest_pkg, return_value=FR()) |
448 |
def test_floating_ips_delete(self, delete): |
449 |
for args in product( |
450 |
('', '192.193.194.195'), |
451 |
(204,),
|
452 |
({}, {'k': 'v'})): |
453 |
ip, success, kwargs = args |
454 |
r = self.client.floating_ips_delete(*args[:2], **kwargs) |
455 |
self.assertTrue(isinstance(r, FR)) |
456 |
expected = '' if not ip else '/%s' % ip |
457 |
self.assertEqual(delete.mock_calls[-1], call( |
458 |
'/os-floating-ips%s' % expected, success=success, **kwargs))
|
459 |
|
460 |
|
461 |
class ComputeClient(TestCase): |
462 |
|
463 |
def assert_dicts_are_equal(self, d1, d2): |
464 |
for k, v in d1.items(): |
465 |
self.assertTrue(k in d2) |
466 |
if isinstance(v, dict): |
467 |
self.assert_dicts_are_equal(v, d2[k])
|
468 |
else:
|
469 |
self.assertEqual(unicode(v), unicode(d2[k])) |
470 |
|
471 |
"""Set up a Cyclades thorough test"""
|
472 |
def setUp(self): |
473 |
self.url = 'http://cyclades.example.com' |
474 |
self.token = 'cyc14d3s70k3n' |
475 |
self.client = compute.ComputeClient(self.url, self.token) |
476 |
|
477 |
def tearDown(self): |
478 |
FR.status_code = 200
|
479 |
FR.json = vm_recv |
480 |
|
481 |
def test_create_server(self): |
482 |
with patch.object(
|
483 |
compute.ComputeClient, 'servers_post',
|
484 |
side_effect=ClientError( |
485 |
'REQUEST ENTITY TOO LARGE',
|
486 |
status=403)):
|
487 |
self.assertRaises(
|
488 |
ClientError, |
489 |
self.client.create_server,
|
490 |
vm_name, fid, img_ref) |
491 |
|
492 |
for params in product( |
493 |
('security_group', None), |
494 |
('user_data', None), |
495 |
('availability_zone', None), |
496 |
(None, {'os': 'debian', 'users': 'root'})): |
497 |
kwargs = dict()
|
498 |
for i, k in enumerate(( |
499 |
'security_group', 'user_data', 'availability_zone')): |
500 |
if params[i]:
|
501 |
kwargs[k] = params[i] |
502 |
with patch.object(
|
503 |
compute.ComputeClient, 'servers_post',
|
504 |
return_value=FR()) as post:
|
505 |
r = self.client.create_server(vm_name, fid, img_ref, **kwargs)
|
506 |
self.assertEqual(r, FR.json['server']) |
507 |
exp_json = dict(server=dict( |
508 |
flavorRef=fid, name=vm_name, imageRef=img_ref)) |
509 |
for k in set([ |
510 |
'security_group',
|
511 |
'user_data',
|
512 |
'availability_zone']).difference(kwargs):
|
513 |
kwargs[k] = None
|
514 |
self.assertEqual(
|
515 |
post.mock_calls[-1], call(json_data=exp_json, **kwargs))
|
516 |
prsn = 'Personality string (does not work with real servers)'
|
517 |
self.client.create_server(
|
518 |
vm_name, fid, img_ref, personality=prsn, **kwargs) |
519 |
exp_json['server']['personality'] = prsn |
520 |
self.assertEqual(
|
521 |
post.mock_calls[-1], call(json_data=exp_json, **kwargs))
|
522 |
kwargs.pop('personality', None) |
523 |
exp_json['server'].pop('personality', None) |
524 |
mtdt = 'Metadata dict here'
|
525 |
self.client.create_server(
|
526 |
vm_name, fid, img_ref, metadata=mtdt, **kwargs) |
527 |
exp_json['server']['metadata'] = mtdt |
528 |
self.assertEqual(
|
529 |
post.mock_calls[-1], call(json_data=exp_json, **kwargs))
|
530 |
|
531 |
@patch('%s.servers_get' % compute_pkg, return_value=FR()) |
532 |
def test_list_servers(self, SG): |
533 |
FR.json = vm_list |
534 |
for args in product( |
535 |
(False, True), |
536 |
({}, dict(status='status')), |
537 |
({}, dict(name='name')), |
538 |
({}, dict(image='image')), |
539 |
({}, dict(flavor='flavor')), |
540 |
({}, dict(host='host')), |
541 |
({}, dict(limit='limit')), |
542 |
({}, dict(marker='marker')), |
543 |
({}, dict(changes_since='changes_since'))): |
544 |
detail = args[0]
|
545 |
kwargs = dict()
|
546 |
for param in args[1:]: |
547 |
kwargs.update(param) |
548 |
r = self.client.list_servers(detail, **kwargs)
|
549 |
for k in set([ |
550 |
'status', 'name', |
551 |
'image', 'flavor', |
552 |
'host', 'limit', |
553 |
'marker', 'changes_since']).difference(kwargs): |
554 |
kwargs[k] = None
|
555 |
self.assertEqual(SG.mock_calls[-1], call(detail=detail, **kwargs)) |
556 |
for i, vm in enumerate(vm_list['servers']): |
557 |
self.assert_dicts_are_equal(r[i], vm)
|
558 |
self.assertEqual(i + 1, len(r)) |
559 |
|
560 |
@patch('%s.servers_get' % compute_pkg, return_value=FR()) |
561 |
def test_get_server_details(self, SG): |
562 |
vm_id = vm_recv['server']['id'] |
563 |
for args in product( |
564 |
({}, dict(status='status')), |
565 |
({}, dict(name='name')), |
566 |
({}, dict(image='image')), |
567 |
({}, dict(flavor='flavor')), |
568 |
({}, dict(host='host')), |
569 |
({}, dict(limit='limit')), |
570 |
({}, dict(marker='marker')), |
571 |
({}, dict(changes_since='changes_since'))): |
572 |
kwargs = dict()
|
573 |
for param in args: |
574 |
kwargs.update(param) |
575 |
r = self.client.get_server_details(vm_id, **kwargs)
|
576 |
for k in set([ |
577 |
'status', 'name', |
578 |
'image', 'flavor', |
579 |
'host', 'limit', |
580 |
'marker', 'changes_since']).difference(kwargs): |
581 |
kwargs[k] = None
|
582 |
self.assertEqual(SG.mock_calls[-1], call(vm_id, **kwargs)) |
583 |
self.assert_dicts_are_equal(r, vm_recv['server']) |
584 |
|
585 |
@patch('%s.servers_put' % compute_pkg, return_value=FR()) |
586 |
def test_update_server_name(self, SP): |
587 |
vm_id = vm_recv['server']['id'] |
588 |
new_name = vm_name + '_new'
|
589 |
self.client.update_server_name(vm_id, new_name)
|
590 |
SP.assert_called_once_with(vm_id, json_data=dict(
|
591 |
server=dict(name=new_name)))
|
592 |
|
593 |
@patch('%s.servers_action_post' % compute_pkg, return_value=FR()) |
594 |
def test_reboot_server(self, SP): |
595 |
vm_id = vm_recv['server']['id'] |
596 |
for hard in (None, True): |
597 |
self.client.reboot_server(vm_id, hard=hard)
|
598 |
self.assertEqual(SP.mock_calls[-1], call(vm_id, json_data=dict( |
599 |
reboot=dict(type='HARD' if hard else 'SOFT')))) |
600 |
|
601 |
@patch('%s.servers_action_post' % compute_pkg, return_value=FR()) |
602 |
def test_resize_server(self, SP): |
603 |
vm_id, flavor = vm_recv['server']['id'], flavor_list['flavors'][1] |
604 |
self.client.resize_server(vm_id, flavor['id']) |
605 |
exp = dict(resize=dict(flavorRef=flavor['id'])) |
606 |
SP.assert_called_once_with(vm_id, json_data=exp) |
607 |
|
608 |
@patch('%s.servers_metadata_put' % compute_pkg, return_value=FR()) |
609 |
def test_create_server_metadata(self, SP): |
610 |
vm_id = vm_recv['server']['id'] |
611 |
metadata = dict(m1='v1', m2='v2', m3='v3') |
612 |
FR.json = dict(meta=vm_recv['server']) |
613 |
for k, v in metadata.items(): |
614 |
r = self.client.create_server_metadata(vm_id, k, v)
|
615 |
self.assert_dicts_are_equal(r, vm_recv['server']) |
616 |
self.assertEqual(SP.mock_calls[-1], call( |
617 |
vm_id, '%s' % k,
|
618 |
json_data=dict(meta={k: v}), success=201)) |
619 |
|
620 |
@patch('%s.servers_metadata_get' % compute_pkg, return_value=FR()) |
621 |
def test_get_server_metadata(self, SG): |
622 |
vm_id = vm_recv['server']['id'] |
623 |
metadata = dict(m1='v1', m2='v2', m3='v3') |
624 |
FR.json = dict(metadata=metadata)
|
625 |
r = self.client.get_server_metadata(vm_id)
|
626 |
FR.json = dict(meta=metadata)
|
627 |
SG.assert_called_once_with(vm_id, '')
|
628 |
self.assert_dicts_are_equal(r, metadata)
|
629 |
|
630 |
for k, v in metadata.items(): |
631 |
FR.json = dict(meta={k: v})
|
632 |
r = self.client.get_server_metadata(vm_id, k)
|
633 |
self.assert_dicts_are_equal(r, {k: v})
|
634 |
self.assertEqual(
|
635 |
SG.mock_calls[-1], call(vm_id, '%s' % k)) |
636 |
|
637 |
@patch('%s.servers_metadata_post' % compute_pkg, return_value=FR()) |
638 |
def test_update_server_metadata(self, SP): |
639 |
vm_id = vm_recv['server']['id'] |
640 |
metadata = dict(m1='v1', m2='v2', m3='v3') |
641 |
FR.json = dict(metadata=metadata)
|
642 |
r = self.client.update_server_metadata(vm_id, **metadata)
|
643 |
self.assert_dicts_are_equal(r, metadata)
|
644 |
SP.assert_called_once_with( |
645 |
vm_id, json_data=dict(metadata=metadata), success=201) |
646 |
|
647 |
@patch('%s.servers_metadata_delete' % compute_pkg, return_value=FR()) |
648 |
def test_delete_server_metadata(self, SD): |
649 |
vm_id = vm_recv['server']['id'] |
650 |
key = 'metakey'
|
651 |
self.client.delete_server_metadata(vm_id, key)
|
652 |
SD.assert_called_once_with(vm_id, key) |
653 |
|
654 |
@patch('%s.flavors_get' % compute_pkg, return_value=FR()) |
655 |
def test_list_flavors(self, FG): |
656 |
FR.json = flavor_list |
657 |
for detail in ('', 'detail'): |
658 |
r = self.client.list_flavors(detail=bool(detail)) |
659 |
self.assertEqual(FG.mock_calls[-1], call(detail=bool(detail))) |
660 |
self.assertEqual(r, flavor_list['flavors']) |
661 |
|
662 |
@patch('%s.flavors_get' % compute_pkg, return_value=FR()) |
663 |
def test_get_flavor_details(self, FG): |
664 |
FR.json = dict(flavor=flavor_list['flavors'][0]) |
665 |
r = self.client.get_flavor_details(fid)
|
666 |
FG.assert_called_once_with(fid) |
667 |
self.assert_dicts_are_equal(r, flavor_list['flavors'][0]) |
668 |
|
669 |
@patch('%s.images_get' % compute_pkg, return_value=FR()) |
670 |
def test_list_images(self, IG): |
671 |
FR.json = img_list |
672 |
for detail in ('', 'detail'): |
673 |
r = self.client.list_images(detail=detail)
|
674 |
self.assertEqual(IG.mock_calls[-1], call(detail=bool(detail))) |
675 |
expected = img_list['images']
|
676 |
for i in range(len(r)): |
677 |
self.assert_dicts_are_equal(expected[i], r[i])
|
678 |
|
679 |
@patch('%s.images_get' % compute_pkg, return_value=FR()) |
680 |
def test_get_image_details(self, IG): |
681 |
FR.json = img_recv |
682 |
r = self.client.get_image_details(img_ref)
|
683 |
IG.assert_called_once_with(img_ref) |
684 |
self.assert_dicts_are_equal(r, img_recv['image']) |
685 |
|
686 |
@patch('%s.images_metadata_get' % compute_pkg, return_value=FR()) |
687 |
def test_get_image_metadata(self, IG): |
688 |
for key in ('', '50m3k3y'): |
689 |
FR.json = dict(meta=img_recv['image']) if ( |
690 |
key) else dict(metadata=img_recv['image']) |
691 |
r = self.client.get_image_metadata(img_ref, key)
|
692 |
self.assertEqual(IG.mock_calls[-1], call(img_ref, key or '')) |
693 |
self.assert_dicts_are_equal(img_recv['image'], r) |
694 |
|
695 |
@patch('%s.servers_delete' % compute_pkg, return_value=FR()) |
696 |
def test_delete_server(self, SD): |
697 |
vm_id = vm_recv['server']['id'] |
698 |
self.client.delete_server(vm_id)
|
699 |
SD.assert_called_once_with(vm_id) |
700 |
|
701 |
@patch('%s.images_delete' % compute_pkg, return_value=FR()) |
702 |
def test_delete_image(self, ID): |
703 |
self.client.delete_image(img_ref)
|
704 |
ID.assert_called_once_with(img_ref) |
705 |
|
706 |
@patch('%s.images_metadata_put' % compute_pkg, return_value=FR()) |
707 |
def test_create_image_metadata(self, IP): |
708 |
(key, val) = ('k1', 'v1') |
709 |
FR.json = dict(meta=img_recv['image']) |
710 |
r = self.client.create_image_metadata(img_ref, key, val)
|
711 |
IP.assert_called_once_with( |
712 |
img_ref, '%s' % key,
|
713 |
json_data=dict(meta={key: val}))
|
714 |
self.assert_dicts_are_equal(r, img_recv['image']) |
715 |
|
716 |
@patch('%s.images_metadata_post' % compute_pkg, return_value=FR()) |
717 |
def test_update_image_metadata(self, IP): |
718 |
metadata = dict(m1='v1', m2='v2', m3='v3') |
719 |
FR.json = dict(metadata=metadata)
|
720 |
r = self.client.update_image_metadata(img_ref, **metadata)
|
721 |
IP.assert_called_once_with( |
722 |
img_ref, json_data=dict(metadata=metadata))
|
723 |
self.assert_dicts_are_equal(r, metadata)
|
724 |
|
725 |
@patch('%s.images_metadata_delete' % compute_pkg, return_value=FR()) |
726 |
def test_delete_image_metadata(self, ID): |
727 |
key = 'metakey'
|
728 |
self.client.delete_image_metadata(img_ref, key)
|
729 |
ID.assert_called_once_with(img_ref, '%s' % key)
|
730 |
|
731 |
@patch('%s.floating_ip_pools_get' % compute_pkg, return_value=FR()) |
732 |
def test_get_floating_ip_pools(self, get): |
733 |
tid = 't3n@nt_1d'
|
734 |
r = self.client.get_floating_ip_pools(tid)
|
735 |
self.assert_dicts_are_equal(r, FR.json)
|
736 |
self.assertEqual(get.mock_calls[-1], call(tid)) |
737 |
|
738 |
@patch('%s.floating_ips_get' % compute_pkg, return_value=FR()) |
739 |
def test_get_floating_ips(self, get): |
740 |
tid = 't3n@nt_1d'
|
741 |
r = self.client.get_floating_ips(tid)
|
742 |
self.assert_dicts_are_equal(r, FR.json)
|
743 |
self.assertEqual(get.mock_calls[-1], call(tid)) |
744 |
|
745 |
@patch('%s.floating_ips_post' % compute_pkg, return_value=FR()) |
746 |
def test_alloc_floating_ip(self, post): |
747 |
FR.json = dict(floating_ip=dict( |
748 |
fixed_ip='fip',
|
749 |
id=1,
|
750 |
instance_id='lala',
|
751 |
ip='102.0.0.1',
|
752 |
pool='pisine'))
|
753 |
for args in product( |
754 |
('t1', 't2'), |
755 |
(None, 'pisine')): |
756 |
r = self.client.alloc_floating_ip(*args)
|
757 |
tenant_id, pool = args |
758 |
self.assert_dicts_are_equal(r, FR.json['floating_ip']) |
759 |
expected = dict(pool=pool) if pool else dict() |
760 |
self.assertEqual(post.mock_calls[-1], call(tenant_id, expected)) |
761 |
|
762 |
@patch('%s.floating_ips_get' % compute_pkg, return_value=FR()) |
763 |
def test_get_floating_ip(self, get): |
764 |
FR.json = dict(floating_ips=[dict( |
765 |
fixed_ip='fip',
|
766 |
id=1,
|
767 |
instance_id='lala',
|
768 |
ip='102.0.0.1',
|
769 |
pool='pisine'), ])
|
770 |
for args in product( |
771 |
('t1', 't2'), |
772 |
(None, 'fip')): |
773 |
r = self.client.get_floating_ip(*args)
|
774 |
tenant_id, fip = args |
775 |
self.assertEqual(r, FR.json['floating_ips']) |
776 |
self.assertEqual(get.mock_calls[-1], call(tenant_id, fip)) |
777 |
|
778 |
@patch('%s.floating_ips_delete' % compute_pkg, return_value=FR()) |
779 |
def test_delete_floating_ip(self, delete): |
780 |
for args in product( |
781 |
('t1', 't2'), |
782 |
(None, 'fip')): |
783 |
r = self.client.delete_floating_ip(*args)
|
784 |
tenant_id, fip = args |
785 |
self.assertEqual(r, FR.headers)
|
786 |
self.assertEqual(delete.mock_calls[-1], call(tenant_id, fip)) |
787 |
|
788 |
|
789 |
if __name__ == '__main__': |
790 |
from sys import argv |
791 |
from kamaki.clients.test import runTestCase |
792 |
not_found = True
|
793 |
if not argv[1:] or argv[1] == 'ComputeClient': |
794 |
not_found = False
|
795 |
runTestCase(ComputeClient, 'Compute Client', argv[2:]) |
796 |
if not argv[1:] or argv[1] == 'ComputeRest': |
797 |
not_found = False
|
798 |
runTestCase(ComputeRestClient, 'ComputeRest Client', argv[2:]) |
799 |
if not_found:
|
800 |
print('TestCase %s not found' % argv[1]) |