Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / logic / tests / callbacks.py @ 18cb3999

History | View | Annotate | Download (29.2 kB)

1 b8033991 Georgios Gousios
# vim: set fileencoding=utf-8 :
2 0208770b Christos Stavrakakis
# Copyright 2013 GRNET S.A. All rights reserved.
3 09c936a7 Vassilios Karakoidas
#
4 48130e66 Georgios Gousios
# Redistribution and use in source and binary forms, with or without
5 48130e66 Georgios Gousios
# modification, are permitted provided that the following conditions
6 48130e66 Georgios Gousios
# are met:
7 09c936a7 Vassilios Karakoidas
#
8 48130e66 Georgios Gousios
#   1. Redistributions of source code must retain the above copyright
9 48130e66 Georgios Gousios
#      notice, this list of conditions and the following disclaimer.
10 48130e66 Georgios Gousios
#
11 48130e66 Georgios Gousios
#  2. Redistributions in binary form must reproduce the above copyright
12 48130e66 Georgios Gousios
#     notice, this list of conditions and the following disclaimer in the
13 48130e66 Georgios Gousios
#     documentation and/or other materials provided with the distribution.
14 09c936a7 Vassilios Karakoidas
#
15 48130e66 Georgios Gousios
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
16 48130e66 Georgios Gousios
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 48130e66 Georgios Gousios
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 48130e66 Georgios Gousios
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
19 48130e66 Georgios Gousios
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 48130e66 Georgios Gousios
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 48130e66 Georgios Gousios
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 48130e66 Georgios Gousios
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 48130e66 Georgios Gousios
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 48130e66 Georgios Gousios
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 48130e66 Georgios Gousios
# SUCH DAMAGE.
26 09c936a7 Vassilios Karakoidas
#
27 48130e66 Georgios Gousios
# The views and conclusions contained in the software and documentation are
28 48130e66 Georgios Gousios
# those of the authors and should not be interpreted as representing official
29 48130e66 Georgios Gousios
# policies, either expressed or implied, of GRNET S.A.
30 48130e66 Georgios Gousios
31 48130e66 Georgios Gousios
# Provides automated tests for logic module
32 92c53da1 Vassilios Karakoidas
33 c25cc9ec Vangelis Koukis
from random import randint
34 c25cc9ec Vangelis Koukis
35 c25cc9ec Vangelis Koukis
from django.test import TestCase
36 c25cc9ec Vangelis Koukis
37 326c3ec8 Christos Stavrakakis
from synnefo.db.models import (VirtualMachine, IPAddress, BackendNetwork,
38 0208770b Christos Stavrakakis
                               Network, BridgePoolTable, MacPrefixPoolTable)
39 47eeffa9 Christos Stavrakakis
from synnefo.db import models_factory as mfactory
40 47eeffa9 Christos Stavrakakis
from synnefo.lib.utils import split_time
41 47eeffa9 Christos Stavrakakis
from datetime import datetime
42 47eeffa9 Christos Stavrakakis
from mock import patch
43 47eeffa9 Christos Stavrakakis
from synnefo.api.util import allocate_resource
44 fd95834e Christos Stavrakakis
from synnefo.logic.callbacks import (update_db, update_network,
45 cc92b70f Christos Stavrakakis
                                     update_build_progress)
46 184a2a8c Christos Stavrakakis
from snf_django.utils.testing import mocked_quotaholder
47 198d91c3 Christos Stavrakakis
from synnefo.logic.rapi import GanetiApiError
48 47eeffa9 Christos Stavrakakis
49 47eeffa9 Christos Stavrakakis
now = datetime.now
50 47eeffa9 Christos Stavrakakis
from time import time
51 47eeffa9 Christos Stavrakakis
import json
52 47eeffa9 Christos Stavrakakis
53 41a7fae7 Christos Stavrakakis
54 47eeffa9 Christos Stavrakakis
## Test Callbacks
55 47eeffa9 Christos Stavrakakis
@patch('synnefo.lib.amqp.AMQPClient')
56 47eeffa9 Christos Stavrakakis
class UpdateDBTest(TestCase):
57 47eeffa9 Christos Stavrakakis
    def create_msg(self, **kwargs):
58 47eeffa9 Christos Stavrakakis
        """Create snf-ganeti-eventd message"""
59 47eeffa9 Christos Stavrakakis
        msg = {'event_time': split_time(time())}
60 47eeffa9 Christos Stavrakakis
        msg['type'] = 'ganeti-op-status'
61 47eeffa9 Christos Stavrakakis
        msg['status'] = 'success'
62 47eeffa9 Christos Stavrakakis
        msg['jobId'] = 1
63 47eeffa9 Christos Stavrakakis
        msg['logmsg'] = 'Dummy Log'
64 47eeffa9 Christos Stavrakakis
        for key, val in kwargs.items():
65 47eeffa9 Christos Stavrakakis
            msg[key] = val
66 47eeffa9 Christos Stavrakakis
        message = {'body': json.dumps(msg)}
67 47eeffa9 Christos Stavrakakis
        return message
68 47eeffa9 Christos Stavrakakis
69 47eeffa9 Christos Stavrakakis
    def test_missing_attribute(self, client):
70 47eeffa9 Christos Stavrakakis
        update_db(client, json.dumps({'body': {}}))
71 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
72 47eeffa9 Christos Stavrakakis
73 47eeffa9 Christos Stavrakakis
    def test_unhandled_exception(self, client):
74 47eeffa9 Christos Stavrakakis
        update_db(client, {})
75 47eeffa9 Christos Stavrakakis
        client.basic_reject.assert_called_once()
76 47eeffa9 Christos Stavrakakis
77 47eeffa9 Christos Stavrakakis
    def test_missing_instance(self, client):
78 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
79 47eeffa9 Christos Stavrakakis
                              instance='foo')
80 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
81 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
82 47eeffa9 Christos Stavrakakis
83 47eeffa9 Christos Stavrakakis
    def test_wrong_type(self, client):
84 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(type="WRONG_TYPE")
85 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
86 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_nack.called)
87 47eeffa9 Christos Stavrakakis
88 b66e4833 Christos Stavrakakis
    def test_old_msg(self, client):
