Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / test / cyclades.py @ d8abe9e6

History | View | Annotate | Download (28 kB)

1
# Copyright 2012-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
from mock import patch, Mock
34
from unittest import TestCase
35
from json import loads
36

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

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

    
115

    
116
class Cyclades(TestCase):
117

    
118
    def assert_dicts_are_equal(self, d1, d2):
119
        for k, v in d1.items():
120
            self.assertTrue(k in d2)
121
            if isinstance(v, dict):
122
                self.assert_dicts_are_equal(v, d2[k])
123
            else:
124
                self.assertEqual(unicode(v), unicode(d2[k]))
125

    
126
    class FR(object):
127
        """FR stands for Fake Response"""
128
        json = vm_recv
129
        headers = {}
130
        content = json
131
        status = None
132
        status_code = 200
133

    
134
        def release(self):
135
            pass
136

    
137
    """Set up a Cyclades thorough test"""
138
    def setUp(self):
139
        self.url = 'http://cyclades.example.com'
140
        self.token = 'cyc14d3s70k3n'
141
        self.client = CycladesClient(self.url, self.token)
142
        from kamaki.clients.connection.kamakicon import KamakiHTTPConnection
143
        self.C = KamakiHTTPConnection
144

    
145
    def tearDown(self):
146
        self.FR.status_code = 200
147
        self.FR.json = vm_recv
148

    
149
    def test_create_server(self):
150
        self.client.get_image_details = Mock(return_value=img_recv['image'])
151
        with patch.object(Client, 'request', side_effect=ClientError(
152
                'REQUEST ENTITY TOO LARGE',
153
                status=403)):
154
            self.assertRaises(
155
                ClientError,
156
                self.client.create_server,
157
                vm_name, fid, img_ref)
158

    
159
        with patch.object(
160
                self.C,
161
                'perform_request',
162
                return_value=self.FR()) as perform_req:
163
            self.assertRaises(
164
                ClientError,
165
                self.client.create_server,
166
                vm_name, fid, img_ref)
167
            self.FR.status_code = 202
168
            r = self.client.create_server(vm_name, fid, img_ref)
169
            self.assertEqual(self.client.http_client.url, self.url)
170
            self.assertEqual(self.client.http_client.path, '/servers')
171
            (method, data, a_headers, a_params) = perform_req.call_args[0]
172
            self.assert_dicts_are_equal(loads(data), vm_send)
173
            self.assert_dicts_are_equal(r, vm_recv['server'])
174
            prsn = 'Personality string (does not work with real servers)'
175
            self.client.create_server(vm_name, fid, img_ref, prsn)
176
            (method, data, a_headers, a_params) = perform_req.call_args[0]
177
            data = loads(data)
178
            self.assertTrue('personality' in data['server'])
179
            self.assertEqual(prsn, data['server']['personality'])
180

    
181
    def test_list_servers(self):
182
        self.FR.json = vm_list
183
        with patch.object(
184
                self.C,
185
                'perform_request',
186
                return_value=self.FR()) as perform_req:
187
            r = self.client.list_servers()
188
            self.assertEqual(self.client.http_client.url, self.url)
189
            self.assertEqual(self.client.http_client.path, '/servers')
190
            (method, data, a_headers, a_params) = perform_req.call_args[0]
191
            self.assert_dicts_are_equal(dict(values=r), vm_list['servers'])
192
            r = self.client.list_servers(detail=True)
193
            self.assertEqual(self.client.http_client.url, self.url)
194
            self.assertEqual(self.client.http_client.path, '/servers/detail')
195
        with patch.object(
196
                CycladesClientApi,
197
                'servers_get',
198
                return_value=self.FR()) as servers_get:
199
            self.client.list_servers(changes_since=True)
200
            self.assertTrue(servers_get.call_args[1]['changes_since'])
201

    
202
    def test_get_server_details(self):
203
        vm_id = vm_recv['server']['id']
204
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
205
            r = self.client.get_server_details(vm_id)
206
            self.assertEqual(self.client.http_client.url, self.url)
