Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / logic / tests / callbacks.py @ 326c3ec8

History | View | Annotate | Download (29.6 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 ed2064f8 Christos Stavrakakis
from django.conf import settings
48 198d91c3 Christos Stavrakakis
from synnefo.logic.rapi import GanetiApiError
49 47eeffa9 Christos Stavrakakis
50 47eeffa9 Christos Stavrakakis
now = datetime.now
51 47eeffa9 Christos Stavrakakis
from time import time
52 47eeffa9 Christos Stavrakakis
import json
53 47eeffa9 Christos Stavrakakis
54 41a7fae7 Christos Stavrakakis
55 47eeffa9 Christos Stavrakakis
## Test Callbacks
56 47eeffa9 Christos Stavrakakis
@patch('synnefo.lib.amqp.AMQPClient')
57 47eeffa9 Christos Stavrakakis
class UpdateDBTest(TestCase):
58 47eeffa9 Christos Stavrakakis
    def create_msg(self, **kwargs):
59 47eeffa9 Christos Stavrakakis
        """Create snf-ganeti-eventd message"""
60 47eeffa9 Christos Stavrakakis
        msg = {'event_time': split_time(time())}
61 47eeffa9 Christos Stavrakakis
        msg['type'] = 'ganeti-op-status'
62 47eeffa9 Christos Stavrakakis
        msg['status'] = 'success'
63 47eeffa9 Christos Stavrakakis
        msg['jobId'] = 1
64 47eeffa9 Christos Stavrakakis
        msg['logmsg'] = 'Dummy Log'
65 47eeffa9 Christos Stavrakakis
        for key, val in kwargs.items():
66 47eeffa9 Christos Stavrakakis
            msg[key] = val
67 47eeffa9 Christos Stavrakakis
        message = {'body': json.dumps(msg)}
68 47eeffa9 Christos Stavrakakis
        return message
69 47eeffa9 Christos Stavrakakis
70 47eeffa9 Christos Stavrakakis
    def test_missing_attribute(self, client):
71 47eeffa9 Christos Stavrakakis
        update_db(client, json.dumps({'body': {}}))
72 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
73 47eeffa9 Christos Stavrakakis
74 47eeffa9 Christos Stavrakakis
    def test_unhandled_exception(self, client):
75 47eeffa9 Christos Stavrakakis
        update_db(client, {})
76 47eeffa9 Christos Stavrakakis
        client.basic_reject.assert_called_once()
77 47eeffa9 Christos Stavrakakis
78 47eeffa9 Christos Stavrakakis
    def test_missing_instance(self, client):
79 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
80 47eeffa9 Christos Stavrakakis
                              instance='foo')
81 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
82 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
83 47eeffa9 Christos Stavrakakis
84 47eeffa9 Christos Stavrakakis
    def test_wrong_type(self, client):
85 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(type="WRONG_TYPE")
86 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
87 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_nack.called)
88 47eeffa9 Christos Stavrakakis
89 b66e4833 Christos Stavrakakis
    def test_old_msg(self, client):
90 b66e4833 Christos Stavrakakis
        from time import sleep
91 b66e4833 Christos Stavrakakis
        from datetime import datetime
92 b66e4833 Christos Stavrakakis
        old_time = time()
93 b66e4833 Christos Stavrakakis
        sleep(0.01)
94 b66e4833 Christos Stavrakakis
        new_time = datetime.fromtimestamp(time())
95 b66e4833 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(backendtime=new_time)
96 b66e4833 Christos Stavrakakis
        vm.operstate = 'STOPPED'
97 b66e4833 Christos Stavrakakis
        vm.save()
98 b66e4833 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
99 b66e4833 Christos Stavrakakis
                              event_time=split_time(old_time),
100 b66e4833 Christos Stavrakakis
                              instance=vm.backend_vm_id)
101 b66e4833 Christos Stavrakakis
        update_db(client, msg)
102 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
103 b66e4833 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
104 b66e4833 Christos Stavrakakis
        self.assertEquals(db_vm.operstate, "STOPPED")
105 b66e4833 Christos Stavrakakis
        self.assertEquals(db_vm.backendtime, new_time)
106 b66e4833 Christos Stavrakakis
107 47eeffa9 Christos Stavrakakis
    def test_start(self, client):
108 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
109 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
110 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
111 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
112 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
113 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
114 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
115 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'STARTED')
116 47eeffa9 Christos Stavrakakis
117 47eeffa9 Christos Stavrakakis
    def test_stop(self, client):
118 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
119 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_SHUTDOWN',
120 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
121 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
122 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
123 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
124 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
125 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'STOPPED')
126 47eeffa9 Christos Stavrakakis
127 47eeffa9 Christos Stavrakakis
    def test_reboot(self, client):
128 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
129 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_REBOOT',
130 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
131 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
132 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
133 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
134 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'STARTED')
135 47eeffa9 Christos Stavrakakis
136 47eeffa9 Christos Stavrakakis
    def test_remove(self, client):
137 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
138 47eeffa9 Christos Stavrakakis
        # Also create a NIC
139 72dea98f Christos Stavrakakis
        nic = mfactory.NetworkInterfaceFactory(machine=vm)
140 72dea98f Christos Stavrakakis
        nic.network.get_pool().reserve(nic.ipv4)
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 72dea98f Christos Stavrakakis
        self.assertTrue(nic.network.get_pool().is_available(nic.ipv4))
152 72dea98f Christos Stavrakakis
        vm2 = mfactory.VirtualMachineFactory()
153 0c50c760 Christos Stavrakakis
        network = mfactory.NetworkFactory(floating_ip_pool=True)
154 326c3ec8 Christos Stavrakakis
        fp1 = mfactory.IPAddressFactory(machine=vm2, network=network)
