Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / db / tests.py @ bd87213f

History | View | Annotate | Download (11.1 kB)

1 c8908e51 Christos Stavrakakis
# Copyright 2012 GRNET S.A. All rights reserved.
2 7bd50624 Vassilios Karakoidas
#
3 ace4bd5d Georgios Gousios
# Redistribution and use in source and binary forms, with or without
4 ace4bd5d Georgios Gousios
# modification, are permitted provided that the following conditions
5 ace4bd5d Georgios Gousios
# are met:
6 7bd50624 Vassilios Karakoidas
#
7 ace4bd5d Georgios Gousios
#   1. Redistributions of source code must retain the above copyright
8 ace4bd5d Georgios Gousios
#      notice, this list of conditions and the following disclaimer.
9 7bd50624 Vassilios Karakoidas
#
10 ace4bd5d Georgios Gousios
#  2. Redistributions in binary form must reproduce the above copyright
11 ace4bd5d Georgios Gousios
#     notice, this list of conditions and the following disclaimer in the
12 ace4bd5d Georgios Gousios
#     documentation and/or other materials provided with the distribution.
13 d8e682ed Vassilios Karakoidas
#
14 ace4bd5d Georgios Gousios
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15 ace4bd5d Georgios Gousios
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 ace4bd5d Georgios Gousios
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ace4bd5d Georgios Gousios
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18 ace4bd5d Georgios Gousios
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 ace4bd5d Georgios Gousios
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 ace4bd5d Georgios Gousios
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 ace4bd5d Georgios Gousios
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 ace4bd5d Georgios Gousios
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 ace4bd5d Georgios Gousios
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 ace4bd5d Georgios Gousios
# SUCH DAMAGE.
25 ace4bd5d Georgios Gousios
#
26 ace4bd5d Georgios Gousios
# The views and conclusions contained in the software and documentation are
27 ace4bd5d Georgios Gousios
# those of the authors and should not be interpreted as representing official
28 ace4bd5d Georgios Gousios
# policies, either expressed or implied, of GRNET S.A.
29 ace4bd5d Georgios Gousios
30 ace4bd5d Georgios Gousios
# Unit Tests for db
31 ace4bd5d Georgios Gousios
#
32 ace4bd5d Georgios Gousios
# Provides automated tests for db module
33 d8e682ed Vassilios Karakoidas
34 d39ea372 Vassilios Karakoidas
from django.test import TestCase
35 d8e682ed Vassilios Karakoidas
36 bd87213f Christos Stavrakakis
from synnefo import settings
37 35e2f2d4 Christos Stavrakakis
# Import pool tests
38 35e2f2d4 Christos Stavrakakis
from synnefo.db.pools.tests import *
39 35e2f2d4 Christos Stavrakakis
40 c8908e51 Christos Stavrakakis
from synnefo.db.models import *
41 c8908e51 Christos Stavrakakis
from synnefo.db import models_factory as mfact
42 bb8fb9af Christos Stavrakakis
from synnefo.db.pools import IPPool, EmptyPool
43 c8908e51 Christos Stavrakakis
44 c8908e51 Christos Stavrakakis
from django.db import IntegrityError
45 c8908e51 Christos Stavrakakis
from django.core.exceptions import MultipleObjectsReturned
46 bd87213f Christos Stavrakakis
from snf_django.utils.testing import override_settings
47 c8908e51 Christos Stavrakakis
from mock import patch
48 c8908e51 Christos Stavrakakis
49 c8908e51 Christos Stavrakakis
50 c8908e51 Christos Stavrakakis
class FlavorTest(TestCase):
51 c8908e51 Christos Stavrakakis
    def test_flavor_name(self):
52 c8908e51 Christos Stavrakakis
        """Test a flavor object name method."""
53 b65a3b04 Christos Stavrakakis
        flavor = mfact.FlavorFactory(cpu=1, ram=1024, disk=40,
54 b65a3b04 Christos Stavrakakis
                                     disk_template="temp")