207
            self.assertEqual(
208
                self.client.http_client.path,
209
                '/servers/%s' % vm_id)
210
            self.assert_dicts_are_equal(r, vm_recv['server'])
211

    
212
    def test_update_server_name(self):
213
        vm_id = vm_recv['server']['id']
214
        new_name = vm_name + '_new'
215
        self.FR.status_code = 204
216
        with patch.object(
217
                self.C,
218
                'perform_request',
219
                return_value=self.FR()) as perform_req:
220
            self.client.update_server_name(vm_id, new_name)
221
            self.assertEqual(self.client.http_client.url, self.url)
222
            self.assertEqual(
223
                self.client.http_client.path,
224
                '/servers/%s' % vm_id)
225
            (method, data, a_headers, a_params) = perform_req.call_args[0]
226
            self.assert_dicts_are_equal(
227
                dict(server=dict(name=new_name)),
228
                loads(data))
229

    
230
    def test_reboot_server(self):
231
        vm_id = vm_recv['server']['id']
232
        self.FR.status_code = 202
233
        with patch.object(
234
                self.C,
235
                'perform_request',
236
                return_value=self.FR()) as perform_req:
237
            self.client.reboot_server(vm_id)
238
            self.assertEqual(self.client.http_client.url, self.url)
239
            self.assertEqual(
240
                self.client.http_client.path,
241
                '/servers/%s/action' % vm_id)
242
            (method, data, a_headers, a_params) = perform_req.call_args[0]
243
            self.assert_dicts_are_equal(
244
                dict(reboot=dict(type='SOFT')),
245
                loads(data))
246

    
247
    def test_create_server_metadata(self):
248
        vm_id = vm_recv['server']['id']
249
        metadata = dict(m1='v1', m2='v2', m3='v3')
250
        self.FR.json = dict(meta=vm_recv['server'])
251
        with patch.object(
252
                self.C,
253
                'perform_request',
254
                return_value=self.FR()) as perform_req:
255
            self.assertRaises(
256
                ClientError,
257
                self.client.create_server_metadata,
258
                vm_id, 'key', 'value')
259
            self.FR.status_code = 201
260
            for k, v in metadata.items():
261
                r = self.client.create_server_metadata(vm_id, k, v)
262
                self.assertEqual(self.client.http_client.url, self.url)
263
                self.assertEqual(
264
                    self.client.http_client.path,
265
                    '/servers/%s/meta/%s' % (vm_id, k))
266
                (method, data, a_headers, a_params) = perform_req.call_args[0]
267
                self.assertEqual(dict(meta={k: v}), loads(data))
268
                self.assert_dicts_are_equal(r, vm_recv['server'])
269

    
270
    def test_get_server_metadata(self):
271
        vm_id = vm_recv['server']['id']
272
        metadata = dict(m1='v1', m2='v2', m3='v3')
273
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
274
            self.FR.json = dict(metadata=dict(values=metadata))
275
            r = self.client.get_server_metadata(vm_id)
276
            self.assertEqual(self.client.http_client.url, self.url)
277
            self.assertEqual(
278
                self.client.http_client.path,
279
                '/servers/%s/meta' % vm_id)
280
            self.assert_dicts_are_equal(r, metadata)
281

    
282
            for k, v in metadata.items():
283
                self.FR.json = dict(meta={k: v})
284
                r = self.client.get_server_metadata(vm_id, k)
285
                self.assertEqual(self.client.http_client.url, self.url)
286
                self.assertEqual(
287
                    self.client.http_client.path,
288
                    '/servers/%s/meta/%s' % (vm_id, k))
289
                self.assert_dicts_are_equal(r, {k: v})
290

    
291
    def test_update_server_metadata(self):
292
        vm_id = vm_recv['server']['id']
293
        metadata = dict(m1='v1', m2='v2', m3='v3')
294
        self.FR.json = dict(metadata=metadata)
295
        with patch.object(
296
                CycladesClientApi,
297
                'servers_post',
298
                return_value=self.FR()) as servers_post:
299
            r = self.client.update_server_metadata(vm_id, **metadata)
300
            self.assert_dicts_are_equal(r, metadata)
