Move udev rules blacklisting to utils layer

Also add udevadm_settle() to utils

Change-Id: I9bce65fa545c93b3f9b556171c9030baa3795b3e
Closes-Bug: #1477537
This commit is contained in:
Alexander Gordeev
2015-07-27 18:58:15 +03:00
parent 355c08a049
commit dee9f2eb7e
8 changed files with 307 additions and 105 deletions

View File

@@ -268,12 +268,10 @@ class TestManager(unittest2.TestCase):
mock.call('swap', '', '', '/dev/mapper/os-swap')]
self.assertEqual(mock_fu_mf_expected_calls, mock_fu_mf.call_args_list)
@mock.patch('six.moves.builtins.open')
@mock.patch.object(os, 'symlink')
@mock.patch.object(os, 'remove')
@mock.patch.object(os, 'path')
@mock.patch.object(os, 'listdir')
@mock.patch.object(utils, 'execute')
@mock.patch.object(manager.os.path, 'exists')
@mock.patch.object(manager.utils, 'blacklist_udev_rules')
@mock.patch.object(manager.utils, 'unblacklist_udev_rules')
@mock.patch.object(manager.utils, 'execute')
@mock.patch.object(mu, 'mdclean_all')
@mock.patch.object(lu, 'lvremove_all')
@mock.patch.object(lu, 'vgremove_all')
@@ -292,11 +290,9 @@ class TestManager(unittest2.TestCase):
mock_pu_spf, mock_pu_sgt, mock_mu_m, mock_lu_p,
mock_lu_v, mock_lu_l, mock_fu_mf, mock_pvr,
mock_vgr, mock_lvr, mock_mdr, mock_exec,
mock_os_ld, mock_os_p, mock_os_r, mock_os_s,
mock_open):
mock_os_ld.return_value = ['not_a_rule', 'fake.rules']
mock_os_p.exists.return_value = True
mock_unbl, mock_bl, mock_os_path):
mock_hu_lbd.return_value = test_nailgun.LIST_BLOCK_DEVICES_SAMPLE
mock_os_path.return_value = True
self.mgr.driver.partition_scheme.mds = [
objects.MD('fake_md1', 'mirror', devices=['/dev/sda1',
'/dev/sdb1']),
@@ -310,12 +306,10 @@ class TestManager(unittest2.TestCase):
['/dev/sdb3', '/dev/sdc1'])],
mock_mu_m.call_args_list)
@mock.patch('six.moves.builtins.open')
@mock.patch.object(os, 'symlink')
@mock.patch.object(os, 'remove')
@mock.patch.object(os, 'path')
@mock.patch.object(os, 'listdir')
@mock.patch.object(utils, 'execute')
@mock.patch.object(manager.os.path, 'exists')
@mock.patch.object(manager.utils, 'blacklist_udev_rules')
@mock.patch.object(manager.utils, 'unblacklist_udev_rules')
@mock.patch.object(manager.utils, 'execute')
@mock.patch.object(mu, 'mdclean_all')
@mock.patch.object(lu, 'lvremove_all')
@mock.patch.object(lu, 'vgremove_all')
@@ -334,12 +328,16 @@ class TestManager(unittest2.TestCase):
mock_pu_spf, mock_pu_sgt, mock_mu_m, mock_lu_p,
mock_lu_v, mock_lu_l, mock_fu_mf, mock_pvr,
mock_vgr, mock_lvr, mock_mdr, mock_exec,
mock_os_ld, mock_os_p, mock_os_r, mock_os_s,
mock_open):
mock_os_ld.return_value = ['not_a_rule', 'fake.rules']
mock_os_p.exists.return_value = True
mock_unbl, mock_bl, mock_os_path):
mock_os_path.return_value = True
mock_hu_lbd.return_value = test_nailgun.LIST_BLOCK_DEVICES_SAMPLE
self.mgr.do_partitioning()
mock_unbl.assert_called_once_with(udev_rules_dir='/etc/udev/rules.d',
udev_rename_substr='.renamedrule')
mock_bl.assert_called_once_with(udev_rules_dir='/etc/udev/rules.d',
udev_rules_lib_dir='/lib/udev/rules.d',
udev_empty_rule='empty_rule',
udev_rename_substr='.renamedrule')
mock_pu_ml_expected_calls = [mock.call('/dev/sda', 'gpt'),
mock.call('/dev/sdb', 'gpt'),
mock.call('/dev/sdc', 'gpt')]

