Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / tests / networks.py @ d58d0327

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

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

    
43
NETWORK_URL = get_service_path(cyclades_services, 'network',
44
                               version='v2.0')
45
NETWORKS_URL = join_urls(NETWORK_URL, "networks/")
46

    
47

    
48
class NetworkTest(BaseAPITest):
49
    def test_list_networks(self):
50
        response = self.get(NETWORKS_URL)
51
        self.assertSuccess(response)
52
        networks = json.loads(response.content)
53
        self.assertEqual(networks, {"networks": []})
54

    
55
    def test_invalid_create(self):
56
        """Test invalid flavor"""
57
        request = {'network': {}}
58
        response = self.post(NETWORKS_URL, "user1", params=json.dumps(request))
59
        self.assertBadRequest(response)
60
        request = {'network': {"type": "foo"}}
61
        response = self.post(NETWORKS_URL, "user1", params=json.dumps(request))
62
        self.assertBadRequest(response)
63
        request = {'network': {"type": "MAC_FILTERED"}}
64
        with override_settings(settings,
65
                               API_ENABLED_NETWORK_FLAVORS=["CUSTOM"]):
66
            response = self.post(NETWORKS_URL, "user1",
67
                                 params=json.dumps(request))
68
        self.assertEqual(response.status_code, 403)
69
        self.assertEqual(len(Network.objects.filter(userid='user1')), 0)
70

    
71
    def test_invalid_create2(self):
72
        """Test invalid name type"""
73
        request = {
74
            "network": {
75
                "type": "MAC_FILTERED",
76
                "name": ["Test", u"I need\u2602"]
77
            }
78
        }
79
        response = self.post(NETWORKS_URL, params=json.dumps(request))
80
        self.assertBadRequest(response)
81

    
82
    def test_create(self):
83
        request = {
84
            "network": {
85
                "name": u"Funky Network\u2602",
86
                "type": "MAC_FILTERED"
87
            }
88
        }
89
        response = self.post(NETWORKS_URL, params=json.dumps(request))
90
        code = response.status_code
91
        self.assertEqual(code, 503)  # No MAC prefix pool
92
        dbmf.MacPrefixPoolTableFactory()
93
        response = self.post(NETWORKS_URL, params=json.dumps(request))
94
        code = response.status_code
95
        self.assertEqual(code, 201)
96
        res = json.loads(response.content)
97
        self.assertEqual(res["network"]["name"], u"Funky Network\u2602")
98

    
99
        # TEST QUOTAS!!!
100
        name, args, kwargs =\
101
            self.mocked_quotaholder.issue_one_commission.mock_calls[0]
102
        commission_resources = args[2]
103
        self.assertEqual(commission_resources, {"cyclades.network.private": 1})
104
        name, args, kwargs =\
105
            self.mocked_quotaholder.resolve_commissions.mock_calls[0]
106
        serial = QuotaHolderSerial.objects.order_by("-serial")[0]
107
        accepted_serials = args[0]
108
        rejected_serials = args[1]
109
        self.assertEqual(accepted_serials, [serial.serial])
110
        self.assertEqual(rejected_serials, [])
111

    
112
        # test no name
113
        request["network"].pop("name")
114
        response = self.post(NETWORKS_URL, params=json.dumps(request))
115
        code = response.status_code
116
        self.assertEqual(code, 201)
117
        res = json.loads(response.content)
118
        self.assertEqual(res["network"]["name"], "")
119

    
120
    def test_get_unfound_network(self):
121
        url = join_urls(NETWORKS_URL, "123")
122
        response = self.get(url)
123
        self.assertItemNotFound(response)
124

    
125
    def test_get_network(self):
126
        test_net = dbmf.NetworkFactory()
127
        url = join_urls(NETWORKS_URL, str(test_net.id))
128
        response = self.get(url, user=test_net.userid)
129
        # validate response
130
        res = json.loads(response.content)
131
        net = res['network']
132
        keys = net.keys()
133
        must_send = set(["status", "subnets", "name", "admin_state_up",
134
                        "tenant_id", "id"])
135
        self.assertEqual(set(keys).issuperset(must_send), True)
136
        self.assertEqual(response.status_code, 200)
137

    
138
    def test_get_deleted_network(self):
139
        test_net = dbmf.NetworkFactory(flavor="CUSTOM")
140
        url = join_urls(NETWORKS_URL, str(test_net.id))
