summaryrefslogtreecommitdiffstats
path: root/qa/tasks/cephfs/test_subvolume.py
diff options
context:
space:
mode:
Diffstat (limited to 'qa/tasks/cephfs/test_subvolume.py')
-rw-r--r--qa/tasks/cephfs/test_subvolume.py170
1 files changed, 170 insertions, 0 deletions
diff --git a/qa/tasks/cephfs/test_subvolume.py b/qa/tasks/cephfs/test_subvolume.py
new file mode 100644
index 000000000..1ebb137dd
--- /dev/null
+++ b/qa/tasks/cephfs/test_subvolume.py
@@ -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'])