Blame SOURCES/0003-gating-tests-changes.patch

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