Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (10.7 kB)

1
# Copyright 2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
#
7
#   1. Redistributions of source code must retain the above copyright
8
#      notice, this list of conditions and the following disclaimer.
9
#
10
#  2. Redistributions in binary form must reproduce the above copyright
11
#     notice, this list of conditions and the following disclaimer in the
12
#     documentation and/or other materials provided with the distribution.
13
#
14
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
# SUCH DAMAGE.
25
#
26
# The views and conclusions contained in the software and documentation are
27
# those of the authors and should not be interpreted as representing official
28
# policies, either expressed or implied, of GRNET S.A.
29

    
30
# Unit Tests for db
31
#
32
# Provides automated tests for db module
33

    
34
from django.test import TestCase
35

    
36
from django.conf import settings
37
# Import pool tests
38
from synnefo.db.pools.tests import *
39

    
40
from synnefo.db.models import *
41
from synnefo.db import models_factory as mfact
42
from synnefo.db.pools import IPPool, EmptyPool
43

    
44
from django.db import IntegrityError
45
from django.core.exceptions import MultipleObjectsReturned
46
from snf_django.utils.testing import override_settings
47
from mock import patch
48

    
49

    
50
class FlavorTest(TestCase):
51
    def test_flavor_name(self):
52
        """Test a flavor object name method."""
53
        flavor = mfact.FlavorFactory(cpu=1, ram=1024, disk=40,
54
                                     disk_template="temp")
55
        self.assertEqual(
56
            flavor.name, "C1R1024D40temp", "flavor.name is not"
57
            " generated correctly. Name is %s instead of C1R1024D40temp" %
58
            flavor.name)
59

    
60

    
61
class BackendTest(TestCase):
62
    def setUp(self):
63
        self.backend = mfact.BackendFactory()
64

    
65
    @patch("synnefo.db.models.get_rapi_client")
66
    def test_get_client(self, client):
67
        id_ = self.backend.id
68
        hash_ = self.backend.hash
69
        name = self.backend.clustername
70
        passwd = self.backend.password
71
        user = self.backend.username
72
        port = self.backend.port
73
        self.backend.get_client()
74
        client.assert_called_once_with(id_, hash_, name, port, user, passwd)
75

    
76
    def test_save_hash(self):
77
        """Test that backend hash is generated on credential change"""
78
        old_hash = self.backend.hash
79
        for field in ['clustername', 'username', 'password', 'port']:
80
            value = 5181 if field == 'port' else 'foo'
81
            self.backend.__setattr__(field, value)
82
            self.backend.save()
83
            self.assertNotEqual(old_hash, self.backend.hash)
84
            old_hash = self.backend.hash
85

    
86
    def test_unique_index(self):
87
        """Test that each backend gets a unique index"""
88
        backends = [self.backend]
89
        for i in xrange(0, 14):
90
            backends.append(mfact.BackendFactory())
91
        indexes = map(lambda x: x.index, backends)
92
        self.assertEqual(len(indexes), len(set(indexes)))
93

    
94
    def test_backend_number(self):
95
        """Test that no more than 16 backends are created"""
96
        for i in xrange(0, 14):
97
            mfact.BackendFactory()
98
        self.assertRaises(Exception, mfact.BackendFactory, ())
99

    
100
    def test_delete_active_backend(self):
101
        """Test that a backend with non-deleted VMS is not deleted"""
102
        backend = mfact.BackendFactory()
103
        vm = mfact.VirtualMachineFactory(backend=backend)
104
        self.assertRaises(IntegrityError, backend.delete, ())
105
        vm.backend = None
106
        vm.save()
107
        backend.delete()
108

    
109
    def test_password_encryption(self):
110
        password_hash = self.backend.password
111
        self.backend.password = '123'
112
        self.assertNotEqual(self.backend.password_hash, '123')
113
        self.assertNotEqual(self.backend.password_hash, password_hash)
