Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (12.1 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 a95c82a9 Christos Stavrakakis
                                       NetworkInterfaceFactory)
41 e57893cd Christos Stavrakakis
from mock import patch, Mock
42 acda838e Christos Stavrakakis
43 acda838e Christos Stavrakakis
44 acda838e Christos Stavrakakis
URL = "/api/v1.1/os-floating-ips"
45 acda838e Christos Stavrakakis
46 acda838e Christos Stavrakakis
47 acda838e Christos Stavrakakis
class FloatingIPAPITest(BaseAPITest):
48 acda838e Christos Stavrakakis
    def test_no_floating_ip(self):
49 acda838e Christos Stavrakakis
        response = self.get(URL)
50 acda838e Christos Stavrakakis
        self.assertSuccess(response)
51 acda838e Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ips"], [])
52 acda838e Christos Stavrakakis
53 acda838e Christos Stavrakakis
    def test_list_ips(self):
54 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(userid="user1")
55 acda838e Christos Stavrakakis
        FloatingIPFactory(userid="user1", deleted=True)
56 acda838e Christos Stavrakakis
        with mocked_quotaholder():
57 acda838e Christos Stavrakakis
            response = self.get(URL, "user1")
58 acda838e Christos Stavrakakis
        self.assertSuccess(response)
59 acda838e Christos Stavrakakis
        api_ip = json.loads(response.content)["floating_ips"][0]
60 acda838e Christos Stavrakakis
        self.assertEqual(api_ip,
61 acda838e Christos Stavrakakis
                         {"instance_id": str(ip.machine.id), "ip": ip.ipv4,
62 acda838e Christos Stavrakakis
                          "fixed_ip": None, "id": str(ip.id),  "pool":
63 acda838e Christos Stavrakakis
                          str(ip.network.id)})
64 acda838e Christos Stavrakakis
65 acda838e Christos Stavrakakis
    def test_get_ip(self):
66 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(userid="user1")
67 acda838e Christos Stavrakakis
        with mocked_quotaholder():
68 acda838e Christos Stavrakakis
            response = self.get(URL + "/%s" % ip.id, "user1")
69 acda838e Christos Stavrakakis
        self.assertSuccess(response)
70 acda838e Christos Stavrakakis
        api_ip = json.loads(response.content)["floating_ip"]
71 acda838e Christos Stavrakakis
        self.assertEqual(api_ip,
72 acda838e Christos Stavrakakis
                         {"instance_id": str(ip.machine.id), "ip": ip.ipv4,
73 acda838e Christos Stavrakakis
                          "fixed_ip": None, "id": str(ip.id),  "pool":
74 acda838e Christos Stavrakakis
                          str(ip.network.id)})
75 acda838e Christos Stavrakakis
76 acda838e Christos Stavrakakis
    def test_wrong_user(self):
77 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(userid="user1")
78 acda838e Christos Stavrakakis
        with mocked_quotaholder():
79 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, "user2")
80 acda838e Christos Stavrakakis
        self.assertItemNotFound(response)
81 acda838e Christos Stavrakakis
82 acda838e Christos Stavrakakis
    def test_deleted_ip(self):
83 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(userid="user1", deleted=True)
84 acda838e Christos Stavrakakis
        with mocked_quotaholder():
85 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, "user1")
86 acda838e Christos Stavrakakis
        self.assertItemNotFound(response)
87 acda838e Christos Stavrakakis
88 acda838e Christos Stavrakakis
    def test_reserve(self):
89 acda838e Christos Stavrakakis
        net = NetworkFactory(userid="test_user", subnet="192.168.2.0/24",
90 acda838e Christos Stavrakakis
                             gateway=None, public=True)
91 acda838e Christos Stavrakakis
        request = {'pool': net.id}
92 acda838e Christos Stavrakakis
        with mocked_quotaholder():
93 acda838e Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
94 acda838e Christos Stavrakakis
        self.assertSuccess(response)
95 acda838e Christos Stavrakakis
        ip = FloatingIP.objects.get()
96 acda838e Christos Stavrakakis
        self.assertEqual(ip.ipv4, "192.168.2.1")
97 acda838e Christos Stavrakakis
        self.assertEqual(ip.machine, None)
98 acda838e Christos Stavrakakis
        self.assertEqual(ip.network, net)
99 acda838e Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip"],
100 acda838e Christos Stavrakakis
                         {"instance_id": None, "ip": "192.168.2.1",
101 acda838e Christos Stavrakakis
                          "fixed_ip": None, "id": "1", "pool": "1"})
102 acda838e Christos Stavrakakis
103 acda838e Christos Stavrakakis
    def test_reserve_full(self):