301
            (called_id, cmd) = servers_post.call_args[0]
302
            self.assertEqual(called_id, vm_id)
303
            self.assertEqual(cmd, 'meta')
304
            data = servers_post.call_args[1]['json_data']
305
            self.assert_dicts_are_equal(data, dict(metadata=metadata))
306

    
307
    def test_delete_server_metadata(self):
308
        vm_id = vm_recv['server']['id']
309
        key = 'metakey'
310
        with patch.object(
311
                CycladesClientApi,
312
                'servers_delete',
313
                return_value=self.FR()) as servers_delete:
314
            self.client.delete_server_metadata(vm_id, key)
315
            self.assertEqual(
316
                (vm_id, 'meta/' + key),
317
                servers_delete.call_args[0])
318

    
319
    def test_list_flavors(self):
320
        self.FR.json = flavor_list
321
        with patch.object(
322
                self.C,
323
                'perform_request',
324
                return_value=self.FR()) as perform_req:
325
            r = self.client.list_flavors()
326
            self.assertEqual(self.client.http_client.url, self.url)
327
            self.assertEqual(self.client.http_client.path, '/flavors')
328
            (method, data, a_headers, a_params) = perform_req.call_args[0]
329
            self.assert_dicts_are_equal(dict(values=r), flavor_list['flavors'])
330
            r = self.client.list_flavors(detail=True)
331
            self.assertEqual(self.client.http_client.url, self.url)
332
            self.assertEqual(self.client.http_client.path, '/flavors/detail')
333

    
334
    def test_get_flavor_details(self):
335
        self.FR.json = dict(flavor=flavor_list['flavors'])
336
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
337
            r = self.client.get_flavor_details(fid)
338
            self.assertEqual(self.client.http_client.url, self.url)
339
            self.assertEqual(
340
                self.client.http_client.path,
341
                '/flavors/%s' % fid)
342
            self.assert_dicts_are_equal(r, flavor_list['flavors'])
343

    
344
    def test_list_images(self):
345
        self.FR.json = img_list
346
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
347
            r = self.client.list_images()
348
            self.assertEqual(self.client.http_client.url, self.url)
349
            self.assertEqual(self.client.http_client.path, '/images')
350
            expected = img_list['images']['values']
351
            for i in range(len(r)):
352
                self.assert_dicts_are_equal(expected[i], r[i])
353
            self.client.list_images(detail=True)
354
            self.assertEqual(self.client.http_client.url, self.url)
355
            self.assertEqual(self.client.http_client.path, '/images/detail')
356

    
357
    def test_get_image_details(self):
358
        self.FR.json = img_recv
359
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
360
            r = self.client.get_image_details(img_ref)
361
            self.assertEqual(self.client.http_client.url, self.url)
362
            self.assertEqual(
363
                self.client.http_client.path,
364
                '/images/%s' % img_ref)
365
            self.assert_dicts_are_equal(r, img_recv['image'])
366

    
367
    def test_get_image_metadata(self):
368
        self.FR.json = dict(metadata=dict(values=img_recv['image']))
369
        with patch.object(
370
                CycladesClient,
371
                'images_get',
372
                return_value=self.FR()) as inner:
373
            r = self.client.get_image_metadata(img_ref)
374
            self.assertEqual(inner.call_args[0], ('%s' % img_ref, '/meta'))
375
            self.assert_dicts_are_equal(img_recv['image'], r)
376
            self.FR.json = dict(meta=img_recv['image'])
377
            key = 'somekey'
378
            self.client.get_image_metadata(img_ref, key)
379
            self.assertEqual(
380
                inner.call_args[0],
381
                ('%s' % img_ref, '/meta/%s' % key))
382

    
383
    def test_shutdown_server(self):
384
        vm_id = vm_recv['server']['id']
385
        self.FR.status_code = 202
386
        with patch.object(
387
                self.C,
388
                'perform_request',
389
                return_value=self.FR()) as perform_req:
390
            self.client.shutdown_server(vm_id)
391
            self.assertEqual(self.client.http_client.url, self.url)
