Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / tests / ports.py @ f32e8021

History | View | Annotate | Download (13.4 kB)

1
# Copyright 2011-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.i
33

    
34
from django.conf import settings
35
from snf_django.utils.testing import BaseAPITest, override_settings
36
from django.utils import simplejson as json
37
from synnefo.cyclades_settings import cyclades_services
38
from synnefo.lib.services import get_service_path
39
from synnefo.lib import join_urls
40
from mock import patch
41
import synnefo.db.models_factory as dbmf
42

    
43
COMPUTE_URL = get_service_path(cyclades_services, 'compute',
44
                               version='v2.0')
45
PORTS_URL = join_urls(COMPUTE_URL, "ports/")
46

    
47

    
48
class PortTest(BaseAPITest):
49
    def test_get_ports(self):
50
        url = join_urls(PORTS_URL)
51
        response = self.get(url)
52
        self.assertEqual(response.status_code, 200)
53
        ports = json.loads(response.content)
54
        self.assertEqual(ports, {"ports": []})
55

    
56
    def test_get_port_unfound(self):
57
        url = join_urls(PORTS_URL, "123")
58
        response = self.get(url)
59
        self.assertEqual(response.status_code, 404)
60

    
61
    def test_get_port(self):
62
        nic = dbmf.NetworkInterfaceFactory()
63
        url = join_urls(PORTS_URL, str(nic.id))
64
        response = self.get(url, user=nic.network.userid)
65
        self.assertEqual(response.status_code, 200)
66

    
67
    @patch("synnefo.db.models.get_rapi_client")
68
    def test_delete_port(self, mrapi):
69
        nic = dbmf.NetworkInterfaceFactory(device_owner='vm')
70
        url = join_urls(PORTS_URL, str(nic.id))
71
        mrapi().ModifyInstance.return_value = 42
72
        with override_settings(settings, GANETI_USE_HOTPLUG=True):
73
            response = self.delete(url, user=nic.network.userid)
74
        self.assertEqual(response.status_code, 204)
75
        with override_settings(settings, GANETI_USE_HOTPLUG=False):
76
            response = self.delete(url, user=nic.network.userid)
77
        self.assertEqual(response.status_code, 400)
78

    
79
    def test_delete_port_from_nonvm(self):
80
        nic = dbmf.NetworkInterfaceFactory(device_owner='router')
81
        url = join_urls(PORTS_URL, str(nic.id))
82
        response = self.delete(url, user=nic.network.userid)
83
        self.assertEqual(response.status_code, 400)
84

    
85
    def test_remove_nic_malformed(self):
86
        url = join_urls(PORTS_URL, "123")
87
        response = self.delete(url)
88
        self.assertItemNotFound(response)
89

    
90
    def test_update_port_name(self):
91
        nic = dbmf.NetworkInterfaceFactory(device_owner='vm')
92
        url = join_urls(PORTS_URL, str(nic.id))
93
        request = {'port': {"name": "test-name"}}
94
        response = self.put(url, params=json.dumps(request),
95
                            user=nic.network.userid)
96
        self.assertEqual(response.status_code, 200)
97
        res = json.loads(response.content)
98
        self.assertEqual(res['port']['name'], "test-name")
99

    
100
    def test_update_port_sg_unfound(self):
101
        sg1 = dbmf.SecurityGroupFactory()
102
        nic = dbmf.NetworkInterfaceFactory(device_owner='vm')
103
        nic.security_groups.add(sg1)
104
        nic.save()
105
        url = join_urls(PORTS_URL, str(nic.id))
106
        request = {'port': {"security_groups": ["123"]}}
107
        response = self.put(url, params=json.dumps(request),
108
                            user=nic.network.userid)
109
        self.assertEqual(response.status_code, 404)
110

    
111
    def test_update_port_sg(self):
112
        sg1 = dbmf.SecurityGroupFactory()
113
        sg2 = dbmf.SecurityGroupFactory()
114
        sg3 = dbmf.SecurityGroupFactory()
115
        nic = dbmf.NetworkInterfaceFactory(device_owner='vm')
116
        nic.security_groups.add(sg1)
117
        nic.save()
118
        url = join_urls(PORTS_URL, str(nic.id))
119
        request = {'port': {"security_groups": [str(sg2.id), str(sg3.id)]}}
120
        response = self.put(url, params=json.dumps(request),
121
                            user=nic.network.userid)
122
        res = json.loads(response.content)