89 b66e4833 Christos Stavrakakis
        from time import sleep
90 b66e4833 Christos Stavrakakis
        from datetime import datetime
91 b66e4833 Christos Stavrakakis
        old_time = time()
92 b66e4833 Christos Stavrakakis
        sleep(0.01)
93 b66e4833 Christos Stavrakakis
        new_time = datetime.fromtimestamp(time())
94 b66e4833 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(backendtime=new_time)
95 b66e4833 Christos Stavrakakis
        vm.operstate = 'STOPPED'
96 b66e4833 Christos Stavrakakis
        vm.save()
97 b66e4833 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
98 b66e4833 Christos Stavrakakis
                              event_time=split_time(old_time),
99 b66e4833 Christos Stavrakakis
                              instance=vm.backend_vm_id)
100 b66e4833 Christos Stavrakakis
        update_db(client, msg)
101 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
102 b66e4833 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
103 b66e4833 Christos Stavrakakis
        self.assertEquals(db_vm.operstate, "STOPPED")
104 b66e4833 Christos Stavrakakis
        self.assertEquals(db_vm.backendtime, new_time)
105 b66e4833 Christos Stavrakakis
106 47eeffa9 Christos Stavrakakis
    def test_start(self, client):
107 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
108 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
109 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
110 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
111 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
112 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
113 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
114 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'STARTED')
115 47eeffa9 Christos Stavrakakis
116 47eeffa9 Christos Stavrakakis
    def test_stop(self, client):
117 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
118 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_SHUTDOWN',
119 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
120 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
121 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
122 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
123 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
124 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'STOPPED')
125 47eeffa9 Christos Stavrakakis
126 47eeffa9 Christos Stavrakakis
    def test_reboot(self, client):
127 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
128 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_REBOOT',
129 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
130 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
131 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
132 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
133 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'STARTED')
134 47eeffa9 Christos Stavrakakis
135 47eeffa9 Christos Stavrakakis
    def test_remove(self, client):
136 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
137 47eeffa9 Christos Stavrakakis
        # Also create a NIC
138 8764d304 Christos Stavrakakis
        ip = mfactory.IPv4AddressFactory(nic__machine=vm)
139 8764d304 Christos Stavrakakis
        nic = ip.nic
140 3b2984dc Christos Stavrakakis
        nic.network.get_ip_pools()[0].reserve(nic.ipv4_address)
141 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_REMOVE',
142 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
143 184a2a8c Christos Stavrakakis
        with mocked_quotaholder():
144 184a2a8c Christos Stavrakakis
            update_db(client, msg)
145 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
146 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
147 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'DESTROYED')
148 47eeffa9 Christos Stavrakakis
        self.assertTrue(db_vm.deleted)
149 47eeffa9 Christos Stavrakakis
        # Check that nics are deleted
150 47eeffa9 Christos Stavrakakis
        self.assertFalse(db_vm.nics.all())
151 3b2984dc Christos Stavrakakis
        self.assertTrue(nic.network.get_ip_pools()[0].is_available(ip.address))
152 72dea98f Christos Stavrakakis
        vm2 = mfactory.VirtualMachineFactory()
153 8764d304 Christos Stavrakakis
        fp1 = mfactory.IPv4AddressFactory(nic__machine=vm2, floating_ip=True,
154 8764d304 Christos Stavrakakis
                                          network__floating_ip_pool=True)
155 8764d304 Christos Stavrakakis
        network = fp1.network
156 8764d304 Christos Stavrakakis
        nic1 = mfactory.NetworkInterfaceFactory(machine=vm2)
157 8764d304 Christos Stavrakakis
        fp1.nic = nic1
158 8764d304 Christos Stavrakakis
        fp1.save()
159 3b2984dc Christos Stavrakakis
        pool = network.get_ip_pools()[0]
160 8764d304 Christos Stavrakakis
        pool.reserve(fp1.address)
161 72dea98f Christos Stavrakakis
        pool.save()
162 72dea98f Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_REMOVE',
163 72dea98f Christos Stavrakakis
                              instance=vm2.backend_vm_id)
164 72dea98f Christos Stavrakakis
        with mocked_quotaholder():
165 72dea98f Christos Stavrakakis
            update_db(client, msg)
166 72dea98f Christos Stavrakakis
        client.basic_ack.assert_called_once()
167 72dea98f Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
168 72dea98f Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'DESTROYED')
169 72dea98f Christos Stavrakakis
        self.assertTrue(db_vm.deleted)
170 8764d304 Christos Stavrakakis
        self.assertEqual(IPAddress.objects.get(id=fp1.id).nic, None)
171 3b2984dc Christos Stavrakakis
        pool = network.get_ip_pools()[0]
172 72dea98f Christos Stavrakakis
        # Test that floating ips are not released
173 8764d304 Christos Stavrakakis
        self.assertFalse(pool.is_available(fp1.address))
174 47eeffa9 Christos Stavrakakis
175 198d91c3 Christos Stavrakakis
    @patch("synnefo.logic.rapi_pool.GanetiRapiClient")
176 198d91c3 Christos Stavrakakis
    def test_remove_error(self, rapi, client):
177 198d91c3 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
178 198d91c3 Christos Stavrakakis
        # Also create a NIC
179 198d91c3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_REMOVE',
180 198d91c3 Christos Stavrakakis
                              status="error",
181 198d91c3 Christos Stavrakakis
                              instance=vm.backend_vm_id)
182 198d91c3 Christos Stavrakakis
        rapi().GetInstance.return_value = {}
183 198d91c3 Christos Stavrakakis
        update_db(client, msg)
184 198d91c3 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
185 198d91c3 Christos Stavrakakis
        self.assertFalse(db_vm.deleted)
186 198d91c3 Christos Stavrakakis
187 198d91c3 Christos Stavrakakis
        rapi().GetInstance.side_effect = GanetiApiError(msg="msg",
188 198d91c3 Christos Stavrakakis
                                                        code=503)
189 198d91c3 Christos Stavrakakis
        update_db(client, msg)
