Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / test / floating_ips.py @ 9e8be4fb

History | View | Annotate | Download (13.5 kB)

1 acda838e Christos Stavrakakis
# Copyright 2012 GRNET S.A. All rights reserved.
2 acda838e Christos Stavrakakis
#
3 acda838e Christos Stavrakakis
# Redistribution and use in source and binary forms, with or
4 acda838e Christos Stavrakakis
# without modification, are permitted provided that the following
5 acda838e Christos Stavrakakis
# conditions are met:
6 acda838e Christos Stavrakakis
#
7 acda838e Christos Stavrakakis
#   1. Redistributions of source code must retain the above
8 acda838e Christos Stavrakakis
#      copyright notice, this list of conditions and the following
9 acda838e Christos Stavrakakis
#      disclaimer.
10 acda838e Christos Stavrakakis
#
11 acda838e Christos Stavrakakis
#   2. Redistributions in binary form must reproduce the above
12 acda838e Christos Stavrakakis
#      copyright notice, this list of conditions and the following
13 acda838e Christos Stavrakakis
#      disclaimer in the documentation and/or other materials
14 acda838e Christos Stavrakakis
#      provided with the distribution.
15 acda838e Christos Stavrakakis
#
16 acda838e Christos Stavrakakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 acda838e Christos Stavrakakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 acda838e Christos Stavrakakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 acda838e Christos Stavrakakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 acda838e Christos Stavrakakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 acda838e Christos Stavrakakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 acda838e Christos Stavrakakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 acda838e Christos Stavrakakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 acda838e Christos Stavrakakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 acda838e Christos Stavrakakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 acda838e Christos Stavrakakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 acda838e Christos Stavrakakis
# POSSIBILITY OF SUCH DAMAGE.
28 acda838e Christos Stavrakakis
#
29 acda838e Christos Stavrakakis
# The views and conclusions contained in the software and
30 acda838e Christos Stavrakakis
# documentation are those of the authors and should not be
31 acda838e Christos Stavrakakis
# interpreted as representing official policies, either expressed
32 acda838e Christos Stavrakakis
# or implied, of GRNET S.A.
33 acda838e Christos Stavrakakis
34 acda838e Christos Stavrakakis
import json
35 acda838e Christos Stavrakakis
36 acda838e Christos Stavrakakis
from snf_django.utils.testing import BaseAPITest, mocked_quotaholder
37 acda838e Christos Stavrakakis
from synnefo.db.models import FloatingIP
38 a95c82a9 Christos Stavrakakis
from synnefo.db.models_factory import (FloatingIPFactory, NetworkFactory,
39 a95c82a9 Christos Stavrakakis
                                       VirtualMachineFactory,
40 9e8be4fb Christos Stavrakakis
                                       NetworkInterfaceFactory,
41 9e8be4fb Christos Stavrakakis
                                       BackendNetworkFactory)
42 e57893cd Christos Stavrakakis
from mock import patch, Mock
43 acda838e Christos Stavrakakis
44 acda838e Christos Stavrakakis
45 acda838e Christos Stavrakakis
URL = "/api/v1.1/os-floating-ips"
46 acda838e Christos Stavrakakis
47 acda838e Christos Stavrakakis
48 acda838e Christos Stavrakakis
class FloatingIPAPITest(BaseAPITest):
49 acda838e Christos Stavrakakis
    def test_no_floating_ip(self):
50 acda838e Christos Stavrakakis
        response = self.get(URL)
51 acda838e Christos Stavrakakis
        self.assertSuccess(response)
52 acda838e Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ips"], [])
53 acda838e Christos Stavrakakis
54 acda838e Christos Stavrakakis
    def test_list_ips(self):
55 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(userid="user1")
56 acda838e Christos Stavrakakis
        FloatingIPFactory(userid="user1", deleted=True)
57 acda838e Christos Stavrakakis
        with mocked_quotaholder():
58 acda838e Christos Stavrakakis
            response = self.get(URL, "user1")
59 acda838e Christos Stavrakakis
        self.assertSuccess(response)
60 acda838e Christos Stavrakakis
        api_ip = json.loads(response.content)["floating_ips"][0]
61 acda838e Christos Stavrakakis
        self.assertEqual(api_ip,
62 acda838e Christos Stavrakakis
                         {"instance_id": str(ip.machine.id), "ip": ip.ipv4,
63 acda838e Christos Stavrakakis
                          "fixed_ip": None, "id": str(ip.id),  "pool":
64 acda838e Christos Stavrakakis
                          str(ip.network.id)})
