Explorar el Código

Merge remote-tracking branch 'qubesos/pr/50'

* qubesos/pr/50:
  Add property_get_default method
Marek Marczykowski-Górecki hace 6 años
padre
commit
4a28c560d9
Se han modificado 2 ficheros con 56 adiciones y 1 borrados
  1. 32 1
      qubesadmin/base.py
  2. 24 0
      qubesadmin/tests/vm/properties.py

+ 32 - 1
qubesadmin/base.py

@@ -154,6 +154,25 @@ class PropertyHolder(object):
         assert isinstance(is_default, bool)
         return is_default
 
+    def property_get_default(self, item):
+        '''
+        Get default property value, regardless of the current value
+
+        :param str item: name of property
+        :return: default value
+        '''
+        if item.startswith('_'):
+            raise AttributeError(item)
+        property_str = self.qubesd_call(
+            self._method_dest,
+            self._method_prefix + 'GetDefault',
+            item,
+            None)
+        if not property_str:
+            raise AttributeError(item + ' has no default')
+        (prop_type, value) = property_str.split(b' ', 1)
+        return self._parse_type_value(prop_type, value)
+
     def clone_properties(self, src, proplist=None):
         '''Clone properties from other object.
 
@@ -172,7 +191,6 @@ class PropertyHolder(object):
                 continue
 
     def __getattr__(self, item):
-        # pylint: disable=too-many-return-statements
         if item.startswith('_'):
             raise AttributeError(item)
         try:
@@ -184,6 +202,19 @@ class PropertyHolder(object):
         except qubesadmin.exc.QubesDaemonNoResponseError:
             raise qubesadmin.exc.QubesPropertyAccessError(item)
         (_default, prop_type, value) = property_str.split(b' ', 2)
+        return self._parse_type_value(prop_type, value)
+
+    def _parse_type_value(self, prop_type, value):
+        '''
+        Parse `type=... ...` qubesd response format. Return a value of
+        appropriate type.
+
+        :param bytes prop_type: 'type=...' part of the response (including
+            `type=` prefix)
+        :param bytes value: 'value' part of the response
+        :return: parsed value
+        '''
+        # pylint: disable=too-many-return-statements
         prop_type = prop_type.decode('ascii')
         if not prop_type.startswith('type='):
             raise qubesadmin.exc.QubesDaemonCommunicationError(

+ 24 - 0
qubesadmin/tests/vm/properties.py

@@ -164,6 +164,30 @@ class TC_00_Properties(qubesadmin.tests.vm.VMTestCase):
         del self.vm.prop1
         self.assertAllCalled()
 
+    def test_040_get_default(self):
+        self.app.expected_calls[
+            ('test-vm', 'admin.vm.property.GetDefault', 'prop1', None)] = \
+            b'0\x00type=str some value'
+        default_value = self.vm.property_get_default('prop1')
+        self.assertEqual(default_value, 'some value')
+        self.assertAllCalled()
+
+    def test_041_get_default_int(self):
+        self.app.expected_calls[
+            ('test-vm', 'admin.vm.property.GetDefault', 'prop1', None)] = \
+            b'0\x00type=int 42'
+        default_value = self.vm.property_get_default('prop1')
+        self.assertEqual(default_value, 42)
+        self.assertAllCalled()
+
+    def test_042_get_default_none(self):
+        self.app.expected_calls[
+            ('test-vm', 'admin.vm.property.GetDefault', 'prop1', None)] = \
+            b'0\x00'
+        with self.assertRaises(AttributeError):
+            self.vm.property_get_default('prop1')
+        self.assertAllCalled()
+
 
 class TC_01_SpecialCases(qubesadmin.tests.vm.VMTestCase):
     def test_000_get_name(self):