155 326c3ec8 Christos Stavrakakis
        fp2 = mfactory.IPAddressFactory(machine=vm2, network=network)
156 72dea98f Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm2, network=network,
157 5962d9a6 Christos Stavrakakis
                                         ipv4=fp1.ipv4)
158 72dea98f Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm2, network=network,
159 5962d9a6 Christos Stavrakakis
                                         ipv4=fp2.ipv4)
160 72dea98f Christos Stavrakakis
        pool = network.get_pool()
161 72dea98f Christos Stavrakakis
        pool.reserve(fp1.ipv4)
162 72dea98f Christos Stavrakakis
        pool.reserve(fp2.ipv4)
163 72dea98f Christos Stavrakakis
        pool.save()
164 72dea98f Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_REMOVE',
165 72dea98f Christos Stavrakakis
                              instance=vm2.backend_vm_id)
166 72dea98f Christos Stavrakakis
        with mocked_quotaholder():
167 72dea98f Christos Stavrakakis
            update_db(client, msg)
168 72dea98f Christos Stavrakakis
        client.basic_ack.assert_called_once()
169 72dea98f Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
170 72dea98f Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'DESTROYED')
171 72dea98f Christos Stavrakakis
        self.assertTrue(db_vm.deleted)
172 326c3ec8 Christos Stavrakakis
        self.assertEqual(IPAddress.objects.get(id=fp1.id).machine, None)
173 326c3ec8 Christos Stavrakakis
        self.assertEqual(IPAddress.objects.get(id=fp2.id).machine, None)
174 72dea98f Christos Stavrakakis
        pool = network.get_pool()
175 72dea98f Christos Stavrakakis
        # Test that floating ips are not released
176 72dea98f Christos Stavrakakis
        self.assertFalse(pool.is_available(fp1.ipv4))
177 72dea98f Christos Stavrakakis
        self.assertFalse(pool.is_available(fp2.ipv4))
178 47eeffa9 Christos Stavrakakis
179 198d91c3 Christos Stavrakakis
    @patch("synnefo.logic.rapi_pool.GanetiRapiClient")
180 198d91c3 Christos Stavrakakis
    def test_remove_error(self, rapi, client):
181 198d91c3 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
182 198d91c3 Christos Stavrakakis
        # Also create a NIC
183 198d91c3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_REMOVE',
184 198d91c3 Christos Stavrakakis
                              status="error",
185 198d91c3 Christos Stavrakakis
                              instance=vm.backend_vm_id)
186 198d91c3 Christos Stavrakakis
        rapi().GetInstance.return_value = {}
187 198d91c3 Christos Stavrakakis
        update_db(client, msg)
188 198d91c3 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
189 198d91c3 Christos Stavrakakis
        self.assertFalse(db_vm.deleted)
190 198d91c3 Christos Stavrakakis
191 198d91c3 Christos Stavrakakis
        rapi().GetInstance.side_effect = GanetiApiError(msg="msg",
192 198d91c3 Christos Stavrakakis
                                                        code=503)
193 198d91c3 Christos Stavrakakis
        update_db(client, msg)
194 198d91c3 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
195 198d91c3 Christos Stavrakakis
        self.assertFalse(db_vm.deleted)
196 198d91c3 Christos Stavrakakis
197 198d91c3 Christos Stavrakakis
        rapi().GetInstance.side_effect = GanetiApiError(msg="msg",
198 198d91c3 Christos Stavrakakis
                                                        code=404)
199 198d91c3 Christos Stavrakakis
        with mocked_quotaholder():
200 198d91c3 Christos Stavrakakis
            update_db(client, msg)
201 198d91c3 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
202 198d91c3 Christos Stavrakakis
        self.assertTrue(db_vm.deleted)
203 198d91c3 Christos Stavrakakis
204 47eeffa9 Christos Stavrakakis
    def test_create(self, client):
205 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
206 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_CREATE',
207 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
208 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
209 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
210 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
211 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'STARTED')
212 47eeffa9 Christos Stavrakakis
213 47eeffa9 Christos Stavrakakis
    def test_create_error(self, client):
214 47eeffa9 Christos Stavrakakis
        """Test that error create sets vm to ERROR state"""
215 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
216 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_CREATE',
217 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id,
218 47eeffa9 Christos Stavrakakis
                              status='error')
219 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
220 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
221 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
222 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'ERROR')
223 47eeffa9 Christos Stavrakakis
224 47eeffa9 Christos Stavrakakis
    def test_remove_from_error(self, client):
225 47eeffa9 Christos Stavrakakis
        """Test that error removes delete error builds"""
226 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate='ERROR')
227 47eeffa9 Christos Stavrakakis
        # Also create a NIC
228 47eeffa9 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm)
229 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_REMOVE',
230 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
231 184a2a8c Christos Stavrakakis
        with mocked_quotaholder():
232 184a2a8c Christos Stavrakakis
            update_db(client, msg)
233 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
234 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
235 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'DESTROYED')
236 47eeffa9 Christos Stavrakakis
        self.assertTrue(db_vm.deleted)
237 47eeffa9 Christos Stavrakakis
        # Check that nics are deleted
238 47eeffa9 Christos Stavrakakis
        self.assertFalse(db_vm.nics.all())
239 47eeffa9 Christos Stavrakakis
240 47eeffa9 Christos Stavrakakis
    def test_other_error(self, client):
241 47eeffa9 Christos Stavrakakis
        """Test that other error messages do no affect the VM"""
242 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
243 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
244 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id,
245 47eeffa9 Christos Stavrakakis
                              status='error')
246 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
247 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
248 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
249 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, vm.operstate)
250 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.backendtime, vm.backendtime)
251 47eeffa9 Christos Stavrakakis
252 ca4d59e3 Christos Stavrakakis
    def test_resize_msg(self, client):