123
        self.assertEqual(res['port']['security_groups'],
124
                         [str(sg2.id), str(sg3.id)])
125

    
126
    def test_create_port_no_network(self):
127
        request = {
128
            "port": {
129
                "device_id": "123",
130
                "name": "port1",
131
                "network_id": "123"
132
            }
133
        }
134
        response = self.post(PORTS_URL, params=json.dumps(request))
135
        self.assertEqual(response.status_code, 404)
136

    
137
    @patch("synnefo.db.models.get_rapi_client")
138
    def test_create_port_private_net(self, mrapi):
139
        net = dbmf.NetworkFactory(public=False)
140
        dbmf.IPv4SubnetFactory(network=net)
141
        dbmf.IPv6SubnetFactory(network=net)
142
        sg1 = dbmf.SecurityGroupFactory()
143
        sg2 = dbmf.SecurityGroupFactory()
144
        vm = dbmf.VirtualMachineFactory(userid=net.userid)
145
        request = {
146
            "port": {
147
                "name": "port1",
148
                "network_id": str(net.id),
149
                "device_id": str(vm.id),
150
                "security_groups": [str(sg1.id), str(sg2.id)]
151
            }
152
        }
153
        mrapi().ModifyInstance.return_value = 42
154
        with override_settings(settings, GANETI_USE_HOTPLUG=False):
155
            response = self.post(PORTS_URL, params=json.dumps(request),
156
                                 user=net.userid)
157
        self.assertEqual(response.status_code, 400)
158
        with override_settings(settings, GANETI_USE_HOTPLUG=True):
159
            response = self.post(PORTS_URL, params=json.dumps(request),
160
                                 user=net.userid)
161
        self.assertEqual(response.status_code, 201)
162

    
163
    def test_create_port_public_net_no_ip(self):
164
        net = dbmf.NetworkFactory(public=True)
165
        vm = dbmf.VirtualMachineFactory(userid=net.userid)
166
        request = {
167
            "port": {
168
                "name": "port1",
169
                "network_id": str(net.id),
170
                "device_id": str(vm.id),
171
            }
172
        }
173
        response = self.post(PORTS_URL, params=json.dumps(request),
174
                             user=net.userid)
175
        self.assertEqual(response.status_code, 400)
176

    
177
    def test_create_port_public_net_wrong_ip(self):
178
        net = dbmf.NetworkFactory(public=True)
179
        vm = dbmf.VirtualMachineFactory(userid=net.userid)
180
        request = {
181
            "port": {
182
                "name": "port1",
183
                "network_id": str(net.id),
184
                "device_id": str(vm.id),
185
                "fixed_ips": [{"ip_address": "8.8.8.8"}]
186
            }
187
        }
188
        response = self.post(PORTS_URL, params=json.dumps(request),
189
                             user=net.userid)
190
        self.assertEqual(response.status_code, 404)
191

    
192
    def test_create_port_public_net_conflict(self):
193
        net = dbmf.NetworkFactory(public=True)
194
        fip = dbmf.FloatingIPFactory(nic=None, userid=net.userid)
195
        vm = dbmf.VirtualMachineFactory(userid=net.userid)
196
        request = {
197
            "port": {
198
                "name": "port1",
199
                "network_id": str(net.id),
200
                "device_id": str(vm.id),
201
                "fixed_ips": [{"ip_address": fip.address}]
202
            }
203
        }
204
        response = self.post(PORTS_URL, params=json.dumps(request),
205
                             user=net.userid)
206
        self.assertEqual(response.status_code, 409)
207

    
208
    def test_create_port_public_net_taken_ip(self):
209
        net = dbmf.NetworkFactory(public=True)
210
        fip = dbmf.FloatingIPFactory(network=net, userid=net.userid)
211
        vm = dbmf.VirtualMachineFactory(userid=net.userid)
212
        request = {
213
            "port": {
214
                "name": "port1",
215
                "network_id": str(net.id),
216
                "device_id": str(vm.id),
217
                "fixed_ips": [{"ip_address": fip.address}]
218
            }
219
        }
220
        response = self.post(PORTS_URL, params=json.dumps(request),
221
                             user=net.userid)
222
        self.assertEqual(response.status_code, 409)
223

    
224
    @patch("synnefo.db.models.get_rapi_client")
225
    def test_create_port_with_floating_ip(self, mrapi):
226
        vm = dbmf.VirtualMachineFactory()
227
        fip = dbmf.FloatingIPFactory(network__public=True, nic=None,
228
                                     userid=vm.userid)
