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
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) + 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