392
            self.assertEqual(
393
                self.client.http_client.path,
394
                '/servers/%s/action' % vm_id)
395
            self.assertEqual(
396
                perform_req.call_args[0],
397
                ('post',  '{"shutdown": {}}', {}, {}))
398

    
399
    def test_start_server(self):
400
        vm_id = vm_recv['server']['id']
401
        self.FR.status_code = 202
402
        with patch.object(
403
                self.C,
404
                'perform_request',
405
                return_value=self.FR()) as perform_req:
406
            self.client.start_server(vm_id)
407
            self.assertEqual(self.client.http_client.url, self.url)
408
            self.assertEqual(
409
                self.client.http_client.path,
410
                '/servers/%s/action' % vm_id)
411
            self.assertEqual(
412
                perform_req.call_args[0],
413
                ('post',  '{"start": {}}', {}, {}))
414

    
415
    def test_get_server_console(self):
416
        cnsl = dict(console=dict(info1='i1', info2='i2', info3='i3'))
417
        self.FR.json = cnsl
418
        vm_id = vm_recv['server']['id']
419
        with patch.object(
420
                self.C,
421
                'perform_request',
422
                return_value=self.FR()) as perform_req:
423
            r = self.client.get_server_console(vm_id)
424
            self.assertEqual(self.client.http_client.url, self.url)
425
            self.assertEqual(
426
                self.client.http_client.path,
427
                '/servers/%s/action' % vm_id)
428
            self.assert_dicts_are_equal(cnsl['console'], r)
429
            self.assertEqual(
430
                perform_req.call_args[0],
431
                ('post',  '{"console": {"type": "vnc"}}', {}, {}))
432

    
433
    def test_get_firewall_profile(self):
434
        vm_id = vm_recv['server']['id']
435
        v = 'Some profile'
436
        ret = {'attachments': {'values': [{'firewallProfile': v, 1:1}]}}
437
        with patch.object(
438
                CycladesClient,
439
                'get_server_details',
440
                return_value=ret) as gsd:
441
            r = self.client.get_firewall_profile(vm_id)
442
            self.assertEqual(r, v)
443
            self.assertEqual(gsd.call_args[0], (vm_id,))
444
            ret['attachments']['values'][0].pop('firewallProfile')
445
            self.assertRaises(
446
                ClientError, self.client.get_firewall_profile,
447
                vm_id)
448

    
449
    def test_set_firewall_profile(self):
450
        vm_id = vm_recv['server']['id']
451
        v = 'Some profile'
452
        self.FR.status_code = 202
453
        with patch.object(
454
                self.C,
455
                'perform_request',
456
                return_value=self.FR()) as perform_req:
457
            self.client.set_firewall_profile(vm_id, v)
458
            self.assertEqual(self.client.http_client.url, self.url)
459
            self.assertEqual(
460
                self.client.http_client.path,
461
                '/servers/%s/action' % vm_id)
462
            self.assertEqual(perform_req.call_args[0], (
463
                'post',
464
                '{"firewallProfile": {"profile": "%s"}}' % v,
465
                {},
466
                {}))
467

    
468
    def test_get_server_stats(self):
469
        vm_id = vm_recv['server']['id']
470
        stats = dict(stat1='v1', stat2='v2', stat3='v3', stat4='v4')
471
        self.FR.json = dict(stats=stats)
472
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
473
            r = self.client.get_server_stats(vm_id)
474
            self.assertEqual(self.client.http_client.url, self.url)
475
            self.assertEqual(
476
                self.client.http_client.path,
477
                '/servers/%s/stats' % vm_id)
478
            self.assert_dicts_are_equal(stats, r)
479

    
480
    def test_create_network(self):
481
        net_name = net_send['network']['name']
482
        self.FR.json = net_recv
483
        self.FR.status_code = 202
484
        with patch.object(
485
                self.C,
486
                'perform_request',
487
                return_value=self.FR()) as perform_req:
488
            full_args = dict(
489
                    cidr='192.168.0.0/24',
490
                    gateway='192.168.0.1',
491
                    type='MAC_FILTERED',
492
                    dhcp=True)
