Skip to content

Commit ebffe8c

Browse files
author
anon
committed
add utests and remove unnecessary cache check
1 parent afc6e4d commit ebffe8c

4 files changed

Lines changed: 67 additions & 12 deletions

File tree

qubesadmin/app.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,7 @@ def refresh_cache(self) -> None:
117117
props_dict = dict(vm_prop.split("=", 1)
118118
for vm_prop in props.split(" "))
119119
klass = props_dict["class"]
120-
power_state = (
121-
typing.cast(PowerState, props_dict.get("state"))
122-
if self.app.cache_enabled else None
123-
)
120+
power_state = typing.cast(PowerState, props_dict.get("state"))
124121
new_known_names.add(vm_name)
125122
existing_vm = self._vms.get(vm_name) or\
126123
vms_by_current_name.get(vm_name)

qubesadmin/tests/app.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,71 @@ def test_012_getitem_cached_object(self):
187187
self.assertIsNot(vm1, vm4)
188188
self.assertAllCalled()
189189

190+
def test_013_get_blind_not_in_membership(self):
191+
"""Blind objects must not appear in membership operations."""
192+
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
193+
b'0\x00test-vm class=AppVM state=Running\n'
194+
self.assertIn('test-vm', self.app.domains)
195+
self.app.domains.get_blind('other-vm')
196+
self.assertNotIn('other-vm', self.app.domains)
197+
self.assertNotIn('other-vm', self.app.domains.keys())
198+
self.assertEqual([vm.name for vm in self.app.domains], ['test-vm'])
199+
self.assertAllCalled()
200+
201+
def test_014_refresh_cache_forces_reload(self):
202+
"""refresh_cache() must trigger a new admin.vm.List call even if
203+
already initialised."""
204+
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
205+
b'0\x00test-vm class=AppVM state=Running\n'
206+
self.assertIn('test-vm', self.app.domains)
207+
self.assertNotIn('test-vm2', self.app.domains)
208+
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
209+
b'0\x00test-vm2 class=AppVM state=Running\n'
210+
self.app.domains.refresh_cache()
211+
self.assertNotIn('test-vm', self.app.domains)
212+
self.assertIn('test-vm2', self.app.domains)
213+
self.assertAllCalled()
214+
215+
def test_015_delitem_targeted_cleanup(self):
216+
"""del domains[name] must remove the VM immediately without a
217+
further admin.vm.List call."""
218+
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
219+
b'0\x00test-vm class=AppVM state=Running\n'
220+
self.app.expected_calls[('test-vm', 'admin.vm.Remove', None, None)] = \
221+
b'0\x00'
222+
self.assertIn('test-vm', self.app.domains)
223+
del self.app.domains['test-vm']
224+
self.assertNotIn('test-vm', self.app.domains)
225+
self.assertAllCalled()
226+
227+
def test_016_rename_preserves_identity(self):
228+
"""After a rename, refresh_cache() must return the same object
229+
under the new name."""
230+
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
231+
b'0\x00test-vm class=AppVM state=Running\n'
232+
vm = self.app.domains['test-vm']
233+
# pylint: disable=protected-access
234+
vm._method_dest = 'new-name'
235+
self.app.domains.clear_cache()
236+
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
237+
b'0\x00new-name class=AppVM state=Running\n'
238+
vm2 = self.app.domains['new-name']
239+
self.assertIs(vm, vm2)
240+
self.assertAllCalled()
241+
242+
def test_017_clear_cache_invalidate_name(self):
243+
"""clear_cache(invalidate_name) must drop that VM's object from the
244+
cache so a fresh one is created on next access."""
245+
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
246+
b'0\x00test-vm class=AppVM state=Running\n'
247+
vm1 = self.app.domains['test-vm']
248+
self.app.domains.clear_cache()
249+
vm2 = self.app.domains['test-vm']
250+
self.assertIs(vm1, vm2)
251+
self.app.domains.clear_cache(invalidate_name = 'test-vm')
252+
vm3 = self.app.domains['test-vm']
253+
self.assertIsNot(vm1, vm3)
254+
self.assertAllCalled()
190255

191256

192257
class TC_10_QubesBase(qubesadmin.tests.QubesTestCase):

qubesadmin/tests/tools/qvm_ls.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -388,17 +388,10 @@ def test_101_list_selected(self):
388388
b'0\x00vm1 class=AppVM state=Running\n' \
389389
b'template1 class=TemplateVM state=Halted\n' \
390390
b'sys-net class=AppVM state=Running\n'
391-
self.app.expected_calls[
392-
('vm1', 'admin.vm.CurrentState', None, None)] = \
393-
b'0\x00power_state=Running'
394-
self.app.expected_calls[
395-
('sys-net', 'admin.vm.CurrentState', None, None)] = \
396-
b'0\x00power_state=Running'
397391
props = {
398392
'label': 'type=label green',
399393
'template': 'type=vm template1',
400394
'netvm': 'type=vm sys-net',
401-
# 'virt_mode': b'type=str pv',
402395
}
403396
self.app.expected_calls[
404397
('vm1', 'admin.vm.property.GetAll', None, None)] = \

qubesadmin/vm/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ def get_power_state(self):
212212
213213
"""
214214

215-
if self._power_state_cache is not None:
215+
if self._power_state_cache is not None and self.app.cache_enabled:
216216
return self._power_state_cache
217217
try:
218218
power_state = self._get_current_state()["power_state"]

0 commit comments

Comments
 (0)