104 acda838e Christos Stavrakakis
        net = NetworkFactory(userid="test_user", subnet="192.168.2.0/32",
105 acda838e Christos Stavrakakis
                             gateway=None, public=True)
106 acda838e Christos Stavrakakis
        request = {'pool': net.id}
107 acda838e Christos Stavrakakis
        with mocked_quotaholder():
108 acda838e Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
109 acda838e Christos Stavrakakis
        self.assertEqual(response.status_code, 413)
110 acda838e Christos Stavrakakis
111 a3d99af0 Christos Stavrakakis
    def test_reserve_with_address(self):
112 a3d99af0 Christos Stavrakakis
        net = NetworkFactory(userid="test_user", subnet="192.168.2.0/24",
113 a3d99af0 Christos Stavrakakis
                             gateway=None, public=True)
114 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.2.10"}
115 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
116 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
117 a3d99af0 Christos Stavrakakis
        self.assertSuccess(response)
118 a3d99af0 Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip"],
119 a3d99af0 Christos Stavrakakis
                         {"instance_id": None, "ip": "192.168.2.10",
120 a3d99af0 Christos Stavrakakis
                          "fixed_ip": None, "id": "1", "pool": "1"})
121 a3d99af0 Christos Stavrakakis
122 a3d99af0 Christos Stavrakakis
        # Already reserved
123 a3d99af0 Christos Stavrakakis
        FloatingIPFactory(network=net, ipv4="192.168.2.3")
124 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.2.3"}
125 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
126 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
127 a3d99af0 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
128 a3d99af0 Christos Stavrakakis
129 a3d99af0 Christos Stavrakakis
        # Already used
130 a3d99af0 Christos Stavrakakis
        pool = net.get_pool()
131 a3d99af0 Christos Stavrakakis
        pool.reserve("192.168.2.5")
132 a3d99af0 Christos Stavrakakis
        pool.save()
133 a3d99af0 Christos Stavrakakis
        # ..by another_user
134 a3d99af0 Christos Stavrakakis
        nic = NetworkInterfaceFactory(network=net, ipv4="192.168.2.5",
135 a3d99af0 Christos Stavrakakis
                                      machine__userid="test2")
136 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.2.5"}
137 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
138 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
139 a3d99af0 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
140 a3d99af0 Christos Stavrakakis
        # ..and by him
141 a3d99af0 Christos Stavrakakis
        nic.delete()
142 a3d99af0 Christos Stavrakakis
        NetworkInterfaceFactory(network=net, ipv4="192.168.2.5",
143 a3d99af0 Christos Stavrakakis
                                machine__userid="test_user")
144 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.2.5"}
145 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
146 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
147 a3d99af0 Christos Stavrakakis
        self.assertSuccess(response)
148 a3d99af0 Christos Stavrakakis
149 a3d99af0 Christos Stavrakakis
        # Address out of pool
150 a3d99af0 Christos Stavrakakis
        request = {'pool': net.id, "address": "192.168.3.5"}
151 a3d99af0 Christos Stavrakakis
        with mocked_quotaholder():
152 a3d99af0 Christos Stavrakakis
            response = self.post(URL, "test_user", json.dumps(request), "json")
153 a3d99af0 Christos Stavrakakis
        self.assertBadRequest(response)
154 a3d99af0 Christos Stavrakakis
155 acda838e Christos Stavrakakis
    def test_release_in_use(self):
156 acda838e Christos Stavrakakis
        ip = FloatingIPFactory()
157 a95c82a9 Christos Stavrakakis
        vm = ip.machine
158 a95c82a9 Christos Stavrakakis
        vm.operstate = "ACTIVE"
159 a95c82a9 Christos Stavrakakis
        vm.userid = ip.userid
160 a95c82a9 Christos Stavrakakis
        vm.save()
161 a95c82a9 Christos Stavrakakis
        vm.nics.create(index=0, ipv4=ip.ipv4, network=ip.network,
162 a95c82a9 Christos Stavrakakis
                       state="ACTIVE")
163 a95c82a9 Christos Stavrakakis
        with mocked_quotaholder():
164 a95c82a9 Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, ip.userid)
165 a95c82a9 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
166 a95c82a9 Christos Stavrakakis
        # Also send a notification to remove the NIC and assert that FIP is in
167 a95c82a9 Christos Stavrakakis
        # use until notification from ganeti arrives
168 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": ip.ipv4}}
169 a95c82a9 Christos Stavrakakis
        url = "/api/v1.1/servers/%s/action" % vm.id
170 a95c82a9 Christos Stavrakakis
        with patch('synnefo.logic.rapi_pool.GanetiRapiClient') as c:
