Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / logic / tests.py @ 34c03a51

History | View | Annotate | Download (34.8 kB)

1 b8033991 Georgios Gousios
# vim: set fileencoding=utf-8 :
2 47eeffa9 Christos Stavrakakis
# Copyright 2012 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 41a7fae7 Christos Stavrakakis
from snf_django.lib.api import faults
38 420f2c20 Georgios Gousios
from synnefo.db.models import *
39 47eeffa9 Christos Stavrakakis
from synnefo.db import models_factory as mfactory
40 41a7fae7 Christos Stavrakakis
from synnefo.logic import reconciliation, servers
41 47eeffa9 Christos Stavrakakis
from synnefo.lib.utils import split_time
42 47eeffa9 Christos Stavrakakis
from datetime import datetime
43 47eeffa9 Christos Stavrakakis
from mock import patch
44 47eeffa9 Christos Stavrakakis
from synnefo.api.util import allocate_resource
45 fd95834e Christos Stavrakakis
from synnefo.logic.callbacks import (update_db, update_network,
46 cc92b70f Christos Stavrakakis
                                     update_build_progress)
47 184a2a8c Christos Stavrakakis
from snf_django.utils.testing import mocked_quotaholder
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 41a7fae7 Christos Stavrakakis
@patch("synnefo.logic.rapi_pool.GanetiRapiClient")
55 41a7fae7 Christos Stavrakakis
class ServerCommandTest(TestCase):
56 41a7fae7 Christos Stavrakakis
    def test_pending_task(self, mrapi):
57 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(task="REBOOT", task_job_id=1)
58 41a7fae7 Christos Stavrakakis
        self.assertRaises(faults.BadRequest, servers.start, vm)
59 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(task="BUILD", task_job_id=1)
60 41a7fae7 Christos Stavrakakis
        self.assertRaises(faults.BuildInProgress, servers.start, vm)
61 41a7fae7 Christos Stavrakakis
        # Assert always succeeds
62 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(task="BUILD", task_job_id=1)
63 41a7fae7 Christos Stavrakakis
        mrapi().DeleteInstance.return_value = 1
64 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
65 41a7fae7 Christos Stavrakakis
            servers.destroy(vm)
66 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(task="REBOOT", task_job_id=1)
67 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
68 41a7fae7 Christos Stavrakakis
            servers.destroy(vm)
69 41a7fae7 Christos Stavrakakis
70 41a7fae7 Christos Stavrakakis
    def test_deleted_vm(self, mrapi):
71 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(deleted=True)
72 41a7fae7 Christos Stavrakakis
        self.assertRaises(faults.BadRequest, servers.start, vm)
73 41a7fae7 Christos Stavrakakis
74 41a7fae7 Christos Stavrakakis
    def test_invalid_operstate_for_action(self, mrapi):
75 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate="STARTED")
76 41a7fae7 Christos Stavrakakis
        self.assertRaises(faults.BadRequest, servers.start, vm)
77 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate="STOPPED")
78 41a7fae7 Christos Stavrakakis
        self.assertRaises(faults.BadRequest, servers.stop, vm)
79 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate="STARTED")
80 41a7fae7 Christos Stavrakakis
        self.assertRaises(faults.BadRequest, servers.resize, vm)
81 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate="STOPPED")
82 41a7fae7 Christos Stavrakakis
        self.assertRaises(faults.BadRequest, servers.stop, vm)
83 41a7fae7 Christos Stavrakakis
        #test valid
84 41a7fae7 Christos Stavrakakis
        mrapi().StartupInstance.return_value = 1
85 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
86 41a7fae7 Christos Stavrakakis
            servers.start(vm)
87 41a7fae7 Christos Stavrakakis
        vm.task = None
88 41a7fae7 Christos Stavrakakis
        vm.task_job_id = None
89 41a7fae7 Christos Stavrakakis
        vm.save()
90 41a7fae7 Christos Stavrakakis
        mrapi().RebootInstance.return_value = 1
91 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
92 41a7fae7 Christos Stavrakakis
            servers.reboot(vm, "HARD")
93 41a7fae7 Christos Stavrakakis
94 41a7fae7 Christos Stavrakakis
    def test_commission(self, mrapi):
95 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate="STOPPED")
96 41a7fae7 Christos Stavrakakis
        # Still pending
97 41a7fae7 Christos Stavrakakis
        vm.serial = mfactory.QuotaHolderSerialFactory(serial=200,
98 41a7fae7 Christos Stavrakakis
                                                      resolved=False,
99 41a7fae7 Christos Stavrakakis
                                                      pending=True)
100 41a7fae7 Christos Stavrakakis
        serial = vm.serial
101 41a7fae7 Christos Stavrakakis
        mrapi().StartupInstance.return_value = 1
102 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder() as m:
103 41a7fae7 Christos Stavrakakis
            servers.start(vm)
104 41a7fae7 Christos Stavrakakis
            m.resolve_commissions.assert_called_once_with('', [],
105 41a7fae7 Christos Stavrakakis
                                                          [serial.serial])
106 41a7fae7 Christos Stavrakakis
            self.assertTrue(m.issue_one_commission.called)
107 41a7fae7 Christos Stavrakakis
        # Not pending, rejct
108 41a7fae7 Christos Stavrakakis
        vm.task = None
109 41a7fae7 Christos Stavrakakis
        vm.serial = mfactory.QuotaHolderSerialFactory(serial=400,
110 41a7fae7 Christos Stavrakakis
                                                      resolved=False,
111 41a7fae7 Christos Stavrakakis
                                                      pending=False,
112 41a7fae7 Christos Stavrakakis
                                                      accept=False)
113 41a7fae7 Christos Stavrakakis
        serial = vm.serial
114 41a7fae7 Christos Stavrakakis
        mrapi().StartupInstance.return_value = 1
115 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder() as m:
116 41a7fae7 Christos Stavrakakis
            servers.start(vm)
117 41a7fae7 Christos Stavrakakis
            m.resolve_commissions.assert_called_once_with('', [],
118 41a7fae7 Christos Stavrakakis
                                                          [serial.serial])
119 41a7fae7 Christos Stavrakakis
            self.assertTrue(m.issue_one_commission.called)
120 41a7fae7 Christos Stavrakakis
        # Not pending, accept
121 41a7fae7 Christos Stavrakakis
        vm.task = None
122 41a7fae7 Christos Stavrakakis
        vm.serial = mfactory.QuotaHolderSerialFactory(serial=600,
123 41a7fae7 Christos Stavrakakis
                                                      resolved=False,
124 41a7fae7 Christos Stavrakakis
                                                      pending=False,
125 41a7fae7 Christos Stavrakakis
                                                      accept=True)
126 41a7fae7 Christos Stavrakakis
        serial = vm.serial
127 41a7fae7 Christos Stavrakakis
        mrapi().StartupInstance.return_value = 1
128 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder() as m:
129 41a7fae7 Christos Stavrakakis
            servers.start(vm)
130 41a7fae7 Christos Stavrakakis
            m.resolve_commissions.assert_called_once_with('', [serial.serial],
131 41a7fae7 Christos Stavrakakis
                                                          [])
132 41a7fae7 Christos Stavrakakis
            self.assertTrue(m.issue_one_commission.called)
133 41a7fae7 Christos Stavrakakis
134 41a7fae7 Christos Stavrakakis
        mrapi().StartupInstance.side_effect = ValueError
135 41a7fae7 Christos Stavrakakis
        vm.task = None
136 41a7fae7 Christos Stavrakakis
        vm.serial = None
137 41a7fae7 Christos Stavrakakis
        # Test reject if Ganeti erro
138 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder() as m:
139 41a7fae7 Christos Stavrakakis
            try:
140 41a7fae7 Christos Stavrakakis
                servers.start(vm)
141 41a7fae7 Christos Stavrakakis
            except:
142 41a7fae7 Christos Stavrakakis
                m.resolve_commissions.assert_called_once_with('', [],
143 41a7fae7 Christos Stavrakakis
                                                            [vm.serial.serial])
144 41a7fae7 Christos Stavrakakis
145 41a7fae7 Christos Stavrakakis
    def test_task_after(self, mrapi):
146 41a7fae7 Christos Stavrakakis
        return
147 41a7fae7 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
148 41a7fae7 Christos Stavrakakis
        mrapi().StartupInstance.return_value = 1
149 41a7fae7 Christos Stavrakakis
        mrapi().ShutdownInstance.return_value = 2
150 41a7fae7 Christos Stavrakakis
        mrapi().RebootInstance.return_value = 2
151 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder() as m:
152 41a7fae7 Christos Stavrakakis
            vm.task = None
153 41a7fae7 Christos Stavrakakis
            vm.operstate = "STOPPED"
154 41a7fae7 Christos Stavrakakis
            servers.start(vm)
155 41a7fae7 Christos Stavrakakis
            self.assertEqual(vm.task, "START")
156 41a7fae7 Christos Stavrakakis
            self.assertEqual(vm.task_job_id, 1)
157 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder() as m:
158 41a7fae7 Christos Stavrakakis
            vm.task = None
159 41a7fae7 Christos Stavrakakis
            vm.operstate = "STARTED"
160 41a7fae7 Christos Stavrakakis
            servers.stop(vm)
161 41a7fae7 Christos Stavrakakis
            self.assertEqual(vm.task, "STOP")
162 41a7fae7 Christos Stavrakakis
            self.assertEqual(vm.task_job_id, 2)
163 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder() as m:
164 41a7fae7 Christos Stavrakakis
            vm.task = None
165 41a7fae7 Christos Stavrakakis
            servers.reboot(vm)
166 41a7fae7 Christos Stavrakakis
            self.assertEqual(vm.task, "REBOOT")
167 41a7fae7 Christos Stavrakakis
            self.assertEqual(vm.task_job_id, 3)
168 41a7fae7 Christos Stavrakakis
169 41a7fae7 Christos Stavrakakis
170 41a7fae7 Christos Stavrakakis
171 47eeffa9 Christos Stavrakakis
## Test Callbacks
172 47eeffa9 Christos Stavrakakis
173 47eeffa9 Christos Stavrakakis
174 47eeffa9 Christos Stavrakakis
@patch('synnefo.lib.amqp.AMQPClient')
175 47eeffa9 Christos Stavrakakis
class UpdateDBTest(TestCase):
176 47eeffa9 Christos Stavrakakis
    def create_msg(self, **kwargs):
177 47eeffa9 Christos Stavrakakis
        """Create snf-ganeti-eventd message"""
178 47eeffa9 Christos Stavrakakis
        msg = {'event_time': split_time(time())}
179 47eeffa9 Christos Stavrakakis
        msg['type'] = 'ganeti-op-status'
180 47eeffa9 Christos Stavrakakis
        msg['status'] = 'success'
181 47eeffa9 Christos Stavrakakis
        msg['jobId'] = 1
182 47eeffa9 Christos Stavrakakis
        msg['logmsg'] = 'Dummy Log'
183 47eeffa9 Christos Stavrakakis
        for key, val in kwargs.items():
184 47eeffa9 Christos Stavrakakis
            msg[key] = val
185 47eeffa9 Christos Stavrakakis
        message = {'body': json.dumps(msg)}
186 47eeffa9 Christos Stavrakakis
        return message
187 47eeffa9 Christos Stavrakakis
188 47eeffa9 Christos Stavrakakis
    def test_missing_attribute(self, client):
189 47eeffa9 Christos Stavrakakis
        update_db(client, json.dumps({'body': {}}))
190 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
191 47eeffa9 Christos Stavrakakis
192 47eeffa9 Christos Stavrakakis
    def test_unhandled_exception(self, client):
193 47eeffa9 Christos Stavrakakis
        update_db(client, {})
194 47eeffa9 Christos Stavrakakis
        client.basic_reject.assert_called_once()
195 47eeffa9 Christos Stavrakakis
196 47eeffa9 Christos Stavrakakis
    def test_missing_instance(self, client):
197 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
198 47eeffa9 Christos Stavrakakis
                              instance='foo')
199 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
200 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
201 47eeffa9 Christos Stavrakakis
202 47eeffa9 Christos Stavrakakis
    def test_wrong_type(self, client):
203 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(type="WRONG_TYPE")
204 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
205 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_nack.called)
206 47eeffa9 Christos Stavrakakis
207 b66e4833 Christos Stavrakakis
    def test_old_msg(self, client):
208 b66e4833 Christos Stavrakakis
        from time import sleep
209 b66e4833 Christos Stavrakakis
        from datetime import datetime
210 b66e4833 Christos Stavrakakis
        old_time = time()
211 b66e4833 Christos Stavrakakis
        sleep(0.01)
212 b66e4833 Christos Stavrakakis
        new_time = datetime.fromtimestamp(time())
213 b66e4833 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(backendtime=new_time)
214 b66e4833 Christos Stavrakakis
        vm.operstate = 'STOPPED'
215 b66e4833 Christos Stavrakakis
        vm.save()
216 b66e4833 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
217 b66e4833 Christos Stavrakakis
                              event_time=split_time(old_time),
218 b66e4833 Christos Stavrakakis
                              instance=vm.backend_vm_id)
219 b66e4833 Christos Stavrakakis
        update_db(client, msg)
220 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
221 b66e4833 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
222 b66e4833 Christos Stavrakakis
        self.assertEquals(db_vm.operstate, "STOPPED")
223 b66e4833 Christos Stavrakakis
        self.assertEquals(db_vm.backendtime, new_time)
224 b66e4833 Christos Stavrakakis
225 47eeffa9 Christos Stavrakakis
    def test_start(self, client):
226 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
227 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
228 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
229 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
230 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
231 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
232 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
233 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'STARTED')
234 47eeffa9 Christos Stavrakakis
235 47eeffa9 Christos Stavrakakis
    def test_stop(self, client):
236 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
237 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_SHUTDOWN',
238 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
239 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
240 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
241 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
242 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
243 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'STOPPED')
244 47eeffa9 Christos Stavrakakis
245 47eeffa9 Christos Stavrakakis
    def test_reboot(self, client):
246 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
247 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_REBOOT',
248 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
249 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
250 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
251 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
252 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'STARTED')
253 47eeffa9 Christos Stavrakakis
254 47eeffa9 Christos Stavrakakis
    def test_remove(self, client):
255 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
256 47eeffa9 Christos Stavrakakis
        # Also create a NIC
