summaryrefslogtreecommitdiffstats
path: root/qa/tasks/cephfs/test_subvolume.py
blob: 1ebb137dda93e52d92e3a2c8f24f254d03d7fd90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
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'])