]> git.proxmox.com Git - ceph.git/blob - ceph/qa/tasks/cephfs/test_volumes.py
import ceph nautilus 14.2.2
[ceph.git] / ceph / qa / tasks / cephfs / test_volumes.py
1 import os
2 import json
3 import errno
4 import random
5 import logging
6
7 from tasks.cephfs.cephfs_test_case import CephFSTestCase
8 from teuthology.exceptions import CommandFailedError
9
10 log = logging.getLogger(__name__)
11
12 class TestVolumes(CephFSTestCase):
13 TEST_VOLUME_NAME = "fs_test_vol"
14 TEST_SUBVOLUME_PREFIX="subvolume"
15 TEST_GROUP_PREFIX="group"
16 TEST_SNAPSHOT_PREFIX="snapshot"
17
18 def _fs_cmd(self, *args):
19 return self.mgr_cluster.mon_manager.raw_cluster_cmd("fs", *args)
20
21 def _generate_random_subvolume_name(self):
22 return "{0}_{1}".format(TestVolumes.TEST_SUBVOLUME_PREFIX, random.randint(0, 10000))
23
24 def _generate_random_group_name(self):
25 return "{0}_{1}".format(TestVolumes.TEST_GROUP_PREFIX, random.randint(0, 100))
26
27 def _generate_random_snapshot_name(self):
28 return "{0}_{1}".format(TestVolumes.TEST_SNAPSHOT_PREFIX, random.randint(0, 100))
29
30 def _enable_multi_fs(self):
31 self._fs_cmd("flag", "set", "enable_multiple", "true", "--yes-i-really-mean-it")
32
33 def _create_or_reuse_test_volume(self):
34 result = json.loads(self._fs_cmd("volume", "ls"))
35 if len(result) == 0:
36 self.vol_created = True
37 self.volname = TestVolumes.TEST_VOLUME_NAME
38 self._fs_cmd("volume", "create", self.volname)
39 else:
40 self.volname = result[0]['name']
41
42 def _get_subvolume_path(self, vol_name, subvol_name, group_name=None):
43 args = ["subvolume", "getpath", vol_name, subvol_name]
44 if group_name:
45 args.append(group_name)
46 args = tuple(args)
47 path = self._fs_cmd(*args)
48 # remove the leading '/', and trailing whitespaces
49 return path[1:].rstrip()
50
51 def _delete_test_volume(self):
52 self._fs_cmd("volume", "rm", self.volname)
53
54 def setUp(self):
55 super(TestVolumes, self).setUp()
56 self.volname = None
57 self.vol_created = False
58 self._enable_multi_fs()
59 self._create_or_reuse_test_volume()
60
61 def tearDown(self):
62 if self.vol_created:
63 self._delete_test_volume()
64 super(TestVolumes, self).tearDown()
65
66 ### basic subvolume operations
67
68 def test_subvolume_create_and_rm(self):
69 # create subvolume
70 subvolume = self._generate_random_subvolume_name()
71 self._fs_cmd("subvolume", "create", self.volname, subvolume)
72
73 # make sure it exists
74 subvolpath = self._fs_cmd("subvolume", "getpath", self.volname, subvolume)
75 self.assertNotEqual(subvolpath, None)
76
77 # remove subvolume
78 self._fs_cmd("subvolume", "rm", self.volname, subvolume)
79 # make sure its gone
80 try:
81 self._fs_cmd("subvolume", "getpath", self.volname, subvolume)
82 except CommandFailedError as ce:
83 if ce.exitstatus != errno.ENOENT:
84 raise
85
86 def test_subvolume_create_idempotence(self):
87 # create subvolume
88 subvolume = self._generate_random_subvolume_name()
89 self._fs_cmd("subvolume", "create", self.volname, subvolume)
90
91 # try creating w/ same subvolume name -- should be idempotent
92 self._fs_cmd("subvolume", "create", self.volname, subvolume)
93
94 # remove subvolume
95 self._fs_cmd("subvolume", "rm", self.volname, subvolume)
96
97 def test_nonexistent_subvolume_rm(self):
98 # remove non-existing subvolume
99 subvolume = "non_existent_subvolume"
100
101 # try, remove subvolume
102 try:
103 self._fs_cmd("subvolume", "rm", self.volname, subvolume)
104 except CommandFailedError as ce:
105 if ce.exitstatus != errno.ENOENT:
106 raise
107
108 # force remove subvolume
109 self._fs_cmd("subvolume", "rm", self.volname, subvolume, "--force")
110
111 def test_nonexistent_subvolume_group_create(self):
112 subvolume = self._generate_random_subvolume_name()
113 group = "non_existent_group"
114
115 # try, creating subvolume in a nonexistent group
116 try:
117 self._fs_cmd("subvolume", "create", self.volname, subvolume, "--group_name", group)
118 except CommandFailedError as ce:
119 if ce.exitstatus != errno.ENOENT:
120 raise
121
122 ### subvolume group operations
123
124 def test_subvolume_create_and_rm_in_group(self):
125 subvolume = self._generate_random_subvolume_name()
126 group = self._generate_random_group_name()
127
128 # create group
129 self._fs_cmd("subvolumegroup", "create", self.volname, group)
130
131 # create subvolume in group
132 self._fs_cmd("subvolume", "create", self.volname, subvolume, "--group_name", group)
133
134 # remove subvolume
135 self._fs_cmd("subvolume", "rm", self.volname, subvolume, group)
136
137 # remove group
138 self._fs_cmd("subvolumegroup", "rm", self.volname, group)
139
140 def test_subvolume_group_create_with_desired_data_pool_layout(self):
141 group1 = self._generate_random_group_name()
142 group2 = self._generate_random_group_name()
143
144 # create group
145 self._fs_cmd("subvolumegroup", "create", self.volname, group1)
146 group1_path = os.path.join('volumes', group1)
147
148 default_pool = self.mount_a.getfattr(group1_path, "ceph.dir.layout.pool")
149 new_pool = "new_pool"
150 self.assertNotEqual(default_pool, new_pool)
151
152 # add data pool
153 self.fs.add_data_pool(new_pool)
154
155 # create group specifying the new data pool as its pool layout
156 self._fs_cmd("subvolumegroup", "create", self.volname, group2,
157 "--pool_layout", new_pool)
158 group2_path = os.path.join('volumes', group2)
159
160 desired_pool = self.mount_a.getfattr(group2_path, "ceph.dir.layout.pool")
161 self.assertEqual(desired_pool, new_pool)
162
163 self._fs_cmd("subvolumegroup", "rm", self.volname, group1)
164 self._fs_cmd("subvolumegroup", "rm", self.volname, group2)
165
166 def test_subvolume_create_with_desired_data_pool_layout_in_group(self):
167 subvol1 = self._generate_random_subvolume_name()
168 subvol2 = self._generate_random_subvolume_name()
169 group = self._generate_random_group_name()
170
171 # create group. this also helps set default pool layout for subvolumes
172 # created within the group.
173 self._fs_cmd("subvolumegroup", "create", self.volname, group)
174
175 # create subvolume in group.
176 self._fs_cmd("subvolume", "create", self.volname, subvol1, "--group_name", group)
177 subvol1_path = self._get_subvolume_path(self.volname, subvol1, group_name=group)
178
179 default_pool = self.mount_a.getfattr(subvol1_path, "ceph.dir.layout.pool")
180 new_pool = "new_pool"
181 self.assertNotEqual(default_pool, new_pool)
182
183 # add data pool
184 self.fs.add_data_pool(new_pool)
185
186 # create subvolume specifying the new data pool as its pool layout
187 self._fs_cmd("subvolume", "create", self.volname, subvol2, "--group_name", group,
188 "--pool_layout", new_pool)
189 subvol2_path = self._get_subvolume_path(self.volname, subvol2, group_name=group)
190
191 desired_pool = self.mount_a.getfattr(subvol2_path, "ceph.dir.layout.pool")
192 self.assertEqual(desired_pool, new_pool)
193
194 self._fs_cmd("subvolume", "rm", self.volname, subvol2, group)
195 self._fs_cmd("subvolume", "rm", self.volname, subvol1, group)
196 self._fs_cmd("subvolumegroup", "rm", self.volname, group)
197
198 def test_subvolume_group_create_with_desired_mode(self):
199 group1 = self._generate_random_group_name()
200 group2 = self._generate_random_group_name()
201 # default mode
202 expected_mode1 = "755"
203 # desired mode
204 expected_mode2 = "777"
205
206 # create group
207 self._fs_cmd("subvolumegroup", "create", self.volname, group1)
208 self._fs_cmd("subvolumegroup", "create", self.volname, group2, "--mode", "777")
209
210 group1_path = os.path.join('volumes', group1)
211 group2_path = os.path.join('volumes', group2)
212
213 # check group's mode
214 actual_mode1 = self.mount_a.run_shell(['stat', '-c' '%a', group1_path]).stdout.getvalue().strip()
215 actual_mode2 = self.mount_a.run_shell(['stat', '-c' '%a', group2_path]).stdout.getvalue().strip()
216 self.assertEqual(actual_mode1, expected_mode1)
217 self.assertEqual(actual_mode2, expected_mode2)
218
219 self._fs_cmd("subvolumegroup", "rm", self.volname, group1)
220 self._fs_cmd("subvolumegroup", "rm", self.volname, group2)
221
222 def test_subvolume_create_with_desired_mode_in_group(self):
223 subvol1 = self._generate_random_subvolume_name()
224 subvol2 = self._generate_random_subvolume_name()
225 subvol3 = self._generate_random_subvolume_name()
226 group = self._generate_random_group_name()
227 # default mode
228 expected_mode1 = "755"
229 # desired mode
230 expected_mode2 = "777"
231
232 # create group
233 self._fs_cmd("subvolumegroup", "create", self.volname, group)
234
235 # create subvolume in group
236 self._fs_cmd("subvolume", "create", self.volname, subvol1, "--group_name", group)
237 self._fs_cmd("subvolume", "create", self.volname, subvol2, "--group_name", group, "--mode", "777")
238 # check whether mode 0777 also works
239 self._fs_cmd("subvolume", "create", self.volname, subvol3, "--group_name", group, "--mode", "0777")
240
241 subvol1_path = self._get_subvolume_path(self.volname, subvol1, group_name=group)
242 subvol2_path = self._get_subvolume_path(self.volname, subvol2, group_name=group)
243 subvol3_path = self._get_subvolume_path(self.volname, subvol3, group_name=group)
244
245 # check subvolume's mode
246 actual_mode1 = self.mount_a.run_shell(['stat', '-c' '%a', subvol1_path]).stdout.getvalue().strip()
247 actual_mode2 = self.mount_a.run_shell(['stat', '-c' '%a', subvol2_path]).stdout.getvalue().strip()
248 actual_mode3 = self.mount_a.run_shell(['stat', '-c' '%a', subvol3_path]).stdout.getvalue().strip()
249 self.assertEqual(actual_mode1, expected_mode1)
250 self.assertEqual(actual_mode2, expected_mode2)
251 self.assertEqual(actual_mode3, expected_mode2)
252
253 self._fs_cmd("subvolume", "rm", self.volname, subvol2, group)
254 self._fs_cmd("subvolume", "rm", self.volname, subvol1, group)
255 self._fs_cmd("subvolumegroup", "rm", self.volname, group)
256
257 def test_nonexistent_subvolme_group_rm(self):
258 group = "non_existent_group"
259
260 # try, remove subvolume group
261 try:
262 self._fs_cmd("subvolumegroup", "rm", self.volname, group)
263 except CommandFailedError as ce:
264 if ce.exitstatus != errno.ENOENT:
265 raise
266
267 # force remove subvolume
268 self._fs_cmd("subvolumegroup", "rm", self.volname, group, "--force")
269
270 ### snapshot operations
271
272 def test_subvolume_snapshot_create_and_rm(self):
273 subvolume = self._generate_random_subvolume_name()
274 snapshot = self._generate_random_snapshot_name()
275
276 # create subvolume
277 self._fs_cmd("subvolume", "create", self.volname, subvolume)
278
279 # snapshot subvolume
280 self._fs_cmd("subvolume", "snapshot", "create", self.volname, subvolume, snapshot)
281
282 # remove snapshot
283 self._fs_cmd("subvolume", "snapshot", "rm", self.volname, subvolume, snapshot)
284
285 # remove subvolume
286 self._fs_cmd("subvolume", "rm", self.volname, subvolume)
287
288 def test_subvolume_snapshot_create_idempotence(self):
289 subvolume = self._generate_random_subvolume_name()
290 snapshot = self._generate_random_snapshot_name()
291
292 # create subvolume
293 self._fs_cmd("subvolume", "create", self.volname, subvolume)
294
295 # snapshot subvolume
296 self._fs_cmd("subvolume", "snapshot", "create", self.volname, subvolume, snapshot)
297
298 # try creating w/ same subvolume snapshot name -- should be idempotent
299 self._fs_cmd("subvolume", "snapshot", "create", self.volname, subvolume, snapshot)
300
301 # remove snapshot
302 self._fs_cmd("subvolume", "snapshot", "rm", self.volname, subvolume, snapshot)
303
304 # remove subvolume
305 self._fs_cmd("subvolume", "rm", self.volname, subvolume)
306
307 def test_nonexistent_subvolume_snapshot_rm(self):
308 subvolume = self._generate_random_subvolume_name()
309 snapshot = self._generate_random_snapshot_name()
310
311 # create subvolume
312 self._fs_cmd("subvolume", "create", self.volname, subvolume)
313
314 # snapshot subvolume
315 self._fs_cmd("subvolume", "snapshot", "create", self.volname, subvolume, snapshot)
316
317 # remove snapshot
318 self._fs_cmd("subvolume", "snapshot", "rm", self.volname, subvolume, snapshot)
319
320 # remove snapshot again
321 try:
322 self._fs_cmd("subvolume", "snapshot", "rm", self.volname, subvolume, snapshot)
323 except CommandFailedError as ce:
324 if ce.exitstatus != errno.ENOENT:
325 raise
326
327 # force remove snapshot
328 self._fs_cmd("subvolume", "snapshot", "rm", self.volname, subvolume, snapshot, "--force")
329
330 # remove subvolume
331 self._fs_cmd("subvolume", "rm", self.volname, subvolume)
332
333 def test_subvolume_snapshot_in_group(self):
334 subvolume = self._generate_random_subvolume_name()
335 group = self._generate_random_group_name()
336 snapshot = self._generate_random_snapshot_name()
337
338 # create group
339 self._fs_cmd("subvolumegroup", "create", self.volname, group)
340
341 # create subvolume in group
342 self._fs_cmd("subvolume", "create", self.volname, subvolume, "--group_name", group)
343
344 # snapshot subvolume in group
345 self._fs_cmd("subvolume", "snapshot", "create", self.volname, subvolume, snapshot, group)
346
347 # remove snapshot
348 self._fs_cmd("subvolume", "snapshot", "rm", self.volname, subvolume, snapshot, group)
349
350 # remove subvolume
351 self._fs_cmd("subvolume", "rm", self.volname, subvolume, group)
352
353 # remove group
354 self._fs_cmd("subvolumegroup", "rm", self.volname, group)
355
356 def test_subvolume_group_snapshot_create_and_rm(self):
357 subvolume = self._generate_random_subvolume_name()
358 group = self._generate_random_group_name()
359 snapshot = self._generate_random_snapshot_name()
360
361 # create group
362 self._fs_cmd("subvolumegroup", "create", self.volname, group)
363
364 # create subvolume in group
365 self._fs_cmd("subvolume", "create", self.volname, subvolume, "--group_name", group)
366
367 # snapshot group
368 self._fs_cmd("subvolumegroup", "snapshot", "create", self.volname, group, snapshot)
369
370 # remove snapshot
371 self._fs_cmd("subvolumegroup", "snapshot", "rm", self.volname, group, snapshot)
372
373 # remove subvolume
374 self._fs_cmd("subvolume", "rm", self.volname, subvolume, group)
375
376 # remove group
377 self._fs_cmd("subvolumegroup", "rm", self.volname, group)
378
379 def test_subvolume_group_snapshot_idempotence(self):
380 subvolume = self._generate_random_subvolume_name()
381 group = self._generate_random_group_name()
382 snapshot = self._generate_random_snapshot_name()
383
384 # create group
385 self._fs_cmd("subvolumegroup", "create", self.volname, group)
386
387 # create subvolume in group
388 self._fs_cmd("subvolume", "create", self.volname, subvolume, "--group_name", group)
389
390 # snapshot group
391 self._fs_cmd("subvolumegroup", "snapshot", "create", self.volname, group, snapshot)
392
393 # try creating snapshot w/ same snapshot name -- shoule be idempotent
394 self._fs_cmd("subvolumegroup", "snapshot", "create", self.volname, group, snapshot)
395
396 # remove snapshot
397 self._fs_cmd("subvolumegroup", "snapshot", "rm", self.volname, group, snapshot)
398
399 # remove subvolume
400 self._fs_cmd("subvolume", "rm", self.volname, subvolume, group)
401
402 # remove group
403 self._fs_cmd("subvolumegroup", "rm", self.volname, group)
404
405 def test_nonexistent_subvolume_group_snapshot_rm(self):
406 subvolume = self._generate_random_subvolume_name()
407 group = self._generate_random_group_name()
408 snapshot = self._generate_random_snapshot_name()
409
410 # create group
411 self._fs_cmd("subvolumegroup", "create", self.volname, group)
412
413 # create subvolume in group
414 self._fs_cmd("subvolume", "create", self.volname, subvolume, "--group_name", group)
415
416 # snapshot group
417 self._fs_cmd("subvolumegroup", "snapshot", "create", self.volname, group, snapshot)
418
419 # remove snapshot
420 self._fs_cmd("subvolumegroup", "snapshot", "rm", self.volname, group, snapshot)
421
422 # remove snapshot
423 try:
424 self._fs_cmd("subvolumegroup", "snapshot", "rm", self.volname, group, snapshot)
425 except CommandFailedError as ce:
426 if ce.exitstatus != errno.ENOENT:
427 raise
428
429 # remove subvolume
430 self._fs_cmd("subvolume", "rm", self.volname, subvolume, group)
431
432 # remove group
433 self._fs_cmd("subvolumegroup", "rm", self.volname, group)