257 47eeffa9 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm)
258 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_REMOVE',
259 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
260 184a2a8c Christos Stavrakakis
        with mocked_quotaholder():
261 184a2a8c Christos Stavrakakis
            update_db(client, msg)
262 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
263 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
264 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'DESTROYED')
265 47eeffa9 Christos Stavrakakis
        self.assertTrue(db_vm.deleted)
266 47eeffa9 Christos Stavrakakis
        # Check that nics are deleted
267 47eeffa9 Christos Stavrakakis
        self.assertFalse(db_vm.nics.all())
268 47eeffa9 Christos Stavrakakis
269 47eeffa9 Christos Stavrakakis
    def test_create(self, client):
270 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
271 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_CREATE',
272 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
273 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
274 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
275 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
276 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'STARTED')
277 47eeffa9 Christos Stavrakakis
278 47eeffa9 Christos Stavrakakis
    def test_create_error(self, client):
279 47eeffa9 Christos Stavrakakis
        """Test that error create sets vm to ERROR state"""
280 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
281 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_CREATE',
282 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id,
283 47eeffa9 Christos Stavrakakis
                              status='error')
284 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
285 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
286 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
287 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'ERROR')
288 47eeffa9 Christos Stavrakakis
289 47eeffa9 Christos Stavrakakis
    def test_remove_from_error(self, client):
290 47eeffa9 Christos Stavrakakis
        """Test that error removes delete error builds"""
291 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate='ERROR')
292 47eeffa9 Christos Stavrakakis
        # Also create a NIC
293 47eeffa9 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm)
294 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_REMOVE',
295 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
296 184a2a8c Christos Stavrakakis
        with mocked_quotaholder():
297 184a2a8c Christos Stavrakakis
            update_db(client, msg)
298 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
299 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
300 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, 'DESTROYED')
301 47eeffa9 Christos Stavrakakis
        self.assertTrue(db_vm.deleted)
302 47eeffa9 Christos Stavrakakis
        # Check that nics are deleted
303 47eeffa9 Christos Stavrakakis
        self.assertFalse(db_vm.nics.all())
304 47eeffa9 Christos Stavrakakis
305 47eeffa9 Christos Stavrakakis
    def test_other_error(self, client):
306 47eeffa9 Christos Stavrakakis
        """Test that other error messages do no affect the VM"""
307 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
308 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
309 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id,
310 47eeffa9 Christos Stavrakakis
                              status='error')
311 47eeffa9 Christos Stavrakakis
        update_db(client, msg)
312 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
313 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
314 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, vm.operstate)
315 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_vm.backendtime, vm.backendtime)
316 47eeffa9 Christos Stavrakakis
317 ca4d59e3 Christos Stavrakakis
    def test_resize_msg(self, client):
318 ca4d59e3 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
319 ca4d59e3 Christos Stavrakakis
        # Test empty beparams
320 ca4d59e3 Christos Stavrakakis
        for status in ["success", "error"]:
321 ca4d59e3 Christos Stavrakakis
            msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
322 ca4d59e3 Christos Stavrakakis
                                  instance=vm.backend_vm_id,
323 ca4d59e3 Christos Stavrakakis
                                  beparams={},
324 ca4d59e3 Christos Stavrakakis
                                  status=status)
325 ca4d59e3 Christos Stavrakakis
            client.reset_mock()
326 41a7fae7 Christos Stavrakakis
            with mocked_quotaholder():
327 41a7fae7 Christos Stavrakakis
                update_db(client, msg)
328 ca4d59e3 Christos Stavrakakis
            self.assertTrue(client.basic_ack.called)
329 ca4d59e3 Christos Stavrakakis
            db_vm = VirtualMachine.objects.get(id=vm.id)
330 ca4d59e3 Christos Stavrakakis
            self.assertEqual(db_vm.operstate, vm.operstate)
331 ca4d59e3 Christos Stavrakakis
        # Test intermediate states
332 ca4d59e3 Christos Stavrakakis
        for status in ["queued", "waiting", "running"]:
333 ca4d59e3 Christos Stavrakakis
            msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
334 ca4d59e3 Christos Stavrakakis
                                  instance=vm.backend_vm_id,
335 ca4d59e3 Christos Stavrakakis
                                  beparams={"vcpus": 4, "minmem": 2048,
336 ca4d59e3 Christos Stavrakakis
                                            "maxmem": 2048},
337 ca4d59e3 Christos Stavrakakis
                                  status=status)
338 ca4d59e3 Christos Stavrakakis
            client.reset_mock()
339 ca4d59e3 Christos Stavrakakis
            update_db(client, msg)
340 ca4d59e3 Christos Stavrakakis
            self.assertTrue(client.basic_ack.called)
341 ca4d59e3 Christos Stavrakakis
            db_vm = VirtualMachine.objects.get(id=vm.id)
342 41a7fae7 Christos Stavrakakis
            self.assertEqual(db_vm.operstate, "STOPPED")
343 ca4d59e3 Christos Stavrakakis
        # Test operstate after error
344 ca4d59e3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
345 ca4d59e3 Christos Stavrakakis
                              instance=vm.backend_vm_id,
346 ca4d59e3 Christos Stavrakakis
                              beparams={"vcpus": 4},
347 ca4d59e3 Christos Stavrakakis
                              status="error")
348 ca4d59e3 Christos Stavrakakis
        client.reset_mock()
349 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
350 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
351 ca4d59e3 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
352 ca4d59e3 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
353 ca4d59e3 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, "STOPPED")
354 ca4d59e3 Christos Stavrakakis
        # Test success
355 ca4d59e3 Christos Stavrakakis
        f1 = mfactory.FlavorFactory(cpu=4, ram=1024, disk_template="drbd",
356 ca4d59e3 Christos Stavrakakis
                                    disk=1024)
357 ca4d59e3 Christos Stavrakakis
        vm.flavor = f1
358 ca4d59e3 Christos Stavrakakis
        vm.save()
359 ca4d59e3 Christos Stavrakakis
        f2 = mfactory.FlavorFactory(cpu=8, ram=2048, disk_template="drbd",
360 ca4d59e3 Christos Stavrakakis
                                    disk=1024)
361 ca4d59e3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
362 ca4d59e3 Christos Stavrakakis
                              instance=vm.backend_vm_id,
363 ca4d59e3 Christos Stavrakakis
                              beparams={"vcpus": 8, "minmem": 2048,
364 ca4d59e3 Christos Stavrakakis
                                        "maxmem": 2048},
365 ca4d59e3 Christos Stavrakakis
                              status="success")
366 ca4d59e3 Christos Stavrakakis
        client.reset_mock()
367 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
368 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
369 ca4d59e3 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
370 ca4d59e3 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
371 ca4d59e3 Christos Stavrakakis
        self.assertEqual(db_vm.operstate, "STOPPED")
372 ca4d59e3 Christos Stavrakakis
        self.assertEqual(db_vm.flavor, f2)
373 ca4d59e3 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_SET_PARAMS',
374 ca4d59e3 Christos Stavrakakis
                              instance=vm.backend_vm_id,
375 ca4d59e3 Christos Stavrakakis
                              beparams={"vcpus": 100, "minmem": 2048,
376 ca4d59e3 Christos Stavrakakis
                                        "maxmem": 2048},
377 ca4d59e3 Christos Stavrakakis
                              status="success")