253 ca4d59e3 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
254 ca4d59e3 Christos Stavrakakis
        # Test empty beparams
255 ca4d59e3 Christos Stavrakakis
        for status in ["success", "error"]:
256 ca4d59e3 Christos Stavrakakis
            msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
257 ca4d59e3 Christos Stavrakakis
                                  instance=vm.backend_vm_id,
258 ca4d59e3 Christos Stavrakakis
                                  beparams={},
259 ca4d59e3 Christos Stavrakakis
                                  status=status)
260 ca4d59e3 Christos Stavrakakis
            client.reset_mock()
261 41a7fae7 Christos Stavrakakis
            with mocked_quotaholder():
262 41a7fae7 Christos Stavrakakis
                update_db(client, msg)
263 ca4d59e3 Christos Stavrakakis
            self.assertTrue(client.basic_ack.called)
264 ca4d59e3 Christos Stavrakakis
            db_vm = VirtualMachine.objects.get(id=vm.id)
265 ca4d59e3 Christos Stavrakakis
            self.assertEqual(db_vm.operstate, vm.operstate)
266 ca4d59e3 Christos Stavrakakis
        # Test intermediate states
267 2cd55da6 Christos Stavrakakis
        vm.operstate = "STOPPED"
268 2cd55da6 Christos Stavrakakis
        vm.save()
269 ca4d59e3 Christos Stavrakakis
        for status in ["queued", "waiting", "running"]:
270 ca4d59e3 Christos Stavrakakis
            msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
271 ca4d59e3 Christos Stavrakakis
                                  instance=vm.backend_vm_id,
272 ca4d59e3 Christos Stavrakakis
                                  beparams={"vcpus": 4, "minmem": 2048,
273 ca4d59e3 Christos Stavrakakis
                                            "maxmem": 2048},
274 ca4d59e3 Christos Stavrakakis
                                  status=status)
275 ca4d59e3 Christos Stavrakakis
            client.reset_mock()
276 ca4d59e3 Christos Stavrakakis
            update_db(client, msg)
277 ca4d59e3 Christos Stavrakakis
            self.assertTrue(client.basic_ack.called)
278 ca4d59e3 Christos Stavrakakis
            db_vm = VirtualMachine.objects.get(id=vm.id)
279 41a7fae7 Christos Stavrakakis
            self.assertEqual(db_vm.operstate, "STOPPED")
280 ca4d59e3 Christos Stavrakakis
        # Test operstate after error
281 ca4d59e3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
282 ca4d59e3 Christos Stavrakakis
                              instance=vm.backend_vm_id,
283 ca4d59e3 Christos Stavrakakis
                              beparams={"vcpus": 4},
284 ca4d59e3 Christos Stavrakakis
                              status="error")
285 ca4d59e3 Christos Stavrakakis
        client.reset_mock()
286 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
287 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
288 ca4d59e3 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
289 ca4d59e3 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
290 ca4d59e3 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, "STOPPED")
291 ca4d59e3 Christos Stavrakakis
        # Test success
292 ca4d59e3 Christos Stavrakakis
        f1 = mfactory.FlavorFactory(cpu=4, ram=1024, disk_template="drbd",
293 ca4d59e3 Christos Stavrakakis
                                    disk=1024)
294 ca4d59e3 Christos Stavrakakis
        vm.flavor = f1
295 ca4d59e3 Christos Stavrakakis
        vm.save()
296 ca4d59e3 Christos Stavrakakis
        f2 = mfactory.FlavorFactory(cpu=8, ram=2048, disk_template="drbd",
297 ca4d59e3 Christos Stavrakakis
                                    disk=1024)
298 ca4d59e3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
299 ca4d59e3 Christos Stavrakakis
                              instance=vm.backend_vm_id,
300 ca4d59e3 Christos Stavrakakis
                              beparams={"vcpus": 8, "minmem": 2048,
301 ca4d59e3 Christos Stavrakakis
                                        "maxmem": 2048},
302 ca4d59e3 Christos Stavrakakis
                              status="success")
303 ca4d59e3 Christos Stavrakakis
        client.reset_mock()
304 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
305 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
306 ca4d59e3 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
307 ca4d59e3 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
308 ca4d59e3 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, "STOPPED")
309 ca4d59e3 Christos Stavrakakis
        self.assertEqual(db_vm.flavor, f2)
310 ca4d59e3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
311 ca4d59e3 Christos Stavrakakis
                              instance=vm.backend_vm_id,
312 ca4d59e3 Christos Stavrakakis
                              beparams={"vcpus": 100, "minmem": 2048,
313 ca4d59e3 Christos Stavrakakis
                                        "maxmem": 2048},
314 ca4d59e3 Christos Stavrakakis
                              status="success")
315 ca4d59e3 Christos Stavrakakis
        client.reset_mock()
316 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
317 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
318 ca4d59e3 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
319 ca4d59e3 Christos Stavrakakis
320 47eeffa9 Christos Stavrakakis
321 47eeffa9 Christos Stavrakakis
@patch('synnefo.lib.amqp.AMQPClient')
322 47eeffa9 Christos Stavrakakis
class UpdateNetTest(TestCase):
323 47eeffa9 Christos Stavrakakis
    def create_msg(self, **kwargs):
324 47eeffa9 Christos Stavrakakis
        """Create snf-ganeti-hook message"""
325 47eeffa9 Christos Stavrakakis
        msg = {'event_time': split_time(time())}
326 fd95834e Christos Stavrakakis
        msg['type'] = 'ganeti-op-status'
327 fd95834e Christos Stavrakakis
        msg['operation'] = 'OP_INSTANCE_SET_PARAMS'