114
        self.assertEqual(self.backend.password, '123')
115

    
116
    def test_hypervisor(self):
117
        from synnefo.db.models import snf_settings
118
        kvm_backend = mfact.BackendFactory(hypervisor="kvm")
119
        xen_pvm_backend = mfact.BackendFactory(hypervisor="xen-pvm")
120
        xen_hvm_backend = mfact.BackendFactory(hypervisor="xen-hvm")
121
        with override_settings(snf_settings, GANETI_USE_HOTPLUG=True):
122
            self.assertTrue(kvm_backend.use_hotplug())
123
            self.assertFalse(xen_pvm_backend.use_hotplug())
124
            self.assertFalse(xen_hvm_backend.use_hotplug())
125
        with override_settings(snf_settings, GANETI_USE_HOTPLUG=False):
126
            self.assertFalse(kvm_backend.use_hotplug())
127
            self.assertFalse(xen_pvm_backend.use_hotplug())
128
            self.assertFalse(xen_hvm_backend.use_hotplug())
129
        kwargs = {"os": "snf-image+default",
130
                  "hvparams": {"kvm": {"foo1": "mpaz1"},
131
                               "xen-pvm": {"foo2": "mpaz2"},
132
                               "xen-hvm": {"foo3": "mpaz3"}}}
133
        with override_settings(snf_settings,
134
                               GANETI_CREATEINSTANCE_KWARGS=kwargs):
135
            self.assertEqual(kvm_backend.get_create_params(),
136
                             {"os": "snf-image+default",
137
                              "hvparams": {"foo1": "mpaz1"}})
138
            self.assertEqual(xen_pvm_backend.get_create_params(),
139
                             {"os": "snf-image+default",
140
                              "hvparams": {"foo2": "mpaz2"}})
141
            self.assertEqual(xen_hvm_backend.get_create_params(),
142
                             {"os": "snf-image+default",
143
                              "hvparams": {"foo3": "mpaz3"}})
144
        with override_settings(snf_settings, GANETI_CREATEINSTANCE_KWARGS={}):
145
            self.assertEqual(kvm_backend.get_create_params(), {"hvparams": {}})
146

    
147

    
148
class VirtualMachineTest(TestCase):
149
    def setUp(self):
150
        self.vm = mfact.VirtualMachineFactory()
151

    
152
    @patch("synnefo.db.models.get_rapi_client")
153
    def test_get_client(self, client):
154
        backend = self.vm.backend
155
        id_ = backend.id
156
        hash_ = backend.hash
157
        name = backend.clustername
158
        passwd = backend.password
159
        user = backend.username
160
        port = backend.port
161
        self.vm.get_client()
162
        client.assert_called_once_with(id_, hash_, name, port, user, passwd)
163

    
164
    def test_create(self):
165
        vm = VirtualMachine()
166
        self.assertEqual(vm.action, None)
167
        self.assertEqual(vm.backendjobid, None)
168
        self.assertEqual(vm.backendjobstatus, None)
169
        self.assertEqual(vm.backendopcode, None)
170
        self.assertEqual(vm.backendlogmsg, None)
171
        self.assertEqual(vm.operstate, 'BUILD')
172

    
173

    
174
class NetworkTest(TestCase):
175
    def setUp(self):
176
        self.net = mfact.NetworkWithSubnetFactory()
177

    
178
    def test_tags(self):
179
        net1 = mfact.NetworkFactory(flavor='IP_LESS_ROUTED')
180
        self.assertEqual(net1.backend_tag, ['ip-less-routed'])
181
        net1 = mfact.NetworkFactory(flavor='CUSTOM')
182
        self.assertEqual(net1.backend_tag, [])
183

    
184
    def test_create_backend_network(self):
185
        len_backends = len(Backend.objects.all())
186
        back = mfact.BackendFactory()
187
        self.net.create_backend_network(backend=back)
188
        BackendNetwork.objects.get(network=self.net, backend=back)