171 a95c82a9 Christos Stavrakakis
            c().ModifyInstance.return_value = 10
172 a95c82a9 Christos Stavrakakis
            response = self.post(url, vm.userid, json.dumps(request),
173 a95c82a9 Christos Stavrakakis
                                 "json")
174 a95c82a9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
175 acda838e Christos Stavrakakis
        with mocked_quotaholder():
176 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, ip.userid)
177 acda838e Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
178 acda838e Christos Stavrakakis
179 acda838e Christos Stavrakakis
    def test_release(self):
180 acda838e Christos Stavrakakis
        ip = FloatingIPFactory(machine=None)
181 acda838e Christos Stavrakakis
        with mocked_quotaholder():
182 acda838e Christos Stavrakakis
            response = self.delete(URL + "/%s" % ip.id, ip.userid)
183 acda838e Christos Stavrakakis
        self.assertSuccess(response)
184 acda838e Christos Stavrakakis
        ips_after = FloatingIP.objects.filter(id=ip.id)
185 acda838e Christos Stavrakakis
        self.assertEqual(len(ips_after), 0)
186 7d368e73 Christos Stavrakakis
187 e57893cd Christos Stavrakakis
    @patch("synnefo.logic.backend", Mock())
188 e57893cd Christos Stavrakakis
    def test_delete_network_with_floating_ips(self):
189 e57893cd Christos Stavrakakis
        ip = FloatingIPFactory(machine=None)
190 e57893cd Christos Stavrakakis
        net = ip.network
191 e57893cd Christos Stavrakakis
        # Can not remove network with floating IPs
192 e57893cd Christos Stavrakakis
        with mocked_quotaholder():
193 e57893cd Christos Stavrakakis
            response = self.delete("/api/v1.1/networks/%s" % net.id,
194 e57893cd Christos Stavrakakis
                                   net.userid)
195 e57893cd Christos Stavrakakis
        self.assertFault(response, 421, "networkInUse")
196 e57893cd Christos Stavrakakis
        # But we can with only deleted Floating Ips
197 e57893cd Christos Stavrakakis
        ip.deleted = True
198 e57893cd Christos Stavrakakis
        ip.save()
199 e57893cd Christos Stavrakakis
        with mocked_quotaholder():
200 e57893cd Christos Stavrakakis
            response = self.delete("/api/v1.1/networks/%s" % net.id,
201 e57893cd Christos Stavrakakis
                                   net.userid)
202 e57893cd Christos Stavrakakis
        self.assertSuccess(response)
203 e57893cd Christos Stavrakakis
204 7d368e73 Christos Stavrakakis
205 7d368e73 Christos Stavrakakis
POOLS_URL = "/api/v1.1/os-floating-ip-pools"
206 7d368e73 Christos Stavrakakis
207 7d368e73 Christos Stavrakakis
208 7d368e73 Christos Stavrakakis
class FloatingIPPoolsAPITest(BaseAPITest):
209 7d368e73 Christos Stavrakakis
    def test_no_pool(self):
210 7d368e73 Christos Stavrakakis
        response = self.get(POOLS_URL)
211 7d368e73 Christos Stavrakakis
        self.assertSuccess(response)
212 7d368e73 Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip_pools"], [])
213 7d368e73 Christos Stavrakakis
214 7d368e73 Christos Stavrakakis
    def test_list_pools(self):
215 7d368e73 Christos Stavrakakis
        net = NetworkFactory(public=True, deleted=False)
216 7d368e73 Christos Stavrakakis
        NetworkFactory(public=True, deleted=True)
217 7d368e73 Christos Stavrakakis
        NetworkFactory(public=False, deleted=False)
218 7d368e73 Christos Stavrakakis
        response = self.get(POOLS_URL)
219 7d368e73 Christos Stavrakakis
        self.assertSuccess(response)
220 7d368e73 Christos Stavrakakis
        self.assertEqual(json.loads(response.content)["floating_ip_pools"],
221 7d368e73 Christos Stavrakakis
                        [{"name": str(net.id)}])
222 a95c82a9 Christos Stavrakakis
223 a95c82a9 Christos Stavrakakis
224 a95c82a9 Christos Stavrakakis
class FloatingIPActionsTest(BaseAPITest):
225 a95c82a9 Christos Stavrakakis
    def setUp(self):
226 a95c82a9 Christos Stavrakakis
        vm = VirtualMachineFactory()
227 a95c82a9 Christos Stavrakakis
        vm.operstate = "ACTIVE"
228 a95c82a9 Christos Stavrakakis
        vm.save()
229 a95c82a9 Christos Stavrakakis
        self.vm = vm
