From dd6ef8393a8f27fefad66cce136e52f13350f0df Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Fri, 1 Oct 2021 18:23:10 +0200 Subject: [PATCH] tests: Add LVM2 teardown object existence checks This adds a check for the created stack objects presence after the teardown. Due to the nature of the global lvm2 module update some objects may still hang around after the org.freedesktop.UDisks2.VolumeGroup.Delete(options='tear-down') method call has returned. Until this is properly fixed an explicit timeout had to be added. --- src/tests/dbus-tests/test_20_LVM.py | 80 +++++++++++++++++------------ 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/src/tests/dbus-tests/test_20_LVM.py b/src/tests/dbus-tests/test_20_LVM.py index 56915e580..7fbff0434 100644 --- a/src/tests/dbus-tests/test_20_LVM.py +++ b/src/tests/dbus-tests/test_20_LVM.py @@ -3,6 +3,7 @@ import re import time import unittest +import six from distutils.version import LooseVersion @@ -637,7 +638,8 @@ def _remove_luks(self, device, name, close=True): device.Lock(self.no_options, dbus_interface=self.iface_prefix + '.Encrypted') except dbus.exceptions.DBusException as e: # ignore when luks is actually already locked - if not str(e).endswith('is not unlocked') and not 'No such interface' in str(e): + if not str(e).endswith('is not unlocked') and not 'No such interface' in str(e) and \ + not 'Object does not exist at path' in str(e): raise e try: @@ -645,7 +647,7 @@ def _remove_luks(self, device, name, close=True): d['erase'] = True device.Format('empty', d, dbus_interface=self.iface_prefix + '.Block') except dbus.exceptions.DBusException as e: - if not 'No such interface' in str(e): + if not 'No such interface' in str(e) and not 'Object does not exist at path' in str(e): raise e def _init_stack(self, name): @@ -663,18 +665,19 @@ def _init_stack(self, name): self.assertIsNotNone(self.pv) self.vg = self._create_vg(vgname, dbus.Array([self.pv])) + self.vg_path = self.vg.object_path self.addCleanup(self._remove_vg, self.vg, tear_down=True, ignore_removed=True) # create an LV on it - lv_path = self.vg.CreatePlainVolume(lvname, dbus.UInt64(200 * 1024**2), self.no_options, - dbus_interface=self.iface_prefix + '.VolumeGroup') - self.lv = self.bus.get_object(self.iface_prefix, lv_path) + self.lv_path = self.vg.CreatePlainVolume(lvname, dbus.UInt64(200 * 1024**2), self.no_options, + dbus_interface=self.iface_prefix + '.VolumeGroup') + self.lv = self.bus.get_object(self.iface_prefix, self.lv_path) self.assertIsNotNone(self.lv) - lv_block_path = self.lv.Activate(self.no_options, dbus_interface=self.iface_prefix + '.LogicalVolume') - self.assertIsNotNone(lv_block_path) + self.lv_block_path = self.lv.Activate(self.no_options, dbus_interface=self.iface_prefix + '.LogicalVolume') + self.assertIsNotNone(self.lv_block_path) - self.lv_block = self.get_object(lv_block_path) + self.lv_block = self.get_object(self.lv_block_path) self.assertIsNotNone(self.lv_block) # create LUKS on the LV @@ -702,10 +705,10 @@ def _init_stack(self, name): self.addCleanup(self._remove_luks, self.lv_block, vgname) self.luks_uuid = self.get_property_raw(self.lv_block, '.Block', 'IdUUID') - luks_block_path = self.get_property(self.lv_block, '.Encrypted', 'CleartextDevice') - self.luks_block = self.get_object(luks_block_path.value) - self.assertIsNotNone(self.luks_block) - self.fs_uuid = self.get_property_raw(self.luks_block, '.Block', 'IdUUID') + self.luks_block_path = self.get_property_raw(self.lv_block, '.Encrypted', 'CleartextDevice') + luks_block = self.get_object(self.luks_block_path) + self.assertIsNotNone(luks_block) + self.fs_uuid = self.get_property_raw(luks_block, '.Block', 'IdUUID') # check for present crypttab configuration item conf = self.get_property(self.lv_block, '.Block', 'Configuration') @@ -713,7 +716,7 @@ def _init_stack(self, name): self.assertEqual(conf.value[0][0], 'crypttab') # check for present fstab configuration item on a cleartext block device - conf = self.get_property(self.luks_block, '.Block', 'Configuration') + conf = self.get_property(luks_block, '.Block', 'Configuration') conf.assertTrue() self.assertEqual(conf.value[0][0], 'fstab') @@ -730,6 +733,32 @@ def _init_stack(self, name): self.assertIn(vgname, fstab) self.assertIn(self.fs_uuid, fstab) + def _check_torn_down_stack(self, name): + # check that all created objects don't exist anymore + msg = r'Object does not exist at path|No such interface' + with six.assertRaisesRegex(self, dbus.exceptions.DBusException, msg): + luks_block = self.get_object(self.luks_block_path) + self.get_property_raw(luks_block, '.Block', 'DeviceNumber') + with six.assertRaisesRegex(self, dbus.exceptions.DBusException, msg): + lv_block = self.get_object(self.lv_block_path) + self.get_property_raw(lv_block, '.Block', 'DeviceNumber') + with six.assertRaisesRegex(self, dbus.exceptions.DBusException, msg): + # the lvm2 udisks module is not fully synchronous, see https://github.com/storaged-project/udisks/pull/814 + time.sleep(2) + lv = self.get_object(self.lv_path) + self.get_property_raw(lv, '.LogicalVolume', 'Name') + with six.assertRaisesRegex(self, dbus.exceptions.DBusException, msg): + vg = self.get_object(self.vg_path) + self.get_property_raw(vg, '.VolumeGroup', 'Name') + + # check that fstab and crypttab records have been removed + crypttab = self.read_file('/etc/crypttab') + self.assertNotIn(name, crypttab) + self.assertNotIn(self.luks_uuid, crypttab) + fstab = self.read_file('/etc/fstab') + self.assertNotIn(name, fstab) + self.assertNotIn(self.fs_uuid, fstab) + @udiskstestcase.tag_test(udiskstestcase.TestTags.UNSAFE) def test_teardown_active_vg_unlocked(self): @@ -741,13 +770,7 @@ def test_teardown_active_vg_unlocked(self): self._remove_vg(self.vg, tear_down=True, ignore_removed=False) - # check that fstab and crypttab records have been removed - crypttab = self.read_file('/etc/crypttab') - self.assertNotIn(name, crypttab) - self.assertNotIn(self.luks_uuid, crypttab) - fstab = self.read_file('/etc/fstab') - self.assertNotIn(name, fstab) - self.assertNotIn(self.fs_uuid, fstab) + self._check_torn_down_stack(name) @udiskstestcase.tag_test(udiskstestcase.TestTags.UNSAFE) def test_teardown_active_vg_locked(self): @@ -760,13 +783,7 @@ def test_teardown_active_vg_locked(self): self.lv_block.Lock(self.no_options, dbus_interface=self.iface_prefix + '.Encrypted') self._remove_vg(self.vg, tear_down=True, ignore_removed=False) - # check that fstab and crypttab records have been removed - crypttab = self.read_file('/etc/crypttab') - self.assertNotIn(name, crypttab) - self.assertNotIn(self.luks_uuid, crypttab) - fstab = self.read_file('/etc/fstab') - self.assertNotIn(name, fstab) - self.assertNotIn(self.fs_uuid, fstab) + self._check_torn_down_stack(name) @udiskstestcase.tag_test(udiskstestcase.TestTags.UNSAFE) def test_teardown_inactive_vg_locked(self): @@ -780,13 +797,7 @@ def test_teardown_inactive_vg_locked(self): self.lv.Deactivate(self.no_options, dbus_interface=self.iface_prefix + '.LogicalVolume') self._remove_vg(self.vg, tear_down=True, ignore_removed=False) - # check that fstab and crypttab records have been removed - crypttab = self.read_file('/etc/crypttab') - self.assertNotIn(name, crypttab) - self.assertNotIn(self.luks_uuid, crypttab) - fstab = self.read_file('/etc/fstab') - self.assertNotIn(name, fstab) - self.assertNotIn(self.fs_uuid, fstab) + self._check_torn_down_stack(name) @udiskstestcase.tag_test(udiskstestcase.TestTags.UNSAFE) def test_reformat_inactive_vg_locked(self): @@ -812,6 +823,7 @@ def test_reformat_inactive_vg_locked(self): # check that fstab and crypttab records have been removed # TODO: these checks are the opposite - record shouldn't be present, once this is fixed + # self._check_torn_down_stack(name) crypttab = self.read_file('/etc/crypttab') self.assertIn(name, crypttab) self.assertIn(self.luks_uuid, crypttab)