189
        back1 = mfact.BackendFactory()
190
        back2 = mfact.BackendFactory()
191
        self.net.create_backend_network()
192
        BackendNetwork.objects.get(network=self.net, backend=back1)
193
        BackendNetwork.objects.get(network=self.net, backend=back2)
194
        self.assertEqual(len(BackendNetwork.objects.filter(network=self.net)),
195
                         len_backends + 3)
196

    
197
    def test_pool(self):
198
        pool = self.net.get_ip_pools()[0]
199
        pool.network = self.net
200
        self.assertTrue(isinstance(pool, IPPool))
201

    
202
    def test_reserve_ip(self):
203
        net1 = mfact.NetworkWithSubnetFactory(subnet__cidr='192.168.2.0/24')
204
        pool = net1.get_ip_pools()[0]
205
        self.assertTrue(pool.is_available('192.168.2.12'))
206
        net1.reserve_address('192.168.2.12')
207
        pool = net1.get_ip_pools()[0]
208
        self.assertFalse(pool.is_available('192.168.2.12'))
209
        net1.release_address('192.168.2.12')
210
        pool = net1.get_ip_pools()[0]
211
        self.assertTrue(pool.is_available('192.168.2.12'))
212

    
213

    
214
class BackendNetworkTest(TestCase):
215
    def test_mac_prefix(self):
216
        network = mfact.NetworkFactory(mac_prefix='aa:bb:c')
217
        backend = mfact.BackendFactory()
218
        bnet = mfact.BackendNetworkFactory(network=network, backend=backend)
219
        self.assertTrue(backend.index < 10)
220
        self.assertEqual(bnet.mac_prefix, 'aa:bb:c%s' % backend.index)
221

    
222
    def test_invalid_mac(self):
223
        network = mfact.NetworkFactory(mac_prefix='zz:bb:c')
224
        backend = mfact.BackendFactory()
225
        self.assertRaises(utils.InvalidMacAddress,
226
                          mfact.BackendNetworkFactory,
227
                          network=network, backend=backend)
228

    
229

    
230
class BridgePoolTest(TestCase):
231
    def test_no_pool(self):
232
        self.assertRaises(EmptyPool,
233
                          BridgePoolTable.get_pool)
234

    
235
    def test_two_pools(self):
236
        mfact.BridgePoolTableFactory()
237
        mfact.BridgePoolTableFactory()
238
        self.assertRaises(MultipleObjectsReturned, BridgePoolTable.get_pool)
239

    
240

    
241
class AESTest(TestCase):
242
    def test_encrypt_decrtypt(self):
243
        from synnefo.db import aes_encrypt as aes
244
        old = 'bar'
245
        new = aes.decrypt_db_charfield(aes.encrypt_db_charfield(old))
246
        self.assertEqual(old, new)
247

    
248
    def test_password_change(self):
249
        from synnefo.db import aes_encrypt as aes
250
        old_pass = aes.SECRET_ENCRYPTION_KEY
251
        old = 'bar'
252
        encrypted = aes.encrypt_db_charfield(old)
253
        aes.SECRET_ENCRYPTION_KEY = 'foo2'
254
        self.assertRaises(aes.CorruptedPassword, aes.decrypt_db_charfield,
255
                          encrypted)
256
        aes.SECRET_ENCRYPTION_KEY = old_pass
257
        new = aes.decrypt_db_charfield(encrypted)
258
        self.assertEqual(old, new)
259

    
260
    def test_big_secret(self):
261
        from synnefo.db import aes_encrypt as aes
262
        old = aes.SECRET_ENCRYPTION_KEY
263
        aes.SECRET_ENCRYPTION_KEY = \
264
            '91490231234814234812348913289481294812398421893489'
265
        self.assertRaises(ValueError, aes.encrypt_db_charfield, 'la')
266
        aes.SECRET_ENCRYPTION_KEY = old