On Wed, Nov 9, 2022 at 3:51 PM Albert Esteve <aesteve@redhat.com> wrote:
Remove the outdated version of userstorage
that is stored locally at tests/storage.py

The userstorage library is required
to create the storage before running the
tests with tox, and also in the test
virtual environment. In order to satisfy
this, add a requirements.txt to the root
folder to obtain the latests userstorage
version from PyPI, and add it as a tox
dependency for tests.

Behaviour for missing storage and folder
structure remains as originally intended.

Fixture is adapted to new style so that
is uses setup and teardown before and
after every test, respectively.

Signed-off-by: Albert Esteve <aesteve@redhat.com>
---
 requirements.txt  |   1 +
 tests/conftest.py |  22 ++++---
 tests/storage.py  | 161 +++++++---------------------------------------
 tox.ini           |   1 +
 4 files changed, 36 insertions(+), 149 deletions(-)
 create mode 100644 requirements.txt

diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..d4a4b9f
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+userstorage>=0.5.1

I added tox here.
 
\ No newline at end of file
diff --git a/tests/conftest.py b/tests/conftest.py
index b40852b..79c514b 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -9,13 +9,17 @@ Fixtures for sanlock testing.
 """
 from __future__ import absolute_import

-import os
-
 import pytest
+import userstorage

-from . import storage
 from . import util

+# Mark tests with skip if userstorage is missing
+userstorage.missing_handler = pytest.skip
+
+# Requires relative path from tox basedir
+BACKENDS = userstorage.load_config("./tests/storage.py").BACKENDS
+

 class SanlockIsRunning(Exception):
     """ Raised if sanlock running when it should not """
@@ -38,8 +42,8 @@ def sanlock_daemon():


 @pytest.fixture(params=[
-    pytest.param(storage.BLOCK, id="block"),
-    pytest.param(storage.FILE, id="file"),
+    BACKENDS["block"],
+    BACKENDS["file"],
 ])
 def user_4k_path(request):
     """
@@ -48,11 +52,9 @@ def user_4k_path(request):

     If storage is not available, skip the tests.
     """
-    if not os.path.exists(request.param):
-        pytest.skip(
-            "user storage available - run 'python tests/strorage.py setup' "
-            "to enable 4k storage tests")
-    return request.param
+    backend = request.param
+    with backend:
+        yield backend.path


 @pytest.fixture
diff --git a/tests/storage.py b/tests/storage.py
index 0fe6f56..0b12e47 100644
--- a/tests/storage.py
+++ b/tests/storage.py
@@ -8,145 +8,28 @@
 storage - provide storage for sanlock tests.
 """

-import argparse
-import errno
-import logging
-import os
-import subprocess
+from userstorage import File, Mount, LoopDevice

-BASE_DIR = "/var/tmp/sanlock-storage"
-MOUNTPOINT = os.path.join(BASE_DIR, "mnt")
-
-# For testing sanlock with 4k block device.
-LOOP1 = os.path.join(BASE_DIR, "loop1")
-BACKING1 = os.path.join(BASE_DIR, "backing1")
-
-# For testing sanlock with a filesystem backed by 4k block device.
-LOOP2 = os.path.join(BASE_DIR, "loop2")
-BACKING2 = os.path.join(BASE_DIR, "backing2")
-
-# Test paths.
-BLOCK = LOOP1
-FILE = os.path.join(MOUNTPOINT, "file")
-
-log = logging.getLogger("storage")
-
-
-def main():
-    parser = argparse.ArgumentParser(
-        description='Storage helper for sanlock tests')
-    parser.add_argument("command", choices=["setup", "teardown"])
-    args = parser.parse_args()
-
-    logging.basicConfig(level=logging.INFO, format="storage: %(message)s")
-
-    if args.command == "setup":
-        setup()
-    elif args.command == "teardown":
-        teardown()
-
-
-def setup():
-    create_dir(BASE_DIR)
-
-    if not os.path.exists(LOOP1):
-        create_loop_device(LOOP1, BACKING1)
-
-    if not os.path.exists(LOOP2):
-        create_loop_device(LOOP2, BACKING2)
-        create_dir(MOUNTPOINT)
-        create_filesystem(LOOP2, MOUNTPOINT)
-
-        # Sanlock allocates spaces as needed.
-        with open(FILE, "wb") as f:
-            f.truncate(0)
-
-
-def teardown():
-    if is_mounted(MOUNTPOINT):
-        remove_filesystem(MOUNTPOINT)
-
-    if os.path.exists(LOOP2):
-        remove_loop_device(LOOP2, BACKING2)
-
-    if os.path.exists(LOOP1):
-        remove_loop_device(LOOP1, BACKING1)
-
-
-def create_loop_device(link_path, backing_file, size=1024**3,
-                       sector_size=4096):
-    log.info("Creating loop device %s", link_path)
-
-    with open(backing_file, "wb") as f:
-        f.truncate(size)
-
-    out = subprocess.check_output([
-        "sudo",
-        "losetup",
-        "-f", backing_file,
-        "--sector-size", str(sector_size),
-        "--show",
-    ])
-
-    device = out.decode("utf-8").strip()
-
-    # Remove stale symlink.
-    if os.path.islink(link_path):
-        os.unlink(link_path)
-
-    os.symlink(device, link_path)
-    chown(link_path)
-
-
-def remove_loop_device(link_path, backing_file):
-    log.info("Removing loop device %s", link_path)
-
-    subprocess.check_call(["sudo", "losetup", "-d", link_path])
-    remove_file(link_path)
-    remove_file(backing_file)
-
-
-def create_filesystem(device, mountpoint):
-    log.info("Creating filesystem %s", mountpoint)
-
-    subprocess.check_call(["sudo", "mkfs.xfs", "-q", device])
-    subprocess.check_call(["sudo", "mount", device, mountpoint])
-    chown(mountpoint)
-
-
-def remove_filesystem(mountpoint):
-    log.info("Removing filesystem %s", mountpoint)
-    subprocess.check_call(["sudo", "umount", mountpoint])
-
-
-def is_mounted(mountpoint):
-    with open("/proc/self/mounts") as f:
-        for line in f:
-            if mountpoint in line:
-                return True
-    return False
-
-
-def chown(path):
-    user_group = "%(USER)s:%(USER)s" % os.environ
-    subprocess.check_call(["sudo", "chown", user_group, path])
-
-
-def create_dir(path):
-    try:
-        os.makedirs(path)
-    except EnvironmentError as e:
-        if e.errno != errno.EEXIST:
-            raise
-
-
-def remove_file(path):
-    try:
-        os.remove(path)
-    except EnvironmentError as e:
-        if e.errno != errno.ENOENT:
-            raise
+GiB = 1024**3

+BASE_DIR = "/var/tmp/sanlock-storage"

-if __name__ == "__main__":
-    main()
+BACKENDS = {
+
+    "file":
+        File(
+            Mount(
+                LoopDevice(
+                    base_dir=BASE_DIR,
+                    name="file",
+                    size=GiB,
+                    sector_size=4096))),
+
+    "block":
+        LoopDevice(
+            base_dir=BASE_DIR,
+            name="loop",
+            size=GiB,
+            sector_size=4096),
+
+}
diff --git a/tox.ini b/tox.ini
index 8847b34..c0cf5a1 100644
--- a/tox.ini
+++ b/tox.ini
@@ -17,6 +17,7 @@ setenv =
 whitelist_externals = make
 deps =
     pytest
+    userstorage>=0.5.1
 commands =
     py{36,37,38,39,310}: make BUILDARGS="--build-lib={envsitepackagesdir}"
     pytest {posargs}
--
2.37.3