On Sun, May 5, 2019 at 5:26 PM Nir Soffer <nirsof@gmail.com> wrote:
We added API for using 4k sector size and various alignments, but there
are not tests for the new APIs yet. Testing 4k block size is more
complicated since creating a block device and mounting file systems
requires root, and we like to run the tests as a regular user.

Add new tests for writing and reading lockspace and resource using 4k
storage provided by the user. If a path is not specified the tests are
skipped.

To run the tests, you need to create a block device using 4k sector size
and optionally create a file system and mount it. The process is
explained in README.dev.

Then pass the path of the block device or file on the new file system to
the tests:

    SANLOCK_4K_PATH=/dev/loop2 tox -e py26

py27
 

Adding and removing lockspace and acquiring resources is not tested yet
with 4k.

Signed-off-by: Nir Soffer <nsoffer@redhat.com>
---
 README.dev           | 44 ++++++++++++++++++++++++++
 tests/python_test.py | 73 ++++++++++++++++++++++++++++++++++++++++++++
 tox.ini              |  2 +-
 3 files changed, 118 insertions(+), 1 deletion(-)

diff --git a/README.dev b/README.dev
index 3519993..04617aa 100644
--- a/README.dev
+++ b/README.dev
@@ -22,5 +22,49 @@ To run only test from some modules:
     $ tox tests/daemon_test.py

 To run only tests matching the substring "foo":

     $ tox -- -k 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.
+
+Common setup
+------------
+
+1. Create a backing file:
+
+    $ truncate -s 1G /var/tmp/backing
+
+2. Create a loop device with 4k sector size:
+
+    $ sudo losetup -f /var/tmp/backing --show --sector-size=4096
+    /dev/loop2
+
+3. Change the device (or mountpoint) owner to current user
+
+    $ sudo chown $USER:$USER /dev/loop2
+
+Testing 4k block device
+-----------------------
+
+Run the tests with SANLOCK_4K_PATH environment variable:
+
+    $ SANLOCK_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
+    $ SANLOCK_4K_PATH=/tmp/sanlock-4k/disk tox -e py27
diff --git a/tests/python_test.py b/tests/python_test.py
index a0474f1..290ac51 100644
--- a/tests/python_test.py
+++ b/tests/python_test.py
@@ -2,10 +2,11 @@
 Test sanlock python binding with sanlock daemon.
 """

 import errno
 import io
+import os
 import struct
 import time

 import pytest

@@ -23,10 +24,11 @@ LARGE_FILE_SIZE = 1024**4
 LOCKSPACE_SIZE = 1024**2
 MIN_RES_SIZE = 1024**2

 ALIGNMENT_1M = 1024**2
 SECTOR_SIZE_512 = 512
+SECTOR_SIZE_4K = 4096


 @pytest.mark.parametrize("size,offset", [
     # Smallest offset.
     (LOCKSPACE_SIZE, 0),
@@ -64,10 +66,43 @@ def test_write_lockspace(tmpdir, sanlock_daemon, size, offset):
         # TODO: check more stuff here...

     util.check_guard(path, size)


+@pytest.mark.skipif(
+    "SANLOCK_4K_PATH" not in os.environ,
+    reason="Requires user specified path using 4k block size")
+@pytest.mark.parametrize("align", sanlock.ALIGN_SIZE)
+def test_write_lockspace_4k(sanlock_daemon, align):
+    path = os.environ["SANLOCK_4K_PATH"]
+
+    # Postion lockspace area, ensuring that previous tests will not break this
+    # test, and sanlock does not write after the lockspace area.
+    with io.open(path, "rb+") as f:
+        f.write(align * b"x")
+        f.write(4096 * b"X")
+
+    sanlock.write_lockspace(
+        "name", path, iotimeout=1, align=align, sector=SECTOR_SIZE_4K)
+
+    ls = sanlock.read_lockspace(path, align=align, sector=SECTOR_SIZE_4K)
+
+    assert ls == {"iotimeout": 1, "lockspace": "name"}
+
+    acquired = sanlock.inq_lockspace("name", 1, path, wait=False)
+    assert acquired is False
+
+    with io.open(path, "rb") as f:
+        # Verify that lockspace was written.
+        magic, = struct.unpack("< I", f.read(4))
+        assert magic == constants.DELTA_DISK_MAGIC
+
+        # Check that sanlock did not write after the lockspace area.
+        f.seek(align)
+        assert f.read(4096) == b"X" * 4096
+
+
 @pytest.mark.parametrize("size,offset", [
     # Smallest offset.
     (MIN_RES_SIZE, 0),
     # Large offset.
     (LARGE_FILE_SIZE, LARGE_FILE_SIZE - MIN_RES_SIZE),
@@ -111,10 +146,48 @@ def test_write_resource(tmpdir, sanlock_daemon, size, offset):
         # TODO: check more stuff here...

     util.check_guard(path, size)


+@pytest.mark.skipif(
+    "SANLOCK_4K_PATH" not in os.environ,
+    reason="Requires user specified path using 4k block size")
+@pytest.mark.parametrize("align", sanlock.ALIGN_SIZE)
+def test_write_resource_4k(sanlock_daemon, align):
+    path = os.environ["SANLOCK_4K_PATH"]
+    disks = [(path, 0)]
+
+    # Postion resource area, ensuring that previous tests will not break this
+    # test, and sanlock does not write after the lockspace area.
+    with io.open(path, "rb+") as f:
+        f.write(align * b"x")
+        f.write(4096 * b"X")
+
+    sanlock.write_resource(
+        "ls_name", "res_name", disks, align=align, sector=SECTOR_SIZE_4K)
+
+    res = sanlock.read_resource(path, align=align, sector=SECTOR_SIZE_4K)
+
+    assert res == {
+        "lockspace": "ls_name",
+        "resource": "res_name",
+        "version": 0
+    }
+
+    owners = sanlock.read_resource_owners("ls_name", "res_name", disks)

We need to specify align and sector size here - but we did not add these argument!

I will send v2 after adding align and sector arguments.
 
+    assert owners == []
+
+    with io.open(path, "rb") as f:
+        # Verify that resource was written.
+        magic, = struct.unpack("< I", f.read(4))
+        assert magic == constants.PAXOS_DISK_MAGIC
+
+        # Check that sanlock did not write after the resource area.
+        f.seek(align)
+        assert f.read(4096) == b"X" * 4096
+
+
 @pytest.mark.parametrize("size,offset", [
     # Smallest offset.
     (MIN_RES_SIZE, 0),
     # Large offset.
     (LARGE_FILE_SIZE, LARGE_FILE_SIZE - MIN_RES_SIZE),
diff --git a/tox.ini b/tox.ini
index 1c2349e..d21f2f3 100644
--- a/tox.ini
+++ b/tox.ini
@@ -7,11 +7,11 @@
 envlist = py27,py36
 skipsdist = True
 skip_missing_interpreters = True

 [testenv]
-passenv = USER
+passenv = *
 setenv =
     LD_LIBRARY_PATH={env:PWD}/wdmd:{env:PWD}/src
     SANLOCK_PRIVILEGED=0
     SANLOCK_RUN_DIR=/tmp/sanlock
 whitelist_externals = make
--
2.17.2


DO NOT MERGE :-)