View File

@@ -247,19 +247,20 @@ localhost.localdomain)
mock_mddisplay.return_value = [{'name': '/dev/md11'}]
self.assertRaises(errors.MDRemovingError, mu.mdclean_all)
@mock.patch.object(utils, 'udevadm_settle')
@mock.patch.object(utils, 'execute')
@mock.patch.object(mu, 'get_mdnames')
def test_mdremove_ok(self, mock_get_mdn, mock_exec):
def test_mdremove_ok(self, mock_get_mdn, mock_exec, mock_udev):
# should check if md exists
# should run mdadm command to remove md device
mock_get_mdn.return_value = ['/dev/md0']
expected_calls = [
mock.call('udevadm', 'settle', '--quiet', check_exit_code=[0]),
mock.call('mdadm', '--stop', '/dev/md0', check_exit_code=[0]),
mock.call('mdadm', '--remove', '/dev/md0', check_exit_code=[0, 1])
]
mu.mdremove('/dev/md0')
self.assertEqual(mock_exec.call_args_list, expected_calls)
mock_udev.assert_called_once_with()
@mock.patch.object(mu, 'get_mdnames')
def test_mdremove_notfound(self, mock_get_mdn):

View File

@@ -31,9 +31,10 @@ class TestPartitionUtils(unittest2.TestCase):
pu.wipe('/dev/fake')
mock_label.assert_called_once_with('/dev/fake')
@mock.patch.object(utils, 'udevadm_settle')
@mock.patch.object(pu, 'reread_partitions')
@mock.patch.object(utils, 'execute')
def test_make_label(self, mock_exec, mock_rerd):
def test_make_label(self, mock_exec, mock_rerd, mock_udev):
# should run parted OS command
# in order to create label on a device
mock_exec.return_value = ('out', '')
@@ -41,21 +42,22 @@ class TestPartitionUtils(unittest2.TestCase):
# gpt by default
pu.make_label('/dev/fake')
mock_exec_expected_calls = [
mock.call('udevadm', 'settle', '--quiet', check_exit_code=[0]),
mock.call('parted', '-s', '/dev/fake', 'mklabel', 'gpt',
check_exit_code=[0, 1])]
self.assertEqual(mock_exec_expected_calls, mock_exec.call_args_list)
mock_rerd.assert_called_once_with('/dev/fake', out='out')
mock_udev.assert_called_once_with()
mock_exec.reset_mock()
mock_rerd.reset_mock()
mock_udev.reset_mock()
# label is set explicitly
pu.make_label('/dev/fake', label='msdos')
mock_exec_expected_calls = [
mock.call('udevadm', 'settle', '--quiet', check_exit_code=[0]),
mock.call('parted', '-s', '/dev/fake', 'mklabel', 'msdos',
check_exit_code=[0, 1])]
self.assertEqual(mock_exec_expected_calls, mock_exec.call_args_list)
mock_udev.assert_called_once_with()
mock_rerd.assert_called_once_with('/dev/fake', out='out')
def test_make_label_wrong_label(self):
@@ -64,9 +66,10 @@ class TestPartitionUtils(unittest2.TestCase):
self.assertRaises(errors.WrongPartitionLabelError,
pu.make_label, '/dev/fake', 'wrong')
@mock.patch.object(utils, 'udevadm_settle')
@mock.patch.object(pu, 'reread_partitions')
@mock.patch.object(utils, 'execute')
def test_set_partition_flag(self, mock_exec, mock_rerd):
def test_set_partition_flag(self, mock_exec, mock_rerd, mock_udev):
# should run parted OS command
# in order to set flag on a partition
mock_exec.return_value = ('out', '')
@@ -74,20 +77,21 @@ class TestPartitionUtils(unittest2.TestCase):
# default state is 'on'
pu.set_partition_flag('/dev/fake', 1, 'boot')
mock_exec_expected_calls = [
mock.call('udevadm', 'settle', '--quiet', check_exit_code=[0]),
mock.call('parted', '-s', '/dev/fake', 'set', '1', 'boot', 'on',
check_exit_code=[0, 1])]
mock_udev.assert_called_once_with()
self.assertEqual(mock_exec_expected_calls, mock_exec.call_args_list)
mock_rerd.assert_called_once_with('/dev/fake', out='out')
mock_exec.reset_mock()
mock_rerd.reset_mock()
mock_udev.reset_mock()
# if state argument is given use it
pu.set_partition_flag('/dev/fake', 1, 'boot', state='off')
mock_exec_expected_calls = [
mock.call('udevadm', 'settle', '--quiet', check_exit_code=[0]),
mock.call('parted', '-s', '/dev/fake', 'set', '1', 'boot', 'off',
check_exit_code=[0, 1])]
mock_udev.assert_called_once_with()
self.assertEqual(mock_exec_expected_calls, mock_exec.call_args_list)
mock_rerd.assert_called_once_with('/dev/fake', out='out')
@@ -107,10 +111,11 @@ class TestPartitionUtils(unittest2.TestCase):
pu.set_partition_flag,
'/dev/fake', 1, 'boot', state='wrong')
@mock.patch.object(utils, 'udevadm_settle')
@mock.patch.object(pu, 'reread_partitions')
@mock.patch.object(pu, 'info')
@mock.patch.object(utils, 'execute')
def test_make_partition(self, mock_exec, mock_info, mock_rerd):
def test_make_partition(self, mock_exec, mock_info, mock_rerd, mock_udev):
# should run parted OS command
# in order to create new partition
mock_exec.return_value = ('out', '')
@@ -122,10 +127,10 @@ class TestPartitionUtils(unittest2.TestCase):
}
pu.make_partition('/dev/fake', 100, 200, 'primary')
mock_exec_expected_calls = [
mock.call('udevadm', 'settle', '--quiet', check_exit_code=[0]),
mock.call('parted', '-a', 'optimal', '-s', '/dev/fake', 'unit',
'MiB', 'mkpart', 'primary', '100', '200',
check_exit_code=[0, 1])]
mock_udev.assert_called_once_with()
self.assertEqual(mock_exec_expected_calls, mock_exec.call_args_list)
mock_rerd.assert_called_once_with('/dev/fake', out='out')
@@ -165,10 +170,12 @@ class TestPartitionUtils(unittest2.TestCase):
self.assertEqual(mock_info.call_args_list,
[mock.call('/dev/fake')] * 3)
@mock.patch.object(utils, 'udevadm_settle')
@mock.patch.object(pu, 'reread_partitions')
@mock.patch.object(pu, 'info')
@mock.patch.object(utils, 'execute')
def test_remove_partition(self, mock_exec, mock_info, mock_rerd):
def test_remove_partition(self, mock_exec, mock_info, mock_rerd,
mock_udev):
# should run parted OS command
# in order to remove partition
mock_exec.return_value = ('out', '')
@@ -192,9 +199,9 @@ class TestPartitionUtils(unittest2.TestCase):
}
pu.remove_partition('/dev/fake', 1)
mock_exec_expected_calls = [
mock.call('udevadm', 'settle', '--quiet', check_exit_code=[0]),
mock.call('parted', '-s', '/dev/fake', 'rm', '1',
check_exit_code=[0, 1])]
mock_udev.assert_called_once_with()
self.assertEqual(mock_exec_expected_calls, mock_exec.call_args_list)
mock_rerd.assert_called_once_with('/dev/fake', out='out')
@@ -224,17 +231,19 @@ class TestPartitionUtils(unittest2.TestCase):
self.assertRaises(errors.PartitionNotFoundError, pu.remove_partition,
'/dev/fake', 3)
@mock.patch.object(utils, 'udevadm_settle')
@mock.patch.object(utils, 'execute')
def test_set_gpt_type(self, mock_exec):
def test_set_gpt_type(self, mock_exec, mock_udev):
pu.set_gpt_type('dev', 'num', 'type')
mock_exec_expected_calls = [
mock.call('udevadm', 'settle', '--quiet', check_exit_code=[0]),
mock.call('sgdisk', '--typecode=%s:%s' % ('num', 'type'), 'dev',
check_exit_code=[0])]
self.assertEqual(mock_exec_expected_calls, mock_exec.call_args_list)
mock_udev.assert_called_once_with()
@mock.patch.object(utils, 'udevadm_settle')
@mock.patch.object(utils, 'execute')
def test_info(self, mock_exec):
def test_info(self, mock_exec, mock_udev):
mock_exec.return_value = [
'BYT;\n'
'/dev/fake:476940MiB:scsi:512:4096:msdos:ATA 1BD14;\n'
@@ -261,27 +270,29 @@ class TestPartitionUtils(unittest2.TestCase):
actual = pu.info('/dev/fake')
self.assertEqual(expected, actual)
mock_exec_expected_calls = [
mock.call('udevadm', 'settle', '--quiet', check_exit_code=[0]),
mock.call('parted', '-s', '/dev/fake', '-m', 'unit', 'MiB',
'print', 'free', check_exit_code=[0])]
self.assertEqual(mock_exec_expected_calls, mock_exec.call_args_list)
mock_udev.assert_called_once_with()
@mock.patch.object(utils, 'execute')
def test_reread_partitions_ok(self, mock_exec):
pu.reread_partitions('/dev/fake', out='')
self.assertEqual(mock_exec.call_args_list, [])
@mock.patch.object(utils, 'udevadm_settle')
@mock.patch.object(time, 'sleep')
@mock.patch.object(utils, 'execute')
def test_reread_partitions_device_busy(self, mock_exec, mock_sleep):
def test_reread_partitions_device_busy(self, mock_exec, mock_sleep,
mock_udev):
mock_exec.return_value = ('', '')
pu.reread_partitions('/dev/fake', out='_Device or resource busy_')
mock_exec_expected = [
mock.call('partprobe', '/dev/fake', check_exit_code=[0, 1]),
mock.call('udevadm', 'settle', '--quiet', check_exit_code=[0]),
]
self.assertEqual(mock_exec.call_args_list, mock_exec_expected)
mock_sleep.assert_called_once_with(2)
mock_udev.assert_called_once_with()
@mock.patch.object(utils, 'execute')
def test_reread_partitions_timeout(self, mock_exec):

View File

@@ -212,3 +212,178 @@ class ExecuteTestCase(unittest2.TestCase):
# by default files are sorted in backward direction
self.assertEqual(filename, 'file1')
mock_oslistdir.assert_called_once_with('/some/path')
@mock.patch.object(utils, 'execute')
def test_udevadm_settle(self, mock_exec):
utils.udevadm_settle()
mock_exec.assert_called_once_with('udevadm', 'settle', '--quiet',
check_exit_code=[0])
@mock.patch.object(utils, 'open', create=True, new_callable=mock.mock_open)
@mock.patch.object(utils, 'os', autospec=True)
@mock.patch.object(utils, 'execute')
@mock.patch.object(utils, 'udevadm_settle')
class TestUdevRulesBlacklisting(unittest2.TestCase):
@staticmethod
def _fake_join(path1, path2):
return '{0}/{1}'.format(path1, path2)
def test_blacklist_udev_rules_rule_exists(self, mock_udev, mock_execute,
mock_os, mock_open):
mock_os.path.join.side_effect = self._fake_join
mock_os.path.basename.return_value = 'fake_basename'
mock_os.listdir.return_value = ['fake.rules', 'fake_err.rules']
mock_os.path.isdir.return_value = False
mock_os.path.exists.return_value = True
mock_os.rename.side_effect = [None, OSError]
utils.blacklist_udev_rules('/etc/udev/rules.d', '/lib/udev/rules.d',
'.renamedrule', 'empty_rule')
self.assertEqual([mock.call('/etc/udev/rules.d/fake.rules'),
mock.call('/etc/udev/rules.d/fake_err.rules')],
mock_os.path.exists.call_args_list)
self.assertEqual([mock.call('/etc/udev/rules.d/fake.rules',
'/etc/udev/rules.d/fake.renamedrule'),
mock.call('/etc/udev/rules.d/fake_err.rules',
'/etc/udev/rules.d/fake_err.renamedrule')],
mock_os.rename.call_args_list)
self.assertEqual([mock.call('/etc/udev/rules.d', 'fake_basename'),
mock.call('/etc/udev/rules.d', 'fake.rules'),
mock.call('/etc/udev/rules.d', 'fake_err.rules')],
mock_os.path.join.call_args_list)
mock_os.symlink.assert_called_once_with(
'/etc/udev/rules.d/fake_basename',
'/etc/udev/rules.d/fake.rules')
self.assertEqual(2 * [mock.call()], mock_udev.call_args_list)
def test_blacklist_udev_rules_rule_doesnot_exist(self, mock_udev,
mock_execute, mock_os,
mock_open):
mock_os.path.join.side_effect = self._fake_join
mock_os.path.basename.return_value = 'fake_basename'
mock_os.listdir.return_value = ['fake.rules']
mock_os.path.isdir.return_value = False
mock_os.path.exists.return_value = False
utils.blacklist_udev_rules('/etc/udev/rules.d', '/lib/udev/rules.d',
'.renamedrule', 'empty_rule')
self.assertFalse(mock_os.rename.called)
mock_os.path.isdir.assert_called_once_with(
'/etc/udev/rules.d/fake.rules')
mock_os.path.exists.assert_called_once_with(
'/etc/udev/rules.d/fake.rules')
self.assertEqual([mock.call('/etc/udev/rules.d', 'fake_basename'),
mock.call('/etc/udev/rules.d', 'fake.rules')],
mock_os.path.join.call_args_list)
mock_os.symlink.assert_called_once_with(
'/etc/udev/rules.d/fake_basename',
'/etc/udev/rules.d/fake.rules')
mock_udev.assert_called_once_with()
def test_blacklist_udev_rules_not_a_rule(self, mock_udev, mock_execute,
mock_os, mock_open):
mock_os.path.join.side_effect = self._fake_join
mock_os.path.basename.return_value = 'fake_basename'
mock_os.listdir.return_value = ['not_a_rule', 'dir']
mock_os.path.isdir.side_effect = [False, True]
utils.blacklist_udev_rules('/etc/udev/rules.d', '/lib/udev/rules.d',
'.renamedrule', 'empty_rule')
self.assertFalse(mock_udev.called)
self.assertFalse(mock_os.symlink.called)
self.assertFalse(mock_os.rename.called)
self.assertFalse(mock_os.path.exists.called)
mock_os.listdir.assert_called_once_with('/lib/udev/rules.d')
self.assertEqual([mock.call('/etc/udev/rules.d/not_a_rule'),
mock.call('/etc/udev/rules.d/dir')],
mock_os.path.isdir.call_args_list)
self.assertEqual([mock.call('/etc/udev/rules.d', 'fake_basename'),
mock.call('/etc/udev/rules.d', 'not_a_rule'),
mock.call('/etc/udev/rules.d', 'dir')],
mock_os.path.join.call_args_list)
def test_blacklist_udev_rules_create_empty_rule(self, mock_udev,
mock_execute, mock_os,
mock_open):
mock_os.path.join.side_effect = self._fake_join
mock_os.path.basename.return_value = 'fake_basename'
utils.blacklist_udev_rules('/etc/udev/rules.d', '/lib/udev/rules.d',
'.renamedrule', 'empty_rule')
mock_open.assert_called_once_with('/etc/udev/rules.d/fake_basename',
'w')
file_handler = mock_open.return_value.__enter__.return_value
file_handler.write.assert_called_once_with('#\n')
mock_os.path.basename.assert_called_once_with('empty_rule')
def test_blacklist_udev_rules_execute(self, mock_udev, mock_execute,
mock_os, mock_open):
utils.blacklist_udev_rules('/etc/udev/rules.d', '/lib/udev/rules.d',
'.renamedrule', 'empty_rule')
mock_execute.assert_called_once_with(
'udevadm', 'control', '--reload-rules', check_exit_code=[0])
def test_unblacklist_udev_rules_remove(self, mock_udev, mock_execute,
mock_os, mock_open):
mock_os.path.join.side_effect = self._fake_join
mock_os.listdir.return_value = ['fake.rules', 'fake_err.rules']
mock_os.remove.side_effect = [None, OSError]
mock_os.path.isdir.side_effect = 2 * [False]
mock_os.path.islink.return_value = True
utils.unblacklist_udev_rules('/etc/udev/rules.d', '.renamedrule')
self.assertFalse(mock_os.path.exists.called)
self.assertFalse(mock_os.rename.called)
mock_os.listdir.assert_called_once_with('/etc/udev/rules.d')
expected_rules_calls = [mock.call('/etc/udev/rules.d/fake.rules'),
mock.call('/etc/udev/rules.d/fake_err.rules')]
self.assertEqual(expected_rules_calls,
mock_os.path.islink.call_args_list)
self.assertEqual(expected_rules_calls,
mock_os.remove.call_args_list)
self.assertEqual(2 * [mock.call()], mock_udev.call_args_list)
def test_unblacklist_udev_rules_executes(self, mock_udev, mock_execute,
mock_os, mock_open):
utils.unblacklist_udev_rules('/etc/udev/rules.d', '.renamedrule')
self.assertEqual([mock.call('udevadm', 'control', '--reload-rules',
check_exit_code=[0]),
mock.call('udevadm', 'trigger',
'--subsystem-match=block',
check_exit_code=[0])],
mock_execute.call_args_list)
def test_unblacklist_udev_rules_rename(self, mock_udev, mock_execute,
mock_os, mock_open):
mock_os.path.join.side_effect = self._fake_join
mock_os.listdir.return_value = ['fake.renamedrule',
'fake_err.renamedrule']
mock_os.rename.side_effect = [None, OSError]
mock_os.path.isdir.side_effect = 2 * [False]
utils.unblacklist_udev_rules('/etc/udev/rules.d', '.renamedrule')
self.assertFalse(mock_os.path.islink.called)
self.assertFalse(mock_os.remove.called)
mock_os.listdir.assert_called_once_with('/etc/udev/rules.d')
self.assertEqual([mock.call('/etc/udev/rules.d/fake.renamedrule'),
mock.call('/etc/udev/rules.d/fake_err.renamedrule')],
mock_os.path.exists.call_args_list)
self.assertEqual([mock.call('/etc/udev/rules.d/fake.renamedrule',
'/etc/udev/rules.d/fake.rules'),
mock.call('/etc/udev/rules.d/fake_err.renamedrule',
'/etc/udev/rules.d/fake_err.rules')],
mock_os.rename.call_args_list)
self.assertEqual(2 * [mock.call()], mock_udev.call_args_list)
def test_unblacklist_udev_rules_not_a_rule(self, mock_udev, mock_execute,
mock_os, mock_open):
mock_os.path.join.side_effect = self._fake_join
mock_os.listdir.return_value = ['not_a_rule', 'dir']
mock_os.path.isdir.side_effect = [False, True]
utils.unblacklist_udev_rules('/etc/udev/rules.d', '.renamedrule')
mock_os.listdir.assert_called_once_with('/etc/udev/rules.d')
self.assertEqual([mock.call('/etc/udev/rules.d', 'not_a_rule'),
mock.call('/etc/udev/rules.d', 'dir')],
mock_os.path.join.call_args_list)
self.assertEqual([mock.call('/etc/udev/rules.d/not_a_rule'),
mock.call('/etc/udev/rules.d/dir')],
mock_os.path.isdir.call_args_list)
self.assertFalse(mock_os.path.exists.called)
self.assertFalse(mock_os.remove.called)
self.assertFalse(mock_os.rename.called)
mock_udev.assert_called_once_with()