493
            test_args = dict(full_args)
494
            test_args.update(dict(empty=None, full=None))
495
            for arg, val in test_args.items():
496
                kwargs = {} if arg == 'empty' else full_args if (
497
                    arg == 'full') else {arg: val}
498
                r = self.client.create_network(net_name, **kwargs)
499
                self.assertEqual(self.client.http_client.url, self.url)
500
                self.assertEqual(
501
                    self.client.http_client.path,
502
                    '/networks')
503
                self.assert_dicts_are_equal(r, net_recv['network'])
504
                data = perform_req.call_args[0][1]
505
                expected = dict(network=dict(net_send['network']))
506
                expected['network'].update(kwargs)
507
                self.assert_dicts_are_equal(loads(data), expected)
508

    
509
    def test_connect_server(self):
510
        vm_id = vm_recv['server']['id']
511
        net_id = net_recv['network']['id']
512
        self.FR.status_code = 202
513
        with patch.object(
514
            self.C,
515
            'perform_request',
516
            return_value=self.FR()) as perform_req:
517
            self.client.connect_server(vm_id, net_id)
518
            self.assertEqual(self.client.http_client.url, self.url)
519
            self.assertEqual(
520
                self.client.http_client.path,
521
                '/networks/%s/action' % net_id)
522
            self.assertEqual(
523
                perform_req.call_args[0],
524
                ('post', '{"add": {"serverRef": %s}}' % vm_id, {}, {}))
525

    
526
    def test_disconnect_server(self):
527
        vm_id = vm_recv['server']['id']
528
        net_id = net_recv['network']['id']
529
        nic_id = 'nic-%s-%s' % (net_id, vm_id)
530
        vm_nics = [
531
            dict(id=nic_id, network_id=net_id),
532
            dict(id='another-nic-id', network_id='another-net-id'),
533
            dict(id=nic_id * 2, network_id=net_id * 2)]
534
        with patch.object(
535
                CycladesClient,
536
                'list_server_nics',
537
                return_value=vm_nics) as lsn:
538
            with patch.object(
539
                    CycladesClient,
540
                    'networks_post',
541
                    return_value=self.FR()) as np:
542
                r = self.client.disconnect_server(vm_id, nic_id)
543
                self.assertEqual(r, 1)
544
                self.assertEqual(lsn.call_args[0], (vm_id,))
545
                self.assertEqual(np.call_args[0], (net_id, 'action'))
546
                self.assertEqual(np.call_args[1], dict(json_data=dict(
547
                    remove=dict(attachment=nic_id))))
548

    
549
    def test_list_server_nics(self):
550
        vm_id = vm_recv['server']['id']
551
        nics = dict(addresses=dict(values=[dict(id='nic1'), dict(id='nic2')]))
552
        self.FR.json = nics
553
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
554
            r = self.client.list_server_nics(vm_id)
555
            self.assertEqual(self.client.http_client.url, self.url)
556
            self.assertEqual(
557
                self.client.http_client.path,
558
                '/servers/%s/ips' % vm_id)
559
            expected = nics['addresses']['values']
560
            for i in range(len(r)):
561
                self.assert_dicts_are_equal(r[i], expected[i])
562

    
563
    def test_list_networks(self):
564
        self.FR.json = net_list
565
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
566
            r = self.client.list_networks()
567
            self.assertEqual(self.client.http_client.url, self.url)
568
            self.assertEqual(self.client.http_client.path, '/networks')
569
            expected = net_list['networks']['values']
570
            for i in range(len(r)):
571
                self.assert_dicts_are_equal(expected[i], r[i])
572
            self.client.list_networks(detail=True)
573
            self.assertEqual(self.client.http_client.url, self.url)
574
            self.assertEqual(self.client.http_client.path, '/networks/detail')
575

    
576
    def test_get_network_details(self):
577
        self.FR.json = net_recv
578
        net_id = net_recv['network']['id']
579
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
580
            r = self.client.get_network_details(net_id)
581
            self.assertEqual(self.client.http_client.url, self.url)
