]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
qa: Added workunits for testing problem snippets on rmw workloads
authorChristopher Hoffman <choffman@redhat.com>
Mon, 17 Jun 2024 15:50:51 +0000 (15:50 +0000)
committerChristopher Hoffman <choffman@redhat.com>
Wed, 5 Nov 2025 13:59:34 +0000 (13:59 +0000)
Fixes: https://tracker.ceph.com/issues/66038
Signed-off-by: Christopher Hoffman <choffman@redhat.com>
qa/suites/fs/fscrypt/tasks/1-tests/fscrypt-snippets.yaml [new file with mode: 0644]
qa/tasks/cephfs/test_fscrypt.py
qa/workunits/suites/fscrypt-snippets.py [new file with mode: 0755]
qa/workunits/suites/fscrypt-snippets.sh [new file with mode: 0755]

diff --git a/qa/suites/fs/fscrypt/tasks/1-tests/fscrypt-snippets.yaml b/qa/suites/fs/fscrypt/tasks/1-tests/fscrypt-snippets.yaml
new file mode 100644 (file)
index 0000000..0b2947f
--- /dev/null
@@ -0,0 +1,7 @@
+tasks:
+- workunit:
+    timeout: 6h
+    clients:
+      client.0:
+        - fs/fscrypt.sh none fscrypt-snippets
+        - fs/fscrypt.sh unlocked fscrypt-snippets
index 88c9d246e73f7b497318a90bea341e390f462005..a9a4fb5ae75a053254d43eae70942968965fea21 100644 (file)
@@ -90,6 +90,43 @@ class TestFSCryptRecovery(FSCryptTestCase):
 
         self.mount_a.run_shell_payload(f"cd {self.path} && stat {file}")
 
+class TestFSCryptRMW(FSCryptTestCase):
+    def test_fscrypt_overwrite_block_boundary():
+        """Test writing data with small, half write on previous block and trailing on new block"""
+
+        file = 'file.log'
+
+        size = 5529
+        offset = 3379
+        contents = 's' * size
+        self.mount_a.write_file(file, contents, offset)
+
+        #s = write_fill(fd, 's', 5529, 6144)
+        sleep(10)
+
+        size = 4033
+        offset = 4127
+        contents = 't' * size
+        self.mount_a.write_file(file, contents, offset)
+        #s = write_fill(fd, 't', 4033, 6144)
+
+    def test_fscrypt_huge_hole(self):
+        """Test writing data with huge hole, half write on previous block and trailing on new block"""
+
+        file = 'file.log'
+
+        size = 4096
+        offset = 2147477504
+        contents = 's' * size
+        self.mount_a.write_file(file, contents, offset)
+        #s = write_fill(fd, 's', 4096, 107374182400)
+        sleep(10)
+
+        size = 8
+        offset = 12
+        contents = 't' * size
+        self.mount_a.write_file(file, contents, offset)
+        #s = write_fill(fd, 't', 8, 16)
 
 class TestFSCryptXFS(XFSTestsDev):
 
diff --git a/qa/workunits/suites/fscrypt-snippets.py b/qa/workunits/suites/fscrypt-snippets.py
new file mode 100755 (executable)
index 0000000..6984f18
--- /dev/null
@@ -0,0 +1,167 @@
+#! /usr/bin/env python3
+
+import hashlib
+import os
+from time import sleep
+
+def write_fill(fd, fill, size, offset):
+  s = ''
+  for i in range(0,size):
+    s += fill
+
+  os.lseek(fd, offset - int(size / 2), 0)
+  os.write(fd, str.encode(s))
+
+def test_overwrite_block_boundary():
+  """Test writing data with small, half write on previous block and trailing on new block"""
+
+  file = 'file.log'
+  fd = os.open(file, os.O_RDWR|os.O_CREAT)
+
+  s = write_fill(fd, 's', 5529, 6144)
+  sleep(10)
+  s = write_fill(fd, 't', 4033, 6144)
+
+  os.close(fd)
+  os.remove(file)
+
+def test_huge_hole():
+  """Test writing data with huge hole, half write on previous block and trailing on new block"""
+
+  file = 'file.log'
+  fd = os.open(file, os.O_RDWR|os.O_CREAT)
+
+  s = write_fill(fd, 's', 4096, 107374182400)
+  sleep(10)
+  s = write_fill(fd, 't', 8, 16)
+
+  os.close(fd)
+  os.remove(file)
+
+def test_med_hole_write_boundary():
+  """Test writing data past many holes on offset 0 of block"""
+
+  file = 'file.log'
+
+  fd = os.open(file, os.O_RDWR|os.O_CREAT)
+
+  #reproducing sys calls after ffsb bench has started
+  fill = '\0'
+  size = 3192
+  offset = 60653568
+
+  s = ''
+  for i in range(0,size):
+    s += fill
+
+  os.lseek(fd, offset, 0)
+  os.write(fd, str.encode(s))
+
+  os.close(fd)
+  os.remove(file)
+
+def test_simple_rmw():
+  """ Test simple rmw"""
+
+  file = 'file.log'
+  match_hash='08723317846e79780c8c9521b0f4bc49'
+
+  fd = os.open(file, os.O_RDWR|os.O_CREAT)
+
+  s = write_fill(fd, 's', 32, 16)
+  s = write_fill(fd, 't', 8, 16)
+
+  os.close(fd)
+
+  fd = os.open(file, os.O_RDWR|os.O_CREAT)
+  m = hashlib.md5()
+
+  m.update(os.read(fd, 32))
+  os.close(fd)
+
+  if match_hash != m.hexdigest():
+    raise
+
+  os.remove(file)
+
+def test_truncate_overwrite():
+  """ Test copy smaller file -> larger file gets new file size"""
+
+  file1 = 'file1.log'
+  file2 = 'file2.log'
+  expected_size = 1024
+
+  fd = os.open(file1, os.O_WRONLY|os.O_CREAT)
+  os.close(fd)
+  fd = os.open(file2, os.O_WRONLY|os.O_CREAT)
+  os.close(fd)
+
+  os.truncate(file1, 1048576)
+  os.truncate(file2, 1024)
+
+  #simulate copy file2 -> file1
+  fd = os.open(file1, os.O_WRONLY|os.O_TRUNC)
+  fd2 = os.open(file2, os.O_RDONLY)
+  os.copy_file_range(fd2, fd, 9223372035781033984)
+  os.close(fd)
+  os.close(fd2)
+
+  if os.stat(file1).st_size != expected_size:
+    raise
+
+  os.remove(file1)
+  os.remove(file2)
+
+def test_truncate_path():
+  """ Test overwrite/cp displays effective_size and not real size"""
+
+  file = 'file1.log'
+  expected_size = 68686
+
+  #fstest create test1 0644;
+  fd = os.open(file, os.O_WRONLY|os.O_CREAT)
+  os.close(fd)
+  #fstest truncate test1 68686;
+  os.truncate(file, expected_size)
+
+  #fstest stat test1 size
+  if os.lstat(file).st_size != expected_size:
+      raise
+  #stat above command returns 69632 instead of truncated value.
+
+  os.remove(file)
+
+def test_lchown_symlink():
+  """ Test lchown to ensure target is set"""
+
+  file1 = 'file1.log'
+  fd = os.open(file1, os.O_WRONLY|os.O_CREAT)
+  os.close(fd)
+
+  #fstest symlink file1 symlink1
+  file2 = 'symlink'
+  os.symlink(file1, file2)
+
+  #fstest lchown symlink1 135 579
+  os.lchown(file2, 135, 579)
+
+  # ls -l
+  #-rw-r--r--. 1 root root  0 Apr 22 18:11 file1
+  #lrwxrwxrwx. 1  135  579 46 Apr 22 18:11 symlink1 -> ''$'\266\310''%'$'\005''W'$'\335''.'$'\355\211''kblD'$'\300''gq'$'\002\236\367''3'$'\255\201\001''Z6;'$'\221''&'$'\216\331\177''Q'
+  if os.readlink(file2) != file1:
+      raise
+
+  os.remove(file1)
+  os.remove(file2)
+
+def main():
+  test_overwrite_block_boundary()
+  test_huge_hole()
+  test_med_hole_write_boundary()
+  test_simple_rmw()
+  test_truncate_overwrite()
+  test_truncate_path()
+  test_lchown_symlink()
+
+if __name__ == '__main__':
+  main()
diff --git a/qa/workunits/suites/fscrypt-snippets.sh b/qa/workunits/suites/fscrypt-snippets.sh
new file mode 100755 (executable)
index 0000000..ffb9a54
--- /dev/null
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+#find which dir shell script is ran from
+DIR=$(dirname -- "$( readlink -f -- "$0"; )")
+PYTHON_SCRIPT="fscrypt-snippets.py"
+
+#run it
+${DIR}/${PYTHON_SCRIPT}