Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (24.9 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
from mock import patch, Mock, call
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 FR(object):
117
    """FR stands for Fake Response"""
118
    json = vm_recv
119
    headers = {}
120
    content = json
121
    status = None
122
    status_code = 200
123

    
124
    def release(self):
125
        pass
126

    
127
khttp = 'kamaki.clients.connection.kamakicon.KamakiHTTPConnection'
128
cyclades_pkg = 'kamaki.clients.cyclades.CycladesClient'
129

    
130

    
131
class Cyclades(TestCase):
132

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

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

    
149
    def tearDown(self):
150
        FR.status_code = 200
151
        FR.json = vm_recv
152

    
153
    def test_list_servers(self):
154
        FR.json = vm_list
155
        with patch.object(
156
                self.C,
157
                'perform_request',
158
                return_value=FR()) as perform_req:
159
            r = self.client.list_servers()
160
            self.assertEqual(self.client.http_client.url, self.url)
161
            self.assertEqual(self.client.http_client.path, '/servers')
162
            (method, data, a_headers, a_params) = perform_req.call_args[0]
163
            self.assert_dicts_are_equal(dict(values=r), vm_list['servers'])
164
            r = self.client.list_servers(detail=True)
165
            self.assertEqual(self.client.http_client.url, self.url)
166
            self.assertEqual(self.client.http_client.path, '/servers/detail')
167
        with patch.object(
168
                CycladesClientApi,
169
                'servers_get',
170
                return_value=FR()) as servers_get:
171
            self.client.list_servers(changes_since=True)
172
            self.assertTrue(servers_get.call_args[1]['changes_since'])
173

    
174
    @patch('%s.perform_request' % khttp, return_value=FR())
175
    def test_get_server_details(self, PR):
176
        vm_id = vm_recv['server']['id']
177
        r = self.client.get_server_details(vm_id)
178
        self.assertEqual(self.client.http_client.url, self.url)
179
        self.assertEqual(self.client.http_client.path, '/servers/%s' % vm_id)
180
        self.assert_dicts_are_equal(r, vm_recv['server'])
181

    
182
    @patch('%s.perform_request' % khttp, return_value=FR())
183
    def test_update_server_name(self, PR):
184
        vm_id = vm_recv['server']['id']
185
        new_name = vm_name + '_new'
186
        FR.status_code = 204
187
        self.client.update_server_name(vm_id, new_name)
188
        self.assertEqual(self.client.http_client.url, self.url)
189
        self.assertEqual(self.client.http_client.path, '/servers/%s' % vm_id)
190
        (method, data, a_headers, a_params) = PR.call_args[0]
191
        self.assert_dicts_are_equal(
192
            dict(server=dict(name=new_name)),
193
            loads(data))
194

    
195
    @patch('%s.perform_request' % khttp, return_value=FR())
196
    def test_reboot_server(self, PR):
197
        vm_id = vm_recv['server']['id']
198
        FR.status_code = 202
199
        self.client.reboot_server(vm_id)
200
        self.assertEqual(self.client.http_client.url, self.url)
201
        self.assertEqual(
202
            self.client.http_client.path,
203
            '/servers/%s/action' % vm_id)
204
        (method, data, a_headers, a_params) = PR.call_args[0]
205
        self.assert_dicts_are_equal(
206
            dict(reboot=dict(type='SOFT')),
207
            loads(data))
208

    
209
    @patch('%s.perform_request' % khttp, return_value=FR())
210
    def test_create_server_metadata(self, PR):
211
        vm_id = vm_recv['server']['id']
212
        metadata = dict(m1='v1', m2='v2', m3='v3')
213
        FR.json = dict(meta=vm_recv['server'])
214
        self.assertRaises(
215
            ClientError,
216
            self.client.create_server_metadata,
217
            vm_id, 'key', 'value')
218
        FR.status_code = 201
219
        for k, v in metadata.items():
220
            r = self.client.create_server_metadata(vm_id, k, v)
221
            self.assertEqual(self.client.http_client.url, self.url)
222
            self.assertEqual(
223
                self.client.http_client.path,
224
                '/servers/%s/meta/%s' % (vm_id, k))
225
            (method, data, a_headers, a_params) = PR.call_args[0]
226
            self.assertEqual(dict(meta={k: v}), loads(data))
227
            self.assert_dicts_are_equal(r, vm_recv['server'])
228

    
229
    @patch('%s.perform_request' % khttp, return_value=FR())
230
    def test_get_server_metadata(self, PR):
231
        vm_id = vm_recv['server']['id']
232
        metadata = dict(m1='v1', m2='v2', m3='v3')
233
        FR.json = dict(metadata=dict(values=metadata))
234
        r = self.client.get_server_metadata(vm_id)
235
        self.assertEqual(self.client.http_client.url, self.url)
236
        self.assertEqual(
237
            self.client.http_client.path,
238
            '/servers/%s/meta' % vm_id)
239
        self.assert_dicts_are_equal(r, metadata)
240

    
241
        for k, v in metadata.items():
242
            FR.json = dict(meta={k: v})
243
            r = self.client.get_server_metadata(vm_id, k)
244
            self.assertEqual(self.client.http_client.url, self.url)
245
            self.assertEqual(
246
                self.client.http_client.path,
247
                '/servers/%s/meta/%s' % (vm_id, k))
248
            self.assert_dicts_are_equal(r, {k: v})
249

    
250
    @patch('%s.servers_post' % cyclades_pkg, return_value=FR())
251
    def test_update_server_metadata(self, servers_post):
252
        vm_id = vm_recv['server']['id']
253
        metadata = dict(m1='v1', m2='v2', m3='v3')
254
        FR.json = dict(metadata=metadata)
255
        r = self.client.update_server_metadata(vm_id, **metadata)
256
        self.assert_dicts_are_equal(r, metadata)
257
        (called_id, cmd) = servers_post.call_args[0]
258
        self.assertEqual(called_id, vm_id)
259
        self.assertEqual(cmd, 'meta')
260
        data = servers_post.call_args[1]['json_data']
261
        self.assert_dicts_are_equal(data, dict(metadata=metadata))
262

    
263
    @patch('%s.servers_delete' % cyclades_pkg, return_value=FR())
264
    def test_delete_server_metadata(self, servers_delete):
265
        vm_id = vm_recv['server']['id']
266
        key = 'metakey'
267
        self.client.delete_server_metadata(vm_id, key)
268
        self.assertEqual((vm_id, 'meta/' + key), servers_delete.call_args[0])
269

    
270
    @patch('%s.perform_request' % khttp, return_value=FR())
271
    def test_list_flavors(self, PR):
272
        FR.json = flavor_list
273
        r = self.client.list_flavors()
274
        self.assertEqual(self.client.http_client.url, self.url)
275
        self.assertEqual(self.client.http_client.path, '/flavors')
276
        (method, data, a_headers, a_params) = PR.call_args[0]
277
        self.assert_dicts_are_equal(dict(values=r), flavor_list['flavors'])
278
        r = self.client.list_flavors(detail=True)
279
        self.assertEqual(self.client.http_client.url, self.url)
280
        self.assertEqual(self.client.http_client.path, '/flavors/detail')
281

    
282
    @patch('%s.perform_request' % khttp, return_value=FR())
283
    def test_get_flavor_details(self, PR):
284
        FR.json = dict(flavor=flavor_list['flavors'])
285
        r = self.client.get_flavor_details(fid)
286
        self.assertEqual(self.client.http_client.url, self.url)
287
        self.assertEqual(self.client.http_client.path, '/flavors/%s' % fid)
288
        self.assert_dicts_are_equal(r, flavor_list['flavors'])
289

    
290
    @patch('%s.perform_request' % khttp, return_value=FR())
291
    def test_list_images(self, PR):
292
        FR.json = img_list
293
        r = self.client.list_images()
294
        self.assertEqual(self.client.http_client.url, self.url)
295
        self.assertEqual(self.client.http_client.path, '/images')
296
        expected = img_list['images']['values']
297
        for i in range(len(r)):
298
            self.assert_dicts_are_equal(expected[i], r[i])
299
        self.client.list_images(detail=True)
300
        self.assertEqual(self.client.http_client.url, self.url)
301
        self.assertEqual(self.client.http_client.path, '/images/detail')
302

    
303
    @patch('%s.perform_request' % khttp, return_value=FR())
304
    def test_get_image_details(self, PR):
305
        FR.json = img_recv
306
        r = self.client.get_image_details(img_ref)
307
        self.assertEqual(self.client.http_client.url, self.url)
308
        self.assertEqual(self.client.http_client.path, '/images/%s' % img_ref)
309
        self.assert_dicts_are_equal(r, img_recv['image'])
310

    
311
    @patch('%s.images_get' % cyclades_pkg, return_value=FR())
312
    def test_get_image_metadata(self, IG):
313
        FR.json = dict(metadata=dict(values=img_recv['image']))
314
        r = self.client.get_image_metadata(img_ref)
315
        self.assertEqual(IG.call_args[0], ('%s' % img_ref, '/meta'))
316
        self.assert_dicts_are_equal(img_recv['image'], r)
317
        FR.json = dict(meta=img_recv['image'])
318
        key = 'somekey'
319
        self.client.get_image_metadata(img_ref, key)
320
        self.assertEqual(IG.call_args[0], ('%s' % img_ref, '/meta/%s' % key))
321

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

    
335
    @patch('%s.perform_request' % khttp, return_value=FR())
336
    def test_start_server(self, PR):
337
        vm_id = vm_recv['server']['id']
338
        FR.status_code = 202
339
        self.client.start_server(vm_id)
340
        self.assertEqual(self.client.http_client.url, self.url)
341
        self.assertEqual(
342
            self.client.http_client.path,
343
            '/servers/%s/action' % vm_id)
344
        self.assertEqual(PR.call_args[0], ('post',  '{"start": {}}', {}, {}))
345

    
346
    @patch('%s.perform_request' % khttp, return_value=FR())
347
    def test_get_server_console(self, PR):
348
        cnsl = dict(console=dict(info1='i1', info2='i2', info3='i3'))
349
        FR.json = cnsl
350
        vm_id = vm_recv['server']['id']
351
        r = self.client.get_server_console(vm_id)
352
        self.assertEqual(self.client.http_client.url, self.url)
353
        self.assertEqual(
354
            self.client.http_client.path,
355
            '/servers/%s/action' % vm_id)
356
        self.assert_dicts_are_equal(cnsl['console'], r)
357
        self.assertEqual(
358
            PR.call_args[0],
359
            ('post',  '{"console": {"type": "vnc"}}', {}, {}))
360

    
361
    def test_get_firewall_profile(self):
362
        vm_id = vm_recv['server']['id']
363
        v = 'Some profile'
364
        ret = {'attachments': {'values': [{'firewallProfile': v, 1:1}]}}
365
        with patch.object(
366
                CycladesClient,
367
                'get_server_details',
368
                return_value=ret) as GSD:
369
            r = self.client.get_firewall_profile(vm_id)
370
            self.assertEqual(r, v)
371
            self.assertEqual(GSD.call_args[0], (vm_id,))
372
            ret['attachments']['values'][0].pop('firewallProfile')
373
            self.assertRaises(
374
                ClientError,
375
                self.client.get_firewall_profile,
376
                vm_id)
377

    
378
    @patch('%s.perform_request' % khttp, return_value=FR())
379
    def test_set_firewall_profile(self, PR):
380
        vm_id = vm_recv['server']['id']
381
        v = 'Some profile'
382
        FR.status_code = 202
383
        self.client.set_firewall_profile(vm_id, v)
384
        self.assertEqual(self.client.http_client.url, self.url)
385
        self.assertEqual(
386
            self.client.http_client.path,
387
            '/servers/%s/action' % vm_id)
388
        self.assertEqual(PR.call_args[0], (
389
            'post',
390
            '{"firewallProfile": {"profile": "%s"}}' % v,
391
            {},
392
            {}))
393

    
394
    @patch('%s.perform_request' % khttp, return_value=FR())
395
    def test_get_server_stats(self, PR):
396
        vm_id = vm_recv['server']['id']
397
        stats = dict(stat1='v1', stat2='v2', stat3='v3', stat4='v4')
398
        FR.json = dict(stats=stats)
399
        r = self.client.get_server_stats(vm_id)
400
        self.assertEqual(self.client.http_client.url, self.url)
401
        self.assertEqual(
402
            self.client.http_client.path,
403
            '/servers/%s/stats' % vm_id)
404
        self.assert_dicts_are_equal(stats, r)
405

    
406
    @patch('%s.perform_request' % khttp, return_value=FR())
407
    def test_create_network(self, PR):
408
        net_name = net_send['network']['name']
409
        FR.json = net_recv
410
        FR.status_code = 202
411
        full_args = dict(
412
                cidr='192.168.0.0/24',
413
                gateway='192.168.0.1',
414
                type='MAC_FILTERED',
415
                dhcp=True)
416
        test_args = dict(full_args)
417
        test_args.update(dict(empty=None, full=None))
418
        for arg, val in test_args.items():
419
            kwargs = {} if arg == 'empty' else full_args if (
420
                arg == 'full') else {arg: val}
421
            r = self.client.create_network(net_name, **kwargs)
422
            self.assertEqual(self.client.http_client.url, self.url)
423
            self.assertEqual(
424
                self.client.http_client.path,
425
                '/networks')
426
            self.assert_dicts_are_equal(r, net_recv['network'])
427
            data = PR.call_args[0][1]
428
            expected = dict(network=dict(net_send['network']))
429
            expected['network'].update(kwargs)
430
            self.assert_dicts_are_equal(loads(data), expected)
431

    
432
    @patch('%s.perform_request' % khttp, return_value=FR())
433
    def test_connect_server(self, PR):
434
        vm_id = vm_recv['server']['id']
435
        net_id = net_recv['network']['id']
436
        FR.status_code = 202
437
        self.client.connect_server(vm_id, net_id)
438
        self.assertEqual(self.client.http_client.url, self.url)
439
        self.assertEqual(
440
            self.client.http_client.path,
441
            '/networks/%s/action' % net_id)
442
        self.assertEqual(
443
            PR.call_args[0],
444
            ('post', '{"add": {"serverRef": %s}}' % vm_id, {}, {}))
445

    
446
    @patch('%s.networks_post' % cyclades_pkg, return_value=FR())
447
    def test_disconnect_server(self, NP):
448
        vm_id = vm_recv['server']['id']
449
        net_id = net_recv['network']['id']
450
        nic_id = 'nic-%s-%s' % (net_id, vm_id)
451
        vm_nics = [
452
            dict(id=nic_id, network_id=net_id),
453
            dict(id='another-nic-id', network_id='another-net-id'),
454
            dict(id=nic_id * 2, network_id=net_id * 2)]
455
        with patch.object(
456
                CycladesClient,
457
                'list_server_nics',
458
                return_value=vm_nics) as LSN:
459
            r = self.client.disconnect_server(vm_id, nic_id)
460
            self.assertEqual(r, 1)
461
            self.assertEqual(LSN.call_args[0], (vm_id,))
462
            self.assertEqual(NP.call_args[0], (net_id, 'action'))
463
            self.assertEqual(
464
                NP.call_args[1],
465
                dict(json_data=dict(remove=dict(attachment=nic_id))))
466

    
467
    @patch('%s.perform_request' % khttp, return_value=FR())
468
    def test_list_server_nics(self, PR):
469
        vm_id = vm_recv['server']['id']
470
        nics = dict(addresses=dict(values=[dict(id='nic1'), dict(id='nic2')]))
471
        FR.json = nics
472
        r = self.client.list_server_nics(vm_id)
473
        self.assertEqual(self.client.http_client.url, self.url)
474
        self.assertEqual(
475
            self.client.http_client.path,
476
            '/servers/%s/ips' % vm_id)
477
        expected = nics['addresses']['values']
478
        for i in range(len(r)):
479
            self.assert_dicts_are_equal(r[i], expected[i])
480

    
481
    @patch('%s.perform_request' % khttp, return_value=FR())
482
    def test_list_networks(self, PR):
483
        FR.json = net_list
484
        r = self.client.list_networks()
485
        self.assertEqual(self.client.http_client.url, self.url)
486
        self.assertEqual(self.client.http_client.path, '/networks')
487
        expected = net_list['networks']['values']
488
        for i in range(len(r)):
489
            self.assert_dicts_are_equal(expected[i], r[i])
490
        self.client.list_networks(detail=True)
491
        self.assertEqual(self.client.http_client.url, self.url)
492
        self.assertEqual(self.client.http_client.path, '/networks/detail')
493

    
494
    @patch('%s.perform_request' % khttp, return_value=FR())
495
    def test_list_network_nics(self, PR):
496
        net_id = net_recv['network']['id']
497
        FR.json = net_recv
498
        r = self.client.list_network_nics(net_id)
499
        self.assertEqual(self.client.http_client.url, self.url)
500
        self.assertEqual(
501
            self.client.http_client.path,
502
            '/networks/%s' % net_id)
503
        expected = net_recv['network']['attachments']['values']
504
        for i in range(len(r)):
505
            self.assert_dicts_are_equal(r[i], expected[i])
506

    
507
    @patch('%s.networks_post' % cyclades_pkg, return_value=FR())
508
    def test_disconnect_network_nics(self, NP):
509
        net_id = net_recv['network']['id']
510
        nics = ['nic1', 'nic2', 'nic3']
511
        with patch.object(
512
                CycladesClient,
513
                'list_network_nics',
514
                return_value=nics) as lnn:
515
            self.client.disconnect_network_nics(net_id)
516
            lnn.assert_called_once_with(net_id)
517
            for i in range(len(nics)):
518
                expected = call(net_id, 'action', json_data=dict(
519
                    remove=dict(attachment=nics[i])))
520
                self.assertEqual(expected, NP.mock_calls[i])
521

    
522
    @patch('%s.perform_request' % khttp, return_value=FR())
523
    def test_get_network_details(self, PR):
524
        FR.json = net_recv
525
        net_id = net_recv['network']['id']
526
        r = self.client.get_network_details(net_id)
527
        self.assertEqual(self.client.http_client.url, self.url)
528
        self.assertEqual(
529
            self.client.http_client.path,
530
            '/networks/%s' % net_id)
531
        self.assert_dicts_are_equal(r, net_recv['network'])
532

    
533
    @patch('%s.perform_request' % khttp, return_value=FR())
534
    def test_update_network_name(self, PR):
535
        net_id = net_recv['network']['id']
536
        new_name = '%s_new' % net_id
537
        FR.status_code = 204
538
        self.client.update_network_name(net_id, new_name)
539
        self.assertEqual(self.client.http_client.url, self.url)
540
        self.assertEqual(self.client.http_client.path, '/networks/%s' % net_id)
541
        (method, data, a_headers, a_params) = PR.call_args[0]
542
        self.assert_dicts_are_equal(
543
            dict(network=dict(name=new_name)),
544
            loads(data))
545

    
546
    @patch('%s.perform_request' % khttp, return_value=FR())
547
    def test_delete_server(self, PR):
548
        vm_id = vm_recv['server']['id']
549
        FR.status_code = 204
550
        self.client.delete_server(vm_id)
551
        self.assertEqual(self.client.http_client.url, self.url)
552
        self.assertEqual(self.client.http_client.path, '/servers/%s' % vm_id)
553

    
554
    @patch('%s.perform_request' % khttp, return_value=FR())
555
    def test_delete_image(self, PR):
556
        FR.status_code = 204
557
        self.client.delete_image(img_ref)
558
        self.assertEqual(self.client.http_client.url, self.url)
559
        self.assertEqual(self.client.http_client.path, '/images/%s' % img_ref)
560

    
561
    @patch('%s.perform_request' % khttp, return_value=FR())
562
    def test_delete_network(self, PR):
563
        net_id = net_recv['network']['id']
564
        FR.status_code = 204
565
        self.client.delete_network(net_id)
566
        self.assertEqual(self.client.http_client.url, self.url)
567
        self.assertEqual(self.client.http_client.path, '/networks/%s' % net_id)
568

    
569
    @patch('%s.perform_request' % khttp, return_value=FR())
570
    def test_create_image_metadata(self, PR):
571
        metadata = dict(m1='v1', m2='v2', m3='v3')
572
        FR.json = dict(meta=img_recv['image'])
573
        self.assertRaises(
574
            ClientError,
575
            self.client.create_image_metadata,
576
            img_ref, 'key', 'value')
577
        FR.status_code = 201
578
        for k, v in metadata.items():
579
            r = self.client.create_image_metadata(img_ref, k, v)
580
            self.assertEqual(self.client.http_client.url, self.url)
581
            self.assertEqual(
582
                self.client.http_client.path,
583
                '/images/%s/meta/%s' % (img_ref, k))
584
            (method, data, a_headers, a_params) = PR.call_args[0]
585
            self.assertEqual(dict(meta={k: v}), loads(data))
586
            self.assert_dicts_are_equal(r, img_recv['image'])
587

    
588
    @patch('%s.images_post' % cyclades_pkg, return_value=FR())
589
    def test_update_image_metadata(self, images_post):
590
        metadata = dict(m1='v1', m2='v2', m3='v3')
591
        FR.json = dict(metadata=metadata)
592
        r = self.client.update_image_metadata(img_ref, **metadata)
593
        self.assert_dicts_are_equal(r, metadata)
594
        (called_id, cmd) = images_post.call_args[0]
595
        self.assertEqual(called_id, img_ref)
596
        self.assertEqual(cmd, 'meta')
597
        data = images_post.call_args[1]['json_data']
598
        self.assert_dicts_are_equal(data, dict(metadata=metadata))
599

    
600
    @patch('%s.images_delete' % cyclades_pkg, return_value=FR())
601
    def test_delete_image_metadata(self, images_delete):
602
        key = 'metakey'
603
        self.client.delete_image_metadata(img_ref, key)
604
        self.assertEqual(
605
            (img_ref, '/meta/' + key),
606
            images_delete.call_args[0])
607

    
608
if __name__ == '__main__':
609
    from sys import argv
610
    from kamaki.clients.test import runTestCase
611
    runTestCase(Cyclades, 'Cyclades (multi) Client', argv[1:])