582
            self.assertEqual(
583
                self.client.http_client.path,
584
                '/networks/%s' % net_id)
585
            self.assert_dicts_are_equal(r, net_recv['network'])
586

    
587
    def test_update_network_name(self):
588
        net_id = net_recv['network']['id']
589
        new_name = '%s_new' % net_id
590
        self.FR.status_code = 204
591
        with patch.object(
592
                self.C,
593
                'perform_request',
594
                return_value=self.FR()) as perform_req:
595
            self.client.update_network_name(net_id, new_name)
596
            self.assertEqual(self.client.http_client.url, self.url)
597
            self.assertEqual(
598
                self.client.http_client.path,
599
                '/networks/%s' % net_id)
600
            (method, data, a_headers, a_params) = perform_req.call_args[0]
601
            self.assert_dicts_are_equal(
602
                dict(network=dict(name=new_name)),
603
                loads(data))
604

    
605
    def test_delete_server(self):
606
        vm_id = vm_recv['server']['id']
607
        self.FR.status_code = 204
608
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
609
            self.client.delete_server(vm_id)
610
            self.assertEqual(self.client.http_client.url, self.url)
611
            self.assertEqual(
612
                self.client.http_client.path,
613
                '/servers/%s' % vm_id)
614

    
615
    def test_delete_image(self):
616
        self.FR.status_code = 204
617
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
618
            self.client.delete_image(img_ref)
619
            self.assertEqual(self.client.http_client.url, self.url)
620
            self.assertEqual(
621
                self.client.http_client.path,
622
                '/images/%s' % img_ref)
623

    
624
    def test_delete_network(self):
625
        net_id = net_recv['network']['id']
626
        self.FR.status_code = 204
627
        with patch.object(self.C, 'perform_request', return_value=self.FR()):
628
            self.client.delete_network(net_id)
629
            self.assertEqual(self.client.http_client.url, self.url)
630
            self.assertEqual(
631
                self.client.http_client.path,
632
                '/networks/%s' % net_id)
633

    
634
    def test_create_image_metadata(self):
635
        metadata = dict(m1='v1', m2='v2', m3='v3')
636
        self.FR.json = dict(meta=img_recv['image'])
637
        with patch.object(
638
                self.C,
639
                'perform_request',
640
                return_value=self.FR()) as perform_req:
641
            self.assertRaises(
642
                ClientError,
643
                self.client.create_image_metadata,
644
                img_ref, 'key', 'value')
645
            self.FR.status_code = 201
646
            for k, v in metadata.items():
647
                r = self.client.create_image_metadata(img_ref, k, v)
648
                self.assertEqual(self.client.http_client.url, self.url)
649
                self.assertEqual(
650
                    self.client.http_client.path,
651
                    '/images/%s/meta/%s' % (img_ref, k))
652
                (method, data, a_headers, a_params) = perform_req.call_args[0]
653
                self.assertEqual(dict(meta={k: v}), loads(data))
654
                self.assert_dicts_are_equal(r, img_recv['image'])
655

    
656
    def test_update_image_metadata(self):
657
        metadata = dict(m1='v1', m2='v2', m3='v3')
658
        self.FR.json = dict(metadata=metadata)
659
        with patch.object(
660
                CycladesClientApi,
661
                'images_post',
662
                return_value=self.FR()) as images_post:
663
            r = self.client.update_image_metadata(img_ref, **metadata)
664
            self.assert_dicts_are_equal(r, metadata)
665
            (called_id, cmd) = images_post.call_args[0]
666
            self.assertEqual(called_id, img_ref)
667
            self.assertEqual(cmd, 'meta')
668
            data = images_post.call_args[1]['json_data']
669
            self.assert_dicts_are_equal(data, dict(metadata=metadata))
670

    
671
    def test_delete_image_metadata(self):
672
        key = 'metakey'
673
        with patch.object(
674
                CycladesClientApi,
675
                'images_delete',
676
                return_value=self.FR()) as images_delete:
677
            self.client.delete_image_metadata(img_ref, key)
678
            self.assertEqual(
679
                (img_ref, '/meta/' + key),
680
                images_delete.call_args[0])