diff --git a/SOURCES/0003-gating-tests-changes.patch b/SOURCES/0003-gating-tests-changes.patch new file mode 100644 index 0000000..5ec9c06 --- /dev/null +++ b/SOURCES/0003-gating-tests-changes.patch @@ -0,0 +1,2676 @@ +From 3a513b4d7f14406d94614643327ce2d8ab35f7eb Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Thu, 14 Mar 2019 09:34:02 +0100 +Subject: [PATCH 01/10] Add a decorator for "tagging" tests + +Tests function (or classes) can be tagged with one or more tags. +This provides easier way to skip slow/unstable/dangerous tests +and/or or some subset of the tests (e.g. run only unstable tests +to check if the test is still failing). +--- + tests/utils.py | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/tests/utils.py b/tests/utils.py +index a9eb430..82b5494 100644 +--- a/tests/utils.py ++++ b/tests/utils.py +@@ -10,6 +10,7 @@ import unittest + import time + import sys + from contextlib import contextmanager ++from enum import Enum + from itertools import chain + + from gi.repository import GLib +@@ -342,6 +343,31 @@ def unstable_test(test): + return decorated_test + + ++class TestTags(Enum): ++ SLOW = 1 # slow tests ++ UNSTABLE = 2 # randomly failing tests ++ UNSAFE = 3 # tests that change system configuration ++ CORE = 4 # tests covering core functionality ++ NOSTORAGE = 5 # tests that don't work with storage ++ EXTRADEPS = 6 # tests that require special configuration and/or device to run ++ REGRESSION = 7 # regression tests ++ ++ ++def tag_test(*tags): ++ def decorator(func): ++ func.slow = TestTags.SLOW in tags ++ func.unstable = TestTags.UNSTABLE in tags ++ func.unsafe = TestTags.UNSAFE in tags ++ func.core = TestTags.CORE in tags ++ func.nostorage = TestTags.NOSTORAGE in tags ++ func.extradeps = TestTags.EXTRADEPS in tags ++ func.regression = TestTags.REGRESSION in tags ++ ++ return func ++ ++ return decorator ++ ++ + def run(cmd_string): + """ + Run the a command with file descriptors closed as lvm is trying to +-- +2.20.1 + + +From f3648fed9c98e779c9f265262a4a77a905689fe7 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Thu, 14 Mar 2019 09:37:18 +0100 +Subject: [PATCH 02/10] Use test tags for skipping tests + +This loads all individual test functions from the suite and checks +the tags to decide whether the test should be skippend or not. +We are abusing some unittest internal API to do this, but all +private functions works with Python 2 and Python 3 and general +looks like "stable enough" API. +--- + tests/run_tests.py | 130 ++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 124 insertions(+), 6 deletions(-) + +diff --git a/tests/run_tests.py b/tests/run_tests.py +index 6f74430..5301d07 100644 +--- a/tests/run_tests.py ++++ b/tests/run_tests.py +@@ -16,6 +16,82 @@ LIBDIRS = 'src/utils/.libs:src/plugins/.libs:src/plugins/fs/.libs:src/lib/.libs' + GIDIR = 'src/lib' + + ++def _get_tests_from_suite(suite, tests): ++ """ Extract tests from the test suite """ ++ # 'tests' we get from 'unittest.defaultTestLoader.discover' are "wrapped" ++ # in multiple 'unittest.suite.TestSuite' classes/lists so we need to "unpack" ++ # the indivudual test cases ++ for test in suite: ++ if isinstance(test, unittest.suite.TestSuite): ++ _get_tests_from_suite(test, tests) ++ ++ if isinstance(test, unittest.TestCase): ++ tests.append(test) ++ ++ return tests ++ ++ ++def _get_test_tags(test): ++ """ Get test tags for single test case """ ++ ++ tags = [] ++ ++ # test failed to load, usually some ImportError or something really broken ++ # in the test file, just return empty list and let it fail ++ # with python2 the loader will raise an exception directly without returning ++ # a "fake" FailedTest test case ++ if six.PY3 and isinstance(test, unittest.loader._FailedTest): ++ return tags ++ ++ test_fn = getattr(test, test._testMethodName) ++ ++ # it is possible to either tag a test funcion or the class so we need to ++ # check both for the tag ++ if getattr(test_fn, "slow", False) or getattr(test_fn.__self__, "slow", False): ++ tags.append(TestTags.SLOW) ++ if getattr(test_fn, "unstable", False) or getattr(test_fn.__self__, "unstable", False): ++ tags.append(TestTags.UNSTABLE) ++ if getattr(test_fn, "unsafe", False) or getattr(test_fn.__self__, "unsafe", False): ++ tags.append(TestTags.UNSAFE) ++ if getattr(test_fn, "core", False) or getattr(test_fn.__self__, "core", False): ++ tags.append(TestTags.CORE) ++ if getattr(test_fn, "nostorage", False) or getattr(test_fn.__self__, "nostorage", False): ++ tags.append(TestTags.NOSTORAGE) ++ if getattr(test_fn, "extradeps", False) or getattr(test_fn.__self__, "extradeps", False): ++ tags.append(TestTags.EXTRADEPS) ++ if getattr(test_fn, "regression", False) or getattr(test_fn.__self__, "regression", False): ++ tags.append(TestTags.REGRESSION) ++ ++ return tags ++ ++ ++def _print_skip_message(test, skip_tag): ++ ++ # test.id() looks like 'crypto_test.CryptoTestResize.test_luks2_resize' ++ # and we want to print 'test_luks2_resize (crypto_test.CryptoTestResize)' ++ test_desc = test.id().split(".") ++ test_name = test_desc[-1] ++ test_module = ".".join(test_desc[:-1]) ++ ++ if skip_tag == TestTags.SLOW: ++ reason = "skipping slow tests" ++ elif skip_tag == TestTags.UNSTABLE: ++ reason = "skipping unstable tests" ++ elif skip_tag == TestTags.UNSAFE: ++ reason = "skipping test that modifies system configuration" ++ elif skip_tag == TestTags.EXTRADEPS: ++ reason = "skipping test that requires special configuration" ++ elif skip_tag == TestTags.CORE: ++ reason = "skipping non-core test" ++ else: ++ reason = "unknown reason" # just to be sure there is some default value ++ ++ if test._testMethodDoc: ++ print("%s (%s)\n%s ... skipped '%s'" % (test_name, test_module, test._testMethodDoc, reason)) ++ else: ++ print("%s (%s) ... skipped '%s'" % (test_name, test_module, reason)) ++ ++ + if __name__ == '__main__': + + testdir = os.path.abspath(os.path.dirname(__file__)) +@@ -45,6 +121,9 @@ if __name__ == '__main__': + argparser.add_argument('-j', '--jenkins', dest='jenkins', + help='run also tests that should run only in a CI environment', + action='store_true') ++ argparser.add_argument('-c', '--core', dest='core', ++ help='run tests that cover basic functionality of the library and regression tests', ++ action='store_true') + argparser.add_argument('-s', '--stop', dest='stop', + help='stop executing after first failed test', + action='store_true') +@@ -57,21 +136,60 @@ if __name__ == '__main__': + if args.jenkins: + os.environ['JENKINS_HOME'] = '' + ++ # read the environmental variables for backwards compatibility ++ if 'JENKINS_HOME' in os.environ: ++ args.jenkins = True ++ if 'SKIP_SLOW' in os.environ: ++ args.fast = True ++ if 'FEELINGLUCKY' in os.environ: ++ args.lucky = True ++ + sys.path.append(testdir) + sys.path.append(projdir) + sys.path.append(os.path.join(projdir, 'src/python')) + + start_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + ++ loader = unittest.defaultTestLoader + suite = unittest.TestSuite() ++ + if args.testname: +- loader = unittest.TestLoader() +- tests = loader.loadTestsFromNames(args.testname) +- suite.addTests(tests) ++ test_cases = loader.loadTestsFromNames(args.testname) + else: +- loader = unittest.TestLoader() +- tests = loader.discover(start_dir=testdir, pattern='*_test*.py') +- suite.addTests(tests) ++ test_cases = loader.discover(start_dir=testdir, pattern='*_test*.py') ++ ++ # extract list of test classes so we can check/run them manually one by one ++ tests = [] ++ tests = _get_tests_from_suite(test_cases, tests) ++ ++ # for some reason overrides_hack will fail if we import this at the start ++ # of the file ++ from utils import TestTags ++ ++ for test in tests: ++ # get tags and (possibly) skip the test ++ tags = _get_test_tags(test) ++ ++ if TestTags.SLOW in tags and args.fast: ++ _print_skip_message(test, TestTags.SLOW) ++ continue ++ if TestTags.UNSTABLE in tags and not args.lucky: ++ _print_skip_message(test, TestTags.UNSTABLE) ++ continue ++ if TestTags.UNSAFE in tags or TestTags.EXTRADEPS in tags and not args.jenkins: ++ _print_skip_message(test, TestTags.UNSAFE) ++ continue ++ if TestTags.EXTRADEPS in tags and not args.jenkins: ++ _print_skip_message(test, TestTags.EXTRADEPS) ++ continue ++ ++ if args.core and TestTags.CORE not in tags and TestTags.REGRESSION not in tags: ++ _print_skip_message(test, TestTags.CORE) ++ continue ++ ++ # finally add the test to the suite ++ suite.addTest(test) ++ + result = unittest.TextTestRunner(verbosity=2, failfast=args.stop).run(suite) + + # dump cropped journal to log file +-- +2.20.1 + + +From f4dd0bfff61d117096c1802ab793b3ab9a31dae3 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Thu, 14 Mar 2019 09:43:37 +0100 +Subject: [PATCH 03/10] Use the new test tags in tests + +--- + tests/btrfs_test.py | 14 ++++++-- + tests/crypto_test.py | 73 +++++++++++++++++++++-------------------- + tests/dm_test.py | 5 ++- + tests/fs_test.py | 18 +++++++--- + tests/kbd_test.py | 24 +++++++------- + tests/library_test.py | 13 +++++--- + tests/loop_test.py | 5 ++- + tests/lvm_dbus_tests.py | 44 ++++++++++++++++--------- + tests/lvm_test.py | 44 ++++++++++++++++--------- + tests/mdraid_test.py | 38 ++++++++++++--------- + tests/mpath_test.py | 5 ++- + tests/nvdimm_test.py | 9 +++-- + tests/overrides_test.py | 5 +++ + tests/part_test.py | 11 ++++++- + tests/s390_test.py | 6 +++- + tests/swap_test.py | 7 +++- + tests/utils_test.py | 10 ++++-- + tests/vdo_test.py | 13 ++++++-- + 18 files changed, 227 insertions(+), 117 deletions(-) + +diff --git a/tests/btrfs_test.py b/tests/btrfs_test.py +index ac1594f..eab25db 100644 +--- a/tests/btrfs_test.py ++++ b/tests/btrfs_test.py +@@ -10,7 +10,7 @@ from distutils.version import LooseVersion + from distutils.spawn import find_executable + + import overrides_hack +-from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, skip_on, mount, umount, run_command ++from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, mount, umount, run_command, TestTags, tag_test + from gi.repository import GLib, BlockDev + + TEST_MNT = "/tmp/libblockdev_test_mnt" +@@ -74,6 +74,7 @@ class BtrfsTestCase(unittest.TestCase): + return LooseVersion(m.groups()[0]) + + class BtrfsTestCreateQuerySimple(BtrfsTestCase): ++ @tag_test(TestTags.CORE) + def test_create_and_query_volume(self): + """Verify that btrfs volume creation and querying works""" + +@@ -180,6 +181,7 @@ class BtrfsTestAddRemoveDevice(BtrfsTestCase): + self.assertEqual(len(devs), 1) + + class BtrfsTestCreateDeleteSubvolume(BtrfsTestCase): ++ @tag_test(TestTags.CORE) + def test_create_delete_subvolume(self): + """Verify that it is possible to create/delete subvolume""" + +@@ -306,6 +308,7 @@ class BtrfsTestSetDefaultSubvolumeID(BtrfsTestCase): + self.assertEqual(ret, 5) + + class BtrfsTestListDevices(BtrfsTestCase): ++ @tag_test(TestTags.CORE) + def test_list_devices(self): + """Verify that it is possible to get info about devices""" + +@@ -324,6 +327,7 @@ class BtrfsTestListDevices(BtrfsTestCase): + self.assertTrue(devs[1].used >= 0) + + class BtrfsTestListSubvolumes(BtrfsTestCase): ++ @tag_test(TestTags.CORE) + def test_list_subvolumes(self): + """Verify that it is possible to get info about subvolumes""" + +@@ -344,6 +348,7 @@ class BtrfsTestListSubvolumes(BtrfsTestCase): + self.assertEqual(subvols[0].path, "subvol1") + + class BtrfsTestFilesystemInfo(BtrfsTestCase): ++ @tag_test(TestTags.CORE) + def test_filesystem_info(self): + """Verify that it is possible to get filesystem info""" + +@@ -376,6 +381,7 @@ class BtrfsTestFilesystemInfoNoLabel(BtrfsTestCase): + self.assertTrue(info.used >= 0) + + class BtrfsTestMkfs(BtrfsTestCase): ++ @tag_test(TestTags.CORE) + def test_mkfs(self): + """Verify that it is possible to create a btrfs filesystem""" + +@@ -489,7 +495,6 @@ class BtrfsTooSmallTestCase (BtrfsTestCase): + pass + os.unlink(self.dev_file2) + +- @skip_on("fedora", "25", reason="Min sizes for Btrfs are different on F25") + def test_create_too_small(self): + """Verify that an attempt to create BTRFS on a too small device fails""" + +@@ -527,7 +532,6 @@ class BtrfsJustBigEnoughTestCase (BtrfsTestCase): + pass + os.unlink(self.dev_file2) + +- @skip_on("fedora", "25", reason="Min sizes for Btrfs are different on F25") + def test_create_just_enough(self): + """Verify that creating BTRFS on a just big enough devices works""" + +@@ -541,6 +545,7 @@ class FakeBtrfsUtilsTestCase(BtrfsTestCase): + def setUp(self): + pass + ++ @tag_test(TestTags.NOSTORAGE) + def test_list_subvols_weird_docker_data(self): + """Verify that list_subvolumes works as expected on weird data from one Docker use case""" + +@@ -562,6 +567,7 @@ class BTRFSUnloadTest(BtrfsTestCase): + # tests + self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_low_version(self): + """Verify that checking the minimum BTRFS version works as expected""" + +@@ -579,6 +585,7 @@ class BTRFSUnloadTest(BtrfsTestCase): + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + self.assertIn("btrfs", BlockDev.get_available_plugin_names()) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_new_version_format(self): + """Verify that checking the minimum BTRFS version works as expected with the new format""" + +@@ -594,6 +601,7 @@ class BTRFSUnloadTest(BtrfsTestCase): + BlockDev.reinit(self.requested_plugins, True, None) + self.assertIn("btrfs", BlockDev.get_available_plugin_names()) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_no_btrfs(self): + """Verify that checking btrfs tool availability works as expected""" + +diff --git a/tests/crypto_test.py b/tests/crypto_test.py +index 7320e74..b062505 100644 +--- a/tests/crypto_test.py ++++ b/tests/crypto_test.py +@@ -9,7 +9,7 @@ import locale + import re + import tarfile + +-from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, skip_on, get_avail_locales, requires_locales, run_command, read_file ++from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, skip_on, get_avail_locales, requires_locales, run_command, read_file, TestTags, tag_test + from gi.repository import BlockDev, GLib + + PASSWD = "myshinylittlepassword" +@@ -92,6 +92,7 @@ class CryptoTestGenerateBackupPassphrase(CryptoTestCase): + # we don't need block devices for this test + pass + ++ @tag_test(TestTags.NOSTORAGE) + def test_generate_backup_passhprase(self): + """Verify that backup passphrase generation works as expected""" + +@@ -101,7 +102,7 @@ class CryptoTestGenerateBackupPassphrase(CryptoTestCase): + six.assertRegex(self, bp, exp) + + class CryptoTestFormat(CryptoTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW, TestTags.CORE) + def test_luks_format(self): + """Verify that formating device as LUKS works""" + +@@ -121,7 +122,7 @@ class CryptoTestFormat(CryptoTestCase): + succ = BlockDev.crypto_luks_format_blob(self.loop_dev, "aes-cbc-essiv:sha256", 0, [ord(c) for c in PASSWD], 0) + self.assertTrue(succ) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW, TestTags.CORE) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_format(self): + """Verify that formating device as LUKS 2 works""" +@@ -222,7 +223,7 @@ class CryptoTestFormat(CryptoTestCase): + self.assertEqual(int(m.group(1)), 5) + + class CryptoTestResize(CryptoTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_luks_resize(self): + """Verify that resizing LUKS device works""" + +@@ -244,7 +245,7 @@ class CryptoTestResize(CryptoTestCase): + succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") + self.assertTrue(succ) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_resize(self): + """Verify that resizing LUKS 2 device works""" +@@ -304,11 +305,11 @@ class CryptoTestOpenClose(CryptoTestCase): + succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") + self.assertTrue(succ) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW, TestTags.CORE) + def test_luks_open_close(self): + self._luks_open_close(self._luks_format) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW, TestTags.CORE) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_open_close(self): + self._luks_open_close(self._luks2_format) +@@ -329,11 +330,11 @@ class CryptoTestAddKey(CryptoTestCase): + succ = BlockDev.crypto_luks_add_key_blob(self.loop_dev, [ord(c) for c in PASSWD2], [ord(c) for c in PASSWD3]) + self.assertTrue(succ) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_luks_add_key(self): + self._add_key(self._luks_format) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_add_key(self): + self._add_key(self._luks2_format) +@@ -360,11 +361,11 @@ class CryptoTestRemoveKey(CryptoTestCase): + succ = BlockDev.crypto_luks_remove_key_blob(self.loop_dev, [ord(c) for c in PASSWD2]) + self.assertTrue(succ) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_luks_remove_key(self): + self._remove_key(self._luks_format) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_remove_key(self): + self._remove_key(self._luks2_format) +@@ -380,7 +381,7 @@ class CryptoTestErrorLocale(CryptoTestCase): + if self._orig_loc: + locale.setlocale(locale.LC_ALL, self._orig_loc) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @requires_locales({"cs_CZ.UTF-8"}) + def test_error_locale_key(self): + """Verify that the error msg is locale agnostic""" +@@ -407,11 +408,11 @@ class CryptoTestChangeKey(CryptoTestCase): + succ = BlockDev.crypto_luks_change_key_blob(self.loop_dev, [ord(c) for c in PASSWD2], [ord(c) for c in PASSWD3]) + self.assertTrue(succ) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_luks_change_key(self): + self._change_key(self._luks_format) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_change_key(self): + self._change_key(self._luks2_format) +@@ -432,11 +433,11 @@ class CryptoTestIsLuks(CryptoTestCase): + is_luks = BlockDev.crypto_device_is_luks(self.loop_dev2) + self.assertFalse(is_luks) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_is_luks(self): + self._is_luks(self._luks_format) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_is_luks2(self): + self._is_luks(self._luks2_format) +@@ -468,11 +469,11 @@ class CryptoTestLuksStatus(CryptoTestCase): + with self.assertRaises(GLib.GError): + BlockDev.crypto_luks_status("libblockdevTestLUKS") + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_luks_status(self): + self._luks_status(self._luks_format) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_status(self): + self._luks_status(self._luks2_format) +@@ -490,18 +491,18 @@ class CryptoTestGetUUID(CryptoTestCase): + with self.assertRaises(GLib.GError): + uuid = BlockDev.crypto_luks_uuid(self.loop_dev2) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_luks_get_uuid(self): + self._get_uuid(self._luks_format) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_get_uuid(self): + self._get_uuid(self._luks2_format) + + class CryptoTestGetMetadataSize(CryptoTestCase): + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_get_metadata_size(self): + """Verify that getting LUKS 2 device metadata size works""" +@@ -521,7 +522,7 @@ class CryptoTestGetMetadataSize(CryptoTestCase): + offset = int(m.group(1)) + self.assertEquals(meta_size, offset, "LUKS 2 metadata sizes differ") + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_luks_get_metadata_size(self): + """Verify that getting LUKS device metadata size works""" + +@@ -570,11 +571,11 @@ class CryptoTestLuksOpenRW(CryptoTestCase): + succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") + self.assertTrue(succ) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_luks_open_rw(self): + self._luks_open_rw(self._luks_format) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_open_rw(self): + self._luks_open_rw(self._luks2_format) +@@ -609,7 +610,7 @@ class CryptoTestEscrow(CryptoTestCase): + '-a', '-o', self.public_cert]) + self.addCleanup(os.unlink, self.public_cert) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @skip_on(("centos", "enterprise_linux"), "7", reason="volume_key asks for password in non-interactive mode on this release") + @skip_on("debian", reason="volume_key asks for password in non-interactive mode on this release") + def test_escrow_packet(self): +@@ -654,7 +655,7 @@ class CryptoTestEscrow(CryptoTestCase): + succ = BlockDev.crypto_luks_open(self.loop_dev, 'libblockdevTestLUKS', PASSWD3, None) + self.assertTrue(succ) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_backup_passphrase(self): + """Verify that a backup passphrase can be created for a device""" + succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) +@@ -735,12 +736,12 @@ class CryptoTestSuspendResume(CryptoTestCase): + succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") + self.assertTrue(succ) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_luks_suspend_resume(self): + """Verify that suspending/resuming LUKS device works""" + self._luks_suspend_resume(self._luks_format) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_suspend_resume(self): + """Verify that suspending/resuming LUKS 2 device works""" +@@ -781,12 +782,12 @@ class CryptoTestKillSlot(CryptoTestCase): + succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") + self.assertTrue(succ) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_luks_kill_slot(self): + """Verify that killing a key slot on LUKS device works""" + self._luks_kill_slot(self._luks_format) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_kill_slot(self): + """Verify that killing a key slot on LUKS 2 device works""" +@@ -836,19 +837,19 @@ class CryptoTestHeaderBackupRestore(CryptoTestCase): + succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") + self.assertTrue(succ) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_luks_header_backup_restore(self): + """Verify that header backup/restore with LUKS works""" + self._luks_header_backup_restore(self._luks_format) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_header_backup_restore(self): + """Verify that header backup/restore with LUKS2 works""" + self._luks_header_backup_restore(self._luks2_format) + + class CryptoTestInfo(CryptoTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW, TestTags.CORE) + def test_luks_format(self): + """Verify that we can get information about a LUKS device""" + +@@ -872,7 +873,7 @@ class CryptoTestInfo(CryptoTestCase): + succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") + self.assertTrue(succ) + +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW, TestTags.CORE) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_format(self): + """Verify that we can get information about a LUKS 2 device""" +@@ -903,7 +904,7 @@ class CryptoTestInfo(CryptoTestCase): + self.assertTrue(succ) + + class CryptoTestIntegrity(CryptoTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + @unittest.skipUnless(HAVE_LUKS2, "LUKS 2 not supported") + def test_luks2_integrity(self): + """Verify that we can get create a LUKS 2 device with integrity""" +@@ -983,6 +984,7 @@ class CryptoTestTrueCrypt(CryptoTestCase): + if not succ: + raise RuntimeError("Failed to tear down loop device used for testing") + ++ @tag_test(TestTags.NOSTORAGE) + def test_truecrypt_open_close(self): + """Verify that opening/closing TrueCrypt device works""" + +@@ -1003,6 +1005,7 @@ class CryptoTestTrueCrypt(CryptoTestCase): + self.assertTrue(succ) + self.assertFalse(os.path.exists("/dev/mapper/libblockdevTestTC")) + ++ @tag_test(TestTags.NOSTORAGE) + def test_veracrypt_open_close(self): + """Verify that opening/closing VeraCrypt device works""" + +diff --git a/tests/dm_test.py b/tests/dm_test.py +index 0dd1861..936e305 100644 +--- a/tests/dm_test.py ++++ b/tests/dm_test.py +@@ -2,7 +2,7 @@ import unittest + import os + import overrides_hack + +-from utils import run, create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path ++from utils import run, create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, TestTags, tag_test + from gi.repository import BlockDev, GLib + + +@@ -65,6 +65,7 @@ class DevMapperGetSubsystemFromName(DevMapperTestCase): + self.assertEqual(subsystem, "CRYPT") + + class DevMapperCreateRemoveLinear(DevMapperTestCase): ++ @tag_test(TestTags.CORE) + def test_create_remove_linear(self): + """Verify that it is possible to create new linear mapping and remove it""" + +@@ -120,6 +121,7 @@ class DMUnloadTest(DevMapperTestCase): + # tests + self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_low_version(self): + """Verify that checking the minimum dmsetup version works as expected""" + +@@ -137,6 +139,7 @@ class DMUnloadTest(DevMapperTestCase): + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + self.assertIn("dm", BlockDev.get_available_plugin_names()) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_no_dm(self): + """Verify that checking dmsetup tool availability works as expected""" + +diff --git a/tests/fs_test.py b/tests/fs_test.py +index d3f3353..adcf312 100644 +--- a/tests/fs_test.py ++++ b/tests/fs_test.py +@@ -5,7 +5,7 @@ import subprocess + import tempfile + from contextlib import contextmanager + import utils +-from utils import run, create_sparse_tempfile, mount, umount, unstable_test ++from utils import run, create_sparse_tempfile, mount, umount, TestTags, tag_test + import six + import overrides_hack + +@@ -97,6 +97,7 @@ class FSTestCase(unittest.TestCase): + self.fail("Failed to set %s read-write" % device) + + class TestGenericWipe(FSTestCase): ++ @tag_test(TestTags.CORE) + def test_generic_wipe(self): + """Verify that generic signature wipe works as expected""" + +@@ -210,16 +211,19 @@ class ExtTestMkfs(FSTestCase): + + BlockDev.fs_wipe(self.loop_dev, True) + ++ @tag_test(TestTags.CORE) + def test_ext2_mkfs(self): + """Verify that it is possible to create a new ext2 file system""" + self._test_ext_mkfs(mkfs_function=BlockDev.fs_ext2_mkfs, + ext_version="ext2") + ++ @tag_test(TestTags.CORE) + def test_ext3_mkfs(self): + """Verify that it is possible to create a new ext3 file system""" + self._test_ext_mkfs(mkfs_function=BlockDev.fs_ext3_mkfs, + ext_version="ext3") + ++ @tag_test(TestTags.CORE) + def test_ext4_mkfs(self): + """Verify that it is possible to create a new ext4 file system""" + self._test_ext_mkfs(mkfs_function=BlockDev.fs_ext4_mkfs, +@@ -385,16 +389,19 @@ class ExtGetInfo(FSTestCase): + self.assertTrue(fi.uuid) + self.assertTrue(fi.state, "clean") + ++ @tag_test(TestTags.CORE) + def test_ext2_get_info(self): + """Verify that it is possible to get info about an ext2 file system""" + self._test_ext_get_info(mkfs_function=BlockDev.fs_ext2_mkfs, + info_function=BlockDev.fs_ext2_get_info) + ++ @tag_test(TestTags.CORE) + def test_ext3_get_info(self): + """Verify that it is possible to get info about an ext3 file system""" + self._test_ext_get_info(mkfs_function=BlockDev.fs_ext3_mkfs, + info_function=BlockDev.fs_ext3_get_info) + ++ @tag_test(TestTags.CORE) + def test_ext4_get_info(self): + """Verify that it is possible to get info about an ext4 file system""" + self._test_ext_get_info(mkfs_function=BlockDev.fs_ext4_mkfs, +@@ -511,6 +518,7 @@ class ExtResize(FSTestCase): + resize_function=BlockDev.fs_ext4_resize) + + class XfsTestMkfs(FSTestCase): ++ @tag_test(TestTags.CORE) + def test_xfs_mkfs(self): + """Verify that it is possible to create a new xfs file system""" + +@@ -597,6 +605,7 @@ class XfsTestRepair(FSTestCase): + self.assertTrue(succ) + + class XfsGetInfo(FSTestCase): ++ @tag_test(TestTags.CORE) + def test_xfs_get_info(self): + """Verify that it is possible to get info about an xfs file system""" + +@@ -970,6 +979,7 @@ class MountTest(FSTestCase): + if ret != 0: + self.fail("Failed to remove user user '%s': %s" % (self.username, err)) + ++ @tag_test(TestTags.CORE) + def test_mount(self): + """ Test basic mounting and unmounting """ + +@@ -1053,7 +1063,7 @@ class MountTest(FSTestCase): + BlockDev.fs_mount(loop_dev, tmp_dir, None, "rw", None) + self.assertFalse(os.path.ismount(tmp_dir)) + +- @unittest.skipUnless("JENKINS_HOME" in os.environ, "skipping test that modifies system configuration") ++ @tag_test(TestTags.UNSAFE) + def test_mount_fstab(self): + """ Test mounting and unmounting devices in /etc/fstab """ + # this test will change /etc/fstab, we want to revert the changes when it finishes +@@ -1088,7 +1098,7 @@ class MountTest(FSTestCase): + self.assertTrue(succ) + self.assertFalse(os.path.ismount(tmp)) + +- @unittest.skipUnless("JENKINS_HOME" in os.environ, "skipping test that modifies system configuration") ++ @tag_test(TestTags.UNSAFE) + def test_mount_fstab_user(self): + """ Test mounting and unmounting devices in /etc/fstab as non-root user """ + # this test will change /etc/fstab, we want to revert the changes when it finishes +@@ -1360,7 +1370,7 @@ class GenericResize(FSTestCase): + fs_info_func=info_prepare, + info_size_func=expected_size) + +- @unstable_test ++ @tag_test(TestTags.UNSTABLE) + def test_vfat_generic_resize(self): + """Test generic resize function with a vfat file system""" + self._test_generic_resize(mkfs_function=BlockDev.fs_vfat_mkfs) +diff --git a/tests/kbd_test.py b/tests/kbd_test.py +index b6cfb3c..5e872c4 100644 +--- a/tests/kbd_test.py ++++ b/tests/kbd_test.py +@@ -4,7 +4,7 @@ import re + import time + from contextlib import contextmanager + from distutils.version import LooseVersion +-from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, wipe_all, fake_path, read_file, skip_on, unstable_test ++from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, wipe_all, fake_path, read_file, skip_on, TestTags, tag_test + from bytesize import bytesize + import overrides_hack + +@@ -66,7 +66,7 @@ class KbdZRAMTestCase(unittest.TestCase): + + class KbdZRAMDevicesTestCase(KbdZRAMTestCase): + @unittest.skipUnless(_can_load_zram(), "cannot load the 'zram' module") +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_create_destroy_devices(self): + # the easiest case + with _track_module_load(self, "zram", "_loaded_zram_module"): +@@ -113,7 +113,7 @@ class KbdZRAMDevicesTestCase(KbdZRAMTestCase): + time.sleep(1) + + @unittest.skipUnless(_can_load_zram(), "cannot load the 'zram' module") +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_zram_add_remove_device(self): + """Verify that it is possible to add and remove a zram device""" + +@@ -268,6 +268,7 @@ class KbdBcacheNodevTestCase(unittest.TestCase): + BlockDev.reinit(cls.requested_plugins, True, None) + + @skip_on(("centos", "enterprise_linux")) ++ @tag_test(TestTags.NOSTORAGE) + def test_bcache_mode_str_bijection(self): + """Verify that it's possible to transform between cache modes and their string representations""" + +@@ -333,7 +334,7 @@ class KbdBcacheTestCase(unittest.TestCase): + + class KbdTestBcacheCreate(KbdBcacheTestCase): + @skip_on(("centos", "enterprise_linux")) +- @unstable_test ++ @tag_test(TestTags.UNSTABLE) + def test_bcache_create_destroy(self): + """Verify that it's possible to create and destroy a bcache device""" + +@@ -352,7 +353,7 @@ class KbdTestBcacheCreate(KbdBcacheTestCase): + wipe_all(self.loop_dev, self.loop_dev2) + + @skip_on(("centos", "enterprise_linux")) +- @unstable_test ++ @tag_test(TestTags.UNSTABLE) + def test_bcache_create_destroy_full_path(self): + """Verify that it's possible to create and destroy a bcache device with full device path""" + +@@ -372,7 +373,7 @@ class KbdTestBcacheCreate(KbdBcacheTestCase): + + class KbdTestBcacheAttachDetach(KbdBcacheTestCase): + @skip_on(("centos", "enterprise_linux")) +- @unstable_test ++ @tag_test(TestTags.UNSTABLE) + def test_bcache_attach_detach(self): + """Verify that it's possible to detach/attach a cache from/to a bcache device""" + +@@ -398,7 +399,7 @@ class KbdTestBcacheAttachDetach(KbdBcacheTestCase): + wipe_all(self.loop_dev, self.loop_dev2) + + @skip_on(("centos", "enterprise_linux")) +- @unstable_test ++ @tag_test(TestTags.UNSTABLE) + def test_bcache_attach_detach_full_path(self): + """Verify that it's possible to detach/attach a cache from/to a bcache device with full device path""" + +@@ -424,7 +425,7 @@ class KbdTestBcacheAttachDetach(KbdBcacheTestCase): + wipe_all(self.loop_dev, self.loop_dev2) + + @skip_on(("centos", "enterprise_linux")) +- @unstable_test ++ @tag_test(TestTags.UNSTABLE) + def test_bcache_detach_destroy(self): + """Verify that it's possible to destroy a bcache device with no cache attached""" + +@@ -448,7 +449,7 @@ class KbdTestBcacheAttachDetach(KbdBcacheTestCase): + + class KbdTestBcacheGetSetMode(KbdBcacheTestCase): + @skip_on(("centos", "enterprise_linux")) +- @unstable_test ++ @tag_test(TestTags.UNSTABLE) + def test_bcache_get_set_mode(self): + """Verify that it is possible to get and set Bcache mode""" + +@@ -505,7 +506,7 @@ class KbdTestBcacheStatusTest(KbdBcacheTestCase): + return sum(int(read_file(os.path.realpath(c) + '/../size')) for c in caches) + + @skip_on(("centos", "enterprise_linux")) +- @unstable_test ++ @tag_test(TestTags.UNSTABLE) + def test_bcache_status(self): + succ, dev = BlockDev.kbd_bcache_create(self.loop_dev, self.loop_dev2, None) + self.assertTrue(succ) +@@ -538,7 +539,7 @@ class KbdTestBcacheStatusTest(KbdBcacheTestCase): + + class KbdTestBcacheBackingCacheDevTest(KbdBcacheTestCase): + @skip_on(("centos", "enterprise_linux")) +- @unstable_test ++ @tag_test(TestTags.UNSTABLE) + def test_bcache_backing_cache_dev(self): + """Verify that is is possible to get the backing and cache devices for a Bcache""" + +@@ -566,6 +567,7 @@ class KbdUnloadTest(KbdBcacheTestCase): + self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None) + + @skip_on(("centos", "enterprise_linux")) ++ @tag_test(TestTags.NOSTORAGE) + def test_check_no_bcache_progs(self): + """Verify that checking the availability of make-bcache works as expected""" + +diff --git a/tests/library_test.py b/tests/library_test.py +index 159031a..fa33b53 100644 +--- a/tests/library_test.py ++++ b/tests/library_test.py +@@ -2,7 +2,7 @@ import os + import unittest + import re + import overrides_hack +-from utils import fake_path ++from utils import fake_path, TestTags, tag_test + + from gi.repository import GLib, BlockDev + +@@ -40,7 +40,7 @@ class LibraryOpsTestCase(unittest.TestCase): + BlockDev.reinit(self.requested_plugins, True, None) + + # recompiles the LVM plugin +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW, TestTags.CORE) + def test_reload(self): + """Verify that reloading plugins works as expected""" + +@@ -72,7 +72,7 @@ class LibraryOpsTestCase(unittest.TestCase): + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + + # recompiles the LVM plugin +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_force_plugin(self): + """Verify that forcing plugin to be used works as expected""" + +@@ -118,7 +118,7 @@ class LibraryOpsTestCase(unittest.TestCase): + self.assertEqual(BlockDev.lvm_get_max_lv_size(), orig_max_size) + + # recompiles the LVM plugin +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_plugin_priority(self): + """Verify that preferring plugin to be used works as expected""" + +@@ -181,7 +181,7 @@ class LibraryOpsTestCase(unittest.TestCase): + os.system ("rm -f src/plugins/.libs/libbd_lvm2.so") + + # recompiles the LVM plugin +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_plugin_fallback(self): + """Verify that fallback when loading plugins works as expected""" + +@@ -250,6 +250,7 @@ class LibraryOpsTestCase(unittest.TestCase): + + self.log += msg + "\n" + ++ @tag_test(TestTags.CORE) + def test_logging_setup(self): + """Verify that setting up logging works as expected""" + +@@ -280,6 +281,7 @@ class LibraryOpsTestCase(unittest.TestCase): + self.assertIn("stderr[%s]:" % task_id2, self.log) + self.assertIn("...done [%s] (exit code: 0)" % task_id2, self.log) + ++ @tag_test(TestTags.CORE) + def test_require_plugins(self): + """Verify that loading only required plugins works as expected""" + +@@ -290,6 +292,7 @@ class LibraryOpsTestCase(unittest.TestCase): + self.assertEqual(BlockDev.get_available_plugin_names(), ["swap"]) + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + ++ @tag_test(TestTags.CORE) + def test_not_implemented(self): + """Verify that unloaded/unimplemented functions report errors""" + +diff --git a/tests/loop_test.py b/tests/loop_test.py +index 9e9d9ac..5aaf928 100644 +--- a/tests/loop_test.py ++++ b/tests/loop_test.py +@@ -3,7 +3,7 @@ import unittest + import time + import overrides_hack + +-from utils import create_sparse_tempfile ++from utils import create_sparse_tempfile, TestTags, tag_test + from gi.repository import BlockDev, GLib + + +@@ -31,6 +31,7 @@ class LoopTestCase(unittest.TestCase): + os.unlink(self.dev_file) + + class LoopTestSetupBasic(LoopTestCase): ++ @tag_test(TestTags.CORE) + def testLoop_setup_teardown_basic(self): + """Verify that basic loop_setup and loop_teardown work as expected""" + +@@ -97,6 +98,7 @@ class LoopTestSetupReadOnly(LoopTestCase): + # XXX: any sane way how to test part_probe=True/False? + + class LoopTestGetLoopName(LoopTestCase): ++ @tag_test(TestTags.CORE) + def testLoop_get_loop_name(self): + """Verify that loop_get_loop_name works as expected""" + +@@ -107,6 +109,7 @@ class LoopTestGetLoopName(LoopTestCase): + self.assertEqual(ret_loop, self.loop) + + class LoopTestGetBackingFile(LoopTestCase): ++ @tag_test(TestTags.CORE) + def testLoop_get_backing_file(self): + """Verify that loop_get_backing_file works as expected""" + +diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py +index 7c3b4cc..625a392 100644 +--- a/tests/lvm_dbus_tests.py ++++ b/tests/lvm_dbus_tests.py +@@ -8,7 +8,7 @@ import re + import subprocess + from itertools import chain + +-from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, skip_on, run_command ++from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, run_command, TestTags, tag_test + from gi.repository import BlockDev, GLib + + import dbus +@@ -38,6 +38,7 @@ class LvmNoDevTestCase(LVMTestCase): + super(LvmNoDevTestCase, self).__init__(*args, **kwargs) + self._log = "" + ++ @tag_test(TestTags.NOSTORAGE) + def test_is_supported_pe_size(self): + """Verify that lvm_is_supported_pe_size works as expected""" + +@@ -53,12 +54,14 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertFalse(BlockDev.lvm_is_supported_pe_size(65535)) + self.assertFalse(BlockDev.lvm_is_supported_pe_size(32 * 1024**3)) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_supported_pe_sizes(self): + """Verify that supported PE sizes are really supported""" + + for size in BlockDev.lvm_get_supported_pe_sizes(): + self.assertTrue(BlockDev.lvm_is_supported_pe_size(size)) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_max_lv_size(self): + """Verify that max LV size is correctly determined""" + +@@ -71,6 +74,7 @@ class LvmNoDevTestCase(LVMTestCase): + + self.assertEqual(BlockDev.lvm_get_max_lv_size(), expected) + ++ @tag_test(TestTags.NOSTORAGE) + def test_round_size_to_pe(self): + """Verify that round_size_to_pe works as expected""" + +@@ -95,6 +99,7 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertEqual(BlockDev.lvm_round_size_to_pe(biggest_multiple - (2 * 4 * 1024**2) + 1, 4 * 1024**2, False), + biggest_multiple - (2 * 4 * 1024**2)) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_lv_physical_size(self): + """Verify that get_lv_physical_size works as expected""" + +@@ -108,6 +113,7 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertEqual(BlockDev.lvm_get_lv_physical_size(11 * 1024**2, 4 * 1024**2), + 12 * 1024**2) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_thpool_padding(self): + """Verify that get_thpool_padding works as expected""" + +@@ -121,6 +127,7 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertEqual(BlockDev.lvm_get_thpool_padding(11 * 1024**2, 4 * 1024**2, True), + expected_padding) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_thpool_meta_size(self): + """Verify that getting recommended thin pool metadata size works as expected""" + +@@ -139,6 +146,7 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertEqual(BlockDev.lvm_get_thpool_meta_size (100 * 1024**2, 128 * 1024, 100), + BlockDev.LVM_MIN_THPOOL_MD_SIZE) + ++ @tag_test(TestTags.NOSTORAGE) + def test_is_valid_thpool_md_size(self): + """Verify that is_valid_thpool_md_size works as expected""" + +@@ -149,6 +157,7 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(1 * 1024**2)) + self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(17 * 1024**3)) + ++ @tag_test(TestTags.NOSTORAGE) + def test_is_valid_thpool_chunk_size(self): + """Verify that is_valid_thpool_chunk_size works as expected""" + +@@ -167,6 +176,7 @@ class LvmNoDevTestCase(LVMTestCase): + def _store_log(self, lvl, msg): + self._log += str((lvl, msg)) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_set_global_config(self): + """Verify that getting and setting global config works as expected""" + +@@ -207,6 +217,7 @@ class LvmNoDevTestCase(LVMTestCase): + succ = BlockDev.lvm_set_global_config(None) + self.assertTrue(succ) + ++ @tag_test(TestTags.NOSTORAGE) + def test_cache_get_default_md_size(self): + """Verify that default cache metadata size is calculated properly""" + +@@ -215,6 +226,7 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertEqual(BlockDev.lvm_cache_get_default_md_size(80 * 1024**3), (80 * 1024**3) // 1000) + self.assertEqual(BlockDev.lvm_cache_get_default_md_size(6 * 1024**3), 8 * 1024**2) + ++ @tag_test(TestTags.NOSTORAGE) + def test_cache_mode_bijection(self): + """Verify that cache modes and their string representations map to each other""" + +@@ -275,6 +287,7 @@ class LvmPVonlyTestCase(LVMTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmTestPVcreateRemove(LvmPVonlyTestCase): ++ @tag_test(TestTags.CORE) + def test_pvcreate_and_pvremove(self): + """Verify that it's possible to create and destroy a PV""" + +@@ -380,6 +393,7 @@ class LvmPVVGTestCase(LvmPVonlyTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmTestVGcreateRemove(LvmPVVGTestCase): ++ @tag_test(TestTags.CORE) + def test_vgcreate_vgremove(self): + """Verify that it is possible to create and destroy a VG""" + +@@ -406,6 +420,7 @@ class LvmTestVGcreateRemove(LvmPVVGTestCase): + with self.assertRaises(GLib.GError): + BlockDev.lvm_vgremove("testVG", None) + ++@unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmTestVGrename(LvmPVVGTestCase): + def test_vgrename(self): + """Verify that it is possible to rename a VG""" +@@ -465,7 +480,6 @@ class LvmTestVGactivateDeactivate(LvmPVVGTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmTestVGextendReduce(LvmPVVGTestCase): +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") + def test_vgextend_vgreduce(self): + """Verify that it is possible to extend/reduce a VG""" + +@@ -571,6 +585,7 @@ class LvmPVVGLVTestCase(LvmPVVGTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmTestLVcreateRemove(LvmPVVGLVTestCase): ++ @tag_test(TestTags.CORE) + def test_lvcreate_lvremove(self): + """Verify that it's possible to create/destroy an LV""" + +@@ -619,6 +634,7 @@ class LvmTestLVcreateRemove(LvmPVVGLVTestCase): + with self.assertRaises(GLib.GError): + BlockDev.lvm_lvremove("testVG", "testLV", True, None) + ++@unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmTestLVcreateWithExtra(LvmPVVGLVTestCase): + def __init__(self, *args, **kwargs): + LvmPVVGLVTestCase.__init__(self, *args, **kwargs) +@@ -669,7 +685,6 @@ class LvmTestLVcreateWithExtra(LvmPVVGLVTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmTestLVcreateType(LvmPVVGLVTestCase): +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") + def test_lvcreate_type(self): + """Verify it's possible to create LVs with various types""" + +@@ -842,7 +857,7 @@ class LvmTestLVrename(LvmPVVGLVTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmTestLVsnapshots(LvmPVVGLVTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_snapshotcreate_lvorigin_snapshotmerge(self): + """Verify that LV snapshot support works""" + +@@ -957,6 +972,7 @@ class LvmTestLVsAll(LvmPVVGthpoolTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmTestThpoolCreate(LvmPVVGthpoolTestCase): ++ @tag_test(TestTags.CORE) + def test_thpoolcreate(self): + """Verify that it is possible to create a thin pool""" + +@@ -1056,6 +1072,7 @@ class LvmPVVGLVthLVTestCase(LvmPVVGthpoolTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmTestThLVcreate(LvmPVVGLVthLVTestCase): ++ @tag_test(TestTags.CORE) + def test_thlvcreate_thpoolname(self): + """Verify that it is possible to create a thin LV and get its pool name""" + +@@ -1142,8 +1159,7 @@ class LvmPVVGLVcachePoolTestCase(LvmPVVGLVTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmPVVGLVcachePoolCreateRemoveTestCase(LvmPVVGLVcachePoolTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") ++ @tag_test(TestTags.SLOW) + def test_cache_pool_create_remove(self): + """Verify that is it possible to create and remove a cache pool""" + +@@ -1169,8 +1185,7 @@ class LvmPVVGLVcachePoolCreateRemoveTestCase(LvmPVVGLVcachePoolTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmTestCachePoolConvert(LvmPVVGLVcachePoolTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") ++ @tag_test(TestTags.SLOW) + def test_cache_pool_convert(self): + """Verify that it is possible to create a cache pool by conversion""" + +@@ -1193,8 +1208,7 @@ class LvmTestCachePoolConvert(LvmPVVGLVcachePoolTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmPVVGLVcachePoolAttachDetachTestCase(LvmPVVGLVcachePoolTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") ++ @tag_test(TestTags.SLOW) + def test_cache_pool_attach_detach(self): + """Verify that is it possible to attach and detach a cache pool""" + +@@ -1235,8 +1249,7 @@ class LvmPVVGLVcachePoolAttachDetachTestCase(LvmPVVGLVcachePoolTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmPVVGcachedLVTestCase(LvmPVVGLVTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") ++ @tag_test(TestTags.SLOW) + def test_create_cached_lv(self): + """Verify that it is possible to create a cached LV in a single step""" + +@@ -1256,8 +1269,7 @@ class LvmPVVGcachedLVTestCase(LvmPVVGLVTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmPVVGcachedLVpoolTestCase(LvmPVVGLVTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") ++ @tag_test(TestTags.SLOW) + def test_cache_get_pool_name(self): + """Verify that it is possible to get the name of the cache pool""" + +@@ -1283,8 +1295,7 @@ class LvmPVVGcachedLVpoolTestCase(LvmPVVGLVTestCase): + + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmPVVGcachedLVstatsTestCase(LvmPVVGLVTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") ++ @tag_test(TestTags.SLOW) + def test_cache_get_stats(self): + """Verify that it is possible to get stats for a cached LV""" + +@@ -1323,6 +1334,7 @@ class LVMTechTest(LVMTestCase): + self.addCleanup(BlockDev.switch_init_checks, True) + self.addCleanup(BlockDev.reinit, [self.ps, self.ps2], True, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_tech_available(self): + """Verify that checking lvm dbus availability by technology works as expected""" + +diff --git a/tests/lvm_test.py b/tests/lvm_test.py +index 4f1640f..28a4b05 100644 +--- a/tests/lvm_test.py ++++ b/tests/lvm_test.py +@@ -7,7 +7,7 @@ import six + import re + import subprocess + +-from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, skip_on ++from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, skip_on, TestTags, tag_test + from gi.repository import BlockDev, GLib + + +@@ -27,6 +27,7 @@ class LvmNoDevTestCase(LVMTestCase): + super(LvmNoDevTestCase, self).__init__(*args, **kwargs) + self._log = "" + ++ @tag_test(TestTags.NOSTORAGE) + def test_is_supported_pe_size(self): + """Verify that lvm_is_supported_pe_size works as expected""" + +@@ -42,12 +43,14 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertFalse(BlockDev.lvm_is_supported_pe_size(65535)) + self.assertFalse(BlockDev.lvm_is_supported_pe_size(32 * 1024**3)) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_supported_pe_sizes(self): + """Verify that supported PE sizes are really supported""" + + for size in BlockDev.lvm_get_supported_pe_sizes(): + self.assertTrue(BlockDev.lvm_is_supported_pe_size(size)) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_max_lv_size(self): + """Verify that max LV size is correctly determined""" + +@@ -60,6 +63,7 @@ class LvmNoDevTestCase(LVMTestCase): + + self.assertEqual(BlockDev.lvm_get_max_lv_size(), expected) + ++ @tag_test(TestTags.NOSTORAGE) + def test_round_size_to_pe(self): + """Verify that round_size_to_pe works as expected""" + +@@ -84,6 +88,7 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertEqual(BlockDev.lvm_round_size_to_pe(biggest_multiple - (2 * 4 * 1024**2) + 1, 4 * 1024**2, False), + biggest_multiple - (2 * 4 * 1024**2)) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_lv_physical_size(self): + """Verify that get_lv_physical_size works as expected""" + +@@ -97,6 +102,7 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertEqual(BlockDev.lvm_get_lv_physical_size(11 * 1024**2, 4 * 1024**2), + 12 * 1024**2) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_thpool_padding(self): + """Verify that get_thpool_padding works as expected""" + +@@ -110,6 +116,7 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertEqual(BlockDev.lvm_get_thpool_padding(11 * 1024**2, 4 * 1024**2, True), + expected_padding) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_thpool_meta_size(self): + """Verify that getting recommended thin pool metadata size works as expected""" + +@@ -128,6 +135,7 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertEqual(BlockDev.lvm_get_thpool_meta_size (100 * 1024**2, 128 * 1024, 100), + BlockDev.LVM_MIN_THPOOL_MD_SIZE) + ++ @tag_test(TestTags.NOSTORAGE) + def test_is_valid_thpool_md_size(self): + """Verify that is_valid_thpool_md_size works as expected""" + +@@ -138,6 +146,7 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(1 * 1024**2)) + self.assertFalse(BlockDev.lvm_is_valid_thpool_md_size(17 * 1024**3)) + ++ @tag_test(TestTags.NOSTORAGE) + def test_is_valid_thpool_chunk_size(self): + """Verify that is_valid_thpool_chunk_size works as expected""" + +@@ -156,6 +165,7 @@ class LvmNoDevTestCase(LVMTestCase): + def _store_log(self, lvl, msg): + self._log += str((lvl, msg)) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_set_global_config(self): + """Verify that getting and setting global config works as expected""" + +@@ -192,6 +202,7 @@ class LvmNoDevTestCase(LVMTestCase): + succ = BlockDev.lvm_set_global_config(None) + self.assertTrue(succ) + ++ @tag_test(TestTags.NOSTORAGE) + def test_cache_get_default_md_size(self): + """Verify that default cache metadata size is calculated properly""" + +@@ -200,6 +211,7 @@ class LvmNoDevTestCase(LVMTestCase): + self.assertEqual(BlockDev.lvm_cache_get_default_md_size(80 * 1024**3), (80 * 1024**3) // 1000) + self.assertEqual(BlockDev.lvm_cache_get_default_md_size(6 * 1024**3), 8 * 1024**2) + ++ @tag_test(TestTags.NOSTORAGE) + def test_cache_mode_bijection(self): + """Verify that cache modes and their string representations map to each other""" + +@@ -258,6 +270,7 @@ class LvmPVonlyTestCase(LVMTestCase): + os.unlink(self.dev_file2) + + class LvmTestPVcreateRemove(LvmPVonlyTestCase): ++ @tag_test(TestTags.CORE) + def test_pvcreate_and_pvremove(self): + """Verify that it's possible to create and destroy a PV""" + +@@ -357,7 +370,8 @@ class LvmPVVGTestCase(LvmPVonlyTestCase): + LvmPVonlyTestCase._clean_up(self) + + class LvmTestVGcreateRemove(LvmPVVGTestCase): +- @skip_on("debian", skip_on_arch="i686", reason="vgremove is broken on 32bit Debian") ++ @skip_on("debian", skip_on_version="9", skip_on_arch="i686", reason="vgremove is broken on 32bit Debian stable") ++ @tag_test(TestTags.CORE) + def test_vgcreate_vgremove(self): + """Verify that it is possible to create and destroy a VG""" + +@@ -543,6 +557,7 @@ class LvmPVVGLVTestCase(LvmPVVGTestCase): + LvmPVVGTestCase._clean_up(self) + + class LvmTestLVcreateRemove(LvmPVVGLVTestCase): ++ @tag_test(TestTags.CORE) + def test_lvcreate_lvremove(self): + """Verify that it's possible to create/destroy an LV""" + +@@ -810,7 +825,7 @@ class LvmTestLVrename(LvmPVVGLVTestCase): + BlockDev.lvm_lvrename("testVG", "testLV", "testLV", None) + + class LvmTestLVsnapshots(LvmPVVGLVTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_snapshotcreate_lvorigin_snapshotmerge(self): + """Verify that LV snapshot support works""" + +@@ -920,6 +935,7 @@ class LvmTestLVsAll(LvmPVVGthpoolTestCase): + self.assertGreater(len(lvs), 3) + + class LvmTestThpoolCreate(LvmPVVGthpoolTestCase): ++ @tag_test(TestTags.CORE) + def test_thpoolcreate(self): + """Verify that it is possible to create a thin pool""" + +@@ -1016,6 +1032,7 @@ class LvmPVVGLVthLVTestCase(LvmPVVGthpoolTestCase): + LvmPVVGthpoolTestCase._clean_up(self) + + class LvmTestThLVcreate(LvmPVVGLVthLVTestCase): ++ @tag_test(TestTags.CORE) + def test_thlvcreate_thpoolname(self): + """Verify that it is possible to create a thin LV and get its pool name""" + +@@ -1098,8 +1115,7 @@ class LvmPVVGLVcachePoolTestCase(LvmPVVGLVTestCase): + LvmPVVGLVTestCase._clean_up(self) + + class LvmPVVGLVcachePoolCreateRemoveTestCase(LvmPVVGLVcachePoolTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") ++ @tag_test(TestTags.SLOW) + @skip_on(("centos", "enterprise_linux"), "7") + def test_cache_pool_create_remove(self): + """Verify that is it possible to create and remove a cache pool""" +@@ -1125,8 +1141,7 @@ class LvmPVVGLVcachePoolCreateRemoveTestCase(LvmPVVGLVcachePoolTestCase): + self.assertTrue(succ) + + class LvmTestCachePoolConvert(LvmPVVGLVcachePoolTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") ++ @tag_test(TestTags.SLOW) + def test_cache_pool_convert(self): + """Verify that it is possible to create a cache pool by conversion""" + +@@ -1149,8 +1164,7 @@ class LvmTestCachePoolConvert(LvmPVVGLVcachePoolTestCase): + + + class LvmPVVGLVcachePoolAttachDetachTestCase(LvmPVVGLVcachePoolTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") ++ @tag_test(TestTags.SLOW) + def test_cache_pool_attach_detach(self): + """Verify that is it possible to attach and detach a cache pool""" + +@@ -1190,8 +1204,7 @@ class LvmPVVGLVcachePoolAttachDetachTestCase(LvmPVVGLVcachePoolTestCase): + self.assertTrue(any(info.lv_name == "testCache" for info in lvs)) + + class LvmPVVGcachedLVTestCase(LvmPVVGLVTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") ++ @tag_test(TestTags.SLOW) + def test_create_cached_lv(self): + """Verify that it is possible to create a cached LV in a single step""" + +@@ -1210,8 +1223,7 @@ class LvmPVVGcachedLVTestCase(LvmPVVGLVTestCase): + self.assertTrue(succ) + + class LvmPVVGcachedLVpoolTestCase(LvmPVVGLVTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") ++ @tag_test(TestTags.SLOW) + def test_cache_get_pool_name(self): + """Verify that it is possible to get the name of the cache pool""" + +@@ -1236,8 +1248,7 @@ class LvmPVVGcachedLVpoolTestCase(LvmPVVGLVTestCase): + self.assertEqual(BlockDev.lvm_cache_pool_name("testVG", "testLV"), "testCache") + + class LvmPVVGcachedLVstatsTestCase(LvmPVVGLVTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @skip_on("fedora", "27", reason="LVM is broken in many ways on rawhide") ++ @tag_test(TestTags.SLOW) + def test_cache_get_stats(self): + """Verify that it is possible to get stats for a cached LV""" + +@@ -1271,6 +1282,7 @@ class LVMUnloadTest(LVMTestCase): + # tests + self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_low_version(self): + """Verify that checking the minimum LVM version works as expected""" + +@@ -1288,6 +1300,7 @@ class LVMUnloadTest(LVMTestCase): + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + self.assertIn("lvm", BlockDev.get_available_plugin_names()) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_no_lvm(self): + """Verify that checking lvm tool availability works as expected""" + +@@ -1315,6 +1328,7 @@ class LVMTechTest(LVMTestCase): + self.addCleanup(BlockDev.switch_init_checks, True) + self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_tech_available(self): + """Verify that checking lvm tool availability by technology works as expected""" + +diff --git a/tests/mdraid_test.py b/tests/mdraid_test.py +index ea182b2..ea489db 100644 +--- a/tests/mdraid_test.py ++++ b/tests/mdraid_test.py +@@ -6,7 +6,7 @@ from contextlib import contextmanager + import overrides_hack + import six + +-from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path ++from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, skip_on, TestTags, tag_test + from gi.repository import BlockDev, GLib + + +@@ -46,6 +46,7 @@ class MDNoDevTestCase(MDTest): + else: + BlockDev.reinit(cls.requested_plugins, True, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_superblock_size(self): + """Verify that superblock size si calculated properly""" + +@@ -67,6 +68,7 @@ class MDNoDevTestCase(MDTest): + self.assertEqual(BlockDev.md_get_superblock_size(257 * 1024**2, version="unknown version"), + 2 * 1024**2) + ++ @tag_test(TestTags.NOSTORAGE) + def test_canonicalize_uuid(self): + """Verify that UUID canonicalization works as expected""" + +@@ -76,6 +78,7 @@ class MDNoDevTestCase(MDTest): + with six.assertRaisesRegex(self, GLib.GError, r'malformed or invalid'): + BlockDev.md_canonicalize_uuid("malformed-uuid-example") + ++ @tag_test(TestTags.NOSTORAGE) + def test_get_md_uuid(self): + """Verify that getting UUID in MD RAID format works as expected""" + +@@ -162,7 +165,7 @@ class MDTestCase(MDTest): + + + class MDTestCreateDeactivateDestroy(MDTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW, TestTags.CORE) + def test_create_deactivate_destroy(self): + """Verify that it is possible to create, deactivate and destroy an MD RAID""" + +@@ -192,7 +195,7 @@ class MDTestCreateDeactivateDestroy(MDTestCase): + self.assertTrue(succ) + + class MDTestCreateWithChunkSize(MDTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_create_with_chunk_size(self): + """Verify that it is possible to create and MD RAID with specific chunk size """ + +@@ -216,7 +219,7 @@ class MDTestCreateWithChunkSize(MDTestCase): + self.assertTrue(succ) + + class MDTestActivateDeactivate(MDTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW, TestTags.CORE) + def test_activate_deactivate(self): + """Verify that it is possible to activate and deactivate an MD RAID""" + +@@ -255,7 +258,7 @@ class MDTestActivateDeactivate(MDTestCase): + self.assertTrue(succ) + + class MDTestActivateWithUUID(MDTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_activate_with_uuid(self): + """Verify that it is possible to activate an MD RAID with UUID""" + +@@ -277,7 +280,7 @@ class MDTestActivateWithUUID(MDTestCase): + succ = BlockDev.md_activate("bd_test_md", [self.loop_dev, self.loop_dev2, self.loop_dev3], md_info.uuid) + + class MDTestActivateByUUID(MDTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_activate_by_uuid(self): + """Verify that it is possible to activate an MD RAID by UUID""" + +@@ -309,7 +312,7 @@ class MDTestActivateByUUID(MDTestCase): + + + class MDTestNominateDenominate(MDTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_nominate_denominate(self): + """Verify that it is possible to nominate and denominate an MD RAID device""" + +@@ -342,9 +345,7 @@ class MDTestNominateDenominate(MDTestCase): + class MDTestNominateDenominateActive(MDTestCase): + # slow and leaking an MD array because with a nominated spare device, it + # cannot be deactivated in the end (don't ask me why) +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") +- @unittest.skipIf("JENKINS_HOME" in os.environ, "skipping leaky test in jenkins") +- @unittest.skipUnless("FEELINGLUCKY" in os.environ, "skipping, not feeling lucky") ++ @tag_test(TestTags.SLOW, TestTags.UNSAFE, TestTags.UNSTABLE) + def test_nominate_denominate_active(self): + """Verify that nominate and denominate deivice works as expected on (de)activated MD RAID""" + +@@ -371,7 +372,8 @@ class MDTestNominateDenominateActive(MDTestCase): + self.assertTrue(succ) + + class MDTestAddRemove(MDTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) ++ @skip_on("debian", reason="Removing spare disks from an array is broken on Debian") + def test_add_remove(self): + """Verify that it is possible to add a device to and remove from an MD RAID""" + +@@ -431,7 +433,7 @@ class MDTestAddRemove(MDTestCase): + + class MDTestExamineDetail(MDTestCase): + # sleeps to let MD RAID sync things +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_examine_detail(self): + """Verify that it is possible to get info about an MD RAID""" + +@@ -487,7 +489,7 @@ class MDTestExamineDetail(MDTestCase): + self.assertTrue(de_data) + + class MDTestNameNodeBijection(MDTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_name_node_bijection(self): + """Verify that MD RAID node and name match each other""" + +@@ -518,7 +520,7 @@ class MDTestNameNodeBijection(MDTestCase): + self.assertTrue(succ) + + class MDTestSetBitmapLocation(MDTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_set_bitmap_location(self): + """Verify we can change bitmap location for an existing MD array""" + +@@ -567,7 +569,7 @@ class MDTestSetBitmapLocation(MDTestCase): + + + class MDTestRequestSyncAction(MDTestCase): +- @unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") ++ @tag_test(TestTags.SLOW) + def test_request_sync_action(self): + """Verify we can request sync action on an existing MD array""" + +@@ -587,6 +589,7 @@ class MDTestRequestSyncAction(MDTestCase): + + class FakeMDADMutilTest(MDTest): + # no setUp nor tearDown needed, we are gonna use fake utils ++ @tag_test(TestTags.NOSTORAGE) + def test_fw_raid_uppercase_examine(self): + """Verify that md_examine works with output using "RAID" instead of "Raid" and other quirks """ + +@@ -598,6 +601,7 @@ class FakeMDADMutilTest(MDTest): + self.assertEqual(ex_data.uuid, "b42756a2-37e4-3e47-674b-d1dd6e822145") + self.assertEqual(ex_data.device, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_no_metadata_examine(self): + """Verify that md_examine works as expected with no metadata spec""" + +@@ -607,6 +611,7 @@ class FakeMDADMutilTest(MDTest): + + self.assertIs(ex_data.metadata, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_fw_raid_migrating(self): + """Verify that md_examine works when array is migrating ("foo <-- bar" values in output) """ + +@@ -615,6 +620,7 @@ class FakeMDADMutilTest(MDTest): + + self.assertEqual(ex_data.chunk_size, 128 * 1024) + ++ @tag_test(TestTags.NOSTORAGE) + def test_mdadm_name_extra_info(self): + """Verify that md_examine and md_detail work with extra MD RAID name info""" + +@@ -632,6 +638,7 @@ class MDUnloadTest(MDTestCase): + # tests + self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_low_version(self): + """Verify that checking the minimum mdsetup version works as expected""" + +@@ -649,6 +656,7 @@ class MDUnloadTest(MDTestCase): + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + self.assertIn("mdraid", BlockDev.get_available_plugin_names()) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_no_md(self): + """Verify that checking mdsetup tool availability works as expected""" + +diff --git a/tests/mpath_test.py b/tests/mpath_test.py +index e9d1e42..acd3053 100644 +--- a/tests/mpath_test.py ++++ b/tests/mpath_test.py +@@ -2,7 +2,7 @@ import unittest + import os + import overrides_hack + +-from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, skip_on, get_version ++from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, skip_on, get_version, TestTags, tag_test + from gi.repository import BlockDev, GLib + + class MpathTest(unittest.TestCase): +@@ -56,6 +56,7 @@ class MpathUnloadTest(MpathTest): + # tests + self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_low_version(self): + """Verify that checking the minimum dmsetup version works as expected""" + +@@ -74,6 +75,7 @@ class MpathUnloadTest(MpathTest): + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + self.assertIn("mpath", BlockDev.get_available_plugin_names()) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_no_multipath(self): + """Verify that checking multipath tool availability works as expected""" + +@@ -91,6 +93,7 @@ class MpathUnloadTest(MpathTest): + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + self.assertIn("mpath", BlockDev.get_available_plugin_names()) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_no_mpathconf(self): + """Verify that checking mpathconf tool availability works as expected""" + +diff --git a/tests/nvdimm_test.py b/tests/nvdimm_test.py +index a4e6854..1c2fb3c 100644 +--- a/tests/nvdimm_test.py ++++ b/tests/nvdimm_test.py +@@ -6,7 +6,7 @@ import overrides_hack + + from distutils.version import LooseVersion + +-from utils import run_command, read_file, skip_on, fake_path ++from utils import run_command, read_file, skip_on, fake_path, TestTags, tag_test + from gi.repository import BlockDev, GLib + + +@@ -80,6 +80,7 @@ class NVDIMMNamespaceTestCase(NVDIMMTestCase): + # even for modes where sector size doesn't make sense + self.assertEqual(bd_info.sector_size, 512) + ++ @tag_test(TestTags.EXTRADEPS, TestTags.CORE) + def test_namespace_info(self): + # get info about our 'testing' namespace + info = BlockDev.nvdimm_namespace_info(self.sys_info["dev"]) +@@ -96,14 +97,15 @@ class NVDIMMNamespaceTestCase(NVDIMMTestCase): + info = BlockDev.nvdimm_namespace_info("definitely-not-a-namespace") + self.assertIsNone(info) + ++ @tag_test(TestTags.EXTRADEPS, TestTags.CORE) + def test_list_namespaces(self): + bd_namespaces = BlockDev.nvdimm_list_namespaces() + self.assertEqual(len(bd_namespaces), 1) + + self._check_namespace_info(bd_namespaces[0]) + +- @unittest.skipUnless("JENKINS_HOME" in os.environ, "skipping test that modifies system configuration") + @skip_on("fedora", "29", reason="Disabling is broken on rawhide and makes the 'fake' NVDIMM unusable.") ++ @tag_test(TestTags.EXTRADEPS, TestTags.UNSAFE) + def test_enable_disable(self): + # non-existing/unknow namespace + with self.assertRaises(GLib.GError): +@@ -130,8 +132,8 @@ class NVDIMMNamespaceTestCase(NVDIMMTestCase): + info = BlockDev.nvdimm_namespace_info(self.sys_info["dev"]) + self.assertTrue(info.enabled) + +- @unittest.skipUnless("JENKINS_HOME" in os.environ, "skipping test that modifies system configuration") + @skip_on("fedora", "29", reason="Disabling is broken on rawhide and makes the 'fake' NVDIMM unusable.") ++ @tag_test(TestTags.EXTRADEPS, TestTags.UNSAFE) + def test_namespace_reconfigure(self): + # active namespace -- reconfigure doesn't work without force + with self.assertRaises(GLib.GError): +@@ -188,6 +190,7 @@ class NVDIMMUnloadTest(NVDIMMTestCase): + # tests + self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_no_ndctl(self): + """Verify that checking ndctl tool availability works as expected""" + +diff --git a/tests/overrides_test.py b/tests/overrides_test.py +index 53c65b5..8e7f5a5 100644 +--- a/tests/overrides_test.py ++++ b/tests/overrides_test.py +@@ -3,6 +3,8 @@ import math + import overrides_hack + from gi.repository import BlockDev + ++from utils import TestTags, tag_test ++ + + class OverridesTest(unittest.TestCase): + # all plugins except for 'btrfs', 'fs' and 'mpath' -- these don't have all +@@ -19,6 +21,7 @@ class OverridesTest(unittest.TestCase): + BlockDev.reinit(cls.requested_plugins, True, None) + + class OverridesTestCase(OverridesTest): ++ @tag_test(TestTags.NOSTORAGE, TestTags.CORE) + def test_error_proxy(self): + """Verify that the error proxy works as expected""" + +@@ -68,6 +71,7 @@ class OverridesUnloadTestCase(OverridesTest): + # tests + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + ++ @tag_test(TestTags.NOSTORAGE, TestTags.CORE) + def test_xrules(self): + """Verify that regexp-based transformation rules work as expected""" + +@@ -81,6 +85,7 @@ class OverridesUnloadTestCase(OverridesTest): + # load the plugins back + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + ++ @tag_test(TestTags.NOSTORAGE, TestTags.CORE) + def test_exception_inheritance(self): + # unload all plugins first + self.assertTrue(BlockDev.reinit([], True, None)) +diff --git a/tests/part_test.py b/tests/part_test.py +index adbaa9a..9e58cc6 100644 +--- a/tests/part_test.py ++++ b/tests/part_test.py +@@ -1,6 +1,6 @@ + import unittest + import os +-from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, skip_on ++from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, skip_on, TestTags, tag_test + import overrides_hack + + from gi.repository import BlockDev, GLib +@@ -46,6 +46,7 @@ class PartTestCase(unittest.TestCase): + os.unlink(self.dev_file2) + + class PartCreateTableCase(PartTestCase): ++ @tag_test(TestTags.CORE) + def test_create_table(self): + """Verify that it is possible to create a new partition table""" + +@@ -78,6 +79,7 @@ class PartCreateTableCase(PartTestCase): + + + class PartGetDiskSpecCase(PartTestCase): ++ @tag_test(TestTags.CORE) + def test_get_disk_spec(self): + """Verify that it is possible to get information about disk""" + +@@ -115,6 +117,7 @@ class PartGetDiskSpecCase(PartTestCase): + self.assertEqual(ps.flags, 0) + + class PartCreatePartCase(PartTestCase): ++ @tag_test(TestTags.CORE) + def test_create_part_simple(self): + """Verify that it is possible to create a parition""" + +@@ -221,6 +224,7 @@ class PartCreatePartCase(PartTestCase): + self.assertEqual(ps.flags, ps3.flags) + + class PartCreatePartFullCase(PartTestCase): ++ @tag_test(TestTags.CORE) + def test_full_device_partition(self): + # we first need a partition table + succ = BlockDev.part_create_table (self.loop_dev, BlockDev.PartTableType.GPT, True) +@@ -362,6 +366,7 @@ class PartCreatePartFullCase(PartTestCase): + BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.EXTENDED, ps4.start + ps4.size + 1, + 10 * 1024**2, BlockDev.PartAlign.OPTIMAL) + ++ @tag_test(TestTags.CORE) + def test_create_part_with_extended_logical(self): + """Verify that partition creation works as expected with primary, extended and logical parts""" + +@@ -502,6 +507,7 @@ class PartCreatePartFullCase(PartTestCase): + BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.LOGICAL, ps3.start + ps3.size + 1, + 10 * 1024**2, BlockDev.PartAlign.OPTIMAL) + ++ @tag_test(TestTags.CORE) + def test_create_part_next(self): + """Verify that partition creation works as expected with the NEXT (auto) type""" + +@@ -589,6 +595,7 @@ class PartCreatePartFullCase(PartTestCase): + BlockDev.part_create_part (self.loop_dev, BlockDev.PartTypeReq.EXTENDED, ps4.start + ps4.size + 1, + 10 * 1024**2, BlockDev.PartAlign.OPTIMAL) + ++ @tag_test(TestTags.CORE) + def test_create_part_next_gpt(self): + """Verify that partition creation works as expected with the NEXT (auto) type on GPT""" + +@@ -664,6 +671,7 @@ class PartGetDiskPartsCase(PartTestCase): + class PartGetDiskFreeRegions(PartTestCase): + @skip_on(("centos", "enterprise_linux"), "7", reason="libparted provides weird values here") + @skip_on("debian", reason="libparted provides weird values here") ++ @tag_test(TestTags.CORE) + def test_get_disk_free_regions(self): + """Verify that it is possible to get info about free regions on a disk""" + +@@ -1057,6 +1065,7 @@ class PartCreateResizePartCase(PartTestCase): + self.assertGreaterEqual(ps.size, initial_size) # at least the requested size + + class PartCreateDeletePartCase(PartTestCase): ++ @tag_test(TestTags.CORE) + def test_create_delete_part_simple(self): + """Verify that it is possible to create and delete a parition""" + +diff --git a/tests/s390_test.py b/tests/s390_test.py +index 98c6b1b..da23a55 100644 +--- a/tests/s390_test.py ++++ b/tests/s390_test.py +@@ -2,7 +2,7 @@ import unittest + import os + import overrides_hack + +-from utils import fake_path ++from utils import fake_path, TestTags, tag_test + from gi.repository import BlockDev, GLib + + @unittest.skipUnless(os.uname()[4].startswith('s390'), "s390x architecture required") +@@ -18,6 +18,7 @@ class S390TestCase(unittest.TestCase): + else: + BlockDev.reinit(cls.requested_plugins, True, None) + ++ @tag_test(TestTags.EXTRADEPS, TestTags.NOSTORAGE) + def test_device_input(self): + """Verify that s390_sanitize_dev_input works as expected""" + dev = "1234" +@@ -42,6 +43,7 @@ class S390TestCase(unittest.TestCase): + dev = "0.0.abcdefgh" + self.assertEqual(BlockDev.s390_sanitize_dev_input(dev), dev) + ++ @tag_test(TestTags.EXTRADEPS, TestTags.NOSTORAGE) + def test_wwpn_input(self): + """Verify that s390_zfcp_sanitize_wwpn_input works as expected""" + # missing "0x" from beginning of wwpn; this should be added by fx +@@ -56,6 +58,7 @@ class S390TestCase(unittest.TestCase): + with self.assertRaises(GLib.GError): + BlockDev.s390_zfcp_sanitize_wwpn_input(wwpn) + ++ @tag_test(TestTags.EXTRADEPS, TestTags.NOSTORAGE) + def test_lun_input(self): + """Verify that s390_zfcp_sanitize_lun_input works as expected""" + # user does not prepend lun with "0x"; this should get added +@@ -91,6 +94,7 @@ class S390UnloadTest(unittest.TestCase): + else: + BlockDev.reinit(cls.requested_plugins, True, None) + ++ @tag_test(TestTags.EXTRADEPS, TestTags.NOSTORAGE) + def test_check_no_dasdfmt(self): + """Verify that checking dasdfmt tool availability works as expected""" + +diff --git a/tests/swap_test.py b/tests/swap_test.py +index 05d0c19..66b5eb2 100644 +--- a/tests/swap_test.py ++++ b/tests/swap_test.py +@@ -2,7 +2,7 @@ import unittest + import os + import overrides_hack + +-from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, run_command ++from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, run_command, run, TestTags, tag_test + from gi.repository import BlockDev, GLib + + +@@ -38,6 +38,7 @@ class SwapTestCase(SwapTest): + pass + os.unlink(self.dev_file) + ++ @tag_test(TestTags.CORE) + def test_all(self): + """Verify that swap_* functions work as expected""" + +@@ -103,6 +104,7 @@ class SwapUnloadTest(SwapTest): + # tests + self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_low_version(self): + """Verify that checking the minimum swap utils versions works as expected""" + +@@ -120,6 +122,7 @@ class SwapUnloadTest(SwapTest): + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + self.assertIn("swap", BlockDev.get_available_plugin_names()) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_no_mkswap(self): + """Verify that checking mkswap and swaplabel tools availability + works as expected +@@ -146,6 +149,7 @@ class SwapUnloadTest(SwapTest): + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + self.assertIn("swap", BlockDev.get_available_plugin_names()) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_no_mkswap_runtime(self): + """Verify that runtime checking mkswap tool availability works as expected""" + +@@ -172,6 +176,7 @@ class SwapTechAvailable(SwapTest): + self.addCleanup(BlockDev.switch_init_checks, True) + self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_tech_available(self): + """Verify that runtime checking mkswap and swaplabel tools availability + works as expected +diff --git a/tests/utils_test.py b/tests/utils_test.py +index 02b0203..66d8a32 100644 +--- a/tests/utils_test.py ++++ b/tests/utils_test.py +@@ -2,7 +2,7 @@ import unittest + import re + import os + import overrides_hack +-from utils import fake_utils, create_sparse_tempfile, create_lio_device, delete_lio_device, run_command ++from utils import fake_utils, create_sparse_tempfile, create_lio_device, delete_lio_device, run_command, TestTags, tag_test + + from gi.repository import BlockDev, GLib + +@@ -25,6 +25,7 @@ class UtilsExecProgressTest(UtilsTestCase): + self.assertTrue(isinstance(completion, int)) + self.log.append(completion) + ++ @tag_test(TestTags.NOSTORAGE, TestTags.CORE) + def test_initialization(self): + """ Verify that progress report can (de)initialized""" + +@@ -54,6 +55,7 @@ class UtilsExecLoggingTest(UtilsTestCase): + + self.log += msg + "\n" + ++ @tag_test(TestTags.NOSTORAGE, TestTags.CORE) + def test_logging(self): + """Verify that setting up and using exec logging works as expected""" + +@@ -91,6 +93,7 @@ class UtilsExecLoggingTest(UtilsTestCase): + self.assertTrue(succ) + self.assertEqual(old_log, self.log) + ++ @tag_test(TestTags.NOSTORAGE, TestTags.CORE) + def test_version_cmp(self): + """Verify that version comparison works as expected""" + +@@ -124,6 +127,7 @@ class UtilsExecLoggingTest(UtilsTestCase): + self.assertEqual(BlockDev.utils_version_cmp("1.1.1", "1.1.1-1"), -1) + self.assertEqual(BlockDev.utils_version_cmp("1.1.2", "1.2"), -1) + ++ @tag_test(TestTags.NOSTORAGE, TestTags.CORE) + def test_util_version(self): + """Verify that checking utility availability works as expected""" + +@@ -167,6 +171,7 @@ class UtilsExecLoggingTest(UtilsTestCase): + self.assertTrue(BlockDev.utils_check_util_version("libblockdev-fake-util-fail", "1.1", "version", "Version:\\s(.*)")) + + class UtilsDevUtilsTestCase(UtilsTestCase): ++ @tag_test(TestTags.NOSTORAGE, TestTags.CORE) + def test_resolve_device(self): + """Verify that resolving device spec works as expected""" + +@@ -199,6 +204,7 @@ class UtilsDevUtilsTestCase(UtilsTestCase): + self.assertEqual(BlockDev.utils_resolve_device(dev_link[5:]), dev) + + class UtilsDevUtilsTestCase(UtilsTestCase): ++ @tag_test(TestTags.NOSTORAGE, TestTags.CORE) + def test_resolve_device(self): + """Verify that resolving device spec works as expected""" + +@@ -248,7 +254,7 @@ class UtilsDevUtilsSymlinksTestCase(UtilsTestCase): + pass + os.unlink(self.dev_file) + +- ++ @tag_test(TestTags.CORE) + def test_get_device_symlinks(self): + """Verify that getting device symlinks works as expected""" + +diff --git a/tests/vdo_test.py b/tests/vdo_test.py +index be8103a..f20ccd5 100644 +--- a/tests/vdo_test.py ++++ b/tests/vdo_test.py +@@ -6,7 +6,7 @@ import unittest + import overrides_hack + import six + +-from utils import run_command, read_file, skip_on, fake_path, create_sparse_tempfile, create_lio_device, delete_lio_device ++from utils import run_command, read_file, skip_on, fake_path, create_sparse_tempfile, create_lio_device, delete_lio_device, TestTags, tag_test + from gi.repository import BlockDev, GLib + from bytesize import bytesize + from distutils.spawn import find_executable +@@ -48,7 +48,6 @@ class VDOTestCase(unittest.TestCase): + os.unlink(self.dev_file) + + +-@unittest.skipIf("SKIP_SLOW" in os.environ, "skipping slow tests") + class VDOTest(VDOTestCase): + + vdo_name = "bd-test-vdo" +@@ -56,6 +55,7 @@ class VDOTest(VDOTestCase): + def _remove_vdo(self, name): + run_command("vdo remove --force -n %s" % name) + ++ @tag_test(TestTags.SLOW, TestTags.CORE) + def test_create_remove(self): + """Verify that it is possible to create and remove a VDO volume""" + +@@ -85,6 +85,7 @@ class VDOTest(VDOTestCase): + + self.assertFalse(os.path.exists("/dev/mapper/%s" % self.vdo_name)) + ++ @tag_test(TestTags.SLOW) + def test_enable_disable_compression(self): + """Verify that it is possible to enable/disable compression on an existing VDO volume""" + +@@ -110,6 +111,7 @@ class VDOTest(VDOTestCase): + info = BlockDev.vdo_info(self.vdo_name) + self.assertTrue(info.compression) + ++ @tag_test(TestTags.SLOW) + def test_enable_disable_deduplication(self): + """Verify that it is possible to enable/disable deduplication on an existing VDO volume""" + +@@ -135,6 +137,7 @@ class VDOTest(VDOTestCase): + info = BlockDev.vdo_info(self.vdo_name) + self.assertTrue(info.deduplication) + ++ @tag_test(TestTags.SLOW) + def test_activate_deactivate(self): + """Verify that it is possible to activate/deactivate an existing VDO volume""" + +@@ -172,6 +175,7 @@ class VDOTest(VDOTestCase): + + self.assertTrue(os.path.exists("/dev/mapper/%s" % self.vdo_name)) + ++ @tag_test(TestTags.SLOW) + def test_change_write_policy(self): + + ret = BlockDev.vdo_create(self.vdo_name, self.loop_dev, 3 * self.loop_size, 0, +@@ -203,6 +207,7 @@ class VDOTest(VDOTestCase): + + return info["VDOs"][name] + ++ @tag_test(TestTags.SLOW, TestTags.CORE) + def test_get_info(self): + """Verify that it is possible to get information about an existing VDO volume""" + +@@ -229,6 +234,7 @@ class VDOTest(VDOTestCase): + self.assertEqual(bd_info.physical_size, bytesize.Size(sys_info["Physical size"])) + self.assertEqual(bd_info.logical_size, bytesize.Size(sys_info["Logical size"])) + ++ @tag_test(TestTags.SLOW) + def test_grow_logical(self): + """Verify that it is possible to grow logical size of an existing VDO volume""" + +@@ -249,6 +255,7 @@ class VDOTest(VDOTestCase): + + self.assertEqual(info.logical_size, new_size) + ++ @tag_test(TestTags.SLOW, TestTags.UNSTABLE) + def test_grow_physical(self): + """Verify that it is possible to grow physical size of an existing VDO volume""" + +@@ -284,6 +291,7 @@ class VDOTest(VDOTestCase): + self.assertEqual(info_before.logical_size, info_after.logical_size) + self.assertGreater(info_after.physical_size, info_before.physical_size) + ++ @tag_test(TestTags.SLOW) + def test_statistics(self): + """Verify that it is possible to retrieve statistics of an existing VDO volume""" + +@@ -311,6 +319,7 @@ class VDOUnloadTest(VDOTestCase): + # tests + self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None) + ++ @tag_test(TestTags.NOSTORAGE) + def test_check_no_vdo(self): + """Verify that checking vdo tool availability works as expected""" + +-- +2.20.1 + + +From c709805db97621889c4354f9771db47916dbc2e5 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Thu, 4 Apr 2019 10:39:21 +0200 +Subject: [PATCH 04/10] Remove duplicate test case + +UtilsDevUtilsTestCase was defined twice, probably because of some +copy paste or merging mistake. +--- + tests/utils_test.py | 32 -------------------------------- + 1 file changed, 32 deletions(-) + +diff --git a/tests/utils_test.py b/tests/utils_test.py +index 66d8a32..e268409 100644 +--- a/tests/utils_test.py ++++ b/tests/utils_test.py +@@ -170,38 +170,6 @@ class UtilsExecLoggingTest(UtilsTestCase): + # exit code != 0 + self.assertTrue(BlockDev.utils_check_util_version("libblockdev-fake-util-fail", "1.1", "version", "Version:\\s(.*)")) + +-class UtilsDevUtilsTestCase(UtilsTestCase): +- @tag_test(TestTags.NOSTORAGE, TestTags.CORE) +- def test_resolve_device(self): +- """Verify that resolving device spec works as expected""" +- +- with self.assertRaises(GLib.GError): +- BlockDev.utils_resolve_device("no_such_device") +- +- dev = "/dev/libblockdev-test-dev" +- with open(dev, "w"): +- pass +- self.addCleanup(os.unlink, dev) +- +- # full path, no symlink, should just return the same +- self.assertEqual(BlockDev.utils_resolve_device(dev), dev) +- +- # just the name of the device, should return the full path +- self.assertEqual(BlockDev.utils_resolve_device(dev[5:]), dev) +- +- dev_dir = "/dev/libblockdev-test-dir" +- os.mkdir(dev_dir) +- self.addCleanup(os.rmdir, dev_dir) +- +- dev_link = dev_dir + "/test-dev-link" +- os.symlink("../" + dev[5:], dev_link) +- self.addCleanup(os.unlink, dev_link) +- +- # should resolve the symlink +- self.assertEqual(BlockDev.utils_resolve_device(dev_link), dev) +- +- # should resolve the symlink even without the "/dev" prefix +- self.assertEqual(BlockDev.utils_resolve_device(dev_link[5:]), dev) + + class UtilsDevUtilsTestCase(UtilsTestCase): + @tag_test(TestTags.NOSTORAGE, TestTags.CORE) +-- +2.20.1 + + +From 09cee5780854f92b28aaeb7c67ea76c6fc853e30 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Thu, 4 Apr 2019 11:23:12 +0200 +Subject: [PATCH 05/10] Allow running tests against installed libblockdev + +--- + tests/overrides_hack.py | 5 +- + tests/run_tests.py | 106 +++++++++++++++++++++++----------------- + 2 files changed, 64 insertions(+), 47 deletions(-) + +diff --git a/tests/overrides_hack.py b/tests/overrides_hack.py +index 0f10ee5..509a961 100644 +--- a/tests/overrides_hack.py ++++ b/tests/overrides_hack.py +@@ -1,5 +1,8 @@ ++import os + import gi.overrides +-if not gi.overrides.__path__[0].endswith("src/python/gi/overrides"): ++ ++if 'LIBBLOCKDEV_TESTS_SKIP_OVERRIDE' not in os.environ and \ ++ not gi.overrides.__path__[0].endswith("src/python/gi/overrides"): + local_overrides = None + # our overrides don't take precedence, let's fix it + for i, path in enumerate(gi.overrides.__path__): +diff --git a/tests/run_tests.py b/tests/run_tests.py +index 5301d07..b67c2e7 100644 +--- a/tests/run_tests.py ++++ b/tests/run_tests.py +@@ -65,49 +65,8 @@ def _get_test_tags(test): + return tags + + +-def _print_skip_message(test, skip_tag): +- +- # test.id() looks like 'crypto_test.CryptoTestResize.test_luks2_resize' +- # and we want to print 'test_luks2_resize (crypto_test.CryptoTestResize)' +- test_desc = test.id().split(".") +- test_name = test_desc[-1] +- test_module = ".".join(test_desc[:-1]) +- +- if skip_tag == TestTags.SLOW: +- reason = "skipping slow tests" +- elif skip_tag == TestTags.UNSTABLE: +- reason = "skipping unstable tests" +- elif skip_tag == TestTags.UNSAFE: +- reason = "skipping test that modifies system configuration" +- elif skip_tag == TestTags.EXTRADEPS: +- reason = "skipping test that requires special configuration" +- elif skip_tag == TestTags.CORE: +- reason = "skipping non-core test" +- else: +- reason = "unknown reason" # just to be sure there is some default value +- +- if test._testMethodDoc: +- print("%s (%s)\n%s ... skipped '%s'" % (test_name, test_module, test._testMethodDoc, reason)) +- else: +- print("%s (%s) ... skipped '%s'" % (test_name, test_module, reason)) +- +- +-if __name__ == '__main__': +- +- testdir = os.path.abspath(os.path.dirname(__file__)) +- projdir = os.path.abspath(os.path.normpath(os.path.join(testdir, '..'))) +- +- if 'LD_LIBRARY_PATH' not in os.environ and 'GI_TYPELIB_PATH' not in os.environ: +- os.environ['LD_LIBRARY_PATH'] = LIBDIRS +- os.environ['GI_TYPELIB_PATH'] = GIDIR +- os.environ['LIBBLOCKDEV_CONFIG_DIR'] = os.path.join(testdir, 'default_config') +- +- try: +- pyver = 'python3' if six.PY3 else 'python' +- os.execv(sys.executable, [pyver] + sys.argv) +- except OSError as e: +- print('Failed re-exec with a new LD_LIBRARY_PATH and GI_TYPELIB_PATH: %s' % str(e)) +- sys.exit(1) ++def parse_args(): ++ """ Parse cmdline arguments """ + + argparser = argparse.ArgumentParser(description='libblockdev test suite') + argparser.add_argument('testname', nargs='*', help='name of test class or ' +@@ -127,6 +86,9 @@ if __name__ == '__main__': + argparser.add_argument('-s', '--stop', dest='stop', + help='stop executing after first failed test', + action='store_true') ++ argparser.add_argument('-i', '--installed', dest='installed', ++ help='run tests against installed version of libblockdev', ++ action='store_true') + args = argparser.parse_args() + + if args.fast: +@@ -144,9 +106,61 @@ if __name__ == '__main__': + if 'FEELINGLUCKY' in os.environ: + args.lucky = True + +- sys.path.append(testdir) +- sys.path.append(projdir) +- sys.path.append(os.path.join(projdir, 'src/python')) ++ return args ++ ++ ++def _print_skip_message(test, skip_tag): ++ ++ # test.id() looks like 'crypto_test.CryptoTestResize.test_luks2_resize' ++ # and we want to print 'test_luks2_resize (crypto_test.CryptoTestResize)' ++ test_desc = test.id().split(".") ++ test_name = test_desc[-1] ++ test_module = ".".join(test_desc[:-1]) ++ ++ if skip_tag == TestTags.SLOW: ++ reason = "skipping slow tests" ++ elif skip_tag == TestTags.UNSTABLE: ++ reason = "skipping unstable tests" ++ elif skip_tag == TestTags.UNSAFE: ++ reason = "skipping test that modifies system configuration" ++ elif skip_tag == TestTags.EXTRADEPS: ++ reason = "skipping test that requires special configuration" ++ elif skip_tag == TestTags.CORE: ++ reason = "skipping non-core test" ++ else: ++ reason = "unknown reason" # just to be sure there is some default value ++ ++ if test._testMethodDoc: ++ print("%s (%s)\n%s ... skipped '%s'" % (test_name, test_module, test._testMethodDoc, reason)) ++ else: ++ print("%s (%s) ... skipped '%s'" % (test_name, test_module, reason)) ++ ++ ++if __name__ == '__main__': ++ ++ testdir = os.path.abspath(os.path.dirname(__file__)) ++ projdir = os.path.abspath(os.path.normpath(os.path.join(testdir, '..'))) ++ ++ args = parse_args() ++ if args.installed: ++ os.environ['LIBBLOCKDEV_TESTS_SKIP_OVERRIDE'] = '' ++ os.environ['LIBBLOCKDEV_CONFIG_DIR'] = '/etc/libblockdev/conf.d/' ++ else: ++ if 'LD_LIBRARY_PATH' not in os.environ and 'GI_TYPELIB_PATH' not in os.environ: ++ os.environ['LD_LIBRARY_PATH'] = LIBDIRS ++ os.environ['GI_TYPELIB_PATH'] = GIDIR ++ os.environ['LIBBLOCKDEV_CONFIG_DIR'] = os.path.join(testdir, 'default_config') ++ ++ try: ++ pyver = 'python3' if six.PY3 else 'python' ++ os.execv(sys.executable, [pyver] + sys.argv) ++ except OSError as e: ++ print('Failed re-exec with a new LD_LIBRARY_PATH and GI_TYPELIB_PATH: %s' % str(e)) ++ sys.exit(1) ++ ++ sys.path.append(testdir) ++ sys.path.append(projdir) ++ sys.path.append(os.path.join(projdir, 'src/python')) + + start_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + +-- +2.20.1 + + +From df65462618e72602b7760f6c750085094b2bddff Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Thu, 4 Apr 2019 11:50:04 +0200 +Subject: [PATCH 06/10] Add a special test tag for library tests that recompile + plugins + +We have some tests that changes lvm plugin and recompile it to +test loading of plugins. We can't run these tests against +installed library, so we need a special tag to skip them. +--- + tests/library_test.py | 8 ++++---- + tests/run_tests.py | 2 ++ + tests/utils.py | 2 ++ + 3 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/tests/library_test.py b/tests/library_test.py +index fa33b53..e8bb175 100644 +--- a/tests/library_test.py ++++ b/tests/library_test.py +@@ -40,7 +40,7 @@ class LibraryOpsTestCase(unittest.TestCase): + BlockDev.reinit(self.requested_plugins, True, None) + + # recompiles the LVM plugin +- @tag_test(TestTags.SLOW, TestTags.CORE) ++ @tag_test(TestTags.SLOW, TestTags.CORE, TestTags.SOURCEONLY) + def test_reload(self): + """Verify that reloading plugins works as expected""" + +@@ -72,7 +72,7 @@ class LibraryOpsTestCase(unittest.TestCase): + self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) + + # recompiles the LVM plugin +- @tag_test(TestTags.SLOW) ++ @tag_test(TestTags.SLOW, TestTags.SOURCEONLY) + def test_force_plugin(self): + """Verify that forcing plugin to be used works as expected""" + +@@ -118,7 +118,7 @@ class LibraryOpsTestCase(unittest.TestCase): + self.assertEqual(BlockDev.lvm_get_max_lv_size(), orig_max_size) + + # recompiles the LVM plugin +- @tag_test(TestTags.SLOW) ++ @tag_test(TestTags.SLOW, TestTags.SOURCEONLY) + def test_plugin_priority(self): + """Verify that preferring plugin to be used works as expected""" + +@@ -181,7 +181,7 @@ class LibraryOpsTestCase(unittest.TestCase): + os.system ("rm -f src/plugins/.libs/libbd_lvm2.so") + + # recompiles the LVM plugin +- @tag_test(TestTags.SLOW) ++ @tag_test(TestTags.SLOW, TestTags.SOURCEONLY) + def test_plugin_fallback(self): + """Verify that fallback when loading plugins works as expected""" + +diff --git a/tests/run_tests.py b/tests/run_tests.py +index b67c2e7..7df9e7d 100644 +--- a/tests/run_tests.py ++++ b/tests/run_tests.py +@@ -61,6 +61,8 @@ def _get_test_tags(test): + tags.append(TestTags.EXTRADEPS) + if getattr(test_fn, "regression", False) or getattr(test_fn.__self__, "regression", False): + tags.append(TestTags.REGRESSION) ++ if getattr(test_fn, "sourceonly", False) or getattr(test_fn.__self__, "sourceonly", False): ++ tags.append(TestTags.SOURCEONLY) + + return tags + +diff --git a/tests/utils.py b/tests/utils.py +index 82b5494..df8e787 100644 +--- a/tests/utils.py ++++ b/tests/utils.py +@@ -351,6 +351,7 @@ class TestTags(Enum): + NOSTORAGE = 5 # tests that don't work with storage + EXTRADEPS = 6 # tests that require special configuration and/or device to run + REGRESSION = 7 # regression tests ++ SOURCEONLY = 8 # tests that can't run against installed library + + + def tag_test(*tags): +@@ -362,6 +363,7 @@ def tag_test(*tags): + func.nostorage = TestTags.NOSTORAGE in tags + func.extradeps = TestTags.EXTRADEPS in tags + func.regression = TestTags.REGRESSION in tags ++ func.sourceonly = TestTags.SOURCEONLY in tags + + return func + +-- +2.20.1 + + +From 74a6630db44bd141b76aec80c4eb81fa15dea593 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Thu, 4 Apr 2019 11:55:32 +0200 +Subject: [PATCH 07/10] Skip "source only" tests when running against installed + version + +--- + tests/run_tests.py | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tests/run_tests.py b/tests/run_tests.py +index 7df9e7d..4244c06 100644 +--- a/tests/run_tests.py ++++ b/tests/run_tests.py +@@ -129,6 +129,8 @@ def _print_skip_message(test, skip_tag): + reason = "skipping test that requires special configuration" + elif skip_tag == TestTags.CORE: + reason = "skipping non-core test" ++ elif skip_tag == TestTags.SOURCEONLY: ++ reason = "skipping test that can run only against library compiled from source" + else: + reason = "unknown reason" # just to be sure there is some default value + +@@ -198,6 +200,9 @@ if __name__ == '__main__': + if TestTags.EXTRADEPS in tags and not args.jenkins: + _print_skip_message(test, TestTags.EXTRADEPS) + continue ++ if TestTags.SOURCEONLY in tags and args.installed: ++ _print_skip_message(test, TestTags.SOURCEONLY) ++ continue + + if args.core and TestTags.CORE not in tags and TestTags.REGRESSION not in tags: + _print_skip_message(test, TestTags.CORE) +-- +2.20.1 + + +From d19f2508dbfb00473b21ab1bd6f5603aec66bf4e Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Thu, 4 Apr 2019 14:26:22 +0200 +Subject: [PATCH 08/10] Force LVM cli plugin in lvm_test + +We can't rely on LVM cli plugin being default in config when +running against installed library. +--- + tests/lvm_test.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/tests/lvm_test.py b/tests/lvm_test.py +index 28a4b05..0b2c5ad 100644 +--- a/tests/lvm_test.py ++++ b/tests/lvm_test.py +@@ -12,10 +12,14 @@ from gi.repository import BlockDev, GLib + + + class LVMTestCase(unittest.TestCase): +- requested_plugins = BlockDev.plugin_specs_from_names(("lvm",)) + + @classmethod + def setUpClass(cls): ++ ps = BlockDev.PluginSpec() ++ ps.name = BlockDev.Plugin.LVM ++ ps.so_name = "libbd_lvm.so" ++ cls.requested_plugins = [ps] ++ + if not BlockDev.is_initialized(): + BlockDev.init(cls.requested_plugins, None) + else: +-- +2.20.1 + + +From f15a7428382d5ee086ed13755b3ba1f8705b79cf Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Thu, 6 Sep 2018 10:27:52 +0200 +Subject: [PATCH 09/10] Fix how we check zram stats from /sys/block/zram0/stat + +There are four new stats since kernel 4.19. Checking if we read +more than 11 values should be enough to be sure that the file +has the stats we want. +--- + tests/kbd_test.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/kbd_test.py b/tests/kbd_test.py +index 5e872c4..23b63c9 100644 +--- a/tests/kbd_test.py ++++ b/tests/kbd_test.py +@@ -192,7 +192,7 @@ class KbdZRAMStatsTestCase(KbdZRAMTestCase): + + # read 'num_reads' and 'num_writes' from '/sys/block/zram0/stat' + sys_stats = read_file("/sys/block/zram0/stat").strip().split() +- self.assertEqual(len(sys_stats), 11) ++ self.assertGreaterEqual(len(sys_stats), 11) # 15 stats since 4.19 + num_reads = int(sys_stats[0]) + num_writes = int(sys_stats[4]) + self.assertEqual(stats.num_reads, num_reads) +-- +2.20.1 + + +From 7e8f6ef031fe3e5e0b117d910cbf8de36f5bd75e Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Wed, 10 Apr 2019 07:51:48 +0200 +Subject: [PATCH 10/10] Mark 'test_set_bitmap_location' as unstable + +This test randomly fails with error message from mdadm: +"mdadm: failed to remove internal bitmap". +--- + tests/mdraid_test.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/mdraid_test.py b/tests/mdraid_test.py +index ea489db..14d0bd4 100644 +--- a/tests/mdraid_test.py ++++ b/tests/mdraid_test.py +@@ -520,7 +520,7 @@ class MDTestNameNodeBijection(MDTestCase): + self.assertTrue(succ) + + class MDTestSetBitmapLocation(MDTestCase): +- @tag_test(TestTags.SLOW) ++ @tag_test(TestTags.SLOW, TestTags.UNSTABLE) + def test_set_bitmap_location(self): + """Verify we can change bitmap location for an existing MD array""" + +-- +2.20.1 + diff --git a/SPECS/libblockdev.spec b/SPECS/libblockdev.spec index 876fe12..9fd0d25 100644 --- a/SPECS/libblockdev.spec +++ b/SPECS/libblockdev.spec @@ -120,13 +120,14 @@ Name: libblockdev Version: 2.19 -Release: 7%{?dist} +Release: 9%{?dist} Summary: A library for low-level manipulation with block devices License: LGPLv2+ URL: https://github.com/storaged-project/libblockdev Source0: https://github.com/storaged-project/libblockdev/releases/download/%{version}-%{release}/%{name}-%{version}.tar.gz Patch0: 0001-swap-error-codes.patch Patch1: 0002-major-minor-macros.patch +Patch2: 0003-gating-tests-changes.patch BuildRequires: glib2-devel %if %{with_gi} @@ -312,7 +313,6 @@ BuildRequires: libblkid-devel BuildRequires: libmount-devel Summary: The FS plugin for the libblockdev library Requires: %{name}-utils%{?_isa} = %{version}-%{release} -Requires: device-mapper-multipath %description fs The libblockdev library plugin (and in the same time a standalone library) @@ -502,7 +502,6 @@ with the libblockdev-nvdimm plugin/library. BuildRequires: parted-devel Summary: The partitioning plugin for the libblockdev library Requires: %{name}-utils%{?_isa} = %{version}-%{release} -Requires: device-mapper-multipath Requires: gdisk Requires: util-linux @@ -659,6 +658,7 @@ A meta-package that pulls all the libblockdev plugins as dependencies. %setup -q -n %{name}-%{version} %patch0 -p1 %patch1 -p1 +%patch2 -p1 %build autoreconf -ivf @@ -958,6 +958,14 @@ find %{buildroot} -type f -name "*.la" | xargs %{__rm} %files plugins-all %changelog +* Mon May 06 2019 Vojtech Trefny - 2.19-9 +- Remove device-mapper-multipath dependency from fs and part plugins (vtrefny) + Resolves: rhbz#1700297 + +* Mon Apr 08 2019 Vojtech Trefny - 2.19-8 +- Allow running tests against installed version of libblockdev (vtrefny) + Related: rhbz#1679668 + * Mon Jan 07 2019 Vojtech Trefny - 2.19-7 - Use major/minor macros from sys/sysmacros.h instead of linux/kdev_t.h (vtrefny) Resolves: rhbz#1644825