Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / cyclades / test.py @ 89a1c636

History | View | Annotate | Download (9.1 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

    
39
from kamaki.clients import ClientError, cyclades
40

    
41
img_ref = "1m4g3-r3f3r3nc3"
42
vm_name = "my new VM"
43
fid = 42
44
vm_recv = dict(server=dict(
45
    status="BUILD",
46
    updated="2013-03-01T10:04:00.637152+00:00",
47
    hostId="",
48
    name=vm_name,
49
    imageRef=img_ref,
50
    created="2013-03-01T10:04:00.087324+00:00",
51
    flavorRef=fid,
52
    adminPass="n0n3sh@11p@55",
53
    suspended=False,
54
    progress=0,
55
    id=31173,
56
    metadata=dict(os="debian", users="root")))
57
vm_list = dict(servers=[
58
    dict(name='n1', id=1),
59
    dict(name='n2', id=2)])
60
net_send = dict(network=dict(dhcp=False, name='someNet'))
61
net_recv = dict(network=dict(
62
    status="PENDING",
63
    updated="2013-03-05T15:04:51.758780+00:00",
64
    name="someNet",
65
    created="2013-03-05T15:04:51.758728+00:00",
66
    cidr6=None,
67
    id="2130",
68
    gateway6=None,
69
    public=False,
70
    dhcp=False,
71
    cidr="192.168.1.0/24",
72
    type="MAC_FILTERED",
73
    gateway=None,
74
    attachments=[dict(name='att1'), dict(name='att2')]))
75
net_list = dict(networks=[
76
    dict(id=1, name='n1'),
77
    dict(id=2, name='n2'),
78
    dict(id=3, name='n3')])
79
firewalls = dict(attachments=[
80
    dict(firewallProfile='50m3_pr0f1L3', otherStuff='57uff')])
81

    
82

    
83
class FR(object):
84
    """FR stands for Fake Response"""
85
    json = vm_recv
86
    headers = {}
87
    content = json
88
    status = None
89
    status_code = 200
90

    
91
rest_pkg = 'kamaki.clients.cyclades.CycladesRestClient'
92
cyclades_pkg = 'kamaki.clients.cyclades.CycladesClient'
93

    
94

    
95
class CycladesRestClient(TestCase):
96

    
97
    def setUp(self):
98
        self.url = 'http://cyclades.example.com'
99
        self.token = 'cyc14d3s70k3n'
100
        self.client = cyclades.CycladesRestClient(self.url, self.token)
101

    
102
    @patch('kamaki.clients.Client.get', return_value='ret')
103
    def test_servers_stats_get(self, get):
104
        server_id = 'server id'
105
        self.assertEqual(self.client.servers_stats_get(server_id), 'ret')
106
        get.assert_called_once_with(
107
            '/servers/%s/stats' % server_id, success=200)
108

    
109
    @patch('kamaki.clients.Client.get', return_value='ret')
110
    def test_servers_diagnostics_get(self, get):
111
        server_id = 'server id'
112
        self.assertEqual(
113
            self.client.servers_diagnostics_get(server_id), 'ret')
114
        get.assert_called_once_with(
115
            '/servers/%s/diagnostics' % server_id, success=200)
116

    
117

    
118
class CycladesNetworkClient(TestCase):
119

    
120
    """Set up a ComputesRest thorough test"""
121
    def setUp(self):
122
        self.url = 'http://network.example.com'
123
        self.token = 'n2tw0rk70k3n'
124
        self.client = cyclades.CycladesNetworkClient(self.url, self.token)
125

    
126
    def tearDown(self):
127
        FR.json = vm_recv
128
        del self.client
129

    
130
    @patch('kamaki.clients.Client.get', return_value=FR)
131
    def test_list_networks(self, get):
132
        FR.json = dict(networks='ret val')
133
        for detail in (True, None):
134
            self.assertEqual(self.client.list_networks(detail), 'ret val')
135
            path = '/networks/detail' if detail else '/networks'
136
            self.assertEqual(get.mock_calls[-1], call(path, success=200))
137

    
138
    @patch(
139
        'kamaki.clients.network.rest_api.NetworkRestClient.networks_post',
140
        return_value=FR())
141
    def test_create_network(self, networks_post):
142
        for name, shared in product((None, 'net name'), (None, True)):
143
            FR.json = dict(network='ret val')
144
            type = 'net type'
145
            self.assertEqual(
146
                self.client.create_network(type, name=name, shared=shared),
147
                'ret val')
148
            req = dict(type=type, admin_state_up=True)
149
            if name:
150
                req['name'] = name
151
            if shared:
152
                req['shared'] = shared
153
            expargs = dict(json_data=dict(network=req), success=201)
154
            self.assertEqual(networks_post.mock_calls[-1], call(**expargs))
155

    
156
    @patch(
157
        'kamaki.clients.network.rest_api.NetworkRestClient.ports_post',
158
        return_value=FR)
159
    def test_create_port(self, ports_post):
160
        network_id, device_id, FR.json = 'netid', 'devid', dict(port='ret v')
161
        for name, sec_grp, fixed_ips in product(
162
                ('port name', None),
163
                ([1, 2, 3], None),
164
                (
165
                    [dict(subnet_id='sid', ip_address='ipa')],
166
                    [dict(subnet_id='sid')], [dict(ip_address='ipa')],
167
                    None)):
168

    
169
            if fixed_ips:
170
                diff = set(['ip_address', ]).difference(fixed_ips[0])
171
                if diff:
172
                    self.assertRaises(
173
                        ValueError, self.client.create_port,
174
                        network_id, device_id,
175
                        name=name,
176
                        security_groups=sec_grp,
177
                        fixed_ips=fixed_ips)
178
                    continue
179
            self.assertEqual(
180
                self.client.create_port(
181
                    network_id, device_id,
182
                    name=name, security_groups=sec_grp, fixed_ips=fixed_ips),
183
                'ret v')
184
            req = dict(network_id=network_id, device_id=device_id)
185
            if sec_grp:
186
                req['security_groups'] = sec_grp
187
            if name:
188
                req['name'] = name
189
            if fixed_ips:
190
                req['fixed_ips'] = fixed_ips
191
            expargs = dict(json_data=dict(port=req), success=201)
192
            self.assertEqual(ports_post.mock_calls[-1], call(**expargs))
193

    
194

    
195
class CycladesClient(TestCase):
196

    
197
    def assert_dicts_are_equal(self, d1, d2):
198
        for k, v in d1.items():
199
            self.assertTrue(k in d2)
200
            if isinstance(v, dict):
201
                self.assert_dicts_are_equal(v, d2[k])
202
            else:
203
                self.assertEqual(unicode(v), unicode(d2[k]))
204

    
205
    """Set up a Cyclades thorough test"""
206
    def setUp(self):
207
        self.url = 'http://cyclades.example.com'
208
        self.token = 'cyc14d3s70k3n'
209
        self.client = cyclades.CycladesClient(self.url, self.token)
210

    
211
    def tearDown(self):
212
        FR.status_code = 200
213
        FR.json = vm_recv
214

    
215
    @patch('%s.servers_action_post' % cyclades_pkg, return_value=FR())
216
    def test_shutdown_server(self, SP):
217
        vm_id = vm_recv['server']['id']
218
        self.client.shutdown_server(vm_id)
219
        SP.assert_called_once_with(
220
            vm_id, json_data=dict(shutdown=dict()), success=202)
221

    
222
    @patch('%s.servers_action_post' % cyclades_pkg, return_value=FR())
223
    def test_start_server(self, SP):
224
        vm_id = vm_recv['server']['id']
225
        self.client.start_server(vm_id)
226
        SP.assert_called_once_with(
227
            vm_id, json_data=dict(start=dict()), success=202)
228

    
229
    @patch('%s.servers_action_post' % cyclades_pkg, return_value=FR())
230
    def test_get_server_console(self, SP):
231
        cnsl = dict(console=dict(info1='i1', info2='i2', info3='i3'))
232
        FR.json = cnsl
233
        vm_id = vm_recv['server']['id']
234
        r = self.client.get_server_console(vm_id)
235
        SP.assert_called_once_with(
236
            vm_id, json_data=dict(console=dict(type='vnc')), success=200)
237
        self.assert_dicts_are_equal(r, cnsl['console'])
238

    
239

    
240
if __name__ == '__main__':
241
    from sys import argv
242
    from kamaki.clients.test import runTestCase
243
    not_found = True
244
    if not argv[1:] or argv[1] == 'CycladesClient':
245
        not_found = False
246
        runTestCase(CycladesNetworkClient, 'Cyclades Client', argv[2:])
247
    if not argv[1:] or argv[1] == 'CycladesNetworkClient':
248
        not_found = False
249
        runTestCase(CycladesNetworkClient, 'CycladesNetwork Client', argv[2:])
250
    if not argv[1:] or argv[1] == 'CycladesRestClient':
251
        not_found = False
252
        runTestCase(CycladesRestClient, 'CycladesRest Client', argv[2:])
253
    if not_found:
254
        print('TestCase %s not found' % argv[1])