141
        self.delete(url, user=test_net.userid)
142
        response = self.get(url, user=test_net.userid)
143
        self.assertEqual(response.status_code, 200)
144

    
145
    def test_delete_unfound_network(self):
146
        url = join_urls(NETWORKS_URL, "123")
147
        response = self.delete(url)
148
        self.assertItemNotFound(response)
149

    
150
    def test_delete_network(self):
151
        test_net = dbmf.NetworkFactory(flavor="CUSTOM")
152
        dbmf.IPv4SubnetFactory(network=test_net)
153
        url = join_urls(NETWORKS_URL, str(test_net.id))
154
        response = self.delete(url, user=test_net.userid)
155
        self.assertEqual(response.status_code, 204)
156
        # But not the public network!!
157
        test_net.public = True
158
        test_net.save()
159
        response = self.delete(url, user=test_net.userid)
160
        self.assertFault(response, 403, 'forbidden')
161

    
162
    def test_delete_network_in_use(self):
163
        test_net = dbmf.NetworkFactory()
164
        dbmf.NetworkInterfaceFactory(network=test_net)
165
        url = join_urls(NETWORKS_URL, str(test_net.id))
166
        response = self.delete(url, user=test_net.userid)
167
        self.assertEqual(response.status_code, 409)
168

    
169
    def test_delete_network_with_floating_ips(self):
170
        test_net = dbmf.NetworkFactory()
171
        dbmf.IPv4AddressFactory(network=test_net, floating_ip=True, nic=None)
172
        url = join_urls(NETWORKS_URL, str(test_net.id))
173
        response = self.delete(url, user=test_net.userid)
174
        self.assertEqual(response.status_code, 409)
175

    
176
    def test_put_unfound_network(self):
177
        url = join_urls(NETWORKS_URL, "123")
178
        response = self.delete(url)
179
        self.assertItemNotFound(response)
180

    
181
    def test_put_network_wrong_data(self):
182
        test_net = dbmf.NetworkFactory()
183
        url = join_urls(NETWORKS_URL, str(test_net.id))
184
        request = {
185
            "network": {
186
                "wrong_field": "new_name"}
187
        }
188
        response = self.put(url, params=json.dumps(request),
189
                            user=test_net.userid)
190
        self.assertEqual(response.status_code, 400)
191

    
192
    def test_put_no_data(self):
193
        test_net = dbmf.NetworkFactory()
194
        url = join_urls(NETWORKS_URL, str(test_net.id))
195
        response = self.put(url, params="", user=test_net.userid)
196
        self.assertEqual(response.status_code, 400)
197

    
198
    def test_rename_network(self):
199
        test_net = dbmf.NetworkFactory(name="foo")
200
        url = join_urls(NETWORKS_URL, str(test_net.id))
201
        request = {'network': {'name': u"Cloud \u2601"}}
202
        response = self.put(url, test_net.userid, json.dumps(request), 'json')
203
        self.assertEqual(response.status_code, 200)
204
        self.assertEqual(Network.objects.get(id=test_net.id).name,
205
                         u"Cloud \u2601")
206
        # test if server deleted
207
        test_net.deleted = True
208
        test_net.save()
209
        response = self.put(url, test_net.userid, json.dumps(request), 'json')
210
        self.assertBadRequest(response)
211
        test_net.deleted = False
212
        test_net.public = True
213
        test_net.save()
214
        response = self.put(url, test_net.userid, json.dumps(request), 'json')
215
        self.assertFault(response, 403, 'forbidden')
216

    
217
    def test_rename_network_invalid_name(self):
218
        test_net = dbmf.NetworkFactory(name="foo")
219
        url = join_urls(NETWORKS_URL, str(test_net.id))
220
        request = {'network': {'name': 'a' * 500}}
221
        response = self.put(url, test_net.userid, json.dumps(request), 'json')
222
        self.assertEqual(response.status_code, 400)
223

    
224
    def test_method_not_allowed(self, *args):
225
        # /networks/ allows only POST, GET
226
        response = self.put(NETWORKS_URL, '', '')
227
        self.assertMethodNotAllowed(response)
228
        response = self.delete(NETWORKS_URL)
229
        self.assertMethodNotAllowed(response)
230

    
231
        # /networks/<srvid>/ allows only GET, PUT, DELETE
232
        url = join_urls(NETWORKS_URL, "42")
233
        response = self.post(url)
234
        self.assertMethodNotAllowed(response)