]> git.proxmox.com Git - ceph.git/blobdiff - ceph/qa/tasks/cephfs/test_subvolume.py
update ceph source to reef 18.1.2
[ceph.git] / ceph / qa / tasks / cephfs / test_subvolume.py
diff --git a/ceph/qa/tasks/cephfs/test_subvolume.py b/ceph/qa/tasks/cephfs/test_subvolume.py
new file mode 100644 (file)
index 0000000..1ebb137
--- /dev/null
@@ -0,0 +1,170 @@
+import logging
+
+from tasks.cephfs.cephfs_test_case import CephFSTestCase
+from teuthology.exceptions import CommandFailedError
+
+log = logging.getLogger(__name__)
+
+
+class TestSubvolume(CephFSTestCase):
+    CLIENTS_REQUIRED = 1
+    MDSS_REQUIRED = 1
+
+    def setUp(self):
+        super().setUp()
+        self.setup_test()
+
+    def tearDown(self):
+        # clean up
+        self.cleanup_test()
+        super().tearDown()
+
+    def setup_test(self):
+        self.mount_a.run_shell(['mkdir', 'group'])
+        self.mount_a.run_shell(['mkdir', 'group/subvol1'])
+        self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume',
+                                '-v', '1', 'group/subvol1'])
+        self.mount_a.run_shell(['mv', 'group/subvol1', 'group/subvol2'])
+
+    def cleanup_test(self):
+        self.mount_a.run_shell(['rm', '-rf', 'group'])
+
+    def test_subvolume_move_out_file(self):
+        """
+        To verify that file can't be moved out of subvolume
+        """
+        self.mount_a.run_shell(['touch', 'group/subvol2/file1'])
+
+        # file can't be moved out of a subvolume
+        with self.assertRaises(CommandFailedError):
+            self.mount_a.run_shell(['rename', 'group/subvol2/file1',
+                                    'group/file1', 'group/subvol2/file1'])
+
+
+    def test_subvolume_move_in_file(self):
+        """
+        To verify that file can't be moved into subvolume
+        """
+        # file can't be moved into a subvolume
+        self.mount_a.run_shell(['touch', 'group/file2'])
+        with self.assertRaises(CommandFailedError):
+            self.mount_a.run_shell(['rename', 'group/file2',
+                                    'group/subvol2/file2', 'group/file2'])
+
+    def test_subvolume_hardlink_to_outside(self):
+        """
+        To verify that file can't be hardlinked to outside subvolume
+        """
+        self.mount_a.run_shell(['touch', 'group/subvol2/file1'])
+
+        # create hard link within subvolume
+        self.mount_a.run_shell(['ln',
+                                'group/subvol2/file1', 'group/subvol2/file1_'])
+
+        # hard link can't be created out of subvolume
+        with self.assertRaises(CommandFailedError):
+            self.mount_a.run_shell(['ln',
+                                    'group/subvol2/file1', 'group/file1_'])
+
+    def test_subvolume_hardlink_to_inside(self):
+        """
+        To verify that file can't be hardlinked to inside subvolume
+        """
+        self.mount_a.run_shell(['touch', 'group/subvol2/file1'])
+
+        # create hard link within subvolume
+        self.mount_a.run_shell(['ln',
+                                'group/subvol2/file1', 'group/subvol2/file1_'])
+
+        # hard link can't be created inside subvolume
+        self.mount_a.run_shell(['touch', 'group/file2'])
+        with self.assertRaises(CommandFailedError):
+            self.mount_a.run_shell(['ln',
+                                    'group/file2', 'group/subvol2/file2_'])
+
+    def test_subvolume_snapshot_inside_subvolume_subdir(self):
+        """
+        To verify that snapshot can't be taken for a subvolume subdir
+        """
+        self.mount_a.run_shell(['touch', 'group/subvol2/file1'])
+
+        # create snapshot at subvolume root
+        self.mount_a.run_shell(['mkdir', 'group/subvol2/.snap/s1'])
+
+        # can't create snapshot in a descendent dir of subvolume
+        self.mount_a.run_shell(['mkdir', 'group/subvol2/dir'])
+        with self.assertRaises(CommandFailedError):
+            self.mount_a.run_shell(['mkdir', 'group/subvol2/dir/.snap/s2'])
+
+        # clean up
+        self.mount_a.run_shell(['rmdir', 'group/subvol2/.snap/s1'])
+
+    def test_subvolume_file_move_across_subvolumes(self):
+        """
+        To verify that file can't be moved across subvolumes
+        """
+        self.mount_a.run_shell(['touch', 'group/subvol2/file1'])
+
+        # create another subvol
+        self.mount_a.run_shell(['mkdir', 'group/subvol3'])
+        self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume',
+                                '-v', '1', 'group/subvol3'])
+
+        # can't move file across subvolumes
+        with self.assertRaises(CommandFailedError):
+            self.mount_a.run_shell(['rename', 'group/subvol2/file1',
+                                    'group/subvol3/file1',
+                                    'group/subvol2/file1'])
+
+    def test_subvolume_hardlink_across_subvolumes(self):
+        """
+        To verify that hardlink can't be created across subvolumes
+        """
+        self.mount_a.run_shell(['touch', 'group/subvol2/file1'])
+
+        # create another subvol
+        self.mount_a.run_shell(['mkdir', 'group/subvol3'])
+        self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume',
+                                '-v', '1', 'group/subvol3'])
+
+        # can't create hard link across subvolumes
+        with self.assertRaises(CommandFailedError):
+            self.mount_a.run_shell(['ln', 'group/subvol2/file1',
+                                    'group/subvol3/file1'])
+
+    def test_subvolume_create_subvolume_inside_subvolume(self):
+        """
+        To verify that subvolume can't be created inside a subvolume
+        """
+        # can't create subvolume inside a subvolume
+        self.mount_a.run_shell(['mkdir', 'group/subvol2/dir'])
+        with self.assertRaises(CommandFailedError):
+            self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume',
+                                    '-v', '1', 'group/subvol2/dir'])
+
+    def test_subvolume_create_snapshot_inside_new_subvolume_parent(self):
+        """
+        To verify that subvolume can't be created inside a new subvolume parent
+        """
+        self.mount_a.run_shell(['touch', 'group/subvol2/file1'])
+
+        # clear subvolume flag
+        self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume',
+                                '-v', '0', 'group/subvol2'])
+
+        # create a snap
+        self.mount_a.run_shell(['mkdir', 'group/subvol2/dir'])
+        self.mount_a.run_shell(['mkdir', 'group/subvol2/dir/.snap/s2'])
+
+        # override subdir subvolume with parent subvolume
+        self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume',
+                                '-v', '1', 'group/subvol2/dir'])
+        self.mount_a.run_shell(['setfattr', '-n', 'ceph.dir.subvolume',
+                                '-v', '1', 'group/subvol2'])
+
+        # can't create a snap in a subdir of a subvol parent
+        with self.assertRaises(CommandFailedError):
+            self.mount_a.run_shell(['mkdir', 'group/subvol2/dir/.snap/s3'])
+
+        # clean up
+        self.mount_a.run_shell(['rmdir', 'group/subvol2/dir/.snap/s2'])