1 # Copyright (C) 2010 Oregon State University et al.
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 from datetime
import datetime
21 from django
.contrib
.auth
.models
import User
, Group
22 from django
.db
.utils
import IntegrityError
23 from django
.test
import TestCase
25 from ganeti
.tests
.rapi_proxy
import (RapiProxy
, INSTANCE
, JOB
, JOB_RUNNING
,
27 from ganeti
import models
, constants
29 VirtualMachine
= models
.VirtualMachine
30 Cluster
= models
.Cluster
32 ClusterUser
= models
.ClusterUser
34 SSHKey
= models
.SSHKey
37 'TestVirtualMachineModel',
38 'VirtualMachineTestCaseMixin',
41 class VirtualMachineTestCaseMixin():
42 def create_virtual_machine(self
, cluster
=None, hostname
='vm1.osuosl.bak'):
43 cluster
= cluster
if cluster
else Cluster(hostname
='test.osuosl.bak', slug
='OSL_TEST', username
='foo', password
='bar')
46 vm
= VirtualMachine(cluster
=cluster
, hostname
=hostname
)
51 class TestVirtualMachineModel(TestCase
, VirtualMachineTestCaseMixin
):
54 models
.client
.GanetiRapiClient
= RapiProxy
57 Job
.objects
.all().delete()
58 VirtualMachine
.objects
.all().delete()
59 Node
.objects
.all().delete()
60 Cluster
.objects
.all().delete()
61 User
.objects
.all().delete()
62 Group
.objects
.all().delete()
63 ClusterUser
.objects
.all().delete()
65 def test_trivial(self
):
67 Test the test case's setUp().
72 def test_instantiate(self
):
75 def test_non_trivial(self
):
77 Test instantiating a VirtualMachine with extra parameters
79 # Define cluster for use
80 vm_hostname
='vm.test.org'
81 cluster
= Cluster(hostname
='test.osuosl.bak', slug
='OSL_TEST')
83 owner
= ClusterUser(id=32, name
='foobar')
86 vm
= VirtualMachine(cluster
=cluster
, hostname
=vm_hostname
)
88 self
.assertTrue(vm
.id)
89 self
.assertEqual('vm.test.org', vm
.hostname
)
90 self
.assertFalse(vm
.error
)
94 vm
= VirtualMachine(cluster
=cluster
, hostname
=vm_hostname
,
95 virtual_cpus
=3, ram
=512, disk_size
=5120,
98 self
.assertTrue(vm
.id)
99 self
.assertEqual('vm.test.org', vm
.hostname
)
100 self
.assertEqual(512, vm
.ram
)
101 self
.assertEqual(5120, vm
.disk_size
)
102 self
.assertEqual('foobar', vm
.owner
.name
)
103 self
.assertFalse(vm
.error
)
105 # test unique constraints
106 #vm = VirtualMachine(cluster=cluster, hostname=vm_hostname)
107 #self.assertRaises(IntegrityError, vm.save)
111 Test saving a VirtualMachine
114 * VirtualMachine can be saved
115 * VirtualMachine can be loaded
116 * Hash is copied from cluster
118 vm
, cluster
= self
.create_virtual_machine()
120 self
.assertFalse(vm
.error
)
121 self
.assertEqual(vm
.cluster_hash
, cluster
.hash)
123 vm
= VirtualMachine
.objects
.get(id=vm
.id)
124 self
.assert_(vm
.info
)
125 self
.assertFalse(vm
.error
)
127 def test_hash_update(self
):
129 When cluster is saved hash for its VirtualMachines should be updated
131 vm0
, cluster
= self
.create_virtual_machine()
132 vm1
, cluster
= self
.create_virtual_machine(cluster
, 'test2.osuosl.bak')
134 self
.assertEqual(vm0
.cluster_hash
, cluster
.hash)
135 self
.assertEqual(vm1
.cluster_hash
, cluster
.hash)
137 # change cluster's hash
138 cluster
.hostname
= 'SomethingDifferent'
140 vm0
= VirtualMachine
.objects
.get(pk
=vm0
.id)
141 vm1
= VirtualMachine
.objects
.get(pk
=vm1
.id)
142 self
.assertEqual(vm0
.cluster_hash
, cluster
.hash, 'VirtualMachine does not have updated cache')
143 self
.assertEqual(vm1
.cluster_hash
, cluster
.hash, 'VirtualMachine does not have updated cache')
145 def test_parse_info(self
):
147 Test parsing values from cached info
150 * mtime and ctime are parsed
151 * ram, virtual_cpus, and disksize are parsed
153 vm
, cluster
= self
.create_virtual_machine()
156 self
.assertEqual(vm
.ctime
, datetime
.fromtimestamp(1285799513.4741000))
157 self
.assertEqual(vm
.mtime
, datetime
.fromtimestamp(1285883187.8692000))
158 self
.assertEqual(vm
.ram
, 512)
159 self
.assertEqual(vm
.virtual_cpus
, 2)
160 self
.assertEqual(vm
.disk_size
, 5120)
162 def test_update_owner_tag(self
):
166 vm
, cluster
= self
.create_virtual_machine()
168 owner0
= ClusterUser(id=74, name
='owner0')
169 owner1
= ClusterUser(id=21, name
='owner1')
175 self
.assertEqual([], vm
.info
['tags'])
180 self
.assertEqual(['%s%s' % (constants
.OWNER_TAG
, owner0
.id)], vm
.info
['tags'])
185 self
.assertEqual(['%s%s' % (constants
.OWNER_TAG
, owner1
.id)], vm
.info
['tags'])
187 # setting owner to none
190 self
.assertEqual([], vm
.info
['tags'])
192 def test_start(self
):
194 Test VirtualMachine.start()
198 * cache is disabled while job is running
199 * cache is reenabled when job is finished
201 vm
, cluster
= self
.create_virtual_machine()
202 vm
.rapi
.GetJobStatus
.response
= JOB_RUNNING
204 # reboot enables ignore_cache flag
205 job_id
= vm
.startup().id
206 vm
= VirtualMachine
.objects
.get(id=vm
.id)
207 self
.assert_(Job
.objects
.filter(id=job_id
).exists())
208 self
.assert_(vm
.ignore_cache
)
209 self
.assert_(vm
.last_job_id
)
211 # finished job resets ignore_cache flag
212 vm
.rapi
.GetJobStatus
.response
= JOB
213 vm
= VirtualMachine
.objects
.get(id=vm
.id)
214 self
.assertFalse(vm
.ignore_cache
)
215 self
.assertFalse(vm
.last_job_id
)
216 self
.assert_(Job
.objects
.get(id=job_id
).finished
)
220 Test VirtualMachine.stop()
224 * cache is disabled while job is running
225 * cache is reenabled when job is finished
227 vm
, cluster
= self
.create_virtual_machine()
228 vm
.rapi
.GetJobStatus
.response
= JOB_RUNNING
230 # reboot enables ignore_cache flag
231 job_id
= vm
.shutdown().id
232 self
.assert_(Job
.objects
.filter(id=job_id
).exists())
233 vm
= VirtualMachine
.objects
.get(id=vm
.id)
234 self
.assert_(vm
.ignore_cache
)
235 self
.assert_(vm
.last_job_id
)
236 self
.assert_(Job
.objects
.filter(id=job_id
).values()[0]['ignore_cache'])
238 # finished job resets ignore_cache flag
239 vm
.rapi
.GetJobStatus
.response
= JOB
240 vm
= VirtualMachine
.objects
.get(id=vm
.id)
241 self
.assertFalse(vm
.ignore_cache
)
242 self
.assertFalse(vm
.last_job_id
)
243 self
.assertFalse(Job
.objects
.filter(id=job_id
).values()[0]['ignore_cache'])
244 self
.assert_(Job
.objects
.get(id=job_id
).finished
)
246 def test_reboot(self
):
252 * cache is disabled while job is running
253 * cache is reenabled when job is finished
255 vm
, cluster
= self
.create_virtual_machine()
256 vm
.rapi
.GetJobStatus
.response
= JOB_RUNNING
258 # reboot enables ignore_cache flag
259 job_id
= vm
.reboot().id
260 self
.assert_(Job
.objects
.filter(id=job_id
).exists())
261 vm
= VirtualMachine
.objects
.get(id=vm
.id)
262 self
.assert_(vm
.ignore_cache
)
263 self
.assert_(vm
.last_job_id
)
264 self
.assert_(Job
.objects
.filter(id=job_id
).values()[0]['ignore_cache'])
266 # finished job resets ignore_cache flag
267 vm
.rapi
.GetJobStatus
.response
= JOB
268 self
.assert_(Job
.objects
.filter(id=job_id
).exists())
269 vm
= VirtualMachine
.objects
.get(id=vm
.id)
270 self
.assertFalse(vm
.ignore_cache
)
271 self
.assertFalse(vm
.last_job_id
)
272 self
.assertFalse(Job
.objects
.filter(id=job_id
).values()[0]['ignore_cache'])
273 self
.assert_(Job
.objects
.get(id=job_id
).finished
)
275 def test_load_pending_delete(self
):
277 Tests loading a VM that has a pending delete
280 * The job is still running so the VM will be loaded
282 vm
, cluster
= self
.create_virtual_machine()
283 vm
.rapi
.GetJobStatus
.response
= JOB_RUNNING
285 vm
.ignore_cache
= True
286 vm
.pending_delete
= True
287 vm
.last_job
= Job
.objects
.create(job_id
=1, obj
=vm
, cluster_id
=vm
.cluster_id
)
290 # Test loading vm, job is running so it should not be deleted yet
291 vm
= VirtualMachine
.objects
.get(pk
=vm
.pk
)
293 self
.assert_(vm
.pending_delete
)
294 self
.assertFalse(vm
.deleted
)
296 def test_load_deleted(self
):
298 Tests loading a VM that has a pending delete
301 * The Job is finished. It will load the VM but it will be deleted
304 vm
, cluster
= self
.create_virtual_machine()
305 vm
.rapi
.GetJobStatus
.response
= JOB_RUNNING
307 vm
.ignore_cache
= True
308 vm
.pending_delete
= True
309 vm
.last_job
= Job
.objects
.create(job_id
=1, obj
=vm
, cluster_id
=vm
.cluster_id
)
312 # Test loading vm, delete job is finished
313 vm
.rapi
.GetJobStatus
.response
= JOB_DELETE_SUCCESS
314 vm
= VirtualMachine
.objects
.get(pk
=vm
.pk
)
315 self
.assertFalse(vm
.id)
316 self
.assert_(vm
.pending_delete
)
317 self
.assert_(vm
.deleted
)
318 self
.assertFalse(VirtualMachine
.objects
.filter(pk
=vm
.pk
).exists())