230 a95c82a9 Christos Stavrakakis
231 a95c82a9 Christos Stavrakakis
    def test_bad_request(self):
232 a95c82a9 Christos Stavrakakis
        url = "/api/v1.1/servers/%s/action" % self.vm.id
233 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps({}), "json")
234 a95c82a9 Christos Stavrakakis
        self.assertBadRequest(response)
235 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid,
236 a95c82a9 Christos Stavrakakis
                             json.dumps({"addFloatingIp": {}}),
237 a95c82a9 Christos Stavrakakis
                             "json")
238 a95c82a9 Christos Stavrakakis
        self.assertBadRequest(response)
239 a95c82a9 Christos Stavrakakis
240 a95c82a9 Christos Stavrakakis
    @patch('synnefo.logic.rapi_pool.GanetiRapiClient')
241 a95c82a9 Christos Stavrakakis
    def test_add_floating_ip(self, mock):
242 a95c82a9 Christos Stavrakakis
        # Not exists
243 a95c82a9 Christos Stavrakakis
        url = "/api/v1.1/servers/%s/action" % self.vm.id
244 a95c82a9 Christos Stavrakakis
        request = {"addFloatingIp": {"address": "10.0.0.1"}}
245 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
246 a95c82a9 Christos Stavrakakis
        self.assertItemNotFound(response)
247 a95c82a9 Christos Stavrakakis
        # In use
248 a95c82a9 Christos Stavrakakis
        vm1 = VirtualMachineFactory()
249 a95c82a9 Christos Stavrakakis
        ip1 = FloatingIPFactory(userid=self.vm.userid, machine=vm1)
250 a95c82a9 Christos Stavrakakis
        request = {"addFloatingIp": {"address": ip1.ipv4}}
251 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
252 a95c82a9 Christos Stavrakakis
        self.assertFault(response, 409, "conflict")
253 a95c82a9 Christos Stavrakakis
        # Success
254 a95c82a9 Christos Stavrakakis
        ip1 = FloatingIPFactory(userid=self.vm.userid, machine=None)
255 a95c82a9 Christos Stavrakakis
        request = {"addFloatingIp": {"address": ip1.ipv4}}
256 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
257 a95c82a9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
258 a95c82a9 Christos Stavrakakis
        ip1_after = FloatingIP.objects.get(id=ip1.id)
259 a95c82a9 Christos Stavrakakis
        self.assertEqual(ip1_after.machine, self.vm)
260 a95c82a9 Christos Stavrakakis
        self.assertTrue(ip1_after.in_use())
261 a95c82a9 Christos Stavrakakis
262 a95c82a9 Christos Stavrakakis
    @patch('synnefo.logic.rapi_pool.GanetiRapiClient')
263 a95c82a9 Christos Stavrakakis
    def test_remove_floating_ip(self, mock):
264 a95c82a9 Christos Stavrakakis
        # Not exists
265 a95c82a9 Christos Stavrakakis
        url = "/api/v1.1/servers/%s/action" % self.vm.id
266 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": "10.0.0.1"}}
267 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
268 a95c82a9 Christos Stavrakakis
        self.assertItemNotFound(response)
269 a95c82a9 Christos Stavrakakis
        # Not In Use
270 a95c82a9 Christos Stavrakakis
        ip1 = FloatingIPFactory(userid=self.vm.userid, machine=None)
271 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": ip1.ipv4}}
272 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
273 a95c82a9 Christos Stavrakakis
        self.assertItemNotFound(response)
274 a95c82a9 Christos Stavrakakis
        # Success
275 a95c82a9 Christos Stavrakakis
        ip1 = FloatingIPFactory(userid=self.vm.userid, machine=self.vm)
276 a95c82a9 Christos Stavrakakis
        NetworkInterfaceFactory(machine=self.vm, ipv4=ip1.ipv4)
277 a95c82a9 Christos Stavrakakis
        request = {"removeFloatingIp": {"address": ip1.ipv4}}
278 a95c82a9 Christos Stavrakakis
        response = self.post(url, self.vm.userid, json.dumps(request), "json")
279 a95c82a9 Christos Stavrakakis
        self.assertEqual(response.status_code, 202)
280 a95c82a9 Christos Stavrakakis
        # Yet used. Wait for the callbacks
281 a95c82a9 Christos Stavrakakis
        ip1_after = FloatingIP.objects.get(id=ip1.id)
282 a95c82a9 Christos Stavrakakis
        self.assertEqual(ip1_after.machine, self.vm)
283 a95c82a9 Christos Stavrakakis
        self.assertTrue(ip1_after.in_use())