[prev in list] [next in list] [prev in thread] [next in thread] 

List:       sanlock-devel
Subject:    [PATCH 3/3] tests: Test reading and writing large offsets
From:       Nir Soffer <nirsof () gmail ! com>
Date:       2019-04-19 15:24:38
Message-ID: 20190419152438.968-4-nsoffer () redhat ! com
[Download RAW message or body]

The python module uses "k" format string[1] to convert lockspace offset
and PyInt_AsLong[2] to convert disk offset.  Both return long, while
sanlock offset use uint64_t.  This is not correct on all systems but I'm
not sure we support any system when sizeof(long) < 8.

Add tests for large offset exceeding LONG_MAX to check that current code
actually works. Vdsm does not use such offset yet, but when using 4k
sector size and 2 MiB alignment, vdsm will access such offset.

Theoretically we can test up to (16 TiB - 1 MiB) offset, but testing
show that practical maximum file size is about 15 TiB.  To make the test
less likely to fail on developer machine or CI slave, use 1 TiB file for
testing large offset.

[1] https://docs.python.org/2.7/c-api/arg.html
    (see k (integer) [unsigned long])
[2] https://docs.python.org/2.7/c-api/int.html#c.PyInt_AsLong

Signed-off-by: Nir Soffer <nsoffer@redhat.com>
---
 tests/python_test.py | 91 +++++++++++++++++++++++++++++++-------------
 1 file changed, 64 insertions(+), 27 deletions(-)

diff --git a/tests/python_test.py b/tests/python_test.py
index be1e3ab..5029924 100644
--- a/tests/python_test.py
+++ b/tests/python_test.py
@@ -12,80 +12,111 @@ import pytest
 import sanlock
 
 from . import constants
 from . import util
 
-
-def test_write_lockspace(tmpdir, sanlock_daemon):
+# Largest file size on ext4 is 16TiB, and on xfs 500 TiB. Use 1 TiB as it is
+# large enough to test large offsets, and less likely to fail on developer
+# machine or CI slave.
+# See https://access.redhat.com/articles/rhel-limits
+LARGE_FILE_SIZE = 1024**4
+
+LOCKSPACE_SIZE = 1024**2
+MIN_RES_SIZE = 1024**2
+
+
+@pytest.mark.parametrize("size,offset", [
+    # Smallest offset.
+    (LOCKSPACE_SIZE, 0),
+    # Large offset.
+    (LARGE_FILE_SIZE, LARGE_FILE_SIZE - LOCKSPACE_SIZE),
+])
+def test_write_lockspace(tmpdir, sanlock_daemon, size, offset):
     path = str(tmpdir.join("lockspace"))
-    size = 1024**2
     util.create_file(path, size)
 
-    sanlock.write_lockspace("name", path, offset=0, iotimeout=1)
+    sanlock.write_lockspace("name", path, offset=offset, iotimeout=1)
 
-    ls = sanlock.read_lockspace(path, offset=0)
+    ls = sanlock.read_lockspace(path, offset=offset)
     assert ls == {"iotimeout": 1, "lockspace": "name"}
 
-    acquired = sanlock.inq_lockspace("name", 1, path, wait=False)
+    acquired = sanlock.inq_lockspace(
+        "name", 1, path, offset=offset, wait=False)
     assert acquired is False
 
     with io.open(path, "rb") as f:
+        f.seek(offset)
         magic, = struct.unpack("< I", f.read(4))
         assert magic == constants.DELTA_DISK_MAGIC
 
         # TODO: check more stuff here...
 
     util.check_guard(path, size)
 
 
-def test_write_resource(tmpdir, sanlock_daemon):
+@pytest.mark.parametrize("size,offset", [
+    # Smallest offset.
+    (MIN_RES_SIZE, 0),
+    # Large offset.
+    (LARGE_FILE_SIZE, LARGE_FILE_SIZE - MIN_RES_SIZE),
+])
+def test_write_resource(tmpdir, sanlock_daemon, size, offset):
     path = str(tmpdir.join("resources"))
-    size = 1024**2
     util.create_file(path, size)
-    disks = [(path, 0)]
+    disks = [(path, offset)]
 
     sanlock.write_resource("ls_name", "res_name", disks)
 
-    res = sanlock.read_resource(path, 0)
+    res = sanlock.read_resource(path, offset=offset)
     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:
+        f.seek(offset)
         magic, = struct.unpack("< I", f.read(4))
         assert magic == constants.PAXOS_DISK_MAGIC
 
         # TODO: check more stuff here...
 
     util.check_guard(path, size)
 
 
-def test_add_rem_lockspace(tmpdir, sanlock_daemon):
+@pytest.mark.parametrize("size,offset", [
+    # Smallest offset.
+    (MIN_RES_SIZE, 0),
+    # Large offset.
+    (LARGE_FILE_SIZE, LARGE_FILE_SIZE - MIN_RES_SIZE),
+])
+def test_add_rem_lockspace(tmpdir, sanlock_daemon, size, offset):
     path = str(tmpdir.join("ls_name"))
-    util.create_file(path, 1024**2)
+    util.create_file(path, size)
 
-    sanlock.write_lockspace("ls_name", path, iotimeout=1)
+    sanlock.write_lockspace("ls_name", path, offset=offset, iotimeout=1)
 
     # Since the lockspace is not acquired, we exepect to get False.
-    acquired = sanlock.inq_lockspace("ls_name", 1, path, wait=False)
+    acquired = sanlock.inq_lockspace(
+        "ls_name", 1, path, offset=offset, wait=False)
     assert acquired is False
 
-    sanlock.add_lockspace("ls_name", 1, path, iotimeout=1)
+    sanlock.add_lockspace("ls_name", 1, path, offset=offset, iotimeout=1)
 
     # Once the lockspace is acquired, we exepect to get True.
-    acquired = sanlock.inq_lockspace("ls_name", 1, path, wait=False)
+    acquired = sanlock.inq_lockspace(
+        "ls_name", 1, path, offset=offset, wait=False)
     assert acquired is True
 
-    sanlock.rem_lockspace("ls_name", 1, path)
+    sanlock.rem_lockspace("ls_name", 1, path, offset=offset)
 
     # Once the lockspace is released, we exepect to get False.
-    acquired = sanlock.inq_lockspace("ls_name", 1, path, wait=False)
+    acquired = sanlock.inq_lockspace(
+        "ls_name", 1, path, offset=offset, wait=False)
     assert acquired is False
 
 
 def test_add_rem_lockspace_async(tmpdir, sanlock_daemon):
     path = str(tmpdir.join("ls_name"))
@@ -121,33 +152,39 @@ def test_add_rem_lockspace_async(tmpdir, sanlock_daemon):
     # Once the lockspace was released, we expect to get False.
     acquired = sanlock.inq_lockspace("ls_name", 1, path, wait=True)
     assert acquired is False
 
 
-def test_acquire_release_resource(tmpdir, sanlock_daemon):
+@pytest.mark.parametrize("size,offset", [
+    # Smallest offset.
+    (MIN_RES_SIZE, 0),
+    # Large offset.
+    (LARGE_FILE_SIZE, LARGE_FILE_SIZE - MIN_RES_SIZE),
+])
+def test_acquire_release_resource(tmpdir, sanlock_daemon, size, offset):
     ls_path = str(tmpdir.join("ls_name"))
-    util.create_file(ls_path, 1024**2)
+    util.create_file(ls_path, size)
 
     res_path = str(tmpdir.join("res_name"))
-    util.create_file(res_path, 1024**2)
+    util.create_file(res_path, size)
 
-    sanlock.write_lockspace("ls_name", ls_path, iotimeout=1)
-    sanlock.add_lockspace("ls_name", 1, ls_path, iotimeout=1)
+    sanlock.write_lockspace("ls_name", ls_path, offset=offset, iotimeout=1)
+    sanlock.add_lockspace("ls_name", 1, ls_path, offset=offset, iotimeout=1)
 
     # Host status is not available until the first renewal.
     with pytest.raises(sanlock.SanlockException) as e:
         sanlock.get_hosts("ls_name", 1)
     assert e.value.errno == errno.EAGAIN
 
     time.sleep(1)
     host = sanlock.get_hosts("ls_name", 1)[0]
     assert host["flags"] == sanlock.HOST_LIVE
 
-    disks = [(res_path, 0)]
+    disks = [(res_path, offset)]
     sanlock.write_resource("ls_name", "res_name", disks)
 
-    res = sanlock.read_resource(res_path, 0)
+    res = sanlock.read_resource(res_path, offset=offset)
     assert res == {
         "lockspace": "ls_name",
         "resource": "res_name",
         "version": 0
     }
@@ -156,11 +193,11 @@ def test_acquire_release_resource(tmpdir, sanlock_daemon):
     assert owners == []
 
     fd = sanlock.register()
     sanlock.acquire("ls_name", "res_name", disks, slkfd=fd)
 
-    res = sanlock.read_resource(res_path, 0)
+    res = sanlock.read_resource(res_path, offset=offset)
     assert res == {
         "lockspace": "ls_name",
         "resource": "res_name",
         "version": 1
     }
@@ -177,11 +214,11 @@ def test_acquire_release_resource(tmpdir, sanlock_daemon):
     assert host["flags"] == sanlock.HOST_LIVE
     assert host["generation"] == owner["generation"]
 
     sanlock.release("ls_name", "res_name", disks, slkfd=fd)
 
-    res = sanlock.read_resource(res_path, 0)
+    res = sanlock.read_resource(res_path, offset=offset)
     assert res == {
         "lockspace": "ls_name",
         "resource": "res_name",
         "version": 1
     }
-- 
2.17.2
_______________________________________________
sanlock-devel mailing list -- sanlock-devel@lists.fedorahosted.org
To unsubscribe send an email to sanlock-devel-leave@lists.fedorahosted.org
Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: https://lists.fedorahosted.org/archives/list/sanlock-devel@lists.fedorahosted.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic