On Sat, May 18, 2019 at 9:54 PM Amit Bawer <abawer@redhat.com> wrote:
loop device is created under /dev/ as /dev/loopX

Of course, but how the tests and teardown scripts know which devices are owned
by the tests?

$ sudo losetup
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE                                          DIO LOG-SEC
/dev/loop1         0      0         1  0 /var/lib/docker/devicemapper/devicemapper/metadata   0     512
/dev/loop2         0      0         0  0 /var/tmp/sanlock-4k/backing1                         0    4096
/dev/loop0         0      0         1  0 /var/lib/docker/devicemapper/devicemapper/data       0     512
/dev/loop3         0      0         0  0 /var/tmp/sanlock-4k/backing2                         0    4096

We could search all loop devices and check which one is backed by
base_dir/backing*, but it is much simpler to use symlinks:

$ ls -lh /var/tmp/sanlock-4k/
total 27M
-rw-rw-r--. 1 nsoffer nsoffer 1.0G May 18 22:03 backing1
-rw-rw-r--. 1 nsoffer nsoffer 1.0G May 18 22:03 backing2
lrwxrwxrwx. 1 nsoffer nsoffer   10 May 18 20:45 loop1 -> /dev/loop2
lrwxrwxrwx. 1 nsoffer nsoffer   10 May 18 20:45 loop2 -> /dev/loop3
drwxr-xr-x. 2 nsoffer nsoffer   18 May 18 20:45 mnt

This is not prefect, there is some information leakage about the structure
of this directory, but I think it is good enough and much better than what
we had before.

not sure what is $base_dir in the script as it is used also for the mapped file and also for the loop device location

This is a temporary directory to hold the backing files, symlinks, and mount directory.

On Sat, May 18, 2019 at 9:26 PM Nir Soffer <nirsof@gmail.com> wrote:
Previously you had to setup the environment manually to enable the 4k
tests, and pass environment variable to tests. The tests used single
path, so you had to run the tests twice to test both 4k block device and
filesystem backed by a 4k block device.

Add setup and teardown scripts to make it easier to enable the 4k tests.

Run the setup scripts once to setup your environment:

   $ tests/setup.sh

This script create both a 4k block device and filesystem backed by a 4k
device. The user_4k_path fixture enables the tests if the device and
mount exists, and run the test twice, once with the loop device, and
once with the filesystem.

To clean up the environment, run:

   $ tests/teardown.sh

Signed-off-by: Nir Soffer <nsoffer@redhat.com>
---

The patch is also available in:
https://github.com/nirs/sanlock/commits/4k

 README.dev        | 45 +++++++++++++--------------------------------
 tests/config.py   |  4 ++++
 tests/conftest.py | 33 +++++++++------------------------
 tests/setup.sh    | 41 +++++++++++++++++++++++++++++++++++++++++
 tests/teardown.sh | 27 +++++++++++++++++++++++++++
 5 files changed, 94 insertions(+), 56 deletions(-)
 create mode 100644 tests/config.py
 create mode 100755 tests/setup.sh
 create mode 100755 tests/teardown.sh

diff --git a/README.dev b/README.dev
index bfb170c..64feb9a 100644
--- a/README.dev
+++ b/README.dev
@@ -27,44 +27,25 @@ To run only tests matching the substring "foo":


 Testing 4K support
 ==================

-This requires manual setup for creating a block device using 4k sector size,
-optionally creating and mounting a file system, and passing the test path to
-tests. The setup must be done as root, but the tests can run later as the
-current user.
+To enable the 4k tests, you need to setup your environment.

-Common setup
-------------
+    $ tests/setup.sh

-1. Create a backing file:
+This creates two loop devices with 4k sector size; one for testing
+sanlock with 4k block device, and the other for testing with a
+filesystem backed by a 4k block device.

-    $ truncate -s 1G /var/tmp/backing
+To teardown your environment:

-2. Create a loop device with 4k sector size:
+    $ tests/teardown.sh

-    $ sudo losetup -f /var/tmp/backing --show --sector-size=4096
-    /dev/loop2
+The script unmounts the filesystem and detaches the loop devices.

-3. Change the device (or mountpoint) owner to current user
+Both scripts use configuraion values in tests/config.py.
+This module is imported by the python test modules.

-    $ sudo chown $USER:$USER /dev/loop2
-
-Testing 4k block device
------------------------
-
-Run the tests with USER_4K_PATH environment variable:
-
-    $ USER_4K_PATH=/dev/loop2 tox -e py27
-
-Testing 4k file system
-----------------------
-
-To test file system on top of 4k block device, create a file system on the
-device, mount it, and create a file for testing lockspace or resources:
-
-    $ sudo mkfs.xfs /dev/loop2
-    $ sudo mount /dev/loop2 /tmp/sanlock-4k
-    $ sudo chown $USER:$USER /tmp/sanlock-4k
-    $ truncate -s 128m /tmp/sanlock-4k/disk
-    $ USER_4K_PATH=/tmp/sanlock-4k/disk tox -e py27
+The scripts use sudo to perform privileged operations. The best way to
+use them is to setup the environment once at the start of the session,
+and teardown when you finish.
diff --git a/tests/config.py b/tests/config.py
new file mode 100644
index 0000000..23f3545
--- /dev/null
+++ b/tests/config.py
@@ -0,0 +1,4 @@
+# Test configuration, used both by the shell and python.
+
+base_dir="/var/tmp/sanlock-4k"
+dev_size=1073741824
diff --git a/tests/conftest.py b/tests/conftest.py
index bb95d45..8037a24 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -5,10 +5,11 @@ Fixtures for sanlock testing.
 import os
 import stat

 import pytest