378 ca4d59e3 Christos Stavrakakis
        client.reset_mock()
379 41a7fae7 Christos Stavrakakis
        with mocked_quotaholder():
380 41a7fae7 Christos Stavrakakis
            update_db(client, msg)
381 ca4d59e3 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
382 ca4d59e3 Christos Stavrakakis
383 47eeffa9 Christos Stavrakakis
384 47eeffa9 Christos Stavrakakis
@patch('synnefo.lib.amqp.AMQPClient')
385 47eeffa9 Christos Stavrakakis
class UpdateNetTest(TestCase):
386 47eeffa9 Christos Stavrakakis
    def create_msg(self, **kwargs):
387 47eeffa9 Christos Stavrakakis
        """Create snf-ganeti-hook message"""
388 47eeffa9 Christos Stavrakakis
        msg = {'event_time': split_time(time())}
389 fd95834e Christos Stavrakakis
        msg['type'] = 'ganeti-op-status'
390 fd95834e Christos Stavrakakis
        msg['operation'] = 'OP_INSTANCE_SET_PARAMS'
391 47eeffa9 Christos Stavrakakis
        msg['status'] = 'success'
392 47eeffa9 Christos Stavrakakis
        msg['jobId'] = 1
393 47eeffa9 Christos Stavrakakis
        msg['logmsg'] = 'Dummy Log'
394 47eeffa9 Christos Stavrakakis
        for key, val in kwargs.items():
395 47eeffa9 Christos Stavrakakis
            msg[key] = val
396 47eeffa9 Christos Stavrakakis
        message = {'body': json.dumps(msg)}
397 47eeffa9 Christos Stavrakakis
        return message
398 47eeffa9 Christos Stavrakakis
399 47eeffa9 Christos Stavrakakis
    def test_missing_attribute(self, client):
400 fd95834e Christos Stavrakakis
        update_db(client, json.dumps({'body': {}}))
401 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
402 47eeffa9 Christos Stavrakakis
403 47eeffa9 Christos Stavrakakis
    def test_unhandled_exception(self, client):
404 fd95834e Christos Stavrakakis
        update_db(client, {})
405 47eeffa9 Christos Stavrakakis
        client.basic_reject.assert_called_once()
406 47eeffa9 Christos Stavrakakis
407 47eeffa9 Christos Stavrakakis
    def test_wrong_type(self, client):
408 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(type="WRONG_TYPE")
409 fd95834e Christos Stavrakakis
        update_db(client, msg)
410 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_nack.called)
411 47eeffa9 Christos Stavrakakis
412 47eeffa9 Christos Stavrakakis
    def test_missing_instance(self, client):
413 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_INSTANCE_STARTUP',
414 47eeffa9 Christos Stavrakakis
                              instance='foo')
415 fd95834e Christos Stavrakakis
        update_db(client, msg)
416 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
417 47eeffa9 Christos Stavrakakis
418 47eeffa9 Christos Stavrakakis
    def test_no_nics(self, client):
419 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate='ERROR')
420 47eeffa9 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm)
421 47eeffa9 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm)
422 47eeffa9 Christos Stavrakakis
        mfactory.NetworkInterfaceFactory(machine=vm)
423 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(vm.nics.all()), 3)
424 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(nics=[],
425 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
426 fd95834e Christos Stavrakakis
        update_db(client, msg)
427 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
428 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
429 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(db_vm.nics.all()), 0)
430 47eeffa9 Christos Stavrakakis
431 47eeffa9 Christos Stavrakakis
    def test_empty_nic(self, client):
432 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate='ERROR')
433 47eeffa9 Christos Stavrakakis
        for public in [True, False]:
434 47eeffa9 Christos Stavrakakis
            net = mfactory.NetworkFactory(public=public)
435 cc92b70f Christos Stavrakakis
            msg = self.create_msg(nics=[{'network': net.backend_id}],
436 47eeffa9 Christos Stavrakakis
                                  instance=vm.backend_vm_id)
437 fd95834e Christos Stavrakakis
            update_db(client, msg)
438 10d9cd27 Christos Stavrakakis
            self.assertTrue(client.basic_ack.called)
439 47eeffa9 Christos Stavrakakis
            db_vm = VirtualMachine.objects.get(id=vm.id)
440 47eeffa9 Christos Stavrakakis
            nics = db_vm.nics.all()
441 47eeffa9 Christos Stavrakakis
            self.assertEqual(len(nics), 1)
442 47eeffa9 Christos Stavrakakis
            self.assertEqual(nics[0].index, 0)
443 47eeffa9 Christos Stavrakakis
            self.assertEqual(nics[0].ipv4, '')
444 47eeffa9 Christos Stavrakakis
            self.assertEqual(nics[0].ipv6, '')
445 47eeffa9 Christos Stavrakakis
            self.assertEqual(nics[0].mac, '')
446 47eeffa9 Christos Stavrakakis
            if public:
447 47eeffa9 Christos Stavrakakis
                self.assertEqual(nics[0].firewall_profile,
448 47eeffa9 Christos Stavrakakis
                                 settings.DEFAULT_FIREWALL_PROFILE)
449 47eeffa9 Christos Stavrakakis
            else:
450 47eeffa9 Christos Stavrakakis
                self.assertEqual(nics[0].firewall_profile, '')
451 47eeffa9 Christos Stavrakakis
452 47eeffa9 Christos Stavrakakis
    def test_full_nic(self, client):
453 47eeffa9 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(operstate='ERROR')
454 47eeffa9 Christos Stavrakakis
        net = mfactory.NetworkFactory(subnet='10.0.0.0/24')
455 47eeffa9 Christos Stavrakakis
        pool = net.get_pool()
456 47eeffa9 Christos Stavrakakis
        self.assertTrue(pool.is_available('10.0.0.22'))
457 47eeffa9 Christos Stavrakakis
        pool.save()
458 cc92b70f Christos Stavrakakis
        msg = self.create_msg(nics=[{'network': net.backend_id,
459 47eeffa9 Christos Stavrakakis
                                     'ip': '10.0.0.22',
460 47eeffa9 Christos Stavrakakis
                                     'mac': 'aa:bb:cc:00:11:22'}],
461 47eeffa9 Christos Stavrakakis
                              instance=vm.backend_vm_id)
462 fd95834e Christos Stavrakakis
        update_db(client, msg)
463 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
464 47eeffa9 Christos Stavrakakis
        db_vm = VirtualMachine.objects.get(id=vm.id)
465 47eeffa9 Christos Stavrakakis
        nics = db_vm.nics.all()
466 47eeffa9 Christos Stavrakakis
        self.assertEqual(len(nics), 1)
467 47eeffa9 Christos Stavrakakis
        self.assertEqual(nics[0].index, 0)
468 47eeffa9 Christos Stavrakakis
        self.assertEqual(nics[0].ipv4, '10.0.0.22')
469 47eeffa9 Christos Stavrakakis
        self.assertEqual(nics[0].ipv6, '')
470 47eeffa9 Christos Stavrakakis
        self.assertEqual(nics[0].mac, 'aa:bb:cc:00:11:22')
471 47eeffa9 Christos Stavrakakis
        pool = net.get_pool()
472 47eeffa9 Christos Stavrakakis
        self.assertFalse(pool.is_available('10.0.0.22'))
473 47eeffa9 Christos Stavrakakis
        pool.save()
474 47eeffa9 Christos Stavrakakis
475 47eeffa9 Christos Stavrakakis
476 47eeffa9 Christos Stavrakakis
@patch('synnefo.lib.amqp.AMQPClient')
477 47eeffa9 Christos Stavrakakis
class UpdateNetworkTest(TestCase):
478 47eeffa9 Christos Stavrakakis
    def create_msg(self, **kwargs):
479 47eeffa9 Christos Stavrakakis
        """Create snf-ganeti-eventd message"""
480 47eeffa9 Christos Stavrakakis
        msg = {'event_time': split_time(time())}
481 47eeffa9 Christos Stavrakakis
        msg['type'] = 'ganeti-network-status'
482 47eeffa9 Christos Stavrakakis
        msg['status'] = 'success'
483 47eeffa9 Christos Stavrakakis
        msg['jobId'] = 1
484 47eeffa9 Christos Stavrakakis
        msg['logmsg'] = 'Dummy Log'
485 47eeffa9 Christos Stavrakakis
        for key, val in kwargs.items():
486 47eeffa9 Christos Stavrakakis
            msg[key] = val
487 47eeffa9 Christos Stavrakakis
        message = {'body': json.dumps(msg)}
488 47eeffa9 Christos Stavrakakis
        return message
489 47eeffa9 Christos Stavrakakis
490 47eeffa9 Christos Stavrakakis
    def test_missing_attribute(self, client):
491 47eeffa9 Christos Stavrakakis
        update_network(client, json.dumps({'body': {}}))
492 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
493 47eeffa9 Christos Stavrakakis
494 47eeffa9 Christos Stavrakakis
    def test_unhandled_exception(self, client):
495 47eeffa9 Christos Stavrakakis
        update_network(client, {})
496 47eeffa9 Christos Stavrakakis
        client.basic_reject.assert_called_once()
497 47eeffa9 Christos Stavrakakis
498 47eeffa9 Christos Stavrakakis
    def test_wrong_type(self, client):
499 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(type="WRONG_TYPE")
500 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
501 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_nack.called)
502 47eeffa9 Christos Stavrakakis
503 47eeffa9 Christos Stavrakakis
    def test_missing_network(self, client):
504 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_CREATE',
505 47eeffa9 Christos Stavrakakis
                              network='foo')
506 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
507 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
508 47eeffa9 Christos Stavrakakis
509 47eeffa9 Christos Stavrakakis
    def test_create(self, client):
510 47eeffa9 Christos Stavrakakis
        back_network = mfactory.BackendNetworkFactory(operstate='PENDING')
511 47eeffa9 Christos Stavrakakis
        net = back_network.network
512 1d04ef8b Christos Stavrakakis
        net.state = 'ACTIVE'
513 1d04ef8b Christos Stavrakakis
        net.save()
514 47eeffa9 Christos Stavrakakis
        back1 = back_network.backend
515 47eeffa9 Christos Stavrakakis
516 47eeffa9 Christos Stavrakakis
        back_network2 = mfactory.BackendNetworkFactory(operstate='PENDING',
517 47eeffa9 Christos Stavrakakis
                                                       network=net)
518 47eeffa9 Christos Stavrakakis
        back2 = back_network2.backend
519 47eeffa9 Christos Stavrakakis
        # Message from first backend network
520 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_CONNECT',
521 47eeffa9 Christos Stavrakakis
                              network=net.backend_id,
522 47eeffa9 Christos Stavrakakis
                              cluster=back1.clustername)
523 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
524 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
525 47eeffa9 Christos Stavrakakis
526 47eeffa9 Christos Stavrakakis
        back_net = BackendNetwork.objects.get(id=back_network.id)
527 47eeffa9 Christos Stavrakakis
        self.assertEqual(back_net.operstate, 'ACTIVE')
528 47eeffa9 Christos Stavrakakis
        db_net = Network.objects.get(id=net.id)
529 1d04ef8b Christos Stavrakakis
        self.assertEqual(db_net.state, 'ACTIVE')
530 47eeffa9 Christos Stavrakakis
        # msg from second backend network
531 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_CONNECT',
532 47eeffa9 Christos Stavrakakis
                              network=net.backend_id,
533 47eeffa9 Christos Stavrakakis
                              cluster=back2.clustername)
534 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
535 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
536 47eeffa9 Christos Stavrakakis
537 47eeffa9 Christos Stavrakakis
        db_net = Network.objects.get(id=net.id)
538 47eeffa9 Christos Stavrakakis
        self.assertEqual(db_net.state, 'ACTIVE')
539 47eeffa9 Christos Stavrakakis
        back_net = BackendNetwork.objects.get(id=back_network.id)
540 47eeffa9 Christos Stavrakakis
        self.assertEqual(back_net.operstate, 'ACTIVE')
541 47eeffa9 Christos Stavrakakis
542 039e3e61 Christos Stavrakakis
    def test_create_offline_backend(self, client):
543 039e3e61 Christos Stavrakakis
        """Test network creation when a backend is offline"""
544 1d04ef8b Christos Stavrakakis
        net = mfactory.NetworkFactory(state='ACTIVE')
545 039e3e61 Christos Stavrakakis
        bn1 = mfactory.BackendNetworkFactory(network=net)
546 039e3e61 Christos Stavrakakis
        bn2 = mfactory.BackendNetworkFactory(network=net,
547 039e3e61 Christos Stavrakakis
                                             backend__offline=True)
548 039e3e61 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_CONNECT',
549 039e3e61 Christos Stavrakakis
                              network=net.backend_id,
550 039e3e61 Christos Stavrakakis
                              cluster=bn1.backend.clustername)
551 039e3e61 Christos Stavrakakis
        update_network(client, msg)
552 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
553 039e3e61 Christos Stavrakakis
        new_net = Network.objects.get(id=net.id)
554 039e3e61 Christos Stavrakakis
        self.assertEqual(new_net.state, 'ACTIVE')
555 039e3e61 Christos Stavrakakis
556 47eeffa9 Christos Stavrakakis
    def test_disconnect(self, client):
557 47eeffa9 Christos Stavrakakis
        bn1 = mfactory.BackendNetworkFactory(operstate='ACTIVE')
558 47eeffa9 Christos Stavrakakis
        net1 = bn1.network
559 1d04ef8b Christos Stavrakakis
        net1.state = "ACTIVE"
560 1d04ef8b Christos Stavrakakis
        net1.state = 'ACTIVE'
561 47eeffa9 Christos Stavrakakis
        net1.save()
562 47eeffa9 Christos Stavrakakis
        bn2 = mfactory.BackendNetworkFactory(operstate='ACTIVE',
563 47eeffa9 Christos Stavrakakis
                                             network=net1)
564 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_DISCONNECT',
565 47eeffa9 Christos Stavrakakis
                              network=net1.backend_id,
566 47eeffa9 Christos Stavrakakis
                              cluster=bn2.backend.clustername)
567 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
568 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
569 1d04ef8b Christos Stavrakakis
        self.assertEqual(Network.objects.get(id=net1.id).state, 'ACTIVE')
570 47eeffa9 Christos Stavrakakis
        self.assertEqual(BackendNetwork.objects.get(id=bn2.id).operstate,
571 cc92b70f Christos Stavrakakis
                         'PENDING')
