]> git.proxmox.com Git - ceph.git/blame - ceph/qa/tasks/cephfs/test_nfs.py
import ceph 16.2.6
[ceph.git] / ceph / qa / tasks / cephfs / test_nfs.py
CommitLineData
f67539c2 1# NOTE: these tests are not yet compatible with vstart_runner.py.
f6b5b4d7
TL
2import errno
3import json
4import time
5import logging
6from io import BytesIO
7
8from tasks.mgr.mgr_test_case import MgrTestCase
9from teuthology.exceptions import CommandFailedError
10
11log = logging.getLogger(__name__)
12
13
14# TODO Add test for cluster update when ganesha can be deployed on multiple ports.
15class TestNFS(MgrTestCase):
f91f0fd5 16 def _cmd(self, *args):
f6b5b4d7
TL
17 return self.mgr_cluster.mon_manager.raw_cluster_cmd(*args)
18
19 def _nfs_cmd(self, *args):
20 return self._cmd("nfs", *args)
21
22 def _orch_cmd(self, *args):
23 return self._cmd("orch", *args)
24
25 def _sys_cmd(self, cmd):
26 cmd[0:0] = ['sudo']
27 ret = self.ctx.cluster.run(args=cmd, check_status=False, stdout=BytesIO(), stderr=BytesIO())
28 stdout = ret[0].stdout
29 if stdout:
30 return stdout.getvalue()
31
32 def setUp(self):
33 super(TestNFS, self).setUp()
b3b6e05e 34 self._load_module('nfs')
f6b5b4d7
TL
35 self.cluster_id = "test"
36 self.export_type = "cephfs"
37 self.pseudo_path = "/cephfs"
38 self.path = "/"
39 self.fs_name = "nfs-cephfs"
f67539c2 40 self.expected_name = "nfs.test"
f6b5b4d7
TL
41 self.sample_export = {
42 "export_id": 1,
43 "path": self.path,
44 "cluster_id": self.cluster_id,
45 "pseudo": self.pseudo_path,
46 "access_type": "RW",
47 "squash": "no_root_squash",
48 "security_label": True,
49 "protocols": [
50 4
51 ],
52 "transports": [
53 "TCP"
54 ],
55 "fsal": {
56 "name": "CEPH",
57 "user_id": "test1",
58 "fs_name": self.fs_name,
59 "sec_label_xattr": ''
60 },
61 "clients": []
62 }
63
f6b5b4d7
TL
64 def _check_nfs_server_status(self):
65 res = self._sys_cmd(['systemctl', 'status', 'nfs-server'])
66 if isinstance(res, bytes) and b'Active: active' in res:
67 self._disable_nfs()
68
69 def _disable_nfs(self):
70 log.info("Disabling NFS")
71 self._sys_cmd(['systemctl', 'disable', 'nfs-server', '--now'])
72
f91f0fd5
TL
73 def _fetch_nfs_status(self):
74 return self._orch_cmd('ps', f'--service_name={self.expected_name}')
75
76 def _check_nfs_cluster_status(self, expected_status, fail_msg):
77 '''
78 Tests if nfs cluster created or deleted successfully
79 :param expected_status: Status to be verified
80 :param fail_msg: Message to be printed if test failed
81 '''
82 # Wait for few seconds as ganesha daemon takes few seconds to be deleted/created
83 wait_time = 10
84 while wait_time <= 60:
85 time.sleep(wait_time)
86 if expected_status in self._fetch_nfs_status():
87 return
88 wait_time += 10
89 self.fail(fail_msg)
f6b5b4d7
TL
90
91 def _check_auth_ls(self, export_id=1, check_in=False):
92 '''
93 Tests export user id creation or deletion.
94 :param export_id: Denotes export number
95 :param check_in: Check specified export id
96 '''
97 output = self._cmd('auth', 'ls')
98 if check_in:
99 self.assertIn(f'client.{self.cluster_id}{export_id}', output)
100 else:
101 self.assertNotIn(f'client-{self.cluster_id}', output)
102
103 def _test_idempotency(self, cmd_func, cmd_args):
104 '''
105 Test idempotency of commands. It first runs the TestNFS test method
106 for a command and then checks the result of command run again. TestNFS
107 test method has required checks to verify that command works.
108 :param cmd_func: TestNFS method
109 :param cmd_args: nfs command arguments to be run
110 '''
111 cmd_func()
112 ret = self.mgr_cluster.mon_manager.raw_cluster_cmd_result(*cmd_args)
113 if ret != 0:
114 self.fail("Idempotency test failed")
115
116 def _test_create_cluster(self):
117 '''
118 Test single nfs cluster deployment.
119 '''
120 # Disable any running nfs ganesha daemon
121 self._check_nfs_server_status()
b3b6e05e 122 self._nfs_cmd('cluster', 'create', self.cluster_id)
f67539c2 123 # Check for expected status and daemon name (nfs.<cluster_id>)
f91f0fd5 124 self._check_nfs_cluster_status('running', 'NFS Ganesha cluster deployment failed')
f6b5b4d7
TL
125
126 def _test_delete_cluster(self):
127 '''
128 Test deletion of a single nfs cluster.
129 '''
b3b6e05e 130 self._nfs_cmd('cluster', 'rm', self.cluster_id)
f91f0fd5
TL
131 self._check_nfs_cluster_status('No daemons reported',
132 'NFS Ganesha cluster could not be deleted')
f6b5b4d7
TL
133
134 def _test_list_cluster(self, empty=False):
135 '''
136 Test listing of deployed nfs clusters. If nfs cluster is deployed then
137 it checks for expected cluster id. Otherwise checks nothing is listed.
138 :param empty: If true it denotes no cluster is deployed.
139 '''
140 if empty:
141 cluster_id = ''
142 else:
143 cluster_id = self.cluster_id
144 nfs_output = self._nfs_cmd('cluster', 'ls')
145 self.assertEqual(cluster_id, nfs_output.strip())
146
147 def _create_export(self, export_id, create_fs=False, extra_cmd=None):
148 '''
149 Test creation of a single export.
150 :param export_id: Denotes export number
151 :param create_fs: If false filesytem exists. Otherwise create it.
152 :param extra_cmd: List of extra arguments for creating export.
153 '''
154 if create_fs:
155 self._cmd('fs', 'volume', 'create', self.fs_name)
156 export_cmd = ['nfs', 'export', 'create', 'cephfs', self.fs_name, self.cluster_id]
157 if isinstance(extra_cmd, list):
158 export_cmd.extend(extra_cmd)
159 else:
160 export_cmd.append(self.pseudo_path)
161 # Runs the nfs export create command
162 self._cmd(*export_cmd)
163 # Check if user id for export is created
164 self._check_auth_ls(export_id, check_in=True)
165 res = self._sys_cmd(['rados', '-p', 'nfs-ganesha', '-N', self.cluster_id, 'get',
166 f'export-{export_id}', '-'])
167 # Check if export object is created
168 if res == b'':
169 self.fail("Export cannot be created")
170
171 def _create_default_export(self):
172 '''
173 Deploy a single nfs cluster and create export with default options.
174 '''
175 self._test_create_cluster()
176 self._create_export(export_id='1', create_fs=True)
177
178 def _delete_export(self):
179 '''
180 Delete an export.
181 '''
b3b6e05e 182 self._nfs_cmd('export', 'rm', self.cluster_id, self.pseudo_path)
f6b5b4d7
TL
183 self._check_auth_ls()
184
185 def _test_list_export(self):
186 '''
187 Test listing of created exports.
188 '''
189 nfs_output = json.loads(self._nfs_cmd('export', 'ls', self.cluster_id))
190 self.assertIn(self.pseudo_path, nfs_output)
191
192 def _test_list_detailed(self, sub_vol_path):
193 '''
194 Test listing of created exports with detailed option.
195 :param sub_vol_path: Denotes path of subvolume
196 '''
197 nfs_output = json.loads(self._nfs_cmd('export', 'ls', self.cluster_id, '--detailed'))
198 # Export-1 with default values (access type = rw and path = '\')
199 self.assertDictEqual(self.sample_export, nfs_output[0])
200 # Export-2 with r only
201 self.sample_export['export_id'] = 2
202 self.sample_export['pseudo'] = self.pseudo_path + '1'
203 self.sample_export['access_type'] = 'RO'
204 self.sample_export['fsal']['user_id'] = self.cluster_id + '2'
205 self.assertDictEqual(self.sample_export, nfs_output[1])
206 # Export-3 for subvolume with r only
207 self.sample_export['export_id'] = 3
208 self.sample_export['path'] = sub_vol_path
209 self.sample_export['pseudo'] = self.pseudo_path + '2'
210 self.sample_export['fsal']['user_id'] = self.cluster_id + '3'
211 self.assertDictEqual(self.sample_export, nfs_output[2])
212 # Export-4 for subvolume
213 self.sample_export['export_id'] = 4
214 self.sample_export['pseudo'] = self.pseudo_path + '3'
215 self.sample_export['access_type'] = 'RW'
216 self.sample_export['fsal']['user_id'] = self.cluster_id + '4'
217 self.assertDictEqual(self.sample_export, nfs_output[3])
218
f67539c2
TL
219 def _get_export(self):
220 '''
221 Returns export block in json format
222 '''
223 return json.loads(self._nfs_cmd('export', 'get', self.cluster_id, self.pseudo_path))
224
f6b5b4d7
TL
225 def _test_get_export(self):
226 '''
227 Test fetching of created export.
228 '''
f67539c2 229 nfs_output = self._get_export()
f6b5b4d7
TL
230 self.assertDictEqual(self.sample_export, nfs_output)
231
232 def _check_export_obj_deleted(self, conf_obj=False):
233 '''
234 Test if export or config object are deleted successfully.
235 :param conf_obj: It denotes config object needs to be checked
236 '''
237 rados_obj_ls = self._sys_cmd(['rados', '-p', 'nfs-ganesha', '-N', self.cluster_id, 'ls'])
238
239 if b'export-' in rados_obj_ls or (conf_obj and b'conf-nfs' in rados_obj_ls):
240 self.fail("Delete export failed")
241
f91f0fd5
TL
242 def _get_port_ip_info(self):
243 '''
244 Return port and ip for a cluster
245 '''
b3b6e05e
TL
246 #{'test': {'backend': [{'hostname': 'smithi068', 'ip': '172.21.15.68', 'port': 2049}]}}
247 info_output = json.loads(self._nfs_cmd('cluster', 'info', self.cluster_id))['test']['backend'][0]
248 return info_output["port"], info_output["ip"]
f91f0fd5
TL
249
250 def _test_mnt(self, pseudo_path, port, ip, check=True):
251 '''
252 Test mounting of created exports
253 :param pseudo_path: It is the pseudo root name
254 :param port: Port of deployed nfs cluster
255 :param ip: IP of deployed nfs cluster
256 :param check: It denotes if i/o testing needs to be done
257 '''
258 try:
259 self.ctx.cluster.run(args=['sudo', 'mount', '-t', 'nfs', '-o', f'port={port}',
260 f'{ip}:{pseudo_path}', '/mnt'])
261 except CommandFailedError as e:
262 # Check if mount failed only when non existing pseudo path is passed
263 if not check and e.exitstatus == 32:
264 return
265 raise
266
522d829b
TL
267 self.ctx.cluster.run(args=['sudo', 'chmod', '1777', '/mnt'])
268
f67539c2 269 try:
522d829b
TL
270 self.ctx.cluster.run(args=['touch', '/mnt/test'])
271 out_mnt = self._sys_cmd(['ls', '/mnt'])
f91f0fd5 272 self.assertEqual(out_mnt, b'test\n')
f67539c2 273 finally:
f91f0fd5
TL
274 self.ctx.cluster.run(args=['sudo', 'umount', '/mnt'])
275
f67539c2
TL
276 def _write_to_read_only_export(self, pseudo_path, port, ip):
277 '''
278 Check if write to read only export fails
279 '''
280 try:
281 self._test_mnt(pseudo_path, port, ip)
282 except CommandFailedError as e:
283 # Write to cephfs export should fail for test to pass
284 if e.exitstatus != errno.EPERM:
285 raise
286
f6b5b4d7
TL
287 def test_create_and_delete_cluster(self):
288 '''
289 Test successful creation and deletion of the nfs cluster.
290 '''
291 self._test_create_cluster()
292 self._test_list_cluster()
293 self._test_delete_cluster()
294 # List clusters again to ensure no cluster is shown
295 self._test_list_cluster(empty=True)
296
297 def test_create_delete_cluster_idempotency(self):
298 '''
299 Test idempotency of cluster create and delete commands.
300 '''
b3b6e05e
TL
301 self._test_idempotency(self._test_create_cluster, ['nfs', 'cluster', 'create', self.cluster_id])
302 self._test_idempotency(self._test_delete_cluster, ['nfs', 'cluster', 'rm', self.cluster_id])
f6b5b4d7
TL
303
304 def test_create_cluster_with_invalid_cluster_id(self):
305 '''
306 Test nfs cluster deployment failure with invalid cluster id.
307 '''
308 try:
309 invalid_cluster_id = '/cluster_test' # Only [A-Za-z0-9-_.] chars are valid
b3b6e05e 310 self._nfs_cmd('cluster', 'create', invalid_cluster_id)
f6b5b4d7
TL
311 self.fail(f"Cluster successfully created with invalid cluster id {invalid_cluster_id}")
312 except CommandFailedError as e:
313 # Command should fail for test to pass
314 if e.exitstatus != errno.EINVAL:
315 raise
316
f6b5b4d7
TL
317 def test_create_and_delete_export(self):
318 '''
319 Test successful creation and deletion of the cephfs export.
320 '''
321 self._create_default_export()
322 self._test_get_export()
f91f0fd5
TL
323 port, ip = self._get_port_ip_info()
324 self._test_mnt(self.pseudo_path, port, ip)
f6b5b4d7
TL
325 self._delete_export()
326 # Check if rados export object is deleted
327 self._check_export_obj_deleted()
f91f0fd5 328 self._test_mnt(self.pseudo_path, port, ip, False)
f6b5b4d7
TL
329 self._test_delete_cluster()
330
331 def test_create_delete_export_idempotency(self):
332 '''
333 Test idempotency of export create and delete commands.
334 '''
335 self._test_idempotency(self._create_default_export, ['nfs', 'export', 'create', 'cephfs',
336 self.fs_name, self.cluster_id,
337 self.pseudo_path])
b3b6e05e 338 self._test_idempotency(self._delete_export, ['nfs', 'export', 'rm', self.cluster_id,
f6b5b4d7
TL
339 self.pseudo_path])
340 self._test_delete_cluster()
341
342 def test_create_multiple_exports(self):
343 '''
344 Test creating multiple exports with different access type and path.
345 '''
346 # Export-1 with default values (access type = rw and path = '\')
347 self._create_default_export()
348 # Export-2 with r only
349 self._create_export(export_id='2', extra_cmd=[self.pseudo_path+'1', '--readonly'])
350 # Export-3 for subvolume with r only
351 self._cmd('fs', 'subvolume', 'create', self.fs_name, 'sub_vol')
352 fs_path = self._cmd('fs', 'subvolume', 'getpath', self.fs_name, 'sub_vol').strip()
353 self._create_export(export_id='3', extra_cmd=[self.pseudo_path+'2', '--readonly', fs_path])
354 # Export-4 for subvolume
355 self._create_export(export_id='4', extra_cmd=[self.pseudo_path+'3', fs_path])
356 # Check if exports gets listed
357 self._test_list_detailed(fs_path)
358 self._test_delete_cluster()
359 # Check if rados ganesha conf object is deleted
360 self._check_export_obj_deleted(conf_obj=True)
361 self._check_auth_ls()
362
363 def test_exports_on_mgr_restart(self):
364 '''
365 Test export availability on restarting mgr.
366 '''
367 self._create_default_export()
368 # unload and load module will restart the mgr
369 self._unload_module("cephadm")
370 self._load_module("cephadm")
371 self._orch_cmd("set", "backend", "cephadm")
f67539c2
TL
372 # Check if ganesha daemon is running
373 self._check_nfs_cluster_status('running', 'Failed to redeploy NFS Ganesha cluster')
f6b5b4d7
TL
374 # Checks if created export is listed
375 self._test_list_export()
f91f0fd5
TL
376 port, ip = self._get_port_ip_info()
377 self._test_mnt(self.pseudo_path, port, ip)
f6b5b4d7
TL
378 self._delete_export()
379 self._test_delete_cluster()
380
381 def test_export_create_with_non_existing_fsname(self):
382 '''
383 Test creating export with non-existing filesystem.
384 '''
385 try:
386 fs_name = 'nfs-test'
387 self._test_create_cluster()
388 self._nfs_cmd('export', 'create', 'cephfs', fs_name, self.cluster_id, self.pseudo_path)
389 self.fail(f"Export created with non-existing filesystem {fs_name}")
390 except CommandFailedError as e:
391 # Command should fail for test to pass
392 if e.exitstatus != errno.ENOENT:
393 raise
394 finally:
395 self._test_delete_cluster()
396
397 def test_export_create_with_non_existing_clusterid(self):
398 '''
399 Test creating cephfs export with non-existing nfs cluster.
400 '''
401 try:
402 cluster_id = 'invalidtest'
403 self._nfs_cmd('export', 'create', 'cephfs', self.fs_name, cluster_id, self.pseudo_path)
404 self.fail(f"Export created with non-existing cluster id {cluster_id}")
405 except CommandFailedError as e:
406 # Command should fail for test to pass
407 if e.exitstatus != errno.ENOENT:
408 raise
409
410 def test_export_create_with_relative_pseudo_path_and_root_directory(self):
411 '''
412 Test creating cephfs export with relative or '/' pseudo path.
413 '''
414 def check_pseudo_path(pseudo_path):
415 try:
416 self._nfs_cmd('export', 'create', 'cephfs', self.fs_name, self.cluster_id,
417 pseudo_path)
418 self.fail(f"Export created for {pseudo_path}")
419 except CommandFailedError as e:
420 # Command should fail for test to pass
421 if e.exitstatus != errno.EINVAL:
422 raise
423
424 self._test_create_cluster()
425 self._cmd('fs', 'volume', 'create', self.fs_name)
426 check_pseudo_path('invalidpath')
427 check_pseudo_path('/')
428 check_pseudo_path('//')
f91f0fd5 429 self._cmd('fs', 'volume', 'rm', self.fs_name, '--yes-i-really-mean-it')
f6b5b4d7
TL
430 self._test_delete_cluster()
431
f67539c2
TL
432 def test_write_to_read_only_export(self):
433 '''
434 Test write to readonly export.
435 '''
436 self._test_create_cluster()
437 self._create_export(export_id='1', create_fs=True, extra_cmd=[self.pseudo_path, '--readonly'])
438 port, ip = self._get_port_ip_info()
439 self._write_to_read_only_export(self.pseudo_path, port, ip)
440 self._test_delete_cluster()
441
f6b5b4d7
TL
442 def test_cluster_info(self):
443 '''
444 Test cluster info outputs correct ip and hostname
445 '''
446 self._test_create_cluster()
447 info_output = json.loads(self._nfs_cmd('cluster', 'info', self.cluster_id))
b3b6e05e
TL
448 print(f'info {info_output}')
449 info_ip = info_output[self.cluster_id].get('backend', [])[0].pop("ip")
450 host_details = {
451 self.cluster_id: {
452 'backend': [
453 {
454 "hostname": self._sys_cmd(['hostname']).decode("utf-8").strip(),
455 "port": 2049
456 }
457 ],
458 "virtual_ip": None,
459 }
460 }
adb31ebb 461 host_ip = self._sys_cmd(['hostname', '-I']).decode("utf-8").split()
b3b6e05e 462 print(f'host_ip is {host_ip}, info_ip is {info_ip}')
f6b5b4d7 463 self.assertDictEqual(info_output, host_details)
b3b6e05e 464 self.assertTrue(info_ip in host_ip)
f6b5b4d7
TL
465 self._test_delete_cluster()
466
467 def test_cluster_set_reset_user_config(self):
468 '''
469 Test cluster is created using user config and reverts back to default
470 config on reset.
471 '''
472 self._test_create_cluster()
f6b5b4d7
TL
473
474 pool = 'nfs-ganesha'
475 user_id = 'test'
476 fs_name = 'user_test_fs'
f91f0fd5 477 pseudo_path = '/ceph'
f6b5b4d7
TL
478 self._cmd('fs', 'volume', 'create', fs_name)
479 time.sleep(20)
480 key = self._cmd('auth', 'get-or-create-key', f'client.{user_id}', 'mon',
481 'allow r', 'osd',
482 f'allow rw pool={pool} namespace={self.cluster_id}, allow rw tag cephfs data={fs_name}',
483 'mds', f'allow rw path={self.path}').strip()
484 config = f""" LOG {{
485 Default_log_level = FULL_DEBUG;
486 }}
487
488 EXPORT {{
489 Export_Id = 100;
490 Transports = TCP;
491 Path = /;
f91f0fd5 492 Pseudo = {pseudo_path};
f6b5b4d7
TL
493 Protocols = 4;
494 Access_Type = RW;
495 Attr_Expiration_Time = 0;
496 Squash = None;
497 FSAL {{
498 Name = CEPH;
499 Filesystem = {fs_name};
500 User_Id = {user_id};
501 Secret_Access_Key = '{key}';
502 }}
503 }}"""
f91f0fd5 504 port, ip = self._get_port_ip_info()
f6b5b4d7
TL
505 self.ctx.cluster.run(args=['sudo', 'ceph', 'nfs', 'cluster', 'config',
506 'set', self.cluster_id, '-i', '-'], stdin=config)
507 time.sleep(30)
f6b5b4d7 508 res = self._sys_cmd(['rados', '-p', pool, '-N', self.cluster_id, 'get',
f67539c2 509 f'userconf-nfs.{user_id}', '-'])
f6b5b4d7 510 self.assertEqual(config, res.decode('utf-8'))
f91f0fd5 511 self._test_mnt(pseudo_path, port, ip)
f6b5b4d7
TL
512 self._nfs_cmd('cluster', 'config', 'reset', self.cluster_id)
513 rados_obj_ls = self._sys_cmd(['rados', '-p', 'nfs-ganesha', '-N', self.cluster_id, 'ls'])
514 if b'conf-nfs' not in rados_obj_ls and b'userconf-nfs' in rados_obj_ls:
515 self.fail("User config not deleted")
516 time.sleep(30)
f91f0fd5 517 self._test_mnt(pseudo_path, port, ip, False)
f6b5b4d7
TL
518 self._cmd('fs', 'volume', 'rm', fs_name, '--yes-i-really-mean-it')
519 self._test_delete_cluster()
f6b5b4d7
TL
520
521 def test_cluster_set_user_config_with_non_existing_clusterid(self):
522 '''
523 Test setting user config for non-existing nfs cluster.
524 '''
525 try:
526 cluster_id = 'invalidtest'
527 self.ctx.cluster.run(args=['sudo', 'ceph', 'nfs', 'cluster',
528 'config', 'set', self.cluster_id, '-i', '-'], stdin='testing')
529 self.fail(f"User config set for non-existing cluster {cluster_id}")
530 except CommandFailedError as e:
531 # Command should fail for test to pass
532 if e.exitstatus != errno.ENOENT:
533 raise
534
535 def test_cluster_reset_user_config_with_non_existing_clusterid(self):
536 '''
537 Test resetting user config for non-existing nfs cluster.
538 '''
539 try:
540 cluster_id = 'invalidtest'
541 self._nfs_cmd('cluster', 'config', 'reset', cluster_id)
542 self.fail(f"User config reset for non-existing cluster {cluster_id}")
543 except CommandFailedError as e:
544 # Command should fail for test to pass
545 if e.exitstatus != errno.ENOENT:
546 raise
f67539c2
TL
547
548 def test_update_export(self):
549 '''
550 Test update of exports
551 '''
552 self._create_default_export()
553 port, ip = self._get_port_ip_info()
554 self._test_mnt(self.pseudo_path, port, ip)
555 export_block = self._get_export()
556 new_pseudo_path = '/testing'
557 export_block['pseudo'] = new_pseudo_path
558 export_block['access_type'] = 'RO'
559 self.ctx.cluster.run(args=['sudo', 'ceph', 'nfs', 'export', 'update', '-i', '-'],
560 stdin=json.dumps(export_block))
561 self._check_nfs_cluster_status('running', 'NFS Ganesha cluster restart failed')
562 self._write_to_read_only_export(new_pseudo_path, port, ip)
563 self._test_delete_cluster()
564
565 def test_update_export_with_invalid_values(self):
566 '''
567 Test update of export with invalid values
568 '''
569 self._create_default_export()
570 export_block = self._get_export()
571
572 def update_with_invalid_values(key, value, fsal=False):
573 export_block_new = dict(export_block)
574 if fsal:
575 export_block_new['fsal'] = dict(export_block['fsal'])
576 export_block_new['fsal'][key] = value
577 else:
578 export_block_new[key] = value
579 try:
580 self.ctx.cluster.run(args=['sudo', 'ceph', 'nfs', 'export', 'update', '-i', '-'],
581 stdin=json.dumps(export_block_new))
582 except CommandFailedError:
583 pass
584
585 update_with_invalid_values('export_id', 9)
586 update_with_invalid_values('cluster_id', 'testing_new')
587 update_with_invalid_values('pseudo', 'test_relpath')
588 update_with_invalid_values('access_type', 'W')
589 update_with_invalid_values('squash', 'no_squash')
590 update_with_invalid_values('security_label', 'invalid')
591 update_with_invalid_values('protocols', [2])
592 update_with_invalid_values('transports', ['UD'])
593 update_with_invalid_values('name', 'RGW', True)
594 update_with_invalid_values('user_id', 'testing_export', True)
595 update_with_invalid_values('fs_name', 'b', True)
596 self._test_delete_cluster()
b3b6e05e
TL
597
598 def test_cmds_without_reqd_args(self):
599 '''
600 Test that cmd fails on not passing required arguments
601 '''
602 def exec_cmd_invalid(*cmd):
603 try:
604 self._nfs_cmd(*cmd)
605 self.fail(f"nfs {cmd} command executed successfully without required arguments")
606 except CommandFailedError as e:
607 # Command should fail for test to pass
608 if e.exitstatus != errno.EINVAL:
609 raise
610
611 exec_cmd_invalid('cluster', 'create')
612 exec_cmd_invalid('cluster', 'delete')
613 exec_cmd_invalid('cluster', 'config', 'set')
614 exec_cmd_invalid('cluster', 'config', 'reset')
615 exec_cmd_invalid('export', 'create', 'cephfs')
616 exec_cmd_invalid('export', 'create', 'cephfs', 'a_fs')
617 exec_cmd_invalid('export', 'create', 'cephfs', 'a_fs', 'clusterid')
618 exec_cmd_invalid('export', 'ls')
619 exec_cmd_invalid('export', 'delete')
620 exec_cmd_invalid('export', 'delete', 'clusterid')
621 exec_cmd_invalid('export', 'get')
622 exec_cmd_invalid('export', 'get', 'clusterid')