229
        request = {
230
            "port": {
231
                "name": "port1",
232
                "network_id": str(fip.network_id),
233
                "device_id": str(vm.id),
234
                "fixed_ips": [{"ip_address": fip.address}]
235
            }
236
        }
237
        mrapi().ModifyInstance.return_value = 42
238
        with override_settings(settings, GANETI_USE_HOTPLUG=True):
239
            response = self.post(PORTS_URL, params=json.dumps(request),
240
                                 user=vm.userid)
241
        self.assertEqual(response.status_code, 201)
242

    
243
    def test_add_nic_to_deleted_network(self):
244
        user = 'userr'
245
        vm = dbmf.VirtualMachineFactory(name='yo', userid=user,
246
                                        operstate="ACTIVE")
247
        net = dbmf.NetworkFactory(state='ACTIVE', userid=user,
248
                                  deleted=True)
249
        request = {
250
            "port": {
251
                "device_id": str(vm.id),
252
                "name": "port1",
253
                "network_id": str(net.id)
254
            }
255
        }
256
        response = self.post(PORTS_URL, params=json.dumps(request),
257
                             user=net.userid)
258
        self.assertBadRequest(response)
259

    
260
    def test_add_nic_to_public_network(self):
261
        user = 'userr'
262
        vm = dbmf.VirtualMachineFactory(name='yo', userid=user)
263
        net = dbmf.NetworkFactory(state='ACTIVE', userid=user, public=True)
264
        request = {
265
            "port": {
266
                "device_id": str(vm.id),
267
                "name": "port1",
268
                "network_id": str(net.id)
269
            }
270
        }
271
        response = self.post(PORTS_URL, params=json.dumps(request),
272
                             user=net.userid)
273
        self.assertBadRequest(response)
274
        #self.assertFault(response, 403, 'forbidden')
275

    
276
    def test_add_nic_malformed_1(self):
277
        user = 'userr'
278
        dbmf.VirtualMachineFactory(name='yo', userid=user)
279
        net = dbmf.NetworkFactory(state='ACTIVE', userid=user)
280
        request = {
281
            "port": {
282
                "name": "port1",
283
                "network_id": str(net.id)
284
            }
285
        }
286
        response = self.post(PORTS_URL, params=json.dumps(request),
287
                             user=net.userid)
288
        self.assertBadRequest(response)
289

    
290
    def test_add_nic_malformed_2(self):
291
        user = 'userr'
292
        vm = dbmf.VirtualMachineFactory(name='yo', userid=user)
293
        net = dbmf.NetworkFactory(state='ACTIVE', userid=user)
294
        request = {
295
            "port": {
296
                "device_id": str(vm.id),
297
                "name": "port1"
298
            }
299
        }
300
        response = self.post(PORTS_URL, params=json.dumps(request),
301
                             user=net.userid)
302
        self.assertBadRequest(response)
303

    
304
    def test_add_nic_not_active(self):
305
        """Test connecting VM to non-active network"""
306
        user = 'dummy'
307
        vm = dbmf.VirtualMachineFactory(name='yo', userid=user)
308
        net = dbmf.NetworkFactory(state='PENDING', userid=user)
309
        request = {
310
            "port": {
311
                "device_id": str(vm.id),
312
                "name": "port1",
313
                "network_id": str(net.id)
314
            }
315
        }
316
        response = self.post(PORTS_URL, params=json.dumps(request),
317
                             user=net.userid)
318
        # Test that returns BuildInProgress
319
        self.assertEqual(response.status_code, 409)
320

    
321
#    def test_add_nic_full_network(self, mrapi):
322
#        """Test connecting VM to a full network"""
323
#        user = 'userr'
324
#        vm = dbmf.VirtualMachineFactory(name='yo', userid=user,
325
#                                            operstate="STARTED")
326
#        net = dbmf.NetworkFactory(state='ACTIVE', subnet='10.0.0.0/30',
327
#                                      userid=user, dhcp=True)
328
#        pool = net.get_pool()
329
#        while not pool.empty():
330
#            pool.get()
331
#        pool.save()
332
#        pool = net.get_pool()
333
#        self.assertTrue(pool.empty())
334
#        request = {'add': {'serverRef': vm.id}}
335
#        response = self.mypost('networks/%d/action' % net.id,
336
#                               net.userid, json.dumps(request), 'json')
337
#        # Test that returns OverLimit
338
#        self.assertEqual(response.status_code, 413)
339
#        self.assertFalse(mrapi.called)