55 b65a3b04 Christos Stavrakakis
        self.assertEqual(flavor.name, "C1R1024D40temp", "flavor.name is not"
56 b65a3b04 Christos Stavrakakis
                " generated correctly. Name is %s instead of C1R1024D40temp" %
57 c8908e51 Christos Stavrakakis
                flavor.name)
58 c8908e51 Christos Stavrakakis
59 c8908e51 Christos Stavrakakis
60 c8908e51 Christos Stavrakakis
class BackendTest(TestCase):
61 c8908e51 Christos Stavrakakis
    def setUp(self):
62 c8908e51 Christos Stavrakakis
        self.backend = mfact.BackendFactory()
63 c8908e51 Christos Stavrakakis
64 c8908e51 Christos Stavrakakis
    @patch("synnefo.db.models.get_rapi_client")
65 c8908e51 Christos Stavrakakis
    def test_get_client(self, client):
66 c8908e51 Christos Stavrakakis
        id_ = self.backend.id
67 c8908e51 Christos Stavrakakis
        hash_ = self.backend.hash
68 c8908e51 Christos Stavrakakis
        name = self.backend.clustername
69 c8908e51 Christos Stavrakakis
        passwd = self.backend.password
70 c8908e51 Christos Stavrakakis
        user = self.backend.username
71 c8908e51 Christos Stavrakakis
        port = self.backend.port
72 c8908e51 Christos Stavrakakis
        self.backend.get_client()
73 c8908e51 Christos Stavrakakis
        client.assert_called_once_with(id_, hash_, name, port, user, passwd)
74 c8908e51 Christos Stavrakakis
75 c8908e51 Christos Stavrakakis
    def test_save_hash(self):
76 c8908e51 Christos Stavrakakis
        """Test that backend hash is generated on credential change"""
77 c8908e51 Christos Stavrakakis
        old_hash = self.backend.hash
78 c8908e51 Christos Stavrakakis
        for field in ['clustername', 'username', 'password', 'port']:
79 c8908e51 Christos Stavrakakis
            value = 5181 if field == 'port' else 'foo'
80 c8908e51 Christos Stavrakakis
            self.backend.__setattr__(field, value)
81 c8908e51 Christos Stavrakakis
            self.backend.save()
82 c8908e51 Christos Stavrakakis
            self.assertNotEqual(old_hash, self.backend.hash)
83 c8908e51 Christos Stavrakakis
            old_hash = self.backend.hash
84 c8908e51 Christos Stavrakakis
85 c8908e51 Christos Stavrakakis
    def test_unique_index(self):
86 c8908e51 Christos Stavrakakis
        """Test that each backend gets a unique index"""
87 c8908e51 Christos Stavrakakis
        backends = [self.backend]
88 c8908e51 Christos Stavrakakis
        for i in xrange(0, 14):
89 c8908e51 Christos Stavrakakis
            backends.append(mfact.BackendFactory())
90 c8908e51 Christos Stavrakakis
        indexes = map(lambda x: x.index, backends)
91 c8908e51 Christos Stavrakakis
        self.assertEqual(len(indexes), len(set(indexes)))
92 c8908e51 Christos Stavrakakis
93 c8908e51 Christos Stavrakakis
    def test_backend_number(self):
94 c8908e51 Christos Stavrakakis
        """Test that no more than 16 backends are created"""
95 c8908e51 Christos Stavrakakis
        for i in xrange(0, 14):
96 c8908e51 Christos Stavrakakis
            mfact.BackendFactory()
97 c8908e51 Christos Stavrakakis
        self.assertRaises(Exception, mfact.BackendFactory, ())
98 c8908e51 Christos Stavrakakis
99 c8908e51 Christos Stavrakakis
    def test_delete_backend(self):
100 c8908e51 Christos Stavrakakis
        vm = mfact.VirtualMachineFactory(backend=self.backend, deleted=True)
101 c8908e51 Christos Stavrakakis
        bnet = mfact.BackendNetworkFactory(backend=self.backend)