+from . import config
 from . import util


 @pytest.fixture
 def sanlock_daemon():
@@ -24,36 +25,20 @@ def sanlock_daemon():
         # which takes about 3 seconds, slowing down the tests.
         p.kill()
         p.wait()


-@pytest.fixture
-def user_4k_path():
+@pytest.fixture(params=[
+    pytest.param("loop1", id="block"),
+    pytest.param("mnt/file", id="file")
+])
+def user_4k_path(request):
     """
     A path to block device or file on file system on top of 4k block device,
     provided by the user.

-    The user must create the block device or the file system before running the
-    tests, and specify the path to the file in the USER_4K_PATH environment
-    variable.
-
-    If USER_4K_PATH was not specified, tests using this fixture will be skipped.
-    If USER_4K_PATH was specified but does not exist, or is not a file or block
-    device, RuntimeError is raised.
-
-    Return path to the user specified file.
+    If 4k tests were not enabled, skip the tests.
     """
-    path = os.environ.get("USER_4K_PATH")
-    if path is None:
-        pytest.skip("USER_4K_PATH pointing to a 4k block device or file was "
-                    "not specified")
-
+    path = os.path.join(config.base_dir, request.param)
     if not os.path.exists(path):
-        raise RuntimeError("USER_4K_PATH {!r} does not exist".format(path))
-
-    mode = os.stat(path).st_mode
-    if not (stat.S_ISBLK(mode) or stat.S_ISREG(mode)):
-        raise RuntimeError(
-            "USER_4K_PATH {!r} is not a block device or regular file"
-            .format(path))
-
+        pytest.skip("4k tests disabled, run tests/setup.sh to enable")
     return path
diff --git a/tests/setup.sh b/tests/setup.sh
new file mode 100755
index 0000000..7f9046b
--- /dev/null
+++ b/tests/setup.sh
@@ -0,0 +1,41 @@
+#!/bin/sh -e
+# Run this once to setup your environment for testing sanlock.
+#
+# The script creates 2 loop devices, and link them to:
+#
+#    $base_dir/loop{1,2}
+#
+# And mount a filesystem on:
+#
+#    $base_dir/mnt
+#
+# The teardown script unmount and detach the loop devices and remove the links.
+#
+
+. tests/config.py
+
+mkdir -p "$base_dir"
+
+if [ ! -e "$base_dir/loop1" ]; then
+    echo "  Creating 4k loop device $base_dir/loop1"
+    truncate -s $dev_size "$base_dir/backing1"
+    loop1=$(sudo losetup -f "$base_dir/backing1" --show --sector-size 4096)
+    ln -s "$loop1" "$base_dir/loop1"
+    sudo chown $USER:$USER "$base_dir/loop1"
+fi
+
+if [ ! -e "$base_dir/loop2" ]; then
+    echo "  Creating 4k loop device $base_dir/loop2"
+    truncate -s $dev_size "$base_dir/backing2"
+    loop2=$(sudo losetup -f "$base_dir/backing2" --show --sector-size 4096)
+    ln -s "$loop2" "$base_dir/loop2"
+
+    echo "  Mounting 4k filesystem at $base_dir/mnt"
+    sudo mkfs.xfs -q "$base_dir/loop2"
+    mkdir -p "$base_dir/mnt"
+    sudo mount "$base_dir/loop2" "$base_dir/mnt"
+    sudo chown $USER:$USER "$base_dir/mnt"
+    touch "$base_dir/mnt/file"
+fi
+
+# vim: set expandtab shiftwidth=4 tabstop=4 :
diff --git a/tests/teardown.sh b/tests/teardown.sh
new file mode 100755
index 0000000..9342e0a
--- /dev/null
+++ b/tests/teardown.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+# Run this to teardown your environment.
+#
+# The script undoes the actions perfomed in setup.sh.
+
+. tests/config.py
+
+if grep -q "$base_dir/mnt" /proc/self/mounts; then
+    echo "  Umounting $base_dir/mnt"
+    sudo umount "$base_dir/mnt"
+fi
+
+if [ -h "$base_dir/loop1" ]; then
+    echo "  Detaching $base_dir/loop2"
+    sudo losetup -d "$base_dir/loop2"
+fi
+
+if [ -h "$base_dir/loop2" ]; then
+    echo "  Detaching $base_dir/loop1"
+    sudo losetup -d "$base_dir/loop1"
+fi
+
+echo "  Cleaning up $base_dir"
+rm -f "$base_dir/loop"*
+rm -f "$base_dir/backing"*
+
+# vim: set expandtab shiftwidth=4 tabstop=4 :
--
2.17.2