Parcourir la source

Cache vm.name property

It doesn't make sense to send mgmt call to _named_ VM just to ask for
its name. Use value that QubesVM object already have.
This also means we can safely access vm.name, no need to touch any
private attribute.

QubesOS/qubes-issues#853
Marek Marczykowski-Górecki il y a 7 ans
Parent
commit
4bbc7a6b1f
5 fichiers modifiés avec 44 ajouts et 5 suppressions
  1. 5 0
      qubesmgmt/app.py
  2. 1 2
      qubesmgmt/base.py
  3. 2 2
      qubesmgmt/tests/app.py
  4. 22 0
      qubesmgmt/tests/vm/properties.py
  5. 14 1
      qubesmgmt/vm/__init__.py

+ 5 - 0
qubesmgmt/app.py

@@ -34,7 +34,12 @@ class VMCollection(object):
         self.app = app
         self._vm_list = None
 
+    def clear_cache(self):
+        '''Clear cached list of VMs'''
+        self._vm_list = None
+
     def refresh_cache(self, force=False):
+        '''Refresh cached list of VMs'''
         if not force and self._vm_list is not None:
             return
         vm_list_data = self.app.qubesd_call(

+ 1 - 2
qubesmgmt/base.py

@@ -138,8 +138,7 @@ class PropertyHolder(object):
                 None)
         else:
             if isinstance(value, qubesmgmt.vm.QubesVM):
-                # pylint: disable=protected-access
-                value = value._name
+                value = value.name
             self.qubesd_call(
                 self._method_dest,
                 self._method_prefix + 'Set',

+ 2 - 2
qubesmgmt/tests/app.py

@@ -35,7 +35,7 @@ class TC_00_VMCollection(qubesmgmt.tests.QubesTestCase):
             b'0\x00test-vm class=AppVM state=running\n'
         try:
             vm = self.app.domains['test-vm']
-            self.assertEqual(vm._name, 'test-vm')
+            self.assertEqual(vm.name, 'test-vm')
         except KeyError:
             self.fail('VM not found in collection')
         self.assertAllCalled()
@@ -56,7 +56,7 @@ class TC_00_VMCollection(qubesmgmt.tests.QubesTestCase):
     def test_003_iter(self):
         self.app.expected_calls[('dom0', 'mgmt.vm.List', None, None)] = \
             b'0\x00test-vm class=AppVM state=running\n'
-        self.assertEqual([vm._name for vm in self.app.domains], ['test-vm'])
+        self.assertEqual([vm.name for vm in self.app.domains], ['test-vm'])
         self.assertAllCalled()
 
 

+ 22 - 0
qubesmgmt/tests/vm/properties.py

@@ -131,3 +131,25 @@ class TC_00_Properties(qubesmgmt.tests.vm.VMTestCase):
         del self.vm.prop1
         self.assertAllCalled()
 
+
+class TC_01_SpecialCases(qubesmgmt.tests.vm.VMTestCase):
+    def test_000_get_name(self):
+        # should not make any mgmt call
+        self.assertEqual(self.vm.name, 'test-vm')
+        self.assertAllCalled()
+
+    def test_001_set_name(self):
+        # but this one should still do a call
+        self.app.expected_calls[
+            ('test-vm', 'mgmt.vm.property.Set', 'name', b'test-vm2')] = \
+            b'0\x00'
+        self.vm.name = 'test-vm2'
+        self.assertEqual(self.vm.name, 'test-vm2')
+        self.assertAllCalled()
+
+        # check if VM list cache was cleared
+        self.app.actual_calls = []
+        del self.app.expected_calls[
+            ('test-vm', 'mgmt.vm.property.Set', 'name', b'test-vm2')]
+        vm = self.app.domains['test-vm']
+        self.assertAllCalled()

+ 14 - 1
qubesmgmt/vm/__init__.py

@@ -23,6 +23,19 @@ import qubesmgmt.base
 
 class QubesVM(qubesmgmt.base.PropertyHolder):
     def __init__(self, app, name, vm_class):
-        self._name = name
         self._class = vm_class
         super(QubesVM, self).__init__(app, 'mgmt.vm.property.', name)
+
+    @property
+    def name(self):
+        return self._method_dest
+
+    @name.setter
+    def name(self, new_value):
+        self.qubesd_call(
+            self._method_dest,
+            self._method_prefix + 'Set',
+            'name',
+            str(new_value).encode('utf-8'))
+        self._method_dest = new_value
+        self.app.domains.clear_cache()