102 c8908e51 Christos Stavrakakis
        self.backend.delete()
103 c8908e51 Christos Stavrakakis
        self.assertRaises(Backend.DoesNotExist, Backend.objects.get,
104 c8908e51 Christos Stavrakakis
                          id=self.backend.id)
105 c8908e51 Christos Stavrakakis
        # Test that VM is not deleted
106 c8908e51 Christos Stavrakakis
        vm2 = VirtualMachine.objects.get(id=vm.id)
107 c8908e51 Christos Stavrakakis
        self.assertEqual(vm2.backend, None)
108 c8908e51 Christos Stavrakakis
        # Test tha backend networks are deleted, but not the network
109 c8908e51 Christos Stavrakakis
        self.assertRaises(BackendNetwork.DoesNotExist,
110 c8908e51 Christos Stavrakakis
                          BackendNetwork.objects.get, id=bnet.id)
111 c8908e51 Christos Stavrakakis
        Network.objects.get(id=bnet.network.id)
112 c8908e51 Christos Stavrakakis
113 c8908e51 Christos Stavrakakis
    def test_delete_active_backend(self):
114 c8908e51 Christos Stavrakakis
        """Test that a backend with non-deleted VMS is not deleted"""
115 c8908e51 Christos Stavrakakis
        mfact.VirtualMachineFactory(backend=self.backend)
116 c8908e51 Christos Stavrakakis
        self.assertRaises(IntegrityError, self.backend.delete, ())
117 c8908e51 Christos Stavrakakis
118 c8908e51 Christos Stavrakakis
    def test_password_encryption(self):
119 c8908e51 Christos Stavrakakis
        password_hash = self.backend.password
120 c8908e51 Christos Stavrakakis
        self.backend.password = '123'
121 c8908e51 Christos Stavrakakis
        self.assertNotEqual(self.backend.password_hash, '123')
122 c8908e51 Christos Stavrakakis
        self.assertNotEqual(self.backend.password_hash, password_hash)
123 c8908e51 Christos Stavrakakis
        self.assertEqual(self.backend.password, '123')
124 c8908e51 Christos Stavrakakis
125 bd87213f Christos Stavrakakis
    def test_hypervisor(self):
126 bd87213f Christos Stavrakakis
        from synnefo.db.models import snf_settings
127 bd87213f Christos Stavrakakis
        kvm_backend = mfact.BackendFactory(hypervisor="kvm")
128 bd87213f Christos Stavrakakis
        xen_pvm_backend = mfact.BackendFactory(hypervisor="xen-pvm")
129 bd87213f Christos Stavrakakis
        xen_hvm_backend = mfact.BackendFactory(hypervisor="xen-hvm")
130 bd87213f Christos Stavrakakis
        with override_settings(snf_settings, GANETI_USE_HOTPLUG=True):
131 bd87213f Christos Stavrakakis
            self.assertTrue(kvm_backend.use_hotplug())
132 bd87213f Christos Stavrakakis
            self.assertFalse(xen_pvm_backend.use_hotplug())
133 bd87213f Christos Stavrakakis
            self.assertFalse(xen_hvm_backend.use_hotplug())
134 bd87213f Christos Stavrakakis
        with override_settings(snf_settings, GANETI_USE_HOTPLUG=False):
135 bd87213f Christos Stavrakakis
            self.assertFalse(kvm_backend.use_hotplug())
136 bd87213f Christos Stavrakakis
            self.assertFalse(xen_pvm_backend.use_hotplug())
137 bd87213f Christos Stavrakakis
            self.assertFalse(xen_hvm_backend.use_hotplug())
138 bd87213f Christos Stavrakakis
        kwargs = {"os": "snf-image+default",
139 bd87213f Christos Stavrakakis
                  "hvparams": {"kvm": {"foo1": "mpaz1"},
140 bd87213f Christos Stavrakakis
                               "xen-pvm": {"foo2": "mpaz2"},
141 bd87213f Christos Stavrakakis
                               "xen-hvm": {"foo3": "mpaz3"}}}