190 198d91c3 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
191 198d91c3 Christos Stavrakakis
        self.assertFalse(db_vm.deleted)
192 198d91c3 Christos Stavrakakis
193 198d91c3 Christos Stavrakakis
        rapi().GetInstance.side_effect = GanetiApiError(msg="msg",
194 198d91c3 Christos Stavrakakis
                                                        code=404)
195 198d91c3 Christos Stavrakakis
        with mocked_quotaholder():
196 198d91c3 Christos Stavrakakis
            update_db(client, msg)
197 198d91c3 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
198 198d91c3 Christos Stavrakakis
        self.assertTrue(db_vm.deleted)
199 198d91c3 Christos Stavrakakis
200 47eeffa9 Christos Stavrakakis
    def test_create(self, client):
201 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
202 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_CREATE',
203 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
204 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
205 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
206 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
207 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'STARTED')
208 47eeffa9 Christos Stavrakakis
209 47eeffa9 Christos Stavrakakis
    def test_create_error(self, client):
210 47eeffa9 Christos Stavrakakis
        """Test that error create sets vm to ERROR state"""
211 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
212 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_CREATE',
213 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id,
214 47eeffa9 Christos Stavrakakis
                              status='error')
215 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
216 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
217 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
218 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'ERROR')
219 47eeffa9 Christos Stavrakakis
220 47eeffa9 Christos Stavrakakis
    def test_remove_from_error(self, client):
221 47eeffa9 Christos Stavrakakis
        """Test that error removes delete error builds"""
222 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate='ERROR')
223 47eeffa9 Christos Stavrakakis
        # Also create a NIC
224 47eeffa9 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm)
225 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_REMOVE',
226 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
227 184a2a8c Christos Stavrakakis
        with mocked_quotaholder():
228 184a2a8c Christos Stavrakakis
            update_db(client, msg)
229 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
230 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
231 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'DESTROYED')
232 47eeffa9 Christos Stavrakakis
        self.assertTrue(db_vm.deleted)
233 47eeffa9 Christos Stavrakakis
        # Check that nics are deleted
234 47eeffa9 Christos Stavrakakis
        self.assertFalse(db_vm.nics.all())
235 47eeffa9 Christos Stavrakakis
236 47eeffa9 Christos Stavrakakis
    def test_other_error(self, client):
237 47eeffa9 Christos Stavrakakis
        """Test that other error messages do no affect the VM"""
238 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
239 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
240 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id,
241 47eeffa9 Christos Stavrakakis
                              status='error')
242 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
243 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
244 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
245 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, vm.operstate)
246 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.backendtime, vm.backendtime)
247 47eeffa9 Christos Stavrakakis
248 ca4d59e3 Christos Stavrakakis
    def test_resize_msg(self, client):
249 ca4d59e3 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
250 ca4d59e3 Christos Stavrakakis
        # Test empty beparams
251 ca4d59e3 Christos Stavrakakis
        for status in ["success", "error"]:
252 ca4d59e3 Christos Stavrakakis
            msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
253 ca4d59e3 Christos Stavrakakis
                                  instance=vm.backend_vm_id,
254 8764d304 Christos Stavrakakis
                                  job_fields={"beparams": {}},
255 ca4d59e3 Christos Stavrakakis
                                  status=status)
256 ca4d59e3 Christos Stavrakakis
            client.reset_mock()
257 41a7fae7 Christos Stavrakakis
            with mocked_quotaholder():
258 41a7fae7 Christos Stavrakakis
                update_db(client, msg)
259 ca4d59e3 Christos Stavrakakis
            self.assertTrue(client.basic_ack.called)
260 ca4d59e3 Christos Stavrakakis
            db_vm = VirtualMachine.objects.get(id=vm.id)
261 ca4d59e3 Christos Stavrakakis
            self.assertEqual(db_vm.operstate, vm.operstate)
262 ca4d59e3 Christos Stavrakakis
        # Test intermediate states
263 2cd55da6 Christos Stavrakakis
        vm.operstate = "STOPPED"
264 2cd55da6 Christos Stavrakakis
        vm.save()
265 ca4d59e3 Christos Stavrakakis
        for status in ["queued", "waiting", "running"]:
266 8764d304 Christos Stavrakakis
            beparams = {"vcpus": 4, "minmem": 2048, "maxmem": 2048}
267 ca4d59e3 Christos Stavrakakis
            msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
268 ca4d59e3 Christos Stavrakakis
                                  instance=vm.backend_vm_id,
269 8764d304 Christos Stavrakakis
                                  job_fields={"beparams": beparams},
270 ca4d59e3 Christos Stavrakakis
                                  status=status)
271 ca4d59e3 Christos Stavrakakis
            client.reset_mock()
272 ca4d59e3 Christos Stavrakakis
            update_db(client, msg)
273 ca4d59e3 Christos Stavrakakis
            self.assertTrue(client.basic_ack.called)
274 ca4d59e3 Christos Stavrakakis
            db_vm = VirtualMachine.objects.get(id=vm.id)
275 41a7fae7 Christos Stavrakakis
            self.assertEqual(db_vm.operstate, "STOPPED")
276 ca4d59e3 Christos Stavrakakis
        # Test operstate after error
277 ca4d59e3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
278 ca4d59e3 Christos Stavrakakis
                              instance=vm.backend_vm_id,
279 ca4d59e3 Christos Stavrakakis
                              beparams={"vcpus": 4},
280 ca4d59e3 Christos Stavrakakis
                              status="error")
281 ca4d59e3 Christos Stavrakakis
        client.reset_mock()
282 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
283 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
284 ca4d59e3 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
285 ca4d59e3 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
286 ca4d59e3 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, "STOPPED")
287 ca4d59e3 Christos Stavrakakis
        # Test success
288 ca4d59e3 Christos Stavrakakis
        f1 = mfactory.FlavorFactory(cpu=4, ram=1024, disk_template="drbd",
289 ca4d59e3 Christos Stavrakakis
                                    disk=1024)
290 ca4d59e3 Christos Stavrakakis
        vm.flavor = f1