572 47eeffa9 Christos Stavrakakis
573 47eeffa9 Christos Stavrakakis
    def test_remove(self, client):
574 47eeffa9 Christos Stavrakakis
        mfactory.MacPrefixPoolTableFactory()
575 47eeffa9 Christos Stavrakakis
        mfactory.BridgePoolTableFactory()
576 47eeffa9 Christos Stavrakakis
        bn = mfactory.BackendNetworkFactory(operstate='ACTIVE')
577 47eeffa9 Christos Stavrakakis
        for old_state in ['success', 'canceled', 'error']:
578 47eeffa9 Christos Stavrakakis
            for flavor in Network.FLAVORS.keys():
579 47eeffa9 Christos Stavrakakis
                bn.operstate = old_state
580 47eeffa9 Christos Stavrakakis
                bn.save()
581 47eeffa9 Christos Stavrakakis
                net = bn.network
582 47eeffa9 Christos Stavrakakis
                net.state = 'ACTIVE'
583 47eeffa9 Christos Stavrakakis
                net.flavor = flavor
584 47eeffa9 Christos Stavrakakis
                if flavor == 'PHYSICAL_VLAN':
585 47eeffa9 Christos Stavrakakis
                    net.link = allocate_resource('bridge')
586 47eeffa9 Christos Stavrakakis
                if flavor == 'MAC_FILTERED':
587 47eeffa9 Christos Stavrakakis
                    net.mac_prefix = allocate_resource('mac_prefix')
588 47eeffa9 Christos Stavrakakis
                net.save()
589 47eeffa9 Christos Stavrakakis
                msg = self.create_msg(operation='OP_NETWORK_REMOVE',
590 47eeffa9 Christos Stavrakakis
                                      network=net.backend_id,
591 47eeffa9 Christos Stavrakakis
                                      cluster=bn.backend.clustername)
592 184a2a8c Christos Stavrakakis
                with mocked_quotaholder():
593 184a2a8c Christos Stavrakakis
                    update_network(client, msg)
594 10d9cd27 Christos Stavrakakis
                self.assertTrue(client.basic_ack.called)
595 47eeffa9 Christos Stavrakakis
                db_bnet = BackendNetwork.objects.get(id=bn.id)
596 47eeffa9 Christos Stavrakakis
                self.assertEqual(db_bnet.operstate,
597 cc92b70f Christos Stavrakakis
                                 'DELETED')
598 47eeffa9 Christos Stavrakakis
                db_net = Network.objects.get(id=net.id)
599 47eeffa9 Christos Stavrakakis
                self.assertEqual(db_net.state, 'DELETED', flavor)
600 47eeffa9 Christos Stavrakakis
                self.assertTrue(db_net.deleted)
601 47eeffa9 Christos Stavrakakis
                if flavor == 'PHYSICAL_VLAN':
602 47eeffa9 Christos Stavrakakis
                    pool = BridgePoolTable.get_pool()
603 47eeffa9 Christos Stavrakakis
                    self.assertTrue(pool.is_available(net.link))
604 47eeffa9 Christos Stavrakakis
                if flavor == 'MAC_FILTERED':
605 47eeffa9 Christos Stavrakakis
                    pool = MacPrefixPoolTable.get_pool()
606 47eeffa9 Christos Stavrakakis
                    self.assertTrue(pool.is_available(net.mac_prefix))
607 47eeffa9 Christos Stavrakakis
608 039e3e61 Christos Stavrakakis
    def test_remove_offline_backend(self, client):
609 039e3e61 Christos Stavrakakis
        """Test network removing when a backend is offline"""
610 3f77e63d Christos Stavrakakis
        mfactory.BridgePoolTableFactory()
611 3f77e63d Christos Stavrakakis
        net = mfactory.NetworkFactory(flavor='PHYSICAL_VLAN',
612 3f77e63d Christos Stavrakakis
                                      state='ACTIVE',
613 3f77e63d Christos Stavrakakis
                                      link='prv12')
614 039e3e61 Christos Stavrakakis
        bn1 = mfactory.BackendNetworkFactory(network=net)
615 039e3e61 Christos Stavrakakis
        mfactory.BackendNetworkFactory(network=net,
616 c6c889f7 Christos Stavrakakis
                                       operstate="ACTIVE",
617 3f77e63d Christos Stavrakakis
                                       backend__offline=True)
618 039e3e61 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_REMOVE',
619 039e3e61 Christos Stavrakakis
                              network=net.backend_id,
620 039e3e61 Christos Stavrakakis
                              cluster=bn1.backend.clustername)
621 184a2a8c Christos Stavrakakis
        with mocked_quotaholder():
622 184a2a8c Christos Stavrakakis
            update_network(client, msg)
623 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
624 039e3e61 Christos Stavrakakis
        new_net = Network.objects.get(id=net.id)
625 1d04ef8b Christos Stavrakakis
        self.assertEqual(new_net.state, 'ACTIVE')
626 1d04ef8b Christos Stavrakakis
        self.assertFalse(new_net.deleted)
627 039e3e61 Christos Stavrakakis
628 47eeffa9 Christos Stavrakakis
    def test_error_opcode(self, client):
629 c6c889f7 Christos Stavrakakis
        mfactory.MacPrefixPoolTableFactory()
630 c6c889f7 Christos Stavrakakis
        mfactory.BridgePoolTableFactory()
631 47eeffa9 Christos Stavrakakis
        for state, _ in Network.OPER_STATES:
632 c6c889f7 Christos Stavrakakis
            bn = mfactory.BackendNetworkFactory(operstate="ACTIVE")
633 47eeffa9 Christos Stavrakakis
            bn.operstate = state
634 47eeffa9 Christos Stavrakakis
            bn.save()
635 47eeffa9 Christos Stavrakakis
            network = bn.network
636 47eeffa9 Christos Stavrakakis
            network.state = state
637 47eeffa9 Christos Stavrakakis
            network.save()
638 47eeffa9 Christos Stavrakakis
            for opcode, _ in BackendNetwork.BACKEND_OPCODES:
639 47eeffa9 Christos Stavrakakis
                if opcode in ['OP_NETWORK_REMOVE', 'OP_NETWORK_ADD']:
640 47eeffa9 Christos Stavrakakis
                    continue
641 47eeffa9 Christos Stavrakakis
                msg = self.create_msg(operation=opcode,
642 47eeffa9 Christos Stavrakakis
                                      network=bn.network.backend_id,
643 47eeffa9 Christos Stavrakakis
                                      status='error',
644 c6c889f7 Christos Stavrakakis
                                      add_reserved_ips=[],
645 c6c889f7 Christos Stavrakakis
                                      remove_reserved_ips=[],
646 47eeffa9 Christos Stavrakakis
                                      cluster=bn.backend.clustername)
647 c6c889f7 Christos Stavrakakis
                with mocked_quotaholder():
648 c6c889f7 Christos Stavrakakis
                    update_network(client, msg)
649 10d9cd27 Christos Stavrakakis
                self.assertTrue(client.basic_ack.called)
650 47eeffa9 Christos Stavrakakis
                db_bnet = BackendNetwork.objects.get(id=bn.id)
651 47eeffa9 Christos Stavrakakis
                self.assertEqual(bn.operstate, db_bnet.operstate)