142 bd87213f Christos Stavrakakis
        with override_settings(snf_settings,
143 bd87213f Christos Stavrakakis
                               GANETI_CREATEINSTANCE_KWARGS=kwargs):
144 bd87213f Christos Stavrakakis
            self.assertEqual(kvm_backend.get_create_params(),
145 bd87213f Christos Stavrakakis
                    {"os": "snf-image+default",
146 bd87213f Christos Stavrakakis
                     "hvparams": {"foo1": "mpaz1"}})
147 bd87213f Christos Stavrakakis
            self.assertEqual(xen_pvm_backend.get_create_params(),
148 bd87213f Christos Stavrakakis
                    {"os": "snf-image+default",
149 bd87213f Christos Stavrakakis
                     "hvparams": {"foo2": "mpaz2"}})
150 bd87213f Christos Stavrakakis
            self.assertEqual(xen_hvm_backend.get_create_params(),
151 bd87213f Christos Stavrakakis
                    {"os": "snf-image+default",
152 bd87213f Christos Stavrakakis
                     "hvparams": {"foo3": "mpaz3"}})
153 bd87213f Christos Stavrakakis
        with override_settings(snf_settings, GANETI_CREATEINSTANCE_KWARGS={}):
154 bd87213f Christos Stavrakakis
            self.assertEqual(kvm_backend.get_create_params(), {"hvparams": {}})
155 bd87213f Christos Stavrakakis
156 c8908e51 Christos Stavrakakis
157 c8908e51 Christos Stavrakakis
class VirtualMachineTest(TestCase):
158 c8908e51 Christos Stavrakakis
    def setUp(self):
159 c8908e51 Christos Stavrakakis
        self.vm = mfact.VirtualMachineFactory()
160 c8908e51 Christos Stavrakakis
161 c8908e51 Christos Stavrakakis
    @patch("synnefo.db.models.get_rapi_client")
162 c8908e51 Christos Stavrakakis
    def test_get_client(self, client):
163 c8908e51 Christos Stavrakakis
        backend = self.vm.backend
164 c8908e51 Christos Stavrakakis
        id_ = backend.id
165 c8908e51 Christos Stavrakakis
        hash_ = backend.hash
166 c8908e51 Christos Stavrakakis
        name = backend.clustername
167 c8908e51 Christos Stavrakakis
        passwd = backend.password
168 c8908e51 Christos Stavrakakis
        user = backend.username
169 c8908e51 Christos Stavrakakis
        port = backend.port
170 c8908e51 Christos Stavrakakis
        self.vm.get_client()
171 c8908e51 Christos Stavrakakis
        client.assert_called_once_with(id_, hash_, name, port, user, passwd)
172 c8908e51 Christos Stavrakakis
173 c8908e51 Christos Stavrakakis
    def test_create(self):
174 c8908e51 Christos Stavrakakis
        vm = mfact.VirtualMachineFactory()
175 c8908e51 Christos Stavrakakis
        self.assertEqual(vm.action, None)
176 c8908e51 Christos Stavrakakis
        self.assertEqual(vm.backendjobid, None)
177 c8908e51 Christos Stavrakakis
        self.assertEqual(vm.backendjobstatus, None)
178 c8908e51 Christos Stavrakakis
        self.assertEqual(vm.backendopcode, None)
179 c8908e51 Christos Stavrakakis
        self.assertEqual(vm.backendlogmsg, None)
180 c8908e51 Christos Stavrakakis
        self.assertEqual(vm.operstate, 'BUILD')
181 c8908e51 Christos Stavrakakis
182 c8908e51 Christos Stavrakakis
183 c8908e51 Christos Stavrakakis
class NetworkTest(TestCase):
184 c8908e51 Christos Stavrakakis
    def setUp(self):
185 c8908e51 Christos Stavrakakis
        self.net = mfact.NetworkFactory()