291 ca4d59e3 Christos Stavrakakis
        vm.save()
292 ca4d59e3 Christos Stavrakakis
        f2 = mfactory.FlavorFactory(cpu=8, ram=2048, disk_template="drbd",
293 ca4d59e3 Christos Stavrakakis
                                    disk=1024)
294 8764d304 Christos Stavrakakis
        beparams = {"vcpus": 8, "minmem": 2048, "maxmem": 2048}
295 ca4d59e3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
296 ca4d59e3 Christos Stavrakakis
                              instance=vm.backend_vm_id,
297 8764d304 Christos Stavrakakis
                              job_fields={"beparams": beparams},
298 ca4d59e3 Christos Stavrakakis
                              status="success")
299 ca4d59e3 Christos Stavrakakis
        client.reset_mock()
300 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
301 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
302 ca4d59e3 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
303 ca4d59e3 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
304 ca4d59e3 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, "STOPPED")
305 ca4d59e3 Christos Stavrakakis
        self.assertEqual(db_vm.flavor, f2)
306 8764d304 Christos Stavrakakis
        beparams = {"vcpus": 100, "minmem": 2048, "maxmem": 2048}
307 ca4d59e3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
308 ca4d59e3 Christos Stavrakakis
                              instance=vm.backend_vm_id,
309 8764d304 Christos Stavrakakis
                              job_fields={"beparams": beparams},
310 ca4d59e3 Christos Stavrakakis
                              status="success")
311 ca4d59e3 Christos Stavrakakis
        client.reset_mock()
312 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
313 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
314 ca4d59e3 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
315 ca4d59e3 Christos Stavrakakis
316 47eeffa9 Christos Stavrakakis
317 47eeffa9 Christos Stavrakakis
@patch('synnefo.lib.amqp.AMQPClient')
318 47eeffa9 Christos Stavrakakis
class UpdateNetTest(TestCase):
319 47eeffa9 Christos Stavrakakis
    def create_msg(self, **kwargs):
320 47eeffa9 Christos Stavrakakis
        """Create snf-ganeti-hook message"""
321 47eeffa9 Christos Stavrakakis
        msg = {'event_time': split_time(time())}
322 fd95834e Christos Stavrakakis
        msg['type'] = 'ganeti-op-status'
323 fd95834e Christos Stavrakakis
        msg['operation'] = 'OP_INSTANCE_SET_PARAMS'
324 47eeffa9 Christos Stavrakakis
        msg['status'] = 'success'
325 47eeffa9 Christos Stavrakakis
        msg['jobId'] = 1
326 47eeffa9 Christos Stavrakakis
        msg['logmsg'] = 'Dummy Log'
327 47eeffa9 Christos Stavrakakis
        for key, val in kwargs.items():
328 47eeffa9 Christos Stavrakakis
            msg[key] = val
329 47eeffa9 Christos Stavrakakis
        message = {'body': json.dumps(msg)}
330 47eeffa9 Christos Stavrakakis
        return message
331 47eeffa9 Christos Stavrakakis
332 47eeffa9 Christos Stavrakakis
    def test_missing_attribute(self, client):
333 fd95834e Christos Stavrakakis
        update_db(client, json.dumps({'body': {}}))
334 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
335 47eeffa9 Christos Stavrakakis
336 47eeffa9 Christos Stavrakakis
    def test_unhandled_exception(self, client):
337 fd95834e Christos Stavrakakis
        update_db(client, {})
338 47eeffa9 Christos Stavrakakis
        client.basic_reject.assert_called_once()
339 47eeffa9 Christos Stavrakakis
340 47eeffa9 Christos Stavrakakis
    def test_wrong_type(self, client):
341 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(type="WRONG_TYPE")
342 fd95834e Christos Stavrakakis
        update_db(client, msg)
343 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_nack.called)
344 47eeffa9 Christos Stavrakakis
345 47eeffa9 Christos Stavrakakis
    def test_missing_instance(self, client):
346 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
347 47eeffa9 Christos Stavrakakis
                              instance='foo')
348 fd95834e Christos Stavrakakis
        update_db(client, msg)
349 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
350 47eeffa9 Christos Stavrakakis
351 47eeffa9 Christos Stavrakakis
    def test_no_nics(self, client):
352 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate='ERROR')
353 8764d304 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm, state="ACTIVE")
354 8764d304 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm, state="ACTIVE")
355 8764d304 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm, state="ACTIVE")
356 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(vm.nics.all()), 3)
357 8764d304 Christos Stavrakakis
        msg = self.create_msg(instance_nics=[],
358 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
359 fd95834e Christos Stavrakakis
        update_db(client, msg)
360 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
361 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
362 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(db_vm.nics.all()), 0)
363 47eeffa9 Christos Stavrakakis
364 3278725f Christos Stavrakakis
    def test_changed_nic(self, client):
365 3278725f Christos Stavrakakis
        ip = mfactory.IPv4AddressFactory(subnet__cidr="10.0.0.0/24",
366 3278725f Christos Stavrakakis
                                         address="10.0.0.2")
367 3278725f Christos Stavrakakis
        network = ip.network
368 3278725f Christos Stavrakakis
        subnet = ip.subnet
369 3278725f Christos Stavrakakis
        vm = ip.nic.machine
370 3b2984dc Christos Stavrakakis
        pool = subnet.get_ip_pools()[0]
371 3278725f Christos Stavrakakis
        pool.reserve("10.0.0.2")
372 47eeffa9 Christos Stavrakakis
        pool.save()
373 3278725f Christos Stavrakakis
374 3278725f Christos Stavrakakis
        msg = self.create_msg(instance_nics=[{'network': network.backend_id,
375 3278725f Christos Stavrakakis
                                              'ip': '10.0.0.3',
376 8764d304 Christos Stavrakakis
                                              'mac': 'aa:bb:cc:00:11:22',
377 3278725f Christos Stavrakakis
                                              'name': ip.nic.backend_uuid}],
378 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
379 fd95834e Christos Stavrakakis
        update_db(client, msg)
380 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
381 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
382 47eeffa9 Christos Stavrakakis
        nics = db_vm.nics.all()
383 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(nics), 1)
384 47eeffa9 Christos Stavrakakis
        self.assertEqual(nics[0].index, 0)
385 3278725f Christos Stavrakakis
        self.assertEqual(nics[0].ipv4_address, '10.0.0.3')
386 47eeffa9 Christos Stavrakakis
        self.assertEqual(nics[0].mac, 'aa:bb:cc:00:11:22')
387 3b2984dc Christos Stavrakakis
        pool = subnet.get_ip_pools()[0]
388 3278725f Christos Stavrakakis
        self.assertTrue(pool.is_available('10.0.0.2'))
389 3278725f Christos Stavrakakis
        self.assertFalse(pool.is_available('10.0.0.3'))
390 47eeffa9 Christos Stavrakakis
        pool.save()
391 47eeffa9 Christos Stavrakakis
392 47eeffa9 Christos Stavrakakis
393 47eeffa9 Christos Stavrakakis
@patch('synnefo.lib.amqp.AMQPClient')
394 47eeffa9 Christos Stavrakakis
class UpdateNetworkTest(TestCase):
395 47eeffa9 Christos Stavrakakis
    def create_msg(self, **kwargs):
396 47eeffa9 Christos Stavrakakis
        """Create snf-ganeti-eventd message"""
397 47eeffa9 Christos Stavrakakis
        msg = {'event_time': split_time(time())}
398 47eeffa9 Christos Stavrakakis
        msg['type'] = 'ganeti-network-status'
399 47eeffa9 Christos Stavrakakis
        msg['status'] = 'success'
400 47eeffa9 Christos Stavrakakis
        msg['jobId'] = 1
401 47eeffa9 Christos Stavrakakis
        msg['logmsg'] = 'Dummy Log'
402 47eeffa9 Christos Stavrakakis
        for key, val in kwargs.items():
403 47eeffa9 Christos Stavrakakis
            msg[key] = val
404 47eeffa9 Christos Stavrakakis
        message = {'body': json.dumps(msg)}
405 47eeffa9 Christos Stavrakakis
        return message
406 47eeffa9 Christos Stavrakakis
407 47eeffa9 Christos Stavrakakis
    def test_missing_attribute(self, client):
408 47eeffa9 Christos Stavrakakis
        update_network(client, json.dumps({'body': {}}))
409 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
410 47eeffa9 Christos Stavrakakis
411 47eeffa9 Christos Stavrakakis
    def test_unhandled_exception(self, client):
412 47eeffa9 Christos Stavrakakis
        update_network(client, {})
413 47eeffa9 Christos Stavrakakis
        client.basic_reject.assert_called_once()
414 47eeffa9 Christos Stavrakakis
415 47eeffa9 Christos Stavrakakis
    def test_wrong_type(self, client):
416 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(type="WRONG_TYPE")
417 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
418 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_nack.called)
419 47eeffa9 Christos Stavrakakis
420 47eeffa9 Christos Stavrakakis
    def test_missing_network(self, client):
421 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_CREATE',
422 47eeffa9 Christos Stavrakakis
                              network='foo')
423 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
424 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
425 47eeffa9 Christos Stavrakakis
426 47eeffa9 Christos Stavrakakis
    def test_create(self, client):
427 47eeffa9 Christos Stavrakakis
        back_network = mfactory.BackendNetworkFactory(operstate='PENDING')
428 47eeffa9 Christos Stavrakakis
        net = back_network.network
429 1d04ef8b Christos Stavrakakis
        net.state = 'ACTIVE'
430 1d04ef8b Christos Stavrakakis
        net.save()
431 47eeffa9 Christos Stavrakakis
        back1 = back_network.backend
432 47eeffa9 Christos Stavrakakis
433 47eeffa9 Christos Stavrakakis
        back_network2 = mfactory.BackendNetworkFactory(operstate='PENDING',
434 47eeffa9 Christos Stavrakakis
                                                       network=net)
435 47eeffa9 Christos Stavrakakis
        back2 = back_network2.backend
436 47eeffa9 Christos Stavrakakis
        # Message from first backend network
437 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_CONNECT',
438 47eeffa9 Christos Stavrakakis
                              network=net.backend_id,
439 47eeffa9 Christos Stavrakakis
                              cluster=back1.clustername)
440 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
441 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
442 47eeffa9 Christos Stavrakakis
443 47eeffa9 Christos Stavrakakis
        back_net = BackendNetwork.objects.get(id=back_network.id)
444 47eeffa9 Christos Stavrakakis
        self.assertEqual(back_net.operstate, 'ACTIVE')
445 47eeffa9 Christos Stavrakakis
        db_net = Network.objects.get(id=net.id)
446 1d04ef8b Christos Stavrakakis
        self.assertEqual(db_net.state, 'ACTIVE')
447 47eeffa9 Christos Stavrakakis
        # msg from second backend network
448 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_CONNECT',
449 47eeffa9 Christos Stavrakakis
                              network=net.backend_id,
450 47eeffa9 Christos Stavrakakis
                              cluster=back2.clustername)
451 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
452 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
453 47eeffa9 Christos Stavrakakis
454 47eeffa9 Christos Stavrakakis
        db_net = Network.objects.get(id=net.id)
455 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_net.state, 'ACTIVE')
456 47eeffa9 Christos Stavrakakis
        back_net = BackendNetwork.objects.get(id=back_network.id)
457 47eeffa9 Christos Stavrakakis
        self.assertEqual(back_net.operstate, 'ACTIVE')
458 47eeffa9 Christos Stavrakakis
459 039e3e61 Christos Stavrakakis
    def test_create_offline_backend(self, client):
460 039e3e61 Christos Stavrakakis
        """Test network creation when a backend is offline"""
461 1d04ef8b Christos Stavrakakis
        net = mfactory.NetworkFactory(state='ACTIVE')
462 039e3e61 Christos Stavrakakis
        bn1 = mfactory.BackendNetworkFactory(network=net)
463 5962d9a6 Christos Stavrakakis
        mfactory.BackendNetworkFactory(network=net,
464 5962d9a6 Christos Stavrakakis
                                       backend__offline=True)