652 47eeffa9 Christos Stavrakakis
                self.assertEqual(bn.network.state, db_bnet.network.state)
653 47eeffa9 Christos Stavrakakis
654 47eeffa9 Christos Stavrakakis
    def test_ips(self, client):
655 47eeffa9 Christos Stavrakakis
        network = mfactory.NetworkFactory(subnet='10.0.0.0/24')
656 47eeffa9 Christos Stavrakakis
        bn = mfactory.BackendNetworkFactory(network=network)
657 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_SET_PARAMS',
658 47eeffa9 Christos Stavrakakis
                              network=network.backend_id,
659 47eeffa9 Christos Stavrakakis
                              cluster=bn.backend.clustername,
660 47eeffa9 Christos Stavrakakis
                              status='success',
661 47eeffa9 Christos Stavrakakis
                              add_reserved_ips=['10.0.0.10', '10.0.0.20'],
662 47eeffa9 Christos Stavrakakis
                              remove_reserved_ips=[])
663 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
664 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
665 47eeffa9 Christos Stavrakakis
        pool = network.get_pool()
666 47eeffa9 Christos Stavrakakis
        self.assertTrue(pool.is_reserved('10.0.0.10'))
667 47eeffa9 Christos Stavrakakis
        self.assertTrue(pool.is_reserved('10.0.0.20'))
668 47eeffa9 Christos Stavrakakis
        pool.save()
669 47eeffa9 Christos Stavrakakis
        # Release them
670 47eeffa9 Christos Stavrakakis
        msg = self.create_msg(operation='OP_NETWORK_SET_PARAMS',
671 47eeffa9 Christos Stavrakakis
                              network=network.backend_id,
672 47eeffa9 Christos Stavrakakis
                              cluster=bn.backend.clustername,
673 47eeffa9 Christos Stavrakakis
                              add_reserved_ips=[],
674 47eeffa9 Christos Stavrakakis
                              remove_reserved_ips=['10.0.0.10', '10.0.0.20'])
675 47eeffa9 Christos Stavrakakis
        update_network(client, msg)
676 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
677 47eeffa9 Christos Stavrakakis
        pool = network.get_pool()
678 47eeffa9 Christos Stavrakakis
        self.assertFalse(pool.is_reserved('10.0.0.10'))
679 47eeffa9 Christos Stavrakakis
        self.assertFalse(pool.is_reserved('10.0.0.20'))
680 95aee02c Vangelis Koukis
681 92c53da1 Vassilios Karakoidas
682 c8908e51 Christos Stavrakakis
@patch('synnefo.lib.amqp.AMQPClient')
683 c8908e51 Christos Stavrakakis
class UpdateBuildProgressTest(TestCase):
684 c8908e51 Christos Stavrakakis
    def setUp(self):
685 c8908e51 Christos Stavrakakis
        self.vm = mfactory.VirtualMachineFactory()
686 95aee02c Vangelis Koukis
687 c8908e51 Christos Stavrakakis
    def get_db_vm(self):
688 c8908e51 Christos Stavrakakis
        return VirtualMachine.objects.get(id=self.vm.id)
689 95aee02c Vangelis Koukis
690 c8908e51 Christos Stavrakakis
    def create_msg(self, **kwargs):
691 c8908e51 Christos Stavrakakis
        """Create snf-progress-monitor message"""
692 c8908e51 Christos Stavrakakis
        msg = {'event_time': split_time(time())}
693 c8908e51 Christos Stavrakakis
        msg['type'] = 'image-copy-progress'
694 c8908e51 Christos Stavrakakis
        msg['progress'] = 0
695 c8908e51 Christos Stavrakakis
        for key, val in kwargs.items():
696 c8908e51 Christos Stavrakakis
            msg[key] = val
697 c8908e51 Christos Stavrakakis
        message = {'body': json.dumps(msg)}
698 c8908e51 Christos Stavrakakis
        return message
699 95aee02c Vangelis Koukis
700 c8908e51 Christos Stavrakakis
    def test_missing_attribute(self, client):
701 c8908e51 Christos Stavrakakis
        update_build_progress(client, json.dumps({'body': {}}))
702 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_reject.called)
703 95aee02c Vangelis Koukis
704 c8908e51 Christos Stavrakakis
    def test_unhandled_exception(self, client):
705 c8908e51 Christos Stavrakakis
        update_build_progress(client, {})
706 c8908e51 Christos Stavrakakis
        client.basic_reject.assert_called_once()
707 c25cc9ec Vangelis Koukis
708 c8908e51 Christos Stavrakakis
    def test_missing_instance(self, client):
709 c8908e51 Christos Stavrakakis
        msg = self.create_msg(instance='foo')
710 c8908e51 Christos Stavrakakis
        update_build_progress(client, msg)
711 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
712 9068cd85 Georgios Gousios
713 c8908e51 Christos Stavrakakis
    def test_wrong_type(self, client):
714 c8908e51 Christos Stavrakakis
        msg = self.create_msg(type="WRONG_TYPE")
715 c8908e51 Christos Stavrakakis
        update_build_progress(client, msg)
716 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_nack.called)
717 9068cd85 Georgios Gousios
718 c8908e51 Christos Stavrakakis
    def test_progress_update(self, client):
719 c25cc9ec Vangelis Koukis
        rprogress = randint(10, 100)
720 c8908e51 Christos Stavrakakis
        msg = self.create_msg(progress=rprogress,
721 c8908e51 Christos Stavrakakis
                              instance=self.vm.backend_vm_id)
722 c8908e51 Christos Stavrakakis
        update_build_progress(client, msg)
723 10d9cd27 Christos Stavrakakis
        self.assertTrue(client.basic_ack.called)
724 c8908e51 Christos Stavrakakis
        vm = self.get_db_vm()
725 c8908e51 Christos Stavrakakis
        self.assertEqual(vm.buildpercentage, rprogress)
726 c8908e51 Christos Stavrakakis
727 c8908e51 Christos Stavrakakis
    def test_invalid_value(self, client):
728 c8908e51 Christos Stavrakakis
        old = self.vm.buildpercentage
729 c8908e51 Christos Stavrakakis
        for rprogress in [0, -1, 'a']:
730 c8908e51 Christos Stavrakakis
            msg = self.create_msg(progress=rprogress,
731 c8908e51 Christos Stavrakakis
                                  instance=self.vm.backend_vm_id)
732 c8908e51 Christos Stavrakakis
            update_build_progress(client, msg)
733 10d9cd27 Christos Stavrakakis
            self.assertTrue(client.basic_ack.called)
734 c8908e51 Christos Stavrakakis
            vm = self.get_db_vm()
735 c8908e51 Christos Stavrakakis
            self.assertEqual(vm.buildpercentage, old)
736 9068cd85 Georgios Gousios
737 9fea53cc Vangelis Koukis
738 7ab30015 Christos Stavrakakis
from synnefo.logic.reconciliation import VMState
739 c8908e51 Christos Stavrakakis
class ReconciliationTest(TestCase):
740 7ab30015 Christos Stavrakakis
    def get_vm(self, operstate, deleted=False):
741 7ab30015 Christos Stavrakakis
        flavor = mfactory.FlavorFactory(cpu=2, ram=1024)
742 7ab30015 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory(deleted=deleted, flavor=flavor)
743 7ab30015 Christos Stavrakakis
        vm.operstate = operstate
744 7ab30015 Christos Stavrakakis
        vm.save()
745 7ab30015 Christos Stavrakakis
        return vm
746 9fea53cc Vangelis Koukis
747 9fea53cc Vangelis Koukis
    def test_get_servers_from_db(self):
748 9fea53cc Vangelis Koukis
        """Test getting a dictionary from each server to its operstate"""
749 8bb3a316 Christos Stavrakakis
        backend = 30000
750 7ab30015 Christos Stavrakakis
        vm1 = self.get_vm('STARTED')
751 7ab30015 Christos Stavrakakis
        vm2 = self.get_vm('DESTROYED', deleted=True)
752 7ab30015 Christos Stavrakakis
        vm3 = self.get_vm('STOPPED')
753 7ab30015 Christos Stavrakakis
        self.assertEquals(reconciliation.get_servers_from_db(),
754 7ab30015 Christos Stavrakakis
                    {vm1.id: VMState(state='STARTED', cpu=2, ram=1024, nics=[]),
755 7ab30015 Christos Stavrakakis
                     vm3.id: VMState(state='STOPPED', cpu=2, ram=1024, nics=[])}
756 7ab30015 Christos Stavrakakis
                    )
757 9fea53cc Vangelis Koukis
758 9fea53cc Vangelis Koukis
    def test_stale_servers_in_db(self):
759 9fea53cc Vangelis Koukis
        """Test discovery of stale entries in DB"""
760 9fea53cc Vangelis Koukis
761 7ab30015 Christos Stavrakakis
        D = {1: None, 2: 'None', 3: None, 30000: 'BUILD',
762 7ab30015 Christos Stavrakakis
             30002: 'None'}
763 47eeffa9 Christos Stavrakakis
        G = {1: True, 3: True, 30000: True}
764 9fea53cc Vangelis Koukis
        self.assertEquals(reconciliation.stale_servers_in_db(D, G),
765 47eeffa9 Christos Stavrakakis
                          set([2, 30002]))
766 9fea53cc Vangelis Koukis
767 c8908e51 Christos Stavrakakis
    @patch("synnefo.db.models.get_rapi_client")
768 c8908e51 Christos Stavrakakis
    def test_stale_building_vm(self, client):
769 c8908e51 Christos Stavrakakis
        vm = mfactory.VirtualMachineFactory()
770 c8908e51 Christos Stavrakakis
        vm.state = 'BUILD'
771 c8908e51 Christos Stavrakakis
        vm.backendjobid = 42
772 c8908e51 Christos Stavrakakis
        vm.save()
773 c8908e51 Christos Stavrakakis
        D = {vm.id: 'BUILD'}
774 c8908e51 Christos Stavrakakis
        G = {}
775 c8908e51 Christos Stavrakakis
        for status in ['queued', 'waiting', 'running']:
776 c8908e51 Christos Stavrakakis
            client.return_value.GetJobStatus.return_value = {'status': status}
777 c8908e51 Christos Stavrakakis
            self.assertEqual(reconciliation.stale_servers_in_db(D, G), set([]))
778 cc92b70f Christos Stavrakakis
            client.return_value.GetJobStatus\
779 cc92b70f Christos Stavrakakis
                               .assert_called_once_with(vm.backendjobid)
780 c8908e51 Christos Stavrakakis
            client.reset_mock()
781 c8908e51 Christos Stavrakakis
        for status in ['success', 'error', 'canceled']:
782 c8908e51 Christos Stavrakakis
            client.return_value.GetJobStatus.return_value = {'status': status}
783 c8908e51 Christos Stavrakakis
            self.assertEqual(reconciliation.stale_servers_in_db(D, G), set([]))
784 cc92b70f Christos Stavrakakis
            client.return_value.GetInstance\
785 cc92b70f Christos Stavrakakis
                               .assert_called_once_with(vm.backend_vm_id)
786 cc92b70f Christos Stavrakakis
            client.return_value.GetJobStatus\
787 cc92b70f Christos Stavrakakis
                               .assert_called_once_with(vm.backendjobid)
788 c8908e51 Christos Stavrakakis
            client.reset_mock()
789 c8908e51 Christos Stavrakakis
        from synnefo.logic.rapi import GanetiApiError
790 c8908e51 Christos Stavrakakis
        client.return_value.GetJobStatus.side_effect = GanetiApiError('Foo')
791 cc92b70f Christos Stavrakakis
        self.assertEqual(reconciliation.stale_servers_in_db(D, G),
792 cc92b70f Christos Stavrakakis
                         set([vm.id]))
793 c8908e51 Christos Stavrakakis
794 9fea53cc Vangelis Koukis
    def test_orphan_instances_in_ganeti(self):
795 9fea53cc Vangelis Koukis
        """Test discovery of orphan instances in Ganeti, without a DB entry"""
796 9fea53cc Vangelis Koukis
797 9fea53cc Vangelis Koukis
        G = {1: True, 2: False, 3: False, 4: True, 50: True}
798 9fea53cc Vangelis Koukis
        D = {1: True, 3: False}
799 9fea53cc Vangelis Koukis
        self.assertEquals(reconciliation.orphan_instances_in_ganeti(D, G),
800 46704e06 Vangelis Koukis
                          set([2, 4, 50]))
801 9fea53cc Vangelis Koukis
802 9fea53cc Vangelis Koukis
    def test_unsynced_operstate(self):
803 9fea53cc Vangelis Koukis
        """Test discovery of unsynced operstate between the DB and Ganeti"""
804 7ab30015 Christos Stavrakakis
        mkstate = lambda state: VMState(state=state, cpu=1, ram=1024, nics=[])
805 7ab30015 Christos Stavrakakis
        vm1 = self.get_vm("STARTED")
806 7ab30015 Christos Stavrakakis
        vm2 = self.get_vm("STARTED")
807 7ab30015 Christos Stavrakakis
        vm3= self.get_vm("BUILD")
808 7ab30015 Christos Stavrakakis
        vm4 = self.get_vm("STARTED")
809 7ab30015 Christos Stavrakakis
        vm5 = self.get_vm("BUILD")
810 7ab30015 Christos Stavrakakis
811 7ab30015 Christos Stavrakakis
        D = {1: mkstate("STARTED"), 2: mkstate("STARTED"), 3: mkstate("BUILD"),
812 7ab30015 Christos Stavrakakis
             4: mkstate("STARTED"), 50: mkstate("BUILD")}
813 7ab30015 Christos Stavrakakis
        G = {vm1.id: mkstate(True), vm2.id: mkstate(False),
814 7ab30015 Christos Stavrakakis
             vm4.id: mkstate(True), vm4.id: mkstate(False),
815 7ab30015 Christos Stavrakakis
             vm5.id: mkstate(False)}
816 9fea53cc Vangelis Koukis
        self.assertEquals(reconciliation.unsynced_operstate(D, G),
817 7ab30015 Christos Stavrakakis
                          set([(vm2.id, "STARTED", False),
818 7ab30015 Christos Stavrakakis
                               (vm4.id, "STARTED", False)]))
819 b66e4833 Christos Stavrakakis
820 b66e4833 Christos Stavrakakis
from synnefo.logic.test.rapi_pool_tests import *
821 b66e4833 Christos Stavrakakis
from synnefo.logic.test.utils_tests import *