vm.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #!/usr/bin/python2 -O
  2. import sys
  3. import unittest
  4. import lxml.etree
  5. sys.path.insert(0, '../')
  6. import qubes
  7. import qubes.events
  8. import qubes.vm
  9. class TestEmitter(qubes.events.Emitter):
  10. def __init__(self):
  11. super(TestEmitter, self).__init__()
  12. self.device_pre_attached_fired = False
  13. self.device_attached_fired = False
  14. self.device_pre_detached_fired = False
  15. self.device_detached_fired = False
  16. @qubes.events.handler('device-pre-attached:testclass')
  17. def on_device_pre_attached(self, event, dev):
  18. self.device_pre_attached_fired = True
  19. @qubes.events.handler('device-attached:testclass')
  20. def on_device_attached(self, event, dev):
  21. if self.device_pre_attached_fired:
  22. self.device_attached_fired = True
  23. @qubes.events.handler('device-pre-detached:testclass')
  24. def on_device_pre_detached(self, event, dev):
  25. if self.device_attached_fired:
  26. self.device_pre_detached_fired = True
  27. @qubes.events.handler('device-detached:testclass')
  28. def on_device_detached(self, event, dev):
  29. if self.device_pre_detached_fired:
  30. self.device_detached_fired = True
  31. class TC_00_DeviceCollection(unittest.TestCase):
  32. def setUp(self):
  33. self.emitter = TestEmitter()
  34. self.collection = qubes.vm.DeviceCollection(self.emitter, 'testclass')
  35. def test_000_init(self):
  36. self.assertFalse(self.collection._set)
  37. def test_001_attach(self):
  38. self.collection.attach('testdev')
  39. self.assertTrue(self.emitter.device_pre_attached_fired)
  40. self.assertTrue(self.emitter.device_attached_fired)
  41. self.assertFalse(self.emitter.device_pre_detached_fired)
  42. self.assertFalse(self.emitter.device_detached_fired)
  43. def test_002_detach(self):
  44. self.collection.attach('testdev')
  45. self.collection.detach('testdev')
  46. self.assertTrue(self.emitter.device_pre_attached_fired)
  47. self.assertTrue(self.emitter.device_attached_fired)
  48. self.assertTrue(self.emitter.device_pre_detached_fired)
  49. self.assertTrue(self.emitter.device_detached_fired)
  50. def test_010_empty_detach(self):
  51. with self.assertRaises(LookupError):
  52. self.collection.detach('testdev')
  53. def test_011_double_attach(self):
  54. self.collection.attach('testdev')
  55. with self.assertRaises(LookupError):
  56. self.collection.attach('testdev')
  57. def test_012_double_detach(self):
  58. self.collection.attach('testdev')
  59. self.collection.detach('testdev')
  60. with self.assertRaises(LookupError):
  61. self.collection.detach('testdev')
  62. class TC_01_DeviceManager(unittest.TestCase):
  63. def setUp(self):
  64. self.emitter = TestEmitter()
  65. self.manager = qubes.vm.DeviceManager(self.emitter)
  66. def test_000_init(self):
  67. self.assertEqual(self.manager, {})
  68. def test_001_missing(self):
  69. self.manager['testclass'].attach('testdev')
  70. self.assertTrue(self.emitter.device_attached_fired)
  71. class TestVM(qubes.vm.BaseVM):
  72. qid = qubes.property('qid', type=int)
  73. name = qubes.property('name')
  74. testprop = qubes.property('testprop')
  75. testlabel = qubes.property('testlabel')
  76. defaultprop = qubes.property('defaultprop', default='defaultvalue')
  77. class TC_10_BaseVM(unittest.TestCase):
  78. def setUp(self):
  79. self.xml = lxml.etree.XML('''
  80. <qubes version="3"> <!-- xmlns="https://qubes-os.org/QubesXML/1" -->
  81. <labels>
  82. <label id="label-1" color="#cc0000">red</label>
  83. </labels>
  84. <domains>
  85. <domain id="domain-1" class="TestVM">
  86. <properties>
  87. <property name="qid">1</property>
  88. <property name="name">domain1</property>
  89. <property name="testprop">testvalue</property>
  90. <property name="testlabel" ref="label-1" />
  91. </properties>
  92. <tags>
  93. <tag name="testtag">tagvalue</tag>
  94. </tags>
  95. <services>
  96. <service>testservice</service>
  97. <service enabled="True">enabledservice</service>
  98. <service enabled="False">disabledservice</service>
  99. </services>
  100. <devices class="pci">
  101. <device>00:11.22</device>
  102. </devices>
  103. <devices class="usb" />
  104. <devices class="audio-in" />
  105. <devices class="firewire" />
  106. <devices class="i2c" />
  107. <devices class="isa" />
  108. </domain>
  109. </domains>
  110. </qubes>
  111. ''')
  112. def test_000_BaseVM_load(self):
  113. node = self.xml.xpath('//domain')[0]
  114. vm = TestVM.fromxml(None, node)
  115. self.assertEqual(vm.qid, 1)
  116. self.assertEqual(vm.testprop, 'testvalue')
  117. self.assertEqual(vm.testprop, 'testvalue')
  118. self.assertEqual(vm.testlabel, 'label-1')
  119. self.assertEqual(vm.defaultprop, 'defaultvalue')
  120. self.assertEqual(vm.tags, {'testtag': 'tagvalue'})
  121. self.assertEqual(vm.devices, {'pci': ['00:11.22']})
  122. self.assertEqual(vm.services, {
  123. 'testservice': True,
  124. 'enabledservice': True,
  125. 'disabledservice': False,
  126. })
  127. lxml.etree.ElementTree(vm.__xml__()).write(sys.stderr, encoding='utf-8', pretty_print=True)
  128. def test_001_BaseVM_nxproperty(self):
  129. xml = lxml.etree.XML('''
  130. <qubes version="3">
  131. <domains>
  132. <domain id="domain-1" class="TestVM">
  133. <properties>
  134. <property name="nxproperty">nxvalue</property>
  135. </properties>
  136. </domain>
  137. </domains>
  138. </qubes>
  139. ''')
  140. node = xml.xpath('//domain')[0]
  141. with self.assertRaises(AttributeError):
  142. TestVM.fromxml(None, node)