65 acda838e Christos Stavrakakis
66 acda838e Christos Stavrakakis
    def test_get_ip(self):
67 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(userid="user1")
68 acda838e Christos Stavrakakis
        with mocked_quotaholder():
69 acda838e Christos Stavrakakis
            response = self.get(URL + "/%s" % ip.id, "user1")
70 acda838e Christos Stavrakakis
        self.assertSuccess(response)
71 acda838e Christos Stavrakakis
        api_ip = json.loads(response.content)["floating_ip"]
72 acda838e Christos Stavrakakis
        self.assertEqual(api_ip,
73 acda838e Christos Stavrakakis
                         {"instance_id": str(ip.machine.id), "ip": ip.ipv4,
74 acda838e Christos Stavrakakis
                          "fixed_ip": None, "id": str(ip.id),  "pool":
75 acda838e Christos Stavrakakis
                          str(ip.network.id)})
76 acda838e Christos Stavrakakis
77 acda838e Christos Stavrakakis
    def test_wrong_user(self):
78 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(userid="user1")
79 acda838e Christos Stavrakakis
        with mocked_quotaholder():
80 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, "user2")
81 acda838e Christos Stavrakakis
        self.assertItemNotFound(response)
82 acda838e Christos Stavrakakis
83 acda838e Christos Stavrakakis
    def test_deleted_ip(self):
84 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(userid="user1", deleted=True)
85 acda838e Christos Stavrakakis
        with mocked_quotaholder():
86 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, "user1")
87 acda838e Christos Stavrakakis
        self.assertItemNotFound(response)
88 acda838e Christos Stavrakakis
89 acda838e Christos Stavrakakis
    def test_reserve(self):
90 acda838e Christos Stavrakakis
        net = NetworkFactory(userid="test_user", subnet="192.168.2.0/24",
91 acda838e Christos Stavrakakis
                             gateway=None, public=True)
92 acda838e Christos Stavrakakis
        request = {'pool': net.id}
93 acda838e Christos Stavrakakis
        with mocked_quotaholder():
94 acda838e Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
95 acda838e Christos Stavrakakis
        self.assertSuccess(response)
96 acda838e Christos Stavrakakis
        ip = FloatingIP.objects.get()
97 acda838e Christos Stavrakakis
        self.assertEqual(ip.ipv4, "192.168.2.1")
98 acda838e Christos Stavrakakis
        self.assertEqual(ip.machine, None)
99 acda838e Christos Stavrakakis
        self.assertEqual(ip.network, net)
100 acda838e Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip"],
101 acda838e Christos Stavrakakis
                         {"instance_id": None, "ip": "192.168.2.1",
102 acda838e Christos Stavrakakis
                          "fixed_ip": None, "id": "1", "pool": "1"})
103 acda838e Christos Stavrakakis
104 9e8be4fb Christos Stavrakakis
    def test_reserve_no_pool(self):
105 9e8be4fb Christos Stavrakakis
        # No networks
106 9e8be4fb Christos Stavrakakis
        with mocked_quotaholder():
107 9e8be4fb Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps({}), "json")
108 9e8be4fb Christos Stavrakakis
        self.assertFault(response, 413, "overLimit")
109 9e8be4fb Christos Stavrakakis
        # Full network
110 9e8be4fb Christos Stavrakakis
        net = NetworkFactory(userid="test_user", subnet="192.168.2.0/32",
111 9e8be4fb Christos Stavrakakis
                             gateway=None, public=True)
112 9e8be4fb Christos Stavrakakis
        with mocked_quotaholder():
113 9e8be4fb Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps({}), "json")
114 9e8be4fb Christos Stavrakakis
        self.assertFault(response, 413, "overLimit")
115 9e8be4fb Christos Stavrakakis
        # Success
116 9e8be4fb Christos Stavrakakis
        net2 = NetworkFactory(userid="test_user", subnet="192.168.2.0/24",
117 9e8be4fb Christos Stavrakakis
                              gateway=None, public=True)
118 9e8be4fb Christos Stavrakakis
        with mocked_quotaholder():
119 9e8be4fb Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps({}), "json")
120 9e8be4fb Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip"],
121 9e8be4fb Christos Stavrakakis
                         {"instance_id": None, "ip": "192.168.2.1",
122 9e8be4fb Christos Stavrakakis
                          "fixed_ip": None, "id": "1", "pool": str(net2.id)})
123 9e8be4fb Christos Stavrakakis
124 acda838e Christos Stavrakakis
    def test_reserve_full(self):
125 acda838e Christos Stavrakakis
        net = NetworkFactory(userid="test_user", subnet="192.168.2.0/32",
126 acda838e Christos Stavrakakis
                             gateway=None, public=True)
127 acda838e Christos Stavrakakis
        request = {'pool': net.id}
128 acda838e Christos Stavrakakis
        with mocked_quotaholder():
129 acda838e Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
130 acda838e Christos Stavrakakis
        self.assertEqual(response.status_code, 413)
131 acda838e Christos Stavrakakis
132 a3d99af0 Christos Stavrakakis
    def test_reserve_with_address(self):
133 a3d99af0 Christos Stavrakakis
        net = NetworkFactory(userid="test_user", subnet="192.168.2.0/24",
134 a3d99af0 Christos Stavrakakis
                             gateway=None, public=True)
135 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.2.10"}
136 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
137 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
138 a3d99af0 Christos Stavrakakis
        self.assertSuccess(response)
139 a3d99af0 Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip"],
140 a3d99af0 Christos Stavrakakis
                         {"instance_id": None, "ip": "192.168.2.10",
141 a3d99af0 Christos Stavrakakis
                          "fixed_ip": None, "id": "1", "pool": "1"})
142 a3d99af0 Christos Stavrakakis
143 a3d99af0 Christos Stavrakakis
        # Already reserved
144 a3d99af0 Christos Stavrakakis
        FloatingIPFactory(network=net, ipv4="192.168.2.3")
145 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.2.3"}
146 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
147 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
148 a3d99af0 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
149 a3d99af0 Christos Stavrakakis
150 a3d99af0 Christos Stavrakakis
        # Already used
151 a3d99af0 Christos Stavrakakis
        pool = net.get_pool()
152 a3d99af0 Christos Stavrakakis
        pool.reserve("192.168.2.5")
153 a3d99af0 Christos Stavrakakis
        pool.save()
154 a3d99af0 Christos Stavrakakis
        # ..by another_user
155 a3d99af0 Christos Stavrakakis
        nic = NetworkInterfaceFactory(network=net, ipv4="192.168.2.5",
156 a3d99af0 Christos Stavrakakis
                                      machine__userid="test2")
157 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.2.5"}
158 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
159 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
160 a3d99af0 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
161 a3d99af0 Christos Stavrakakis
        # ..and by him
162 a3d99af0 Christos Stavrakakis
        nic.delete()
163 a3d99af0 Christos Stavrakakis
        NetworkInterfaceFactory(network=net, ipv4="192.168.2.5",
164 a3d99af0 Christos Stavrakakis
                                machine__userid="test_user")
165 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.2.5"}
166 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
167 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
168 a3d99af0 Christos Stavrakakis
        self.assertSuccess(response)
169 a3d99af0 Christos Stavrakakis
170 a3d99af0 Christos Stavrakakis
        # Address out of pool
171 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.3.5"}
172 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
173 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
174 a3d99af0 Christos Stavrakakis
        self.assertBadRequest(response)
175 a3d99af0 Christos Stavrakakis
176 acda838e Christos Stavrakakis
    def test_release_in_use(self):
177 acda838e Christos Stavrakakis
        ip = FloatingIPFactory()
178 a95c82a9 Christos Stavrakakis
        vm = ip.machine
179 a95c82a9 Christos Stavrakakis
        vm.operstate = "ACTIVE"
180 a95c82a9 Christos Stavrakakis
        vm.userid = ip.userid
181 a95c82a9 Christos Stavrakakis
        vm.save()
182 a95c82a9 Christos Stavrakakis
        vm.nics.create(index=0, ipv4=ip.ipv4, network=ip.network,
183 a95c82a9 Christos Stavrakakis
                       state="ACTIVE")
184 a95c82a9 Christos Stavrakakis
        with mocked_quotaholder():
185 a95c82a9 Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, ip.userid)
186 a95c82a9 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
187 a95c82a9 Christos Stavrakakis
        # Also send a notification to remove the NIC and assert that FIP is in
188 a95c82a9 Christos Stavrakakis
        # use until notification from ganeti arrives
189 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": ip.ipv4}}
190 a95c82a9 Christos Stavrakakis
        url = "/api/v1.1/servers/%s/action" % vm.id
191 a95c82a9 Christos Stavrakakis
        with patch('synnefo.logic.rapi_pool.GanetiRapiClient') as c:
192 a95c82a9 Christos Stavrakakis
            c().ModifyInstance.return_value = 10
193 a95c82a9 Christos Stavrakakis
            response = self.post(url, vm.userid, json.dumps(request),
194 a95c82a9 Christos Stavrakakis
                                 "json")
195 a95c82a9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
196 acda838e Christos Stavrakakis
        with mocked_quotaholder():
197 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, ip.userid)
198 acda838e Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
199 acda838e Christos Stavrakakis
200 acda838e Christos Stavrakakis
    def test_release(self):
201 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(machine=None)
202 acda838e Christos Stavrakakis
        with mocked_quotaholder():
203 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, ip.userid)
204 acda838e Christos Stavrakakis
        self.assertSuccess(response)
205 acda838e Christos Stavrakakis
        ips_after = FloatingIP.objects.filter(id=ip.id)
206 acda838e Christos Stavrakakis
        self.assertEqual(len(ips_after), 0)
207 7d368e73 Christos Stavrakakis
208 e57893cd Christos Stavrakakis
    @patch("synnefo.logic.backend", Mock())
209 e57893cd Christos Stavrakakis
    def test_delete_network_with_floating_ips(self):
210 9e8be4fb Christos Stavrakakis
        ip = FloatingIPFactory(machine=None, network__flavor="IP_LESS_ROUTED")
211 e57893cd Christos Stavrakakis
        net = ip.network
212 e57893cd Christos Stavrakakis
        # Can not remove network with floating IPs
213 e57893cd Christos Stavrakakis
        with mocked_quotaholder():
214 e57893cd Christos Stavrakakis
            response = self.delete("/api/v1.1/networks/%s" % net.id,
215 e57893cd Christos Stavrakakis
                                   net.userid)
216 e57893cd Christos Stavrakakis
        self.assertFault(response, 421, "networkInUse")
217 e57893cd Christos Stavrakakis
        # But we can with only deleted Floating Ips
218 e57893cd Christos Stavrakakis
        ip.deleted = True
219 e57893cd Christos Stavrakakis
        ip.save()
220 e57893cd Christos Stavrakakis
        with mocked_quotaholder():
221 e57893cd Christos Stavrakakis
            response = self.delete("/api/v1.1/networks/%s" % net.id,
222 e57893cd Christos Stavrakakis
                                   net.userid)
223 e57893cd Christos Stavrakakis
        self.assertSuccess(response)
224 e57893cd Christos Stavrakakis
225 7d368e73 Christos Stavrakakis
226 7d368e73 Christos Stavrakakis
POOLS_URL = "/api/v1.1/os-floating-ip-pools"
227 7d368e73 Christos Stavrakakis
228 7d368e73 Christos Stavrakakis
229 7d368e73 Christos Stavrakakis
class FloatingIPPoolsAPITest(BaseAPITest):
230 7d368e73 Christos Stavrakakis
    def test_no_pool(self):
231 7d368e73 Christos Stavrakakis
        response = self.get(POOLS_URL)
232 7d368e73 Christos Stavrakakis
        self.assertSuccess(response)
233 7d368e73 Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip_pools"], [])
234 7d368e73 Christos Stavrakakis
235 7d368e73 Christos Stavrakakis
    def test_list_pools(self):
236 7d368e73 Christos Stavrakakis
        net = NetworkFactory(public=True, deleted=False)
237 7d368e73 Christos Stavrakakis
        NetworkFactory(public=True, deleted=True)
238 7d368e73 Christos Stavrakakis
        NetworkFactory(public=False, deleted=False)
239 7d368e73 Christos Stavrakakis
        response = self.get(POOLS_URL)
240 7d368e73 Christos Stavrakakis
        self.assertSuccess(response)
241 7d368e73 Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip_pools"],
242 7d368e73 Christos Stavrakakis
                        [{"name": str(net.id)}])
243 a95c82a9 Christos Stavrakakis
244 a95c82a9 Christos Stavrakakis
245 a95c82a9 Christos Stavrakakis
class FloatingIPActionsTest(BaseAPITest):
246 a95c82a9 Christos Stavrakakis
    def setUp(self):
247 a95c82a9 Christos Stavrakakis
        vm = VirtualMachineFactory()
248 a95c82a9 Christos Stavrakakis
        vm.operstate = "ACTIVE"
249 a95c82a9 Christos Stavrakakis
        vm.save()
250 a95c82a9 Christos Stavrakakis
        self.vm = vm
251 a95c82a9 Christos Stavrakakis
252 a95c82a9 Christos Stavrakakis
    def test_bad_request(self):
253 a95c82a9 Christos Stavrakakis
        url = "/api/v1.1/servers/%s/action" % self.vm.id
254 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps({}), "json")
255 a95c82a9 Christos Stavrakakis
        self.assertBadRequest(response)
256 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid,
257 a95c82a9 Christos Stavrakakis
                             json.dumps({"addFloatingIp": {}}),
258 a95c82a9 Christos Stavrakakis
                             "json")
259 a95c82a9 Christos Stavrakakis
        self.assertBadRequest(response)
260 a95c82a9 Christos Stavrakakis
261 a95c82a9 Christos Stavrakakis
    @patch('synnefo.logic.rapi_pool.GanetiRapiClient')
262 a95c82a9 Christos Stavrakakis
    def test_add_floating_ip(self, mock):
263 a95c82a9 Christos Stavrakakis
        # Not exists
264 a95c82a9 Christos Stavrakakis
        url = "/api/v1.1/servers/%s/action" % self.vm.id
265 a95c82a9 Christos Stavrakakis
        request = {"addFloatingIp": {"address": "10.0.0.1"}}
266 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
267 a95c82a9 Christos Stavrakakis
        self.assertItemNotFound(response)
268 a95c82a9 Christos Stavrakakis
        # In use
269 a95c82a9 Christos Stavrakakis
        vm1 = VirtualMachineFactory()
270 a95c82a9 Christos Stavrakakis
        ip1 = FloatingIPFactory(userid=self.vm.userid, machine=vm1)
271 9e8be4fb Christos Stavrakakis
        BackendNetworkFactory(network=ip1.network, backend=vm1.backend,
272 9e8be4fb Christos Stavrakakis
                              operstate='ACTIVE')
273 a95c82a9 Christos Stavrakakis
        request = {"addFloatingIp": {"address": ip1.ipv4}}
274 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
275 a95c82a9 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
276 a95c82a9 Christos Stavrakakis
        # Success
277 a95c82a9 Christos Stavrakakis
        ip1 = FloatingIPFactory(userid=self.vm.userid, machine=None)
278 9e8be4fb Christos Stavrakakis
        BackendNetworkFactory(network=ip1.network, backend=self.vm.backend,
279 9e8be4fb Christos Stavrakakis
                              operstate='ACTIVE')
280 a95c82a9 Christos Stavrakakis
        request = {"addFloatingIp": {"address": ip1.ipv4}}
281 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
282 a95c82a9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
283 a95c82a9 Christos Stavrakakis
        ip1_after = FloatingIP.objects.get(id=ip1.id)
284 a95c82a9 Christos Stavrakakis
        self.assertEqual(ip1_after.machine, self.vm)
285 a95c82a9 Christos Stavrakakis
        self.assertTrue(ip1_after.in_use())
286 a95c82a9 Christos Stavrakakis
287 a95c82a9 Christos Stavrakakis
    @patch('synnefo.logic.rapi_pool.GanetiRapiClient')
288 a95c82a9 Christos Stavrakakis
    def test_remove_floating_ip(self, mock):
289 a95c82a9 Christos Stavrakakis
        # Not exists
290 a95c82a9 Christos Stavrakakis
        url = "/api/v1.1/servers/%s/action" % self.vm.id
291 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": "10.0.0.1"}}
292 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
293 a95c82a9 Christos Stavrakakis
        self.assertItemNotFound(response)
294 a95c82a9 Christos Stavrakakis
        # Not In Use
295 a95c82a9 Christos Stavrakakis
        ip1 = FloatingIPFactory(userid=self.vm.userid, machine=None)
296 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": ip1.ipv4}}
297 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
298 a95c82a9 Christos Stavrakakis
        self.assertItemNotFound(response)
299 a95c82a9 Christos Stavrakakis
        # Success
300 a95c82a9 Christos Stavrakakis
        ip1 = FloatingIPFactory(userid=self.vm.userid, machine=self.vm)
301 a95c82a9 Christos Stavrakakis
        NetworkInterfaceFactory(machine=self.vm, ipv4=ip1.ipv4)
302 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": ip1.ipv4}}
303 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
304 a95c82a9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
305 a95c82a9 Christos Stavrakakis
        # Yet used. Wait for the callbacks
306 a95c82a9 Christos Stavrakakis
        ip1_after = FloatingIP.objects.get(id=ip1.id)
307 a95c82a9 Christos Stavrakakis
        self.assertEqual(ip1_after.machine, self.vm)
308 a95c82a9 Christos Stavrakakis
        self.assertTrue(ip1_after.in_use())