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,
18 from __future__
import with_statement
20 from datetime
import datetime
22 from django
.test
import TestCase
24 from ganeti_web
import models
25 from ganeti_web
.cache
import update_cache
26 from ganeti_web
.tests
.rapi_proxy
import RapiProxy
, INSTANCES_BULK
27 from ganeti_web
.tests
.utils
import MuteStdout
28 from ganeti_web
.tests
.virtual_machine
import VirtualMachineTestCaseMixin
31 VirtualMachine
= models
.VirtualMachine
32 Cluster
= models
.Cluster
35 class TestCacheUpdater(TestCase
, VirtualMachineTestCaseMixin
):
38 # Django lacks a monkeypatcher, so...
39 self
._stashedGanetiRapiClient
= models
.client
.GanetiRapiClient
40 models
.client
.GanetiRapiClient
= RapiProxy
43 models
.client
.GanetiRapiClient
= self
._stashedGanetiRapiClient
44 VirtualMachine
.objects
.all().delete()
45 Cluster
.objects
.all().delete()
47 def test_no_updates(self
):
49 Test running the updater running when no vms need to be updated
51 vm0
, cluster
= self
.create_virtual_machine()
52 vm1
, chaff
= self
.create_virtual_machine(cluster
, 'vm2.osuosl.bak')
54 os
= 'image+gentoo-hardened-cf'
55 mtime_timestamp
= 1285883000.8692000
56 mtime
= datetime
.fromtimestamp(mtime_timestamp
)
57 cached
= datetime
.now()
59 # set data so that mtime is up to date. include a data change that
61 data
= list(INSTANCES_BULK
)
62 data
[0]['mtime'] = mtime_timestamp
63 data
[1]['mtime'] = mtime_timestamp
64 cluster
.rapi
.GetInstances
.response
= data
65 VirtualMachine
.objects
.all().update(mtime
=mtime
, cached
=cached
, \
66 operating_system
='image+fake', status
='running')
68 # run updater and refresh the objects from the db
71 vm0
= VirtualMachine
.objects
.filter(pk
=vm0
.id).values('mtime','cached','status','operating_system')[0]
72 vm1
= VirtualMachine
.objects
.filter(pk
=vm1
.id).values('mtime','cached','status','operating_system')[0]
74 # properties should not be updated because mtime and status indicated it
75 # was already up to date
76 self
.assertNotEqual(os
, vm0
['operating_system'])
77 self
.assertNotEqual(os
, vm1
['operating_system'])
79 if cached
> datetime
.fromtimestamp(float(vm0
['cached'])):
80 self
.fail('cache is not newer: %s, %s' % (cached
, vm0
.cached
))
82 if cached
> datetime
.fromtimestamp(float(vm1
['cached'])):
83 self
.fail('cache is not newer: %s, %s' % (cached
, vm1
.cached
))
85 def test_updated_mtime(self
):
87 tests that newer mtime results in update
89 vm0
, cluster
= self
.create_virtual_machine()
90 vm1
, chaff
= self
.create_virtual_machine(cluster
, 'vm2.osuosl.bak')
92 os
= 'image+gentoo-hardened-cf'
93 mtime_timestamp
= 1285883000.1234000
94 mtime
= datetime
.fromtimestamp(mtime_timestamp
)
95 new_mtime_timestamp
= 1999999999.8692000
96 cached
= datetime
.now()
98 # set data so that mtime is up to date. include a data change that
100 data
= list(INSTANCES_BULK
)
101 data
[0]['mtime'] = new_mtime_timestamp
102 data
[1]['mtime'] = new_mtime_timestamp
103 cluster
.rapi
.GetInstances
.response
= data
105 VirtualMachine
.objects
.all().update(mtime
=mtime
, cached
=cached
, \
106 operating_system
='image+fake', status
='running')
108 # run updater and refresh the objects from the db
111 vm0
= VirtualMachine
.objects
.filter(pk
=vm0
.id).values('mtime','cached','status','operating_system')[0]
112 vm1
= VirtualMachine
.objects
.filter(pk
=vm1
.id).values('mtime','cached','status','operating_system')[0]
114 # check for properties that are updated
115 self
.assertEqual(os
, vm0
['operating_system'])
116 self
.assertEqual(os
, vm1
['operating_system'])
117 self
.assertEqual(new_mtime_timestamp
, float(vm0
['mtime']))
118 self
.assertEqual(new_mtime_timestamp
, float(vm1
['mtime']))
119 self
.assertEqual("running", vm0
['status'])
120 self
.assertEqual("running", vm1
['status'])
123 if cached
> datetime
.fromtimestamp(float(vm0
['cached'])):
124 self
.fail('cache is not newer: %s, %s' % (cached
, vm0
.cached
))
126 if cached
> datetime
.fromtimestamp(float(vm1
['cached'])):
127 self
.fail('cache is not newer: %s, %s' % (cached
, vm1
.cached
))
129 def test_null_timestamps(self
):
131 Tests that the cache updater can handle updating records with null
134 vm0
, cluster
= self
.create_virtual_machine()
135 vm1
, chaff
= self
.create_virtual_machine(cluster
, 'vm2.osuosl.bak')
137 os
= 'image+gentoo-hardened-cf'
138 mtime_timestamp
= 1285883000.8692000
139 cached
= datetime
.now()
141 # set data so that mtime is up to date. include a data change that
143 data
= list(INSTANCES_BULK
)
144 data
[0]['mtime'] = mtime_timestamp
145 data
[1]['mtime'] = mtime_timestamp
146 cluster
.rapi
.GetInstances
.response
= data
147 VirtualMachine
.objects
.all().update(mtime
=None, cached
=None, \
148 operating_system
='image+fake', status
='running')
150 # run updater and refresh the objects from the db
153 vm0
= VirtualMachine
.objects
.filter(pk
=vm0
.id).values('mtime','cached','status','operating_system')[0]
154 vm1
= VirtualMachine
.objects
.filter(pk
=vm1
.id).values('mtime','cached','status','operating_system')[0]
156 # properties should not be updated because mtime and status indicated it
157 # was already up to date
158 self
.assertEqual(os
, vm0
['operating_system'])
159 self
.assertEqual(os
, vm1
['operating_system'])
160 self
.assertEqual(mtime_timestamp
, float(vm0
['mtime']))
161 self
.assertEqual(mtime_timestamp
, float(vm1
['mtime']))
162 self
.assertEqual("running", vm0
['status'])
163 self
.assertEqual("running", vm1
['status'])
165 if cached
> datetime
.fromtimestamp(float(vm0
['cached'])):
166 self
.fail('cache is not newer: %s, %s' % (cached
, vm0
.cached
))
168 if cached
> datetime
.fromtimestamp(float(vm1
['cached'])):
169 self
.fail('cache is not newer: %s, %s' % (cached
, vm1
.cached
))
171 def test_missing_vms(self
):
173 Tests the cache updater importing missing vms
175 vm0
, cluster
= self
.create_virtual_machine()
177 os
= 'image+gentoo-hardened-cf'
178 mtime_timestamp
= 1285883000.8692000
179 cached
= datetime
.now()
181 # set data so that mtime is up to date. include a data change that
183 data
= list(INSTANCES_BULK
)
184 data
[0]['mtime'] = mtime_timestamp
185 data
[1]['mtime'] = mtime_timestamp
186 cluster
.rapi
.GetInstances
.response
= data
187 VirtualMachine
.objects
.all().update(mtime
=None, cached
=None, \
188 operating_system
='image+fake', status
='running')
190 # run updater and refresh the objects from the db
193 self
.assert_(VirtualMachine
.objects
.filter(hostname
='vm2.osuosl.bak').exists())
194 vm0
= VirtualMachine
.objects
.filter(pk
=vm0
.id).values('mtime','cached','status','operating_system')[0]
195 vm1
= VirtualMachine
.objects
.filter(hostname
='vm2.osuosl.bak').values('mtime','cached','status','operating_system')[0]
197 # properties should not be updated because mtime and status indicated it
198 # was already up to date
199 self
.assertEqual(os
, vm0
['operating_system'])
200 self
.assertEqual(os
, vm1
['operating_system'])
201 self
.assertEqual(mtime_timestamp
, float(vm0
['mtime']))
202 self
.assertEqual(mtime_timestamp
, float(vm1
['mtime']))
203 self
.assertEqual("running", vm0
['status'])
204 self
.assertEqual("running", vm1
['status'])
206 if cached
> datetime
.fromtimestamp(float(vm0
['cached'])):
207 self
.fail('cache is not newer: %s, %s' % (cached
, vm0
.cached
))
209 if cached
> datetime
.fromtimestamp(float(vm1
['cached'])):
210 self
.fail('cache is not newer: %s, %s' % (cached
, vm1
.cached
))
212 def test_updated_status(self
):
214 Test that updater detects and updates status changes
216 vm0
, cluster
= self
.create_virtual_machine()
217 vm1
, chaff
= self
.create_virtual_machine(cluster
, 'vm2.osuosl.bak')
219 os
= 'image+gentoo-hardened-cf'
220 mtime_timestamp
= 1285883000.8692000
221 mtime
= datetime
.fromtimestamp(mtime_timestamp
)
222 cached
= datetime
.now()
224 # set data so that mtime is up to date. include a data change that
226 data
= list(INSTANCES_BULK
)
227 data
[0]['mtime'] = mtime_timestamp
228 data
[1]['mtime'] = mtime_timestamp
229 cluster
.rapi
.GetInstances
.response
= data
230 VirtualMachine
.objects
.all().update(mtime
=mtime
, cached
=cached
, \
231 operating_system
='image+fake', status
='ADMIN_down')
233 # run updater and refresh the objects from the db
236 vm0
= VirtualMachine
.objects
.filter(pk
=vm0
.id).values('mtime','cached','status','operating_system')[0]
237 vm1
= VirtualMachine
.objects
.filter(pk
=vm1
.id).values('mtime','cached','status','operating_system')[0]
239 # check for properties that are updated
240 self
.assertEqual(os
, vm0
['operating_system'])
241 self
.assertEqual(os
, vm1
['operating_system'])
242 self
.assertEqual(mtime_timestamp
, float(vm0
['mtime']))
243 self
.assertEqual(mtime_timestamp
, float(vm1
['mtime']))
244 self
.assertEqual("running", vm0
['status'])
245 self
.assertEqual("running", vm1
['status'])
247 if cached
> datetime
.fromtimestamp(float(vm0
['cached'])):
248 self
.fail('cache is not newer: %s, %s' % (cached
, vm0
.cached
))
250 if cached
> datetime
.fromtimestamp(float(vm1
['cached'])):
251 self
.fail('cache is not newer: %s, %s' % (cached
, vm1
.cached
))