123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- # pylint: disable=protected-access
- #
- # The Qubes OS Project, https://www.qubes-os.org/
- #
- # Copyright (C) 2014-2015 Joanna Rutkowska <joanna@invisiblethingslab.com>
- # Copyright (C) 2014-2015 Wojtek Porczyk <woju@invisiblethingslab.com>
- #
- # This library is free software; you can redistribute it and/or
- # modify it under the terms of the GNU Lesser General Public
- # License as published by the Free Software Foundation; either
- # version 2.1 of the License, or (at your option) any later version.
- #
- # This library is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- # Lesser General Public License for more details.
- #
- # You should have received a copy of the GNU Lesser General Public
- # License along with this library; if not, see <https://www.gnu.org/licenses/>.
- #
- import lxml.etree
- import qubes
- import qubes.events
- import qubes.vm
- import qubes.tests
- class TestVMM(object):
- def __init__(self):
- super(TestVMM, self).__init__()
- self.offline_mode = True
- class TestApp(object):
- def __init__(self):
- super(TestApp, self).__init__()
- self.domains = {}
- self.vmm = TestVMM()
- class TestVM(qubes.vm.BaseVM):
- qid = qubes.property('qid', type=int)
- name = qubes.property('name')
- testprop = qubes.property('testprop')
- testlabel = qubes.property('testlabel')
- defaultprop = qubes.property('defaultprop', default='defaultvalue')
- class TC_10_BaseVM(qubes.tests.QubesTestCase):
- def setUp(self):
- super().setUp()
- self.xml = lxml.etree.XML('''
- <qubes version="3"> <!-- xmlns="https://qubes-os.org/QubesXML/1" -->
- <labels>
- <label id="label-1" color="#cc0000">red</label>
- </labels>
- <domains>
- <domain id="domain-1" class="TestVM">
- <properties>
- <property name="qid">1</property>
- <property name="name">domain1</property>
- <property name="testprop">testvalue</property>
- <property name="testlabel" ref="label-1" />
- </properties>
- <tags>
- <tag name="testtag"/>
- </tags>
- <features>
- <feature name="testfeature_empty"></feature>
- <feature name="testfeature_aqq">aqq</feature>
- </features>
- <devices class="pci">
- <device backend-domain="domain1" id="00_11.22">
- <option name="no-strict-reset">True</option>
- </device>
- </devices>
- <devices class="usb" />
- <devices class="audio-in" />
- <devices class="firewire" />
- <devices class="i2c" />
- <devices class="isa" />
- </domain>
- </domains>
- </qubes>
- ''')
- def test_000_load(self):
- node = self.xml.xpath('//domain')[0]
- vm = TestVM(TestApp(), node)
- vm.app.domains['domain1'] = vm
- vm.load_properties(load_stage=None)
- vm.load_extras()
- self.assertEqual(vm.qid, 1)
- self.assertEqual(vm.testprop, 'testvalue')
- self.assertEqual(vm.testprop, 'testvalue')
- self.assertEqual(vm.testlabel, 'label-1')
- self.assertEqual(vm.defaultprop, 'defaultvalue')
- self.assertEqual(vm.tags, {'testtag'})
- self.assertEqual(vm.features, {
- 'testfeature_empty': '',
- 'testfeature_aqq': 'aqq',
- })
- self.assertCountEqual(vm.devices.keys(), ('pci',))
- self.assertCountEqual(list(vm.devices['pci'].persistent()),
- [qubes.ext.pci.PCIDevice(vm, '00_11.22')])
- assignments = list(vm.devices['pci'].assignments())
- self.assertEqual(len(assignments), 1)
- self.assertEqual(assignments[0].options, {'no-strict-reset': 'True'})
- self.assertEqual(assignments[0].persistent, True)
- self.assertXMLIsValid(vm.__xml__(), 'domain.rng')
- def test_001_nxproperty(self):
- xml = lxml.etree.XML('''
- <qubes version="3">
- <domains>
- <domain id="domain-1" class="TestVM">
- <properties>
- <property name="qid">1</property>
- <property name="name">domain1</property>
- <property name="nxproperty">nxvalue</property>
- </properties>
- </domain>
- </domains>
- </qubes>
- ''')
- node = xml.xpath('//domain')[0]
- with self.assertRaises(TypeError):
- TestVM(None, node)
- def test_002_save_nxproperty(self):
- vm = TestVM(None, None, qid=1, name='testvm')
- vm.nxproperty = 'value'
- xml = vm.__xml__()
- self.assertNotIn('nxproperty', xml)
- class TC_20_Tags(qubes.tests.QubesTestCase):
- def setUp(self):
- super(TC_20_Tags, self).setUp()
- self.vm = qubes.tests.TestEmitter()
- self.tags = qubes.vm.Tags(self.vm)
- def test_000_add(self):
- self.tags.add('testtag')
- self.assertEventFired(self.vm, 'domain-tag-add:testtag',
- kwargs={'tag': 'testtag'})
- def test_001_add_existing(self):
- self.tags.add('testtag')
- self.vm.fired_events.clear()
- self.tags.add('testtag')
- self.assertEventNotFired(self.vm, 'domain-tag-add:testtag')
- def test_002_remove(self):
- self.tags.add('testtag')
- self.vm.fired_events.clear()
- self.tags.remove('testtag')
- self.assertEventFired(self.vm, 'domain-tag-delete:testtag',
- kwargs={'tag': 'testtag'})
- def test_003_remove_not_present(self):
- with self.assertRaises(KeyError):
- self.tags.remove('testtag')
- self.assertEventNotFired(self.vm, 'domain-tag-delete:testtag')
- def test_004_discard_not_present(self):
- with self.assertNotRaises(KeyError):
- self.tags.discard('testtag')
- self.assertEventNotFired(self.vm, 'domain-tag-delete:testtag')
- def test_005_discard_present(self):
- self.tags.add('testtag')
- with self.assertNotRaises(KeyError):
- self.tags.discard('testtag')
- self.assertEventFired(self.vm, 'domain-tag-delete:testtag',
- kwargs={'tag': 'testtag'})
- def test_006_clear(self):
- self.tags.add('testtag')
- self.tags.add('testtag2')
- self.vm.fired_events.clear()
- self.tags.clear()
- self.assertEventFired(self.vm, 'domain-tag-delete:testtag',
- kwargs={'tag': 'testtag'})
- self.assertEventFired(self.vm, 'domain-tag-delete:testtag2',
- kwargs={'tag': 'testtag2'})
- def test_007_update(self):
- self.tags.add('testtag')
- self.tags.add('testtag2')
- self.vm.fired_events.clear()
- self.tags.update(('testtag2', 'testtag3'))
- self.assertEventFired(self.vm, 'domain-tag-add:testtag3',
- kwargs={'tag': 'testtag3'})
- self.assertEventNotFired(self.vm, 'domain-tag-add:testtag2',
- kwargs={'tag': 'testtag2'})
- class TC_21_Features(qubes.tests.QubesTestCase):
- def setUp(self):
- super(TC_21_Features, self).setUp()
- self.vm = qubes.tests.TestEmitter()
- self.features = qubes.features.Features(self.vm)
- def test_000_set(self):
- self.features['testfeature'] = 'value'
- self.assertEventFired(self.vm, 'domain-feature-set:testfeature',
- kwargs={'feature': 'testfeature', 'value': 'value'})
- def test_001_set_existing(self):
- self.features['test'] = 'oldvalue'
- self.vm.fired_events.clear()
- self.features['test'] = 'value'
- self.assertEventFired(self.vm, 'domain-feature-set:test',
- kwargs={'feature': 'test', 'value': 'value', 'oldvalue':
- 'oldvalue'})
- def test_002_unset(self):
- self.features['test'] = 'value'
- self.vm.fired_events.clear()
- del self.features['test']
- self.assertEventFired(self.vm, 'domain-feature-delete:test',
- kwargs={'feature': 'test'})
- def test_003_unset_not_present(self):
- with self.assertRaises(KeyError):
- del self.features['test']
- self.assertEventNotFired(self.vm, 'domain-feature-delete')
- self.assertEventNotFired(self.vm, 'domain-feature-delete:test')
- def test_004_set_bool_true(self):
- self.features['test'] = True
- self.assertTrue(self.features['test'])
- self.assertEventFired(self.vm, 'domain-feature-set:test',
- kwargs={'feature': 'test', 'value': '1'})
- def test_005_set_bool_false(self):
- self.features['test'] = False
- self.assertFalse(self.features['test'])
- self.assertEventFired(self.vm, 'domain-feature-set:test',
- kwargs={'feature': 'test', 'value': ''})
- def test_006_set_int(self):
- self.features['test'] = 123
- self.assertEventFired(self.vm, 'domain-feature-set:test',
- kwargs={'feature': 'test', 'value': '123'})
- def test_007_clear(self):
- self.features['test'] = 'value1'
- self.features['test2'] = 'value2'
- self.vm.fired_events.clear()
- self.features.clear()
- self.assertEventFired(self.vm, 'domain-feature-delete:test',
- kwargs={'feature': 'test'})
- self.assertEventFired(self.vm, 'domain-feature-delete:test2',
- kwargs={'feature': 'test2'})
- def test_008_update(self):
- self.features['test'] = 'value'
- self.features['test2'] = 'value2'
- self.vm.fired_events.clear()
- self.features.update({'test2': 'value3', 'test3': 'value4'})
- self.assertEqual(self.features['test2'], 'value3')
- self.assertEqual(self.features['test3'], 'value4')
- self.assertEqual(self.features['test'], 'value')
- self.assertEventFired(self.vm, 'domain-feature-set:test2',
- kwargs={'feature': 'test2', 'value': 'value3',
- 'oldvalue': 'value2'})
- self.assertEventFired(self.vm, 'domain-feature-set:test3',
- kwargs={'feature': 'test3', 'value': 'value4'})
|