186 c8908e51 Christos Stavrakakis
187 c8908e51 Christos Stavrakakis
    def test_tags(self):
188 c8908e51 Christos Stavrakakis
        net1 = mfact.NetworkFactory(flavor='IP_LESS_ROUTED')
189 c8908e51 Christos Stavrakakis
        self.assertEqual(net1.backend_tag, ['ip-less-routed'])
190 c8908e51 Christos Stavrakakis
        net1 = mfact.NetworkFactory(flavor='CUSTOM')
191 c8908e51 Christos Stavrakakis
        self.assertEqual(net1.backend_tag, [])
192 c8908e51 Christos Stavrakakis
193 c8908e51 Christos Stavrakakis
    def test_create_backend_network(self):
194 c8908e51 Christos Stavrakakis
        len_backends = len(Backend.objects.all())
195 c8908e51 Christos Stavrakakis
        back = mfact.BackendFactory()
196 c8908e51 Christos Stavrakakis
        self.net.create_backend_network(backend=back)
197 c8908e51 Christos Stavrakakis
        BackendNetwork.objects.get(network=self.net, backend=back)
198 c8908e51 Christos Stavrakakis
        back1 = mfact.BackendFactory()
199 c8908e51 Christos Stavrakakis
        back2 = mfact.BackendFactory()
200 c8908e51 Christos Stavrakakis
        self.net.create_backend_network()
201 c8908e51 Christos Stavrakakis
        BackendNetwork.objects.get(network=self.net, backend=back1)
202 c8908e51 Christos Stavrakakis
        BackendNetwork.objects.get(network=self.net, backend=back2)
203 c8908e51 Christos Stavrakakis
        self.assertEqual(len(BackendNetwork.objects.filter(network=self.net)),
204 c8908e51 Christos Stavrakakis
                         len_backends + 3)
205 c8908e51 Christos Stavrakakis
206 c8908e51 Christos Stavrakakis
    def test_pool(self):
207 c8908e51 Christos Stavrakakis
        pool = self.net.get_pool()
208 c8908e51 Christos Stavrakakis
        pool.network = self.net
209 c8908e51 Christos Stavrakakis
        self.assertTrue(isinstance(pool, IPPool))
210 c8908e51 Christos Stavrakakis
211 c8908e51 Christos Stavrakakis
    def test_reserve_ip(self):
212 c8908e51 Christos Stavrakakis
        net1 = mfact.NetworkFactory(subnet='192.168.2.0/24')
213 c8908e51 Christos Stavrakakis
        net1.reserve_address('192.168.2.12')
214 c8908e51 Christos Stavrakakis
        pool = net1.get_pool()
215 c8908e51 Christos Stavrakakis
        self.assertFalse(pool.is_available('192.168.2.12'))
216 c8908e51 Christos Stavrakakis
        net1.release_address('192.168.2.12')
217 c8908e51 Christos Stavrakakis
        pool = net1.get_pool()
218 c8908e51 Christos Stavrakakis
        self.assertTrue(pool.is_available('192.168.2.12'))
219 c8908e51 Christos Stavrakakis
220 c8908e51 Christos Stavrakakis
221 c8908e51 Christos Stavrakakis
class BackendNetworkTest(TestCase):
222 c8908e51 Christos Stavrakakis
    def test_mac_prefix(self):
223 c8908e51 Christos Stavrakakis
        network = mfact.NetworkFactory(mac_prefix='aa:bb:c')
224 c8908e51 Christos Stavrakakis
        backend = mfact.BackendFactory()
225 c8908e51 Christos Stavrakakis
        bnet = mfact.BackendNetworkFactory(network=network, backend=backend)
226 c8908e51 Christos Stavrakakis
        self.assertTrue(backend.index < 10)
227 c8908e51 Christos Stavrakakis
        self.assertEqual(bnet.mac_prefix, 'aa:bb:c%s' % backend.index)
228 c8908e51 Christos Stavrakakis
229 b66e4833 Christos Stavrakakis
    def test_invalid_mac(self):
