Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / compute / test.py @ ae9c3b5f

History | View | Annotate | Download (24.3 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, Mock, call
35
from unittest import TestCase
36
from json import loads
37

    
38
from kamaki.clients import Client, ClientError
39
from kamaki.clients.cyclades import CycladesClient
40
from kamaki.clients.cyclades_rest_api import CycladesClientApi
41

    
42

    
43
compute_pkg_pkg = 'kamaki.clients.connection.kamakicon.KamakiHTTPConnection'
44
compute_pkg = 'kamaki.clients.cyclades.CycladesClient'
45

    
46
img_ref = "1m4g3-r3f3r3nc3"
47
vm_name = "my new VM"
48
fid = 42
49
vm_send = dict(server=dict(
50
    flavorRef=fid,
51
    name=vm_name,
52
    imageRef=img_ref,
53
    metadata=dict(os="debian", users="root")))
54
vm_recv = dict(server=dict(
55
    status="BUILD",
56
    updated="2013-03-01T10:04:00.637152+00:00",
57
    hostId="",
58
    name=vm_name,
59
    imageRef=img_ref,
60
    created="2013-03-01T10:04:00.087324+00:00",
61
    flavorRef=fid,
62
    adminPass="n0n3sh@11p@55",
63
    suspended=False,
64
    progress=0,
65
    id=31173,
66
    metadata=dict(values=dict(os="debian", users="root"))))
67
img_recv = dict(image=dict(
68
    status="ACTIVE",
69
    updated="2013-02-26T11:10:14+00:00",
70
    name="Debian Base",
71
    created="2013-02-26T11:03:29+00:00",
72
    progress=100,
73
    id=img_ref,
74
    metadata=dict(values=dict(
75
        partition_table="msdos",
76
        kernel="2.6.32",
77
        osfamily="linux",
78
        users="root",
79
        gui="No GUI",
80
        sortorder="1",
81
        os="debian",
82
        root_partition="1",
83
        description="Debian 6.0.7 (Squeeze) Base System"))))
84
vm_list = dict(servers=dict(values=[
85
    dict(name='n1', id=1),
86
    dict(name='n2', id=2)]))
87
flavor_list = dict(flavors=dict(values=[
88
        dict(id=41, name="C1R1024D20"),
89
        dict(id=42, name="C1R1024D40"),
90
        dict(id=43, name="C1R1028D20")]))
91
img_list = dict(images=dict(values=[
92
    dict(name="maelstrom", id="0fb03e45-7d5a-4515-bd4e-e6bbf6457f06"),
93
    dict(name="edx_saas", id="1357163d-5fd8-488e-a117-48734c526206"),
94
    dict(name="Debian_Wheezy_Base", id="1f8454f0-8e3e-4b6c-ab8e-5236b728dffe"),
95
    dict(name="CentOS", id="21894b48-c805-4568-ac8b-7d4bb8eb533d"),
96
    dict(name="Ubuntu Desktop", id="37bc522c-c479-4085-bfb9-464f9b9e2e31"),
97
    dict(name="Ubuntu 12.10", id="3a24fef9-1a8c-47d1-8f11-e07bd5e544fd"),
98
    dict(name="Debian Base", id="40ace203-6254-4e17-a5cb-518d55418a7d"),
99
    dict(name="ubuntu_bundled", id="5336e265-5c7c-4127-95cb-2bf832a79903")]))
100
net_send = dict(network=dict(dhcp=False, name='someNet'))
101
net_recv = dict(network=dict(
102
    status="PENDING",
103
    updated="2013-03-05T15:04:51.758780+00:00",
104
    name="someNet",
105
    created="2013-03-05T15:04:51.758728+00:00",
106
    cidr6=None,
107
    id="2130",
108
    gateway6=None,
109
    public=False,
110
    dhcp=False,
111
    cidr="192.168.1.0/24",
112
    type="MAC_FILTERED",
113
    gateway=None,
114
    attachments=dict(values=[dict(name='att1'), dict(name='att2')])))
115
net_list = dict(networks=dict(values=[
116
    dict(id=1, name='n1'),
117
    dict(id=2, name='n2'),
118
    dict(id=3, name='n3')]))
119

    
120

    
121
class FR(object):
122
    """FR stands for Fake Response"""
123
    json = vm_recv
124
    headers = {}
125
    content = json
126
    status = None
127
    status_code = 200
128

    
129
    def release(self):
130
        pass
131

    
132

    
133
class Cyclades(TestCase):
134

    
135
    def assert_dicts_are_equal(self, d1, d2):
136
        for k, v in d1.items():
137
            self.assertTrue(k in d2)
138
            if isinstance(v, dict):
139
                self.assert_dicts_are_equal(v, d2[k])
140
            else:
141
                self.assertEqual(unicode(v), unicode(d2[k]))
142

    
143
    """Set up a Cyclades thorough test"""
144
    def setUp(self):
145
        self.url = 'http://cyclades.example.com'
146
        self.token = 'cyc14d3s70k3n'
147
        self.client = CycladesClient(self.url, self.token)
148
        from kamaki.clients.connection.kamakicon import KamakiHTTPConnection
149
        self.C = KamakiHTTPConnection
150

    
151
    def tearDown(self):
152
        FR.status_code = 200
153
        FR.json = vm_recv
154

    
155
    @patch(
156
        '%s.get_image_details' % compute_pkg,
157
        return_value=img_recv['image'])
158
    def test_create_server(self, GID):
159
        with patch.object(
160
                CycladesClient, 'servers_post',
161
                side_effect=ClientError(
162
                    'REQUEST ENTITY TOO LARGE',
163
                    status=403)):
164
            self.assertRaises(
165
                ClientError,
166
                self.client.create_server,
167
                vm_name, fid, img_ref)
168
        self.assertEqual(GID.mock_calls[-1], call(img_ref))
169

    
170
        with patch.object(
171
                CycladesClient, 'servers_post',
172
                return_value=FR()) as post:
173
            r = self.client.create_server(vm_name, fid, img_ref)
174
            self.assertEqual(r, FR.json['server'])
175
            self.assertEqual(GID.mock_calls[-1], call(img_ref))
176
            self.assertEqual(post.mock_calls[-1], call(json_data=vm_send))
177
            prsn = 'Personality string (does not work with real servers)'
178
            self.client.create_server(vm_name, fid, img_ref, prsn)
179
            expected = dict(server=dict(vm_send['server']))
180
            expected['server']['personality'] = prsn
181
            self.assertEqual(post.mock_calls[-1], call(json_data=expected))
182

    
183
    @patch('%s.servers_get' % compute_pkg, return_value=FR())
184
    def test_list_servers(self, SG):
185
        FR.json = vm_list
186
        for detail in (False, True):
187
            r = self.client.list_servers(detail)
188
            for i, vm in enumerate(vm_list['servers']['values']):
189
                self.assert_dicts_are_equal(r[i], vm)
190
            self.assertEqual(i + 1, len(r))
191
            self.assertEqual(SG.mock_calls[-1], call(
192
                changes_since=None,
193
                command='detail' if detail else ''))
194

    
195
    @patch('%s.servers_get' % compute_pkg, return_value=FR())
196
    def test_get_server_details(self, SG):
197
        vm_id = vm_recv['server']['id']
198
        r = self.client.get_server_details(vm_id)
199
        self.assert_dicts_are_equal(r, vm_recv['server'])
200
        self.assertEqual(SG.mock_calls[-1], call(vm_id))
201

    
202
    @patch('%s.servers_put' % compute_pkg, return_value=FR())
203
    def test_update_server_name(self, SP):
204
        vm_id = vm_recv['server']['id']
205
        new_name = vm_name + '_new'
206
        self.client.update_server_name(vm_id, new_name)
207
        self.assertEqual(SP.mock_calls[-1], call(vm_id, json_data=dict(
208
            server=dict(name=new_name))))
209

    
210
    @patch('%s.servers_post' % compute_pkg, return_value=FR())
211
    def test_reboot_server(self, SP):
212
        vm_id = vm_recv['server']['id']
213
        for hard in (None, True):
214
            self.client.reboot_server(vm_id, hard=hard)
215
            self.assertEqual(SP.mock_calls[-1], call(
216
                vm_id, 'action',
217
                json_data=dict(reboot=dict(type='HARD' if hard else 'SOFT'))))
218

    
219
    @patch('%s.servers_put' % compute_pkg, return_value=FR())
220
    def test_create_server_metadata(self, SP):
221
        vm_id = vm_recv['server']['id']
222
        metadata = dict(m1='v1', m2='v2', m3='v3')
223
        FR.json = dict(meta=vm_recv['server'])
224
        for k, v in metadata.items():
225
            r = self.client.create_server_metadata(vm_id, k, v)
226
            self.assert_dicts_are_equal(r, vm_recv['server'])
227
            self.assertEqual(SP.mock_calls[-1], call(
228
                vm_id, 'meta/%s' % k,
229
                json_data=dict(meta={k: v}), success=201))
230

    
231
    @patch('%s.servers_get' % compute_pkg, return_value=FR())
232
    def test_get_server_metadata(self, SG):
233
        vm_id = vm_recv['server']['id']
234
        metadata = dict(m1='v1', m2='v2', m3='v3')
235
        FR.json = dict(metadata=dict(values=metadata))
236
        r = self.client.get_server_metadata(vm_id)
237
        self.assertEqual(SG.mock_calls[-1], call(vm_id, '/meta'))
238
        self.assert_dicts_are_equal(r, metadata)
239

    
240
        for k, v in metadata.items():
241
            FR.json = dict(meta={k: v})
242
            r = self.client.get_server_metadata(vm_id, k)
243
            self.assert_dicts_are_equal(r, {k: v})
244
            self.assertEqual(SG.mock_calls[-1], call(vm_id, '/meta/%s' % k))
245

    
246
    @patch('%s.servers_post' % compute_pkg, return_value=FR())
247
    def test_update_server_metadata(self, SP):
248
        vm_id = vm_recv['server']['id']
249
        metadata = dict(m1='v1', m2='v2', m3='v3')
250
        FR.json = dict(metadata=metadata)
251
        r = self.client.update_server_metadata(vm_id, **metadata)
252
        self.assert_dicts_are_equal(r, metadata)
253
        self.assertEqual(SP.mock_calls[-1], call(
254
            vm_id, 'meta',
255
            json_data=dict(metadata=metadata), success=201))
256

    
257
    @patch('%s.servers_delete' % compute_pkg, return_value=FR())
258
    def test_delete_server_metadata(self, SD):
259
        vm_id = vm_recv['server']['id']
260
        key = 'metakey'
261
        self.client.delete_server_metadata(vm_id, key)
262
        self.assertEqual(SD.mock_calls[-1], call(vm_id, 'meta/' + key))
263

    
264
    @patch('%s.flavors_get' % compute_pkg, return_value=FR())
265
    def test_list_flavors(self, FG):
266
        FR.json = flavor_list
267
        for cmd in ('', 'detail'):
268
            r = self.client.list_flavors(detail=(cmd == 'detail'))
269
            self.assertEqual(FG.mock_calls[-1], call(command=cmd))
270
            self.assert_dicts_are_equal(dict(values=r), flavor_list['flavors'])
271

    
272
    @patch('%s.flavors_get' % compute_pkg, return_value=FR())
273
    def test_get_flavor_details(self, FG):
274
        FR.json = dict(flavor=flavor_list['flavors'])
275
        r = self.client.get_flavor_details(fid)
276
        self.assertEqual(FG.mock_calls[-1], call(fid))
277
        self.assert_dicts_are_equal(r, flavor_list['flavors'])
278

    
279
    """
280
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
281
    def test_list_images(self, PR):
282
        FR.json = img_list
283
        r = self.client.list_images()
284
        self.assertEqual(self.client.http_client.url, self.url)
285
        self.assertEqual(self.client.http_client.path, '/images')
286
        expected = img_list['images']['values']
287
        for i in range(len(r)):
288
            self.assert_dicts_are_equal(expected[i], r[i])
289
        self.client.list_images(detail=True)
290
        self.assertEqual(self.client.http_client.url, self.url)
291
        self.assertEqual(self.client.http_client.path, '/images/detail')
292

293
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
294
    def test_get_image_details(self, PR):
295
        FR.json = img_recv
296
        r = self.client.get_image_details(img_ref)
297
        self.assertEqual(self.client.http_client.url, self.url)
298
        self.assertEqual(self.client.http_client.path, '/images/%s' % img_ref)
299
        self.assert_dicts_are_equal(r, img_recv['image'])
300

301
    @patch('%s.images_get' % compute_pkg, return_value=FR())
302
    def test_get_image_metadata(self, IG):
303
        FR.json = dict(metadata=dict(values=img_recv['image']))
304
        r = self.client.get_image_metadata(img_ref)
305
        self.assertEqual(IG.call_args[0], ('%s' % img_ref, '/meta'))
306
        self.assert_dicts_are_equal(img_recv['image'], r)
307
        FR.json = dict(meta=img_recv['image'])
308
        key = 'somekey'
309
        self.client.get_image_metadata(img_ref, key)
310
        self.assertEqual(IG.call_args[0], ('%s' % img_ref, '/meta/%s' % key))
311

312
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
313
    def test_shutdown_server(self, PR):
314
        vm_id = vm_recv['server']['id']
315
        FR.status_code = 202
316
        self.client.shutdown_server(vm_id)
317
        self.assertEqual(self.client.http_client.url, self.url)
318
        self.assertEqual(
319
            self.client.http_client.path,
320
            '/servers/%s/action' % vm_id)
321
        self.assertEqual(
322
            PR.call_args[0],
323
            ('post',  '{"shutdown": {}}', {}, {}))
324

325
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
326
    def test_start_server(self, PR):
327
        vm_id = vm_recv['server']['id']
328
        FR.status_code = 202
329
        self.client.start_server(vm_id)
330
        self.assertEqual(self.client.http_client.url, self.url)
331
        self.assertEqual(
332
            self.client.http_client.path,
333
            '/servers/%s/action' % vm_id)
334
        self.assertEqual(PR.call_args[0], ('post',  '{"start": {}}', {}, {}))
335

336
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
337
    def test_get_server_console(self, PR):
338
        cnsl = dict(console=dict(info1='i1', info2='i2', info3='i3'))
339
        FR.json = cnsl
340
        vm_id = vm_recv['server']['id']
341
        r = self.client.get_server_console(vm_id)
342
        self.assertEqual(self.client.http_client.url, self.url)
343
        self.assertEqual(
344
            self.client.http_client.path,
345
            '/servers/%s/action' % vm_id)
346
        self.assert_dicts_are_equal(cnsl['console'], r)
347
        self.assertEqual(
348
            PR.call_args[0],
349
            ('post',  '{"console": {"type": "vnc"}}', {}, {}))
350

351
    def test_get_firewall_profile(self):
352
        vm_id = vm_recv['server']['id']
353
        v = 'Some profile'
354
        ret = {'attachments': {'values': [{'firewallProfile': v, 1:1}]}}
355
        with patch.object(
356
                CycladesClient,
357
                'get_server_details',
358
                return_value=ret) as GSD:
359
            r = self.client.get_firewall_profile(vm_id)
360
            self.assertEqual(r, v)
361
            self.assertEqual(GSD.call_args[0], (vm_id,))
362
            ret['attachments']['values'][0].pop('firewallProfile')
363
            self.assertRaises(
364
                ClientError,
365
                self.client.get_firewall_profile,
366
                vm_id)
367

368
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
369
    def test_set_firewall_profile(self, PR):
370
        vm_id = vm_recv['server']['id']
371
        v = 'Some profile'
372
        FR.status_code = 202
373
        self.client.set_firewall_profile(vm_id, v)
374
        self.assertEqual(self.client.http_client.url, self.url)
375
        self.assertEqual(
376
            self.client.http_client.path,
377
            '/servers/%s/action' % vm_id)
378
        self.assertEqual(PR.call_args[0], (
379
            'post',
380
            '{"firewallProfile": {"profile": "%s"}}' % v,
381
            {},
382
            {}))
383

384
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
385
    def test_get_server_stats(self, PR):
386
        vm_id = vm_recv['server']['id']
387
        stats = dict(stat1='v1', stat2='v2', stat3='v3', stat4='v4')
388
        FR.json = dict(stats=stats)
389
        r = self.client.get_server_stats(vm_id)
390
        self.assertEqual(self.client.http_client.url, self.url)
391
        self.assertEqual(
392
            self.client.http_client.path,
393
            '/servers/%s/stats' % vm_id)
394
        self.assert_dicts_are_equal(stats, r)
395

396
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
397
    def test_create_network(self, PR):
398
        net_name = net_send['network']['name']
399
        FR.json = net_recv
400
        FR.status_code = 202
401
        full_args = dict(
402
                cidr='192.168.0.0/24',
403
                gateway='192.168.0.1',
404
                type='MAC_FILTERED',
405
                dhcp=True)
406
        test_args = dict(full_args)
407
        test_args.update(dict(empty=None, full=None))
408
        for arg, val in test_args.items():
409
            kwargs = {} if arg == 'empty' else full_args if (
410
                arg == 'full') else {arg: val}
411
            r = self.client.create_network(net_name, **kwargs)
412
            self.assertEqual(self.client.http_client.url, self.url)
413
            self.assertEqual(
414
                self.client.http_client.path,
415
                '/networks')
416
            self.assert_dicts_are_equal(r, net_recv['network'])
417
            data = PR.call_args[0][1]
418
            expected = dict(network=dict(net_send['network']))
419
            expected['network'].update(kwargs)
420
            self.assert_dicts_are_equal(loads(data), expected)
421

422
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
423
    def test_connect_server(self, PR):
424
        vm_id = vm_recv['server']['id']
425
        net_id = net_recv['network']['id']
426
        FR.status_code = 202
427
        self.client.connect_server(vm_id, net_id)
428
        self.assertEqual(self.client.http_client.url, self.url)
429
        self.assertEqual(
430
            self.client.http_client.path,
431
            '/networks/%s/action' % net_id)
432
        self.assertEqual(
433
            PR.call_args[0],
434
            ('post', '{"add": {"serverRef": %s}}' % vm_id, {}, {}))
435

436
    @patch('%s.networks_post' % compute_pkg, return_value=FR())
437
    def test_disconnect_server(self, NP):
438
        vm_id = vm_recv['server']['id']
439
        net_id = net_recv['network']['id']
440
        nic_id = 'nic-%s-%s' % (net_id, vm_id)
441
        vm_nics = [
442
            dict(id=nic_id, network_id=net_id),
443
            dict(id='another-nic-id', network_id='another-net-id'),
444
            dict(id=nic_id * 2, network_id=net_id * 2)]
445
        with patch.object(
446
                CycladesClient,
447
                'list_server_nics',
448
                return_value=vm_nics) as LSN:
449
            r = self.client.disconnect_server(vm_id, nic_id)
450
            self.assertEqual(r, 1)
451
            self.assertEqual(LSN.call_args[0], (vm_id,))
452
            self.assertEqual(NP.call_args[0], (net_id, 'action'))
453
            self.assertEqual(
454
                NP.call_args[1],
455
                dict(json_data=dict(remove=dict(attachment=nic_id))))
456

457
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
458
    def test_list_server_nics(self, PR):
459
        vm_id = vm_recv['server']['id']
460
        nics = dict(addresses=dict(values=[dict(id='nic1'), dict(id='nic2')]))
461
        FR.json = nics
462
        r = self.client.list_server_nics(vm_id)
463
        self.assertEqual(self.client.http_client.url, self.url)
464
        self.assertEqual(
465
            self.client.http_client.path,
466
            '/servers/%s/ips' % vm_id)
467
        expected = nics['addresses']['values']
468
        for i in range(len(r)):
469
            self.assert_dicts_are_equal(r[i], expected[i])
470

471
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
472
    def test_list_networks(self, PR):
473
        FR.json = net_list
474
        r = self.client.list_networks()
475
        self.assertEqual(self.client.http_client.url, self.url)
476
        self.assertEqual(self.client.http_client.path, '/networks')
477
        expected = net_list['networks']['values']
478
        for i in range(len(r)):
479
            self.assert_dicts_are_equal(expected[i], r[i])
480
        self.client.list_networks(detail=True)
481
        self.assertEqual(self.client.http_client.url, self.url)
482
        self.assertEqual(self.client.http_client.path, '/networks/detail')
483

484
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
485
    def test_list_network_nics(self, PR):
486
        net_id = net_recv['network']['id']
487
        FR.json = net_recv
488
        r = self.client.list_network_nics(net_id)
489
        self.assertEqual(self.client.http_client.url, self.url)
490
        self.assertEqual(
491
            self.client.http_client.path,
492
            '/networks/%s' % net_id)
493
        expected = net_recv['network']['attachments']['values']
494
        for i in range(len(r)):
495
            self.assert_dicts_are_equal(r[i], expected[i])
496

497
    @patch('%s.networks_post' % compute_pkg, return_value=FR())
498
    def test_disconnect_network_nics(self, NP):
499
        net_id = net_recv['network']['id']
500
        nics = ['nic1', 'nic2', 'nic3']
501
        with patch.object(
502
                CycladesClient,
503
                'list_network_nics',
504
                return_value=nics) as lnn:
505
            self.client.disconnect_network_nics(net_id)
506
            lnn.assert_called_once_with(net_id)
507
            for i in range(len(nics)):
508
                expected = call(net_id, 'action', json_data=dict(
509
                    remove=dict(attachment=nics[i])))
510
                self.assertEqual(expected, NP.mock_calls[i])
511

512
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
513
    def test_get_network_details(self, PR):
514
        FR.json = net_recv
515
        net_id = net_recv['network']['id']
516
        r = self.client.get_network_details(net_id)
517
        self.assertEqual(self.client.http_client.url, self.url)
518
        self.assertEqual(
519
            self.client.http_client.path,
520
            '/networks/%s' % net_id)
521
        self.assert_dicts_are_equal(r, net_recv['network'])
522

523
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
524
    def test_update_network_name(self, PR):
525
        net_id = net_recv['network']['id']
526
        new_name = '%s_new' % net_id
527
        FR.status_code = 204
528
        self.client.update_network_name(net_id, new_name)
529
        self.assertEqual(self.client.http_client.url, self.url)
530
        self.assertEqual(self.client.http_client.path, '/networks/%s' % net_id)
531
        (method, data, a_headers, a_params) = PR.call_args[0]
532
        self.assert_dicts_are_equal(
533
            dict(network=dict(name=new_name)),
534
            loads(data))
535

536
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
537
    def test_delete_server(self, PR):
538
        vm_id = vm_recv['server']['id']
539
        FR.status_code = 204
540
        self.client.delete_server(vm_id)
541
        self.assertEqual(self.client.http_client.url, self.url)
542
        self.assertEqual(self.client.http_client.path, '/servers/%s' % vm_id)
543

544
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
545
    def test_delete_image(self, PR):
546
        FR.status_code = 204
547
        self.client.delete_image(img_ref)
548
        self.assertEqual(self.client.http_client.url, self.url)
549
        self.assertEqual(self.client.http_client.path, '/images/%s' % img_ref)
550

551
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
552
    def test_delete_network(self, PR):
553
        net_id = net_recv['network']['id']
554
        FR.status_code = 204
555
        self.client.delete_network(net_id)
556
        self.assertEqual(self.client.http_client.url, self.url)
557
        self.assertEqual(self.client.http_client.path, '/networks/%s' % net_id)
558

559
    @patch('%s.perform_request' % compute_pkg, return_value=FR())
560
    def test_create_image_metadata(self, PR):
561
        metadata = dict(m1='v1', m2='v2', m3='v3')
562
        FR.json = dict(meta=img_recv['image'])
563
        self.assertRaises(
564
            ClientError,
565
            self.client.create_image_metadata,
566
            img_ref, 'key', 'value')
567
        FR.status_code = 201
568
        for k, v in metadata.items():
569
            r = self.client.create_image_metadata(img_ref, k, v)
570
            self.assertEqual(self.client.http_client.url, self.url)
571
            self.assertEqual(
572
                self.client.http_client.path,
573
                '/images/%s/meta/%s' % (img_ref, k))
574
            (method, data, a_headers, a_params) = PR.call_args[0]
575
            self.assertEqual(dict(meta={k: v}), loads(data))
576
            self.assert_dicts_are_equal(r, img_recv['image'])
577

578
    @patch('%s.images_post' % compute_pkg, return_value=FR())
579
    def test_update_image_metadata(self, images_post):
580
        metadata = dict(m1='v1', m2='v2', m3='v3')
581
        FR.json = dict(metadata=metadata)
582
        r = self.client.update_image_metadata(img_ref, **metadata)
583
        self.assert_dicts_are_equal(r, metadata)
584
        (called_id, cmd) = images_post.call_args[0]
585
        self.assertEqual(called_id, img_ref)
586
        self.assertEqual(cmd, 'meta')
587
        data = images_post.call_args[1]['json_data']
588
        self.assert_dicts_are_equal(data, dict(metadata=metadata))
589

590
    @patch('%s.images_delete' % compute_pkg, return_value=FR())
591
    def test_delete_image_metadata(self, images_delete):
592
        key = 'metakey'
593
        self.client.delete_image_metadata(img_ref, key)
594
        self.assertEqual(
595
            (img_ref, '/meta/' + key),
596
            images_delete.call_args[0])
597
    """
598

    
599
if __name__ == '__main__':
600
    from sys import argv
601
    from kamaki.clients.test import runTestCase
602
    runTestCase(Cyclades, 'Cyclades (multi) Client', argv[1:])