328 47eeffa9 Christos Stavrakakis
        msg['status'] = 'success'
329 47eeffa9 Christos Stavrakakis
        msg['jobId'] = 1
330 47eeffa9 Christos Stavrakakis
        msg['logmsg'] = 'Dummy Log'
331 47eeffa9 Christos Stavrakakis
        for key, val in kwargs.items():
332 47eeffa9 Christos Stavrakakis
            msg[key] = val
333 47eeffa9 Christos Stavrakakis
        message = {'body': json.dumps(msg)}
334 47eeffa9 Christos Stavrakakis
        return message
335 47eeffa9 Christos Stavrakakis
336 47eeffa9 Christos Stavrakakis
    def test_missing_attribute(self, client):
337 fd95834e Christos Stavrakakis
        update_db(client, json.dumps({'body': {}}))
338 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
339 47eeffa9 Christos Stavrakakis
340 47eeffa9 Christos Stavrakakis
    def test_unhandled_exception(self, client):
341 fd95834e Christos Stavrakakis
        update_db(client, {})
342 47eeffa9 Christos Stavrakakis
        client.basic_reject.assert_called_once()
343 47eeffa9 Christos Stavrakakis
344 47eeffa9 Christos Stavrakakis
    def test_wrong_type(self, client):
345 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(type="WRONG_TYPE")
346 fd95834e Christos Stavrakakis
        update_db(client, msg)
347 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_nack.called)
348 47eeffa9 Christos Stavrakakis
349 47eeffa9 Christos Stavrakakis
    def test_missing_instance(self, client):
350 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
351 47eeffa9 Christos Stavrakakis
                              instance='foo')
352 fd95834e Christos Stavrakakis
        update_db(client, msg)
353 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
354 47eeffa9 Christos Stavrakakis
355 47eeffa9 Christos Stavrakakis
    def test_no_nics(self, client):
356 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate='ERROR')
357 47eeffa9 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm)
358 47eeffa9 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm)
359 47eeffa9 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm)
360 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(vm.nics.all()), 3)
361 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(nics=[],
362 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
363 fd95834e Christos Stavrakakis
        update_db(client, msg)
364 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
365 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
366 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(db_vm.nics.all()), 0)
367 47eeffa9 Christos Stavrakakis
368 47eeffa9 Christos Stavrakakis
    def test_empty_nic(self, client):
369 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate='ERROR')
370 47eeffa9 Christos Stavrakakis
        for public in [True, False]:
371 5962d9a6 Christos Stavrakakis
            net = mfactory.NetworkFactory(public=public, subnet6=None)
372 cc92b70f Christos Stavrakakis
            msg = self.create_msg(nics=[{'network': net.backend_id}],
373 47eeffa9 Christos Stavrakakis
                                  instance=vm.backend_vm_id)
374 fd95834e Christos Stavrakakis
            update_db(client, msg)
375 10d9cd27 Christos Stavrakakis
            self.assertTrue(client.basic_ack.called)
376 47eeffa9 Christos Stavrakakis
            db_vm = VirtualMachine.objects.get(id=vm.id)
377 47eeffa9 Christos Stavrakakis
            nics = db_vm.nics.all()
378 47eeffa9 Christos Stavrakakis
            self.assertEqual(len(nics), 1)
379 47eeffa9 Christos Stavrakakis
            self.assertEqual(nics[0].index, 0)
380 8d325d4b Christos Stavrakakis
            self.assertEqual(nics[0].ipv4, None)
381 8d325d4b Christos Stavrakakis
            self.assertEqual(nics[0].ipv6, None)
382 8d325d4b Christos Stavrakakis
            self.assertEqual(nics[0].mac, None)
383 47eeffa9 Christos Stavrakakis
            if public:
384 47eeffa9 Christos Stavrakakis
                self.assertEqual(nics[0].firewall_profile,
385 47eeffa9 Christos Stavrakakis
                                 settings.DEFAULT_FIREWALL_PROFILE)
386 47eeffa9 Christos Stavrakakis
            else:
387 8d325d4b Christos Stavrakakis
                self.assertEqual(nics[0].firewall_profile, None)
388 47eeffa9 Christos Stavrakakis
389 47eeffa9 Christos Stavrakakis
    def test_full_nic(self, client):
390 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate='ERROR')
391 5962d9a6 Christos Stavrakakis
        net = mfactory.NetworkFactory(subnet='10.0.0.0/24', subnet6=None)
392 47eeffa9 Christos Stavrakakis
        pool = net.get_pool()
393 47eeffa9 Christos Stavrakakis
        self.assertTrue(pool.is_available('10.0.0.22'))
394 47eeffa9 Christos Stavrakakis
        pool.save()
395 cc92b70f Christos Stavrakakis
        msg = self.create_msg(nics=[{'network': net.backend_id,
396 47eeffa9 Christos Stavrakakis
                                     'ip': '10.0.0.22',
397 47eeffa9 Christos Stavrakakis
                                     'mac': 'aa:bb:cc:00:11:22'}],
398 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
399 fd95834e Christos Stavrakakis
        update_db(client, msg)
400 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
401 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
402 47eeffa9 Christos Stavrakakis
        nics = db_vm.nics.all()
403 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(nics), 1)
404 47eeffa9 Christos Stavrakakis
        self.assertEqual(nics[0].index, 0)
405 47eeffa9 Christos Stavrakakis
        self.assertEqual(nics[0].ipv4, '10.0.0.22')
406 8d325d4b Christos Stavrakakis
        self.assertEqual(nics[0].ipv6, None)
407 47eeffa9 Christos Stavrakakis
        self.assertEqual(nics[0].mac, 'aa:bb:cc:00:11:22')
408 47eeffa9 Christos Stavrakakis
        pool = net.get_pool()
409 47eeffa9 Christos Stavrakakis
        self.assertFalse(pool.is_available('10.0.0.22'))
410 47eeffa9 Christos Stavrakakis
        pool.save()
411 47eeffa9 Christos Stavrakakis
412 47eeffa9 Christos Stavrakakis
413 47eeffa9 Christos Stavrakakis
@patch('synnefo.lib.amqp.AMQPClient')
414 47eeffa9 Christos Stavrakakis
class UpdateNetworkTest(TestCase):
415 47eeffa9 Christos Stavrakakis
    def create_msg(self, **kwargs):
416 47eeffa9 Christos Stavrakakis
        """Create snf-ganeti-eventd message"""
417 47eeffa9 Christos Stavrakakis
        msg = {'event_time': split_time(time())}
418 47eeffa9 Christos Stavrakakis
        msg['type'] = 'ganeti-network-status'
419 47eeffa9 Christos Stavrakakis
        msg['status'] = 'success'
420 47eeffa9 Christos Stavrakakis
        msg['jobId'] = 1
421 47eeffa9 Christos Stavrakakis
        msg['logmsg'] = 'Dummy Log'
422 47eeffa9 Christos Stavrakakis
        for key, val in kwargs.items():
423 47eeffa9 Christos Stavrakakis
            msg[key] = val
424 47eeffa9 Christos Stavrakakis
        message = {'body': json.dumps(msg)}
425 47eeffa9 Christos Stavrakakis
        return message
426 47eeffa9 Christos Stavrakakis
427 47eeffa9 Christos Stavrakakis
    def test_missing_attribute(self, client):
428 47eeffa9 Christos Stavrakakis
        update_network(client, json.dumps({'body': {}}))
429 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
430 47eeffa9 Christos Stavrakakis
431 47eeffa9 Christos Stavrakakis
    def test_unhandled_exception(self, client):
432 47eeffa9 Christos Stavrakakis
        update_network(client, {})
433 47eeffa9 Christos Stavrakakis
        client.basic_reject.assert_called_once()
434 47eeffa9 Christos Stavrakakis
435 47eeffa9 Christos Stavrakakis
    def test_wrong_type(self, client):
436 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(type="WRONG_TYPE")
437 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
438 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_nack.called)
439 47eeffa9 Christos Stavrakakis
440 47eeffa9 Christos Stavrakakis
    def test_missing_network(self, client):
441 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_CREATE',
442 47eeffa9 Christos Stavrakakis
                              network='foo')
443 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
444 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
445 47eeffa9 Christos Stavrakakis
446 47eeffa9 Christos Stavrakakis
    def test_create(self, client):
447 47eeffa9 Christos Stavrakakis
        back_network = mfactory.BackendNetworkFactory(operstate='PENDING')
448 47eeffa9 Christos Stavrakakis
        net = back_network.network
449 1d04ef8b Christos Stavrakakis
        net.state = 'ACTIVE'
450 1d04ef8b Christos Stavrakakis
        net.save()
451 47eeffa9 Christos Stavrakakis
        back1 = back_network.backend
452 47eeffa9 Christos Stavrakakis
453 47eeffa9 Christos Stavrakakis
        back_network2 = mfactory.BackendNetworkFactory(operstate='PENDING',
454 47eeffa9 Christos Stavrakakis
                                                       network=net)
455 47eeffa9 Christos Stavrakakis
        back2 = back_network2.backend
456 47eeffa9 Christos Stavrakakis
        # Message from first backend network
457 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_CONNECT',
458 47eeffa9 Christos Stavrakakis
                              network=net.backend_id,
459 47eeffa9 Christos Stavrakakis
                              cluster=back1.clustername)
460 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
461 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
462 47eeffa9 Christos Stavrakakis
463 47eeffa9 Christos Stavrakakis
        back_net = BackendNetwork.objects.get(id=back_network.id)
464 47eeffa9 Christos Stavrakakis
        self.assertEqual(back_net.operstate, 'ACTIVE')
465 47eeffa9 Christos Stavrakakis
        db_net = Network.objects.get(id=net.id)
466 1d04ef8b Christos Stavrakakis
        self.assertEqual(db_net.state, 'ACTIVE')
467 47eeffa9 Christos Stavrakakis
        # msg from second backend network
468 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_CONNECT',
469 47eeffa9 Christos Stavrakakis
                              network=net.backend_id,
470 47eeffa9 Christos Stavrakakis
                              cluster=back2.clustername)
471 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
472 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
473 47eeffa9 Christos Stavrakakis
474 47eeffa9 Christos Stavrakakis
        db_net = Network.objects.get(id=net.id)
475 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_net.state, 'ACTIVE')
476 47eeffa9 Christos Stavrakakis
        back_net = BackendNetwork.objects.get(id=back_network.id)
477 47eeffa9 Christos Stavrakakis
        self.assertEqual(back_net.operstate, 'ACTIVE')
478 47eeffa9 Christos Stavrakakis
479 039e3e61 Christos Stavrakakis
    def test_create_offline_backend(self, client):
480 039e3e61 Christos Stavrakakis
        """Test network creation when a backend is offline"""
481 1d04ef8b Christos Stavrakakis
        net = mfactory.NetworkFactory(state='ACTIVE')
482 039e3e61 Christos Stavrakakis
        bn1 = mfactory.BackendNetworkFactory(network=net)
483 5962d9a6 Christos Stavrakakis
        mfactory.BackendNetworkFactory(network=net,
484 5962d9a6 Christos Stavrakakis
                                       backend__offline=True)
485 039e3e61 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_CONNECT',
486 039e3e61 Christos Stavrakakis
                              network=net.backend_id,