230 b66e4833 Christos Stavrakakis
        network = mfact.NetworkFactory(mac_prefix='zz:bb:c')
231 b66e4833 Christos Stavrakakis
        backend = mfact.BackendFactory()
232 b66e4833 Christos Stavrakakis
        self.assertRaises(utils.InvalidMacAddress,
233 b66e4833 Christos Stavrakakis
                mfact.BackendNetworkFactory, network=network, backend=backend)
234 b66e4833 Christos Stavrakakis
235 c8908e51 Christos Stavrakakis
236 c8908e51 Christos Stavrakakis
class BridgePoolTest(TestCase):
237 c8908e51 Christos Stavrakakis
    def test_no_pool(self):
238 bb8fb9af Christos Stavrakakis
        self.assertRaises(EmptyPool,
239 c8908e51 Christos Stavrakakis
                          BridgePoolTable.get_pool)
240 c8908e51 Christos Stavrakakis
241 c8908e51 Christos Stavrakakis
    def test_two_pools(self):
242 c8908e51 Christos Stavrakakis
        mfact.BridgePoolTableFactory()
243 c8908e51 Christos Stavrakakis
        mfact.BridgePoolTableFactory()
244 c8908e51 Christos Stavrakakis
        self.assertRaises(MultipleObjectsReturned, BridgePoolTable.get_pool)
245 e8fa4283 Vassilios Karakoidas
246 452d2391 Vassilios Karakoidas
247 c8908e51 Christos Stavrakakis
class AESTest(TestCase):
248 c8908e51 Christos Stavrakakis
    def test_encrypt_decrtypt(self):
249 c8908e51 Christos Stavrakakis
        from synnefo.db import aes_encrypt as aes
250 c8908e51 Christos Stavrakakis
        old = 'bar'
251 c8908e51 Christos Stavrakakis
        new = aes.decrypt_db_charfield(aes.encrypt_db_charfield(old))
252 c8908e51 Christos Stavrakakis
        self.assertEqual(old, new)
253 8bda0440 Vassilios Karakoidas
254 c8908e51 Christos Stavrakakis
    def test_password_change(self):
255 c8908e51 Christos Stavrakakis
        from synnefo.db import aes_encrypt as aes
256 c8908e51 Christos Stavrakakis
        old_pass = aes.SECRET_ENCRYPTION_KEY
257 c8908e51 Christos Stavrakakis
        old = 'bar'
258 c8908e51 Christos Stavrakakis
        encrypted = aes.encrypt_db_charfield(old)
259 c8908e51 Christos Stavrakakis
        aes.SECRET_ENCRYPTION_KEY = 'foo2'
260 c8908e51 Christos Stavrakakis
        self.assertRaises(aes.CorruptedPassword, aes.decrypt_db_charfield,
261 c8908e51 Christos Stavrakakis
                          encrypted)
262 c8908e51 Christos Stavrakakis
        aes.SECRET_ENCRYPTION_KEY = old_pass
263 c8908e51 Christos Stavrakakis
        new = aes.decrypt_db_charfield(encrypted)
264 c8908e51 Christos Stavrakakis
        self.assertEqual(old, new)
265 8bda0440 Vassilios Karakoidas
266 c8908e51 Christos Stavrakakis
    def test_big_secret(self):
267 c8908e51 Christos Stavrakakis
        from synnefo.db import aes_encrypt as aes
268 c8908e51 Christos Stavrakakis
        old = aes.SECRET_ENCRYPTION_KEY
269 c8908e51 Christos Stavrakakis
        aes.SECRET_ENCRYPTION_KEY = \
270 c8908e51 Christos Stavrakakis
            '91490231234814234812348913289481294812398421893489'
271 c8908e51 Christos Stavrakakis
        self.assertRaises(ValueError, aes.encrypt_db_charfield, 'la')
272 c8908e51 Christos Stavrakakis
        aes.SECRET_ENCRYPTION_KEY = old