465 039e3e61 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_CONNECT',
466 039e3e61 Christos Stavrakakis
                              network=net.backend_id,
467 039e3e61 Christos Stavrakakis
                              cluster=bn1.backend.clustername)
468 039e3e61 Christos Stavrakakis
        update_network(client, msg)
469 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
470 039e3e61 Christos Stavrakakis
        new_net = Network.objects.get(id=net.id)
471 039e3e61 Christos Stavrakakis
        self.assertEqual(new_net.state, 'ACTIVE')
472 039e3e61 Christos Stavrakakis
473 47eeffa9 Christos Stavrakakis
    def test_disconnect(self, client):
474 47eeffa9 Christos Stavrakakis
        bn1 = mfactory.BackendNetworkFactory(operstate='ACTIVE')
475 47eeffa9 Christos Stavrakakis
        net1 = bn1.network
476 1d04ef8b Christos Stavrakakis
        net1.state = "ACTIVE"
477 1d04ef8b Christos Stavrakakis
        net1.state = 'ACTIVE'
478 47eeffa9 Christos Stavrakakis
        net1.save()
479 47eeffa9 Christos Stavrakakis
        bn2 = mfactory.BackendNetworkFactory(operstate='ACTIVE',
480 47eeffa9 Christos Stavrakakis
                                             network=net1)
481 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_DISCONNECT',
482 47eeffa9 Christos Stavrakakis
                              network=net1.backend_id,
483 47eeffa9 Christos Stavrakakis
                              cluster=bn2.backend.clustername)
484 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
485 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
486 1d04ef8b Christos Stavrakakis
        self.assertEqual(Network.objects.get(id=net1.id).state, 'ACTIVE')
487 47eeffa9 Christos Stavrakakis
        self.assertEqual(BackendNetwork.objects.get(id=bn2.id).operstate,
488 cc92b70f Christos Stavrakakis
                         'PENDING')
489 47eeffa9 Christos Stavrakakis
490 47eeffa9 Christos Stavrakakis
    def test_remove(self, client):
491 47eeffa9 Christos Stavrakakis
        mfactory.MacPrefixPoolTableFactory()
492 47eeffa9 Christos Stavrakakis
        mfactory.BridgePoolTableFactory()
493 47eeffa9 Christos Stavrakakis
        bn = mfactory.BackendNetworkFactory(operstate='ACTIVE')
494 47eeffa9 Christos Stavrakakis
        for old_state in ['success', 'canceled', 'error']:
495 47eeffa9 Christos Stavrakakis
            for flavor in Network.FLAVORS.keys():
496 47eeffa9 Christos Stavrakakis
                bn.operstate = old_state
497 47eeffa9 Christos Stavrakakis
                bn.save()
498 47eeffa9 Christos Stavrakakis
                net = bn.network
499 47eeffa9 Christos Stavrakakis
                net.state = 'ACTIVE'
500 47eeffa9 Christos Stavrakakis
                net.flavor = flavor
501 47eeffa9 Christos Stavrakakis
                if flavor == 'PHYSICAL_VLAN':
502 47eeffa9 Christos Stavrakakis
                    net.link = allocate_resource('bridge')
503 47eeffa9 Christos Stavrakakis
                if flavor == 'MAC_FILTERED':
504 47eeffa9 Christos Stavrakakis
                    net.mac_prefix = allocate_resource('mac_prefix')
505 47eeffa9 Christos Stavrakakis
                net.save()
506 47eeffa9 Christos Stavrakakis
                msg = self.create_msg(operation='OP_NETWORK_REMOVE',
507 47eeffa9 Christos Stavrakakis
                                      network=net.backend_id,
508 47eeffa9 Christos Stavrakakis
                                      cluster=bn.backend.clustername)
509 184a2a8c Christos Stavrakakis
                with mocked_quotaholder():
510 184a2a8c Christos Stavrakakis
                    update_network(client, msg)
511 10d9cd27 Christos Stavrakakis
                self.assertTrue(client.basic_ack.called)
512 e8234183 Christos Stavrakakis
                self.assertFalse(BackendNetwork.objects.filter(id=bn.id)
513 e8234183 Christos Stavrakakis
                                 .exists())
514 47eeffa9 Christos Stavrakakis
                db_net = Network.objects.get(id=net.id)
515 47eeffa9 Christos Stavrakakis
                self.assertEqual(db_net.state, 'DELETED', flavor)
516 47eeffa9 Christos Stavrakakis
                self.assertTrue(db_net.deleted)
517 47eeffa9 Christos Stavrakakis
                if flavor == 'PHYSICAL_VLAN':
518 47eeffa9 Christos Stavrakakis
                    pool = BridgePoolTable.get_pool()
519 47eeffa9 Christos Stavrakakis
                    self.assertTrue(pool.is_available(net.link))
520 47eeffa9 Christos Stavrakakis
                if flavor == 'MAC_FILTERED':
521 47eeffa9 Christos Stavrakakis
                    pool = MacPrefixPoolTable.get_pool()
522 47eeffa9 Christos Stavrakakis
                    self.assertTrue(pool.is_available(net.mac_prefix))
523 47eeffa9 Christos Stavrakakis
524 198d91c3 Christos Stavrakakis
    @patch("synnefo.logic.rapi_pool.GanetiRapiClient")
525 198d91c3 Christos Stavrakakis
    def test_remove_error(self, rapi, client):
526 198d91c3 Christos Stavrakakis
        mfactory.MacPrefixPoolTableFactory()
527 198d91c3 Christos Stavrakakis
        mfactory.BridgePoolTableFactory()
528 198d91c3 Christos Stavrakakis
        bn = mfactory.BackendNetworkFactory(operstate='ACTIVE')
529 198d91c3 Christos Stavrakakis
        network = bn.network
530 198d91c3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_REMOVE',
531 198d91c3 Christos Stavrakakis
                              network=network.backend_id,
532 198d91c3 Christos Stavrakakis
                              status="error",
533 198d91c3 Christos Stavrakakis
                              cluster=bn.backend.clustername)
534 198d91c3 Christos Stavrakakis
        rapi().GetNetwork.return_value = {}
535 198d91c3 Christos Stavrakakis
        update_network(client, msg)
536 198d91c3 Christos Stavrakakis
        bn = BackendNetwork.objects.get(id=bn.id)
537 198d91c3 Christos Stavrakakis
        self.assertNotEqual(bn.operstate, "DELETED")
538 198d91c3 Christos Stavrakakis
        rapi().GetNetwork.side_effect = GanetiApiError(msg="foo", code=404)
539 198d91c3 Christos Stavrakakis
        with mocked_quotaholder():
540 198d91c3 Christos Stavrakakis
            update_network(client, msg)
541 e8234183 Christos Stavrakakis
        self.assertFalse(BackendNetwork.objects.filter(id=bn.id) .exists())
542 198d91c3 Christos Stavrakakis
543 039e3e61 Christos Stavrakakis
    def test_remove_offline_backend(self, client):
544 039e3e61 Christos Stavrakakis
        """Test network removing when a backend is offline"""
545 3f77e63d Christos Stavrakakis
        mfactory.BridgePoolTableFactory()
546 3f77e63d Christos Stavrakakis
        net = mfactory.NetworkFactory(flavor='PHYSICAL_VLAN',
547 3f77e63d Christos Stavrakakis
                                      state='ACTIVE',
548 3f77e63d Christos Stavrakakis
                                      link='prv12')
549 039e3e61 Christos Stavrakakis
        bn1 = mfactory.BackendNetworkFactory(network=net)
550 039e3e61 Christos Stavrakakis
        mfactory.BackendNetworkFactory(network=net,
551 c6c889f7 Christos Stavrakakis
                                       operstate="ACTIVE",
552 3f77e63d Christos Stavrakakis
                                       backend__offline=True)
553 039e3e61 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_REMOVE',
554 039e3e61 Christos Stavrakakis
                              network=net.backend_id,
555 039e3e61 Christos Stavrakakis
                              cluster=bn1.backend.clustername)
556 184a2a8c Christos Stavrakakis
        with mocked_quotaholder():
557 184a2a8c Christos Stavrakakis
            update_network(client, msg)
558 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
559 039e3e61 Christos Stavrakakis
        new_net = Network.objects.get(id=net.id)
560 1d04ef8b Christos Stavrakakis
        self.assertEqual(new_net.state, 'ACTIVE')
561 1d04ef8b Christos Stavrakakis
        self.assertFalse(new_net.deleted)
562 039e3e61 Christos Stavrakakis
563 e8234183 Christos Stavrakakis
    @patch("synnefo.logic.rapi_pool.GanetiRapiClient")
564 e8234183 Christos Stavrakakis
    def test_error_opcode(self, rapi, client):
565 e8234183 Christos Stavrakakis
        # Mock getting network, because code will lookup if network exists
566 e8234183 Christos Stavrakakis
        # in backend
567 e8234183 Christos Stavrakakis
        rapi().GetNetwork.return_value = {}
568 c6c889f7 Christos Stavrakakis
        mfactory.MacPrefixPoolTableFactory()
569 c6c889f7 Christos Stavrakakis
        mfactory.BridgePoolTableFactory()
570 e8234183 Christos Stavrakakis
        network = mfactory.NetworkFactory()
571 e8234183 Christos Stavrakakis
        mfactory.BackendNetworkFactory(network=network,
572 e8234183 Christos Stavrakakis
                                       operstate="ACTIVE")
573 47eeffa9 Christos Stavrakakis
        for state, _ in Network.OPER_STATES:
574 e8234183 Christos Stavrakakis
            bn = mfactory.BackendNetworkFactory(operstate="ACTIVE",
575 e8234183 Christos Stavrakakis
                                                network=network)
576 47eeffa9 Christos Stavrakakis
            bn.operstate = state
577 47eeffa9 Christos Stavrakakis
            bn.save()
578 47eeffa9 Christos Stavrakakis
            network = bn.network
579 47eeffa9 Christos Stavrakakis
            network.state = state
580 47eeffa9 Christos Stavrakakis
            network.save()
581 47eeffa9 Christos Stavrakakis
            for opcode, _ in BackendNetwork.BACKEND_OPCODES:
582 47eeffa9 Christos Stavrakakis
                if opcode in ['OP_NETWORK_REMOVE', 'OP_NETWORK_ADD']:
583 47eeffa9 Christos Stavrakakis
                    continue
584 47eeffa9 Christos Stavrakakis
                msg = self.create_msg(operation=opcode,
585 47eeffa9 Christos Stavrakakis
                                      network=bn.network.backend_id,
586 47eeffa9 Christos Stavrakakis
                                      status='error',
587 c6c889f7 Christos Stavrakakis
                                      add_reserved_ips=[],
588 c6c889f7 Christos Stavrakakis
                                      remove_reserved_ips=[],
589 47eeffa9 Christos Stavrakakis
                                      cluster=bn.backend.clustername)
590 c6c889f7 Christos Stavrakakis
                with mocked_quotaholder():
591 c6c889f7 Christos Stavrakakis
                    update_network(client, msg)
592 10d9cd27 Christos Stavrakakis
                self.assertTrue(client.basic_ack.called)
593 47eeffa9 Christos Stavrakakis
                db_bnet = BackendNetwork.objects.get(id=bn.id)
594 47eeffa9 Christos Stavrakakis
                self.assertEqual(bn.operstate, db_bnet.operstate)
595 47eeffa9 Christos Stavrakakis
                self.assertEqual(bn.network.state, db_bnet.network.state)
596 47eeffa9 Christos Stavrakakis
597 47eeffa9 Christos Stavrakakis
    def test_ips(self, client):
598 8764d304 Christos Stavrakakis
        network = mfactory.NetworkWithSubnetFactory(subnet__cidr='10.0.0.0/24',
599 8764d304 Christos Stavrakakis
                                                    subnet__gateway="10.0.0.1")
600 47eeffa9 Christos Stavrakakis
        bn = mfactory.BackendNetworkFactory(network=network)
601 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_SET_PARAMS',
602 47eeffa9 Christos Stavrakakis
                              network=network.backend_id,
603 47eeffa9 Christos Stavrakakis
                              cluster=bn.backend.clustername,
604 47eeffa9 Christos Stavrakakis
                              status='success',
605 8764d304 Christos Stavrakakis
                              job_fields={"add_reserved_ips": ["10.0.0.10",
606 8764d304 Christos Stavrakakis
                                                               "10.0.0.20"]})
607 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
608 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
609 3b2984dc Christos Stavrakakis
        pool = network.get_ip_pools()[0]
610 47eeffa9 Christos Stavrakakis
        self.assertTrue(pool.is_reserved('10.0.0.10'))
611 47eeffa9 Christos Stavrakakis
        self.assertTrue(pool.is_reserved('10.0.0.20'))
612 47eeffa9 Christos Stavrakakis
        pool.save()
613 8764d304 Christos Stavrakakis
        # Check that they are not released
614 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_SET_PARAMS',
615 47eeffa9 Christos Stavrakakis
                              network=network.backend_id,
616 47eeffa9 Christos Stavrakakis
                              cluster=bn.backend.clustername,
617 8764d304 Christos Stavrakakis
                              job_fields={
618 8764d304 Christos Stavrakakis
                                  "remove_reserved_ips": ["10.0.0.10",
619 8764d304 Christos Stavrakakis
                                                          "10.0.0.20"]})
620 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
621 8764d304 Christos Stavrakakis
        #self.assertTrue(client.basic_ack.called)
622 3b2984dc Christos Stavrakakis
        pool = network.get_ip_pools()[0]
623 8764d304 Christos Stavrakakis
        self.assertTrue(pool.is_reserved('10.0.0.10'))
624 8764d304 Christos Stavrakakis
        self.assertTrue(pool.is_reserved('10.0.0.20'))
625 95aee02c Vangelis Koukis
626 92c53da1 Vassilios Karakoidas
627 c8908e51 Christos Stavrakakis
@patch('synnefo.lib.amqp.AMQPClient')
628 c8908e51 Christos Stavrakakis
class UpdateBuildProgressTest(TestCase):
629 c8908e51 Christos Stavrakakis
    def setUp(self):
630 c8908e51 Christos Stavrakakis
        self.vm = mfactory.VirtualMachineFactory()
631 95aee02c Vangelis Koukis
632 c8908e51 Christos Stavrakakis
    def get_db_vm(self):
633 c8908e51 Christos Stavrakakis
        return VirtualMachine.objects.get(id=self.vm.id)
634 95aee02c Vangelis Koukis
635 c8908e51 Christos Stavrakakis
    def create_msg(self, **kwargs):
636 c8908e51 Christos Stavrakakis
        """Create snf-progress-monitor message"""
637 c8908e51 Christos Stavrakakis
        msg = {'event_time': split_time(time())}
638 c8908e51 Christos Stavrakakis
        msg['type'] = 'image-copy-progress'
639 c8908e51 Christos Stavrakakis
        msg['progress'] = 0
640 c8908e51 Christos Stavrakakis
        for key, val in kwargs.items():
641 c8908e51 Christos Stavrakakis
            msg[key] = val
642 c8908e51 Christos Stavrakakis
        message = {'body': json.dumps(msg)}
643 c8908e51 Christos Stavrakakis
        return message
644 95aee02c Vangelis Koukis
645 c8908e51 Christos Stavrakakis
    def test_missing_attribute(self, client):
646 c8908e51 Christos Stavrakakis
        update_build_progress(client, json.dumps({'body': {}}))
647 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
648 95aee02c Vangelis Koukis
649 c8908e51 Christos Stavrakakis
    def test_unhandled_exception(self, client):
650 c8908e51 Christos Stavrakakis
        update_build_progress(client, {})
651 c8908e51 Christos Stavrakakis
        client.basic_reject.assert_called_once()
652 c25cc9ec Vangelis Koukis
653 c8908e51 Christos Stavrakakis
    def test_missing_instance(self, client):
654 c8908e51 Christos Stavrakakis
        msg = self.create_msg(instance='foo')
655 c8908e51 Christos Stavrakakis
        update_build_progress(client, msg)
656 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
657 9068cd85 Georgios Gousios
658 c8908e51 Christos Stavrakakis
    def test_wrong_type(self, client):
659 c8908e51 Christos Stavrakakis
        msg = self.create_msg(type="WRONG_TYPE")
660 c8908e51 Christos Stavrakakis
        update_build_progress(client, msg)
661 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_nack.called)
662 9068cd85 Georgios Gousios
663 c8908e51 Christos Stavrakakis
    def test_progress_update(self, client):
664 c25cc9ec Vangelis Koukis
        rprogress = randint(10, 100)
665 c8908e51 Christos Stavrakakis
        msg = self.create_msg(progress=rprogress,
666 c8908e51 Christos Stavrakakis
                              instance=self.vm.backend_vm_id)
667 c8908e51 Christos Stavrakakis
        update_build_progress(client, msg)
668 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
669 c8908e51 Christos Stavrakakis
        vm = self.get_db_vm()
670 c8908e51 Christos Stavrakakis
        self.assertEqual(vm.buildpercentage, rprogress)
671 c8908e51 Christos Stavrakakis
672 c8908e51 Christos Stavrakakis
    def test_invalid_value(self, client):
673 c8908e51 Christos Stavrakakis
        old = self.vm.buildpercentage
674 c8908e51 Christos Stavrakakis
        for rprogress in [0, -1, 'a']:
675 c8908e51 Christos Stavrakakis
            msg = self.create_msg(progress=rprogress,
676 c8908e51 Christos Stavrakakis
                                  instance=self.vm.backend_vm_id)
677 c8908e51 Christos Stavrakakis
            update_build_progress(client, msg)
678 10d9cd27 Christos Stavrakakis
            self.assertTrue(client.basic_ack.called)
679 c8908e51 Christos Stavrakakis
            vm = self.get_db_vm()
680 c8908e51 Christos Stavrakakis
            self.assertEqual(vm.buildpercentage, old)