487 039e3e61 Christos Stavrakakis
                              cluster=bn1.backend.clustername)
488 039e3e61 Christos Stavrakakis
        update_network(client, msg)
489 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
490 039e3e61 Christos Stavrakakis
        new_net = Network.objects.get(id=net.id)
491 039e3e61 Christos Stavrakakis
        self.assertEqual(new_net.state, 'ACTIVE')
492 039e3e61 Christos Stavrakakis
493 47eeffa9 Christos Stavrakakis
    def test_disconnect(self, client):
494 47eeffa9 Christos Stavrakakis
        bn1 = mfactory.BackendNetworkFactory(operstate='ACTIVE')
495 47eeffa9 Christos Stavrakakis
        net1 = bn1.network
496 1d04ef8b Christos Stavrakakis
        net1.state = "ACTIVE"
497 1d04ef8b Christos Stavrakakis
        net1.state = 'ACTIVE'
498 47eeffa9 Christos Stavrakakis
        net1.save()
499 47eeffa9 Christos Stavrakakis
        bn2 = mfactory.BackendNetworkFactory(operstate='ACTIVE',
500 47eeffa9 Christos Stavrakakis
                                             network=net1)
501 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_DISCONNECT',
502 47eeffa9 Christos Stavrakakis
                              network=net1.backend_id,
503 47eeffa9 Christos Stavrakakis
                              cluster=bn2.backend.clustername)
504 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
505 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
506 1d04ef8b Christos Stavrakakis
        self.assertEqual(Network.objects.get(id=net1.id).state, 'ACTIVE')
507 47eeffa9 Christos Stavrakakis
        self.assertEqual(BackendNetwork.objects.get(id=bn2.id).operstate,
508 cc92b70f Christos Stavrakakis
                         'PENDING')
509 47eeffa9 Christos Stavrakakis
510 47eeffa9 Christos Stavrakakis
    def test_remove(self, client):
511 47eeffa9 Christos Stavrakakis
        mfactory.MacPrefixPoolTableFactory()
512 47eeffa9 Christos Stavrakakis
        mfactory.BridgePoolTableFactory()
513 47eeffa9 Christos Stavrakakis
        bn = mfactory.BackendNetworkFactory(operstate='ACTIVE')
514 47eeffa9 Christos Stavrakakis
        for old_state in ['success', 'canceled', 'error']:
515 47eeffa9 Christos Stavrakakis
            for flavor in Network.FLAVORS.keys():
516 47eeffa9 Christos Stavrakakis
                bn.operstate = old_state
517 47eeffa9 Christos Stavrakakis
                bn.save()
518 47eeffa9 Christos Stavrakakis
                net = bn.network
519 47eeffa9 Christos Stavrakakis
                net.state = 'ACTIVE'
520 47eeffa9 Christos Stavrakakis
                net.flavor = flavor
521 47eeffa9 Christos Stavrakakis
                if flavor == 'PHYSICAL_VLAN':
522 47eeffa9 Christos Stavrakakis
                    net.link = allocate_resource('bridge')
523 47eeffa9 Christos Stavrakakis
                if flavor == 'MAC_FILTERED':
524 47eeffa9 Christos Stavrakakis
                    net.mac_prefix = allocate_resource('mac_prefix')
525 47eeffa9 Christos Stavrakakis
                net.save()
526 47eeffa9 Christos Stavrakakis
                msg = self.create_msg(operation='OP_NETWORK_REMOVE',
527 47eeffa9 Christos Stavrakakis
                                      network=net.backend_id,
528 47eeffa9 Christos Stavrakakis
                                      cluster=bn.backend.clustername)
529 184a2a8c Christos Stavrakakis
                with mocked_quotaholder():
530 184a2a8c Christos Stavrakakis
                    update_network(client, msg)
531 10d9cd27 Christos Stavrakakis
                self.assertTrue(client.basic_ack.called)
532 47eeffa9 Christos Stavrakakis
                db_bnet = BackendNetwork.objects.get(id=bn.id)
533 47eeffa9 Christos Stavrakakis
                self.assertEqual(db_bnet.operstate,
534 cc92b70f Christos Stavrakakis
                                 'DELETED')
535 47eeffa9 Christos Stavrakakis
                db_net = Network.objects.get(id=net.id)
536 47eeffa9 Christos Stavrakakis
                self.assertEqual(db_net.state, 'DELETED', flavor)
537 47eeffa9 Christos Stavrakakis
                self.assertTrue(db_net.deleted)
538 47eeffa9 Christos Stavrakakis
                if flavor == 'PHYSICAL_VLAN':
539 47eeffa9 Christos Stavrakakis
                    pool = BridgePoolTable.get_pool()
540 47eeffa9 Christos Stavrakakis
                    self.assertTrue(pool.is_available(net.link))
541 47eeffa9 Christos Stavrakakis
                if flavor == 'MAC_FILTERED':
542 47eeffa9 Christos Stavrakakis
                    pool = MacPrefixPoolTable.get_pool()
543 47eeffa9 Christos Stavrakakis
                    self.assertTrue(pool.is_available(net.mac_prefix))
544 47eeffa9 Christos Stavrakakis
545 198d91c3 Christos Stavrakakis
    @patch("synnefo.logic.rapi_pool.GanetiRapiClient")
546 198d91c3 Christos Stavrakakis
    def test_remove_error(self, rapi, client):
547 198d91c3 Christos Stavrakakis
        mfactory.MacPrefixPoolTableFactory()
548 198d91c3 Christos Stavrakakis
        mfactory.BridgePoolTableFactory()
549 198d91c3 Christos Stavrakakis
        bn = mfactory.BackendNetworkFactory(operstate='ACTIVE')
550 198d91c3 Christos Stavrakakis
        network = bn.network
551 198d91c3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_REMOVE',
552 198d91c3 Christos Stavrakakis
                              network=network.backend_id,
553 198d91c3 Christos Stavrakakis
                              status="error",
554 198d91c3 Christos Stavrakakis
                              cluster=bn.backend.clustername)
555 198d91c3 Christos Stavrakakis
        rapi().GetNetwork.return_value = {}
556 198d91c3 Christos Stavrakakis
        update_network(client, msg)
557 198d91c3 Christos Stavrakakis
        bn = BackendNetwork.objects.get(id=bn.id)
558 198d91c3 Christos Stavrakakis
        self.assertNotEqual(bn.operstate, "DELETED")
559 198d91c3 Christos Stavrakakis
        rapi().GetNetwork.side_effect = GanetiApiError(msg="foo", code=404)
560 198d91c3 Christos Stavrakakis
        with mocked_quotaholder():
561 198d91c3 Christos Stavrakakis
            update_network(client, msg)
562 198d91c3 Christos Stavrakakis
        bn = BackendNetwork.objects.get(id=bn.id)
563 198d91c3 Christos Stavrakakis
        self.assertEqual(bn.operstate, "DELETED")
564 198d91c3 Christos Stavrakakis
565 039e3e61 Christos Stavrakakis
    def test_remove_offline_backend(self, client):
566 039e3e61 Christos Stavrakakis
        """Test network removing when a backend is offline"""
567 3f77e63d Christos Stavrakakis
        mfactory.BridgePoolTableFactory()
568 3f77e63d Christos Stavrakakis
        net = mfactory.NetworkFactory(flavor='PHYSICAL_VLAN',
569 3f77e63d Christos Stavrakakis
                                      state='ACTIVE',
570 3f77e63d Christos Stavrakakis
                                      link='prv12')
571 039e3e61 Christos Stavrakakis
        bn1 = mfactory.BackendNetworkFactory(network=net)
572 039e3e61 Christos Stavrakakis
        mfactory.BackendNetworkFactory(network=net,
573 c6c889f7 Christos Stavrakakis
                                       operstate="ACTIVE",
574 3f77e63d Christos Stavrakakis
                                       backend__offline=True)
575 039e3e61 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_REMOVE',
576 039e3e61 Christos Stavrakakis
                              network=net.backend_id,
577 039e3e61 Christos Stavrakakis
                              cluster=bn1.backend.clustername)
578 184a2a8c Christos Stavrakakis
        with mocked_quotaholder():
579 184a2a8c Christos Stavrakakis
            update_network(client, msg)
580 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
581 039e3e61 Christos Stavrakakis
        new_net = Network.objects.get(id=net.id)
582 1d04ef8b Christos Stavrakakis
        self.assertEqual(new_net.state, 'ACTIVE')
583 1d04ef8b Christos Stavrakakis
        self.assertFalse(new_net.deleted)
584 039e3e61 Christos Stavrakakis
585 47eeffa9 Christos Stavrakakis
    def test_error_opcode(self, client):
586 c6c889f7 Christos Stavrakakis
        mfactory.MacPrefixPoolTableFactory()
587 c6c889f7 Christos Stavrakakis
        mfactory.BridgePoolTableFactory()
588 47eeffa9 Christos Stavrakakis
        for state, _ in Network.OPER_STATES:
589 c6c889f7 Christos Stavrakakis
            bn = mfactory.BackendNetworkFactory(operstate="ACTIVE")
590 47eeffa9 Christos Stavrakakis
            bn.operstate = state
591 47eeffa9 Christos Stavrakakis
            bn.save()
592 47eeffa9 Christos Stavrakakis
            network = bn.network
593 47eeffa9 Christos Stavrakakis
            network.state = state
594 47eeffa9 Christos Stavrakakis
            network.save()
595 47eeffa9 Christos Stavrakakis
            for opcode, _ in BackendNetwork.BACKEND_OPCODES:
596 47eeffa9 Christos Stavrakakis
                if opcode in ['OP_NETWORK_REMOVE', 'OP_NETWORK_ADD']:
597 47eeffa9 Christos Stavrakakis
                    continue
598 47eeffa9 Christos Stavrakakis
                msg = self.create_msg(operation=opcode,
599 47eeffa9 Christos Stavrakakis
                                      network=bn.network.backend_id,
600 47eeffa9 Christos Stavrakakis
                                      status='error',
601 c6c889f7 Christos Stavrakakis
                                      add_reserved_ips=[],
602 c6c889f7 Christos Stavrakakis
                                      remove_reserved_ips=[],
603 47eeffa9 Christos Stavrakakis
                                      cluster=bn.backend.clustername)
604 c6c889f7 Christos Stavrakakis
                with mocked_quotaholder():
605 c6c889f7 Christos Stavrakakis
                    update_network(client, msg)
606 10d9cd27 Christos Stavrakakis
                self.assertTrue(client.basic_ack.called)
607 47eeffa9 Christos Stavrakakis
                db_bnet = BackendNetwork.objects.get(id=bn.id)
608 47eeffa9 Christos Stavrakakis
                self.assertEqual(bn.operstate, db_bnet.operstate)
609 47eeffa9 Christos Stavrakakis
                self.assertEqual(bn.network.state, db_bnet.network.state)
610 47eeffa9 Christos Stavrakakis
611 47eeffa9 Christos Stavrakakis
    def test_ips(self, client):
612 47eeffa9 Christos Stavrakakis
        network = mfactory.NetworkFactory(subnet='10.0.0.0/24')
613 47eeffa9 Christos Stavrakakis
        bn = mfactory.BackendNetworkFactory(network=network)
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 47eeffa9 Christos Stavrakakis
                              status='success',
618 47eeffa9 Christos Stavrakakis
                              add_reserved_ips=['10.0.0.10', '10.0.0.20'],
619 47eeffa9 Christos Stavrakakis
                              remove_reserved_ips=[])
620 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
621 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
622 47eeffa9 Christos Stavrakakis
        pool = network.get_pool()
623 47eeffa9 Christos Stavrakakis
        self.assertTrue(pool.is_reserved('10.0.0.10'))
624 47eeffa9 Christos Stavrakakis
        self.assertTrue(pool.is_reserved('10.0.0.20'))
625 47eeffa9 Christos Stavrakakis
        pool.save()
626 47eeffa9 Christos Stavrakakis
        # Release them
627 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_SET_PARAMS',
628 47eeffa9 Christos Stavrakakis
                              network=network.backend_id,
629 47eeffa9 Christos Stavrakakis
                              cluster=bn.backend.clustername,
630 47eeffa9 Christos Stavrakakis
                              add_reserved_ips=[],
631 47eeffa9 Christos Stavrakakis
                              remove_reserved_ips=['10.0.0.10', '10.0.0.20'])
632 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
633 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
634 47eeffa9 Christos Stavrakakis
        pool = network.get_pool()
635 47eeffa9 Christos Stavrakakis
        self.assertFalse(pool.is_reserved('10.0.0.10'))
636 47eeffa9 Christos Stavrakakis
        self.assertFalse(pool.is_reserved('10.0.0.20'))
637 95aee02c Vangelis Koukis
638 92c53da1 Vassilios Karakoidas
639 c8908e51 Christos Stavrakakis
@patch('synnefo.lib.amqp.AMQPClient')
640 c8908e51 Christos Stavrakakis
class UpdateBuildProgressTest(TestCase):
641 c8908e51 Christos Stavrakakis
    def setUp(self):
642 c8908e51 Christos Stavrakakis
        self.vm = mfactory.VirtualMachineFactory()
643 95aee02c Vangelis Koukis
644 c8908e51 Christos Stavrakakis
    def get_db_vm(self):
645 c8908e51 Christos Stavrakakis
        return VirtualMachine.objects.get(id=self.vm.id)
646 95aee02c Vangelis Koukis
647 c8908e51 Christos Stavrakakis
    def create_msg(self, **kwargs):
648 c8908e51 Christos Stavrakakis
        """Create snf-progress-monitor message"""
649 c8908e51 Christos Stavrakakis
        msg = {'event_time': split_time(time())}
650 c8908e51 Christos Stavrakakis
        msg['type'] = 'image-copy-progress'
651 c8908e51 Christos Stavrakakis
        msg['progress'] = 0
652 c8908e51 Christos Stavrakakis
        for key, val in kwargs.items():
653 c8908e51 Christos Stavrakakis
            msg[key] = val
654 c8908e51 Christos Stavrakakis
        message = {'body': json.dumps(msg)}
655 c8908e51 Christos Stavrakakis
        return message
656 95aee02c Vangelis Koukis
657 c8908e51 Christos Stavrakakis
    def test_missing_attribute(self, client):
658 c8908e51 Christos Stavrakakis
        update_build_progress(client, json.dumps({'body': {}}))
659 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
660 95aee02c Vangelis Koukis
661 c8908e51 Christos Stavrakakis
    def test_unhandled_exception(self, client):
662 c8908e51 Christos Stavrakakis
        update_build_progress(client, {})
663 c8908e51 Christos Stavrakakis
        client.basic_reject.assert_called_once()
664 c25cc9ec Vangelis Koukis
665 c8908e51 Christos Stavrakakis
    def test_missing_instance(self, client):
666 c8908e51 Christos Stavrakakis
        msg = self.create_msg(instance='foo')
667 c8908e51 Christos Stavrakakis
        update_build_progress(client, msg)
668 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
669 9068cd85 Georgios Gousios
670 c8908e51 Christos Stavrakakis
    def test_wrong_type(self, client):
671 c8908e51 Christos Stavrakakis
        msg = self.create_msg(type="WRONG_TYPE")
672 c8908e51 Christos Stavrakakis
        update_build_progress(client, msg)
673 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_nack.called)
674 9068cd85 Georgios Gousios
675 c8908e51 Christos Stavrakakis
    def test_progress_update(self, client):
676 c25cc9ec Vangelis Koukis
        rprogress = randint(10, 100)
677 c8908e51 Christos Stavrakakis
        msg = self.create_msg(progress=rprogress,
678 c8908e51 Christos Stavrakakis
                              instance=self.vm.backend_vm_id)
679 c8908e51 Christos Stavrakakis
        update_build_progress(client, msg)
680 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
681 c8908e51 Christos Stavrakakis
        vm = self.get_db_vm()
682 c8908e51 Christos Stavrakakis
        self.assertEqual(vm.buildpercentage, rprogress)
683 c8908e51 Christos Stavrakakis
684 c8908e51 Christos Stavrakakis
    def test_invalid_value(self, client):
685 c8908e51 Christos Stavrakakis
        old = self.vm.buildpercentage
686 c8908e51 Christos Stavrakakis
        for rprogress in [0, -1, 'a']:
687 c8908e51 Christos Stavrakakis
            msg = self.create_msg(progress=rprogress,
688 c8908e51 Christos Stavrakakis
                                  instance=self.vm.backend_vm_id)
689 c8908e51 Christos Stavrakakis
            update_build_progress(client, msg)
690 10d9cd27 Christos Stavrakakis
            self.assertTrue(client.basic_ack.called)
691 c8908e51 Christos Stavrakakis
            vm = self.get_db_vm()
692 c8908e51 Christos Stavrakakis
            self.assertEqual(vm.buildpercentage, old)