]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/pybind/test_ceph_argparse.py
1 #!/usr/bin/env nosetests
2 # -*- mode:python; tab-width:4; indent-tabs-mode:t; coding:utf-8 -*-
3 # vim: ts=4 sw=4 smarttab expandtab fileencoding=utf-8
5 # Ceph - scalable distributed file system
7 # Copyright (C) 2013,2014 Cloudwatt <libre.licensing@cloudwatt.com>
8 # Copyright (C) 2014 Red Hat <contact@redhat.com>
10 # Author: Loic Dachary <loic@dachary.org>
12 # This library is free software; you can redistribute it and/or
13 # modify it under the terms of the GNU Lesser General Public
14 # License as published by the Free Software Foundation; either
15 # version 2.1 of the License, or (at your option) any later version.
18 from nose
.tools
import eq_
as eq
19 from nose
.tools
import *
21 from ceph_argparse
import validate_command
, parse_json_funcsigs
28 from StringIO
import StringIO
30 from io
import StringIO
32 def get_command_descriptions(what
):
33 CEPH_BIN
= os
.environ
['CEPH_BIN']
36 return os
.popen(CEPH_BIN
+ "/get_command_descriptions " + "--" + what
).read()
38 def test_parse_json_funcsigs():
39 commands
= get_command_descriptions("all")
40 cmd_json
= parse_json_funcsigs(commands
, 'cli')
42 # syntax error https://github.com/ceph/ceph/pull/585
43 commands
= get_command_descriptions("pull585")
44 assert_raises(TypeError, parse_json_funcsigs
, commands
, 'cli')
46 sigdict
= parse_json_funcsigs(get_command_descriptions("all"), 'cli')
51 def assert_valid_command(self
, args
):
52 result
= validate_command(sigdict
, args
)
53 assert_not_in(result
, [{}, None])
55 def check_1_natural_arg(self
, prefix
, command
):
56 self
.assert_valid_command([prefix
, command
, '1'])
57 assert_equal({}, validate_command(sigdict
, [prefix
, command
]))
58 assert_equal({}, validate_command(sigdict
, [prefix
, command
, '-1']))
59 assert_equal({}, validate_command(sigdict
, [prefix
, command
, '1',
62 def check_0_or_1_natural_arg(self
, prefix
, command
):
63 self
.assert_valid_command([prefix
, command
, '1'])
64 self
.assert_valid_command([prefix
, command
])
65 assert_equal({}, validate_command(sigdict
, [prefix
, command
, '-1']))
66 assert_equal({}, validate_command(sigdict
, [prefix
, command
, '1',
69 def check_1_string_arg(self
, prefix
, command
):
70 assert_equal({}, validate_command(sigdict
, [prefix
, command
]))
71 self
.assert_valid_command([prefix
, command
, 'string'])
72 assert_equal({}, validate_command(sigdict
, [prefix
,
77 def check_0_or_1_string_arg(self
, prefix
, command
):
78 self
.assert_valid_command([prefix
, command
, 'string'])
79 self
.assert_valid_command([prefix
, command
])
80 assert_equal({}, validate_command(sigdict
, [prefix
, command
, 'string',
83 def check_1_or_more_string_args(self
, prefix
, command
):
84 assert_equal({}, validate_command(sigdict
, [prefix
,
86 self
.assert_valid_command([prefix
,
89 self
.assert_valid_command([prefix
,
94 def check_no_arg(self
, prefix
, command
):
95 self
.assert_valid_command([prefix
,
97 assert_equal({}, validate_command(sigdict
, [prefix
,
101 def capture_output(self
, args
, stdout
=None, stderr
=None):
108 ret
= validate_command(sigdict
, args
)
110 stdout
= stdout
.getvalue().strip()
112 stderr
= stderr
.getvalue().strip()
113 return ret
, stdout
, stderr
118 def test_non_ascii_in_non_options(self
):
119 # ArgumentPrefix("no match for {0}".format(s)) is not able to convert
120 # unicode str parameter into str. and validate_command() should not
122 assert_equal({}, validate_command(sigdict
, [u
'章鱼和鱿鱼']))
123 assert_equal({}, validate_command(sigdict
, [u
'–w']))
124 # actually we always pass unicode strings to validate_command() in "ceph"
125 # CLI, but we also use bytestrings in our tests, so make sure it does not
127 assert_equal({}, validate_command(sigdict
, ['章鱼和鱿鱼']))
128 assert_equal({}, validate_command(sigdict
, ['–w']))
131 class TestPG(TestArgparse
):
134 self
.assert_valid_command(['pg', 'stat'])
136 def test_getmap(self
):
137 self
.assert_valid_command(['pg', 'getmap'])
140 self
.assert_valid_command(['pg', 'dump'])
141 self
.assert_valid_command(['pg', 'dump',
150 assert_equal({}, validate_command(sigdict
, ['pg', 'dump', 'invalid']))
152 def test_dump_json(self
):
153 self
.assert_valid_command(['pg', 'dump_json'])
154 self
.assert_valid_command(['pg', 'dump_json',
161 assert_equal({}, validate_command(sigdict
, ['pg', 'dump_json',
164 def test_dump_pools_json(self
):
165 self
.assert_valid_command(['pg', 'dump_pools_json'])
167 def test_dump_pools_stuck(self
):
168 self
.assert_valid_command(['pg', 'dump_stuck'])
169 self
.assert_valid_command(['pg', 'dump_stuck',
173 assert_equal({}, validate_command(sigdict
, ['pg', 'dump_stuck',
175 self
.assert_valid_command(['pg', 'dump_stuck',
179 def one_pgid(self
, command
):
180 self
.assert_valid_command(['pg', command
, '1.1'])
181 assert_equal({}, validate_command(sigdict
, ['pg', command
]))
182 assert_equal({}, validate_command(sigdict
, ['pg', command
, '1']))
187 def test_scrub(self
):
188 self
.one_pgid('scrub')
190 def test_deep_scrub(self
):
191 self
.one_pgid('deep-scrub')
193 def test_repair(self
):
194 self
.one_pgid('repair')
196 def test_debug(self
):
197 self
.assert_valid_command(['pg',
199 'unfound_objects_exist'])
200 self
.assert_valid_command(['pg',
202 'degraded_pgs_exist'])
203 assert_equal({}, validate_command(sigdict
, ['pg', 'debug']))
204 assert_equal({}, validate_command(sigdict
, ['pg', 'debug',
207 def test_pg_missing_args_output(self
):
208 ret
, _
, stderr
= self
.capture_output(['pg'], stderr
=True)
209 assert_equal({}, ret
)
210 assert_regexp_matches(stderr
, re
.compile('no valid command found.* closest matches'))
212 def test_pg_wrong_arg_output(self
):
213 ret
, _
, stderr
= self
.capture_output(['pg', 'map', 'bad-pgid'],
215 assert_equal({}, ret
)
216 assert_in("Invalid command", stderr
)
219 class TestAuth(TestArgparse
):
221 def test_export(self
):
222 self
.assert_valid_command(['auth', 'export'])
223 self
.assert_valid_command(['auth',
226 assert_equal({}, validate_command(sigdict
, ['auth',
232 self
.check_1_string_arg('auth', 'get')
234 def test_get_key(self
):
235 self
.check_1_string_arg('auth', 'get-key')
237 def test_print_key(self
):
238 self
.check_1_string_arg('auth', 'print-key')
239 self
.check_1_string_arg('auth', 'print_key')
242 self
.check_no_arg('auth', 'list')
244 def test_import(self
):
245 self
.check_no_arg('auth', 'import')
248 self
.check_1_or_more_string_args('auth', 'add')
250 def test_get_or_create_key(self
):
251 self
.check_1_or_more_string_args('auth', 'get-or-create-key')
253 def test_get_or_create(self
):
254 self
.check_1_or_more_string_args('auth', 'get-or-create')
257 assert_equal({}, validate_command(sigdict
, ['auth',
259 assert_equal({}, validate_command(sigdict
, ['auth',
262 self
.assert_valid_command(['auth',
268 self
.check_1_string_arg('auth', 'del')
271 class TestMonitor(TestArgparse
):
273 def test_compact(self
):
274 self
.assert_valid_command(['compact'])
276 def test_scrub(self
):
277 self
.assert_valid_command(['scrub'])
280 self
.assert_valid_command(['fsid'])
283 assert_equal({}, validate_command(sigdict
, ['log']))
284 self
.assert_valid_command(['log', 'a logtext'])
285 self
.assert_valid_command(['log', 'a logtext', 'and another'])
287 def test_injectargs(self
):
288 assert_equal({}, validate_command(sigdict
, ['injectargs']))
289 self
.assert_valid_command(['injectargs', 'one'])
290 self
.assert_valid_command(['injectargs', 'one', 'two'])
292 def test_status(self
):
293 self
.assert_valid_command(['status'])
295 def test_health(self
):
296 self
.assert_valid_command(['health'])
297 self
.assert_valid_command(['health', 'detail'])
298 assert_equal({}, validate_command(sigdict
, ['health', 'invalid']))
299 assert_equal({}, validate_command(sigdict
, ['health', 'detail',
303 self
.assert_valid_command(['df'])
304 self
.assert_valid_command(['df', 'detail'])
305 assert_equal({}, validate_command(sigdict
, ['df', 'invalid']))
306 assert_equal({}, validate_command(sigdict
, ['df', 'detail',
309 def test_report(self
):
310 self
.assert_valid_command(['report'])
311 self
.assert_valid_command(['report', 'tag1'])
312 self
.assert_valid_command(['report', 'tag1', 'tag2'])
314 def test_quorum_status(self
):
315 self
.assert_valid_command(['quorum_status'])
317 def test_mon_status(self
):
318 self
.assert_valid_command(['mon_status'])
320 def test_sync_force(self
):
321 self
.assert_valid_command(['sync',
323 '--yes-i-really-mean-it',
324 '--i-know-what-i-am-doing'])
325 self
.assert_valid_command(['sync',
327 '--yes-i-really-mean-it'])
328 self
.assert_valid_command(['sync',
330 assert_equal({}, validate_command(sigdict
, ['sync']))
331 assert_equal({}, validate_command(sigdict
, ['sync',
333 '--yes-i-really-mean-it',
334 '--i-know-what-i-am-doing',
338 assert_equal({}, validate_command(sigdict
, ['heap']))
339 assert_equal({}, validate_command(sigdict
, ['heap', 'invalid']))
340 self
.assert_valid_command(['heap', 'dump'])
341 self
.assert_valid_command(['heap', 'start_profiler'])
342 self
.assert_valid_command(['heap', 'stop_profiler'])
343 self
.assert_valid_command(['heap', 'release'])
344 self
.assert_valid_command(['heap', 'stats'])
346 def test_quorum(self
):
347 assert_equal({}, validate_command(sigdict
, ['quorum']))
348 assert_equal({}, validate_command(sigdict
, ['quorum', 'invalid']))
349 self
.assert_valid_command(['quorum', 'enter'])
350 self
.assert_valid_command(['quorum', 'exit'])
351 assert_equal({}, validate_command(sigdict
, ['quorum',
356 assert_equal({}, validate_command(sigdict
, ['tell']))
357 assert_equal({}, validate_command(sigdict
, ['tell', 'invalid']))
358 for name
in ('osd', 'mon', 'client', 'mds'):
359 assert_equal({}, validate_command(sigdict
, ['tell', name
]))
360 assert_equal({}, validate_command(sigdict
, ['tell',
362 self
.assert_valid_command(['tell', name
+ ".42", 'something'])
363 self
.assert_valid_command(['tell', name
+ ".42",
368 class TestMDS(TestArgparse
):
371 self
.check_no_arg('mds', 'stat')
373 def test_compat_show(self
):
374 self
.assert_valid_command(['mds', 'compat', 'show'])
375 assert_equal({}, validate_command(sigdict
, ['mds', 'compat']))
376 assert_equal({}, validate_command(sigdict
, ['mds', 'compat',
379 def test_set_state(self
):
380 self
.assert_valid_command(['mds', 'set_state', '1', '2'])
381 assert_equal({}, validate_command(sigdict
, ['mds', 'set_state']))
382 assert_equal({}, validate_command(sigdict
, ['mds', 'set_state', '-1']))
383 assert_equal({}, validate_command(sigdict
, ['mds', 'set_state',
385 assert_equal({}, validate_command(sigdict
, ['mds', 'set_state',
389 self
.check_1_string_arg('mds', 'fail')
392 # Valid: single GID argument present
393 self
.assert_valid_command(['mds', 'rm', '1'])
395 # Missing GID arg: invalid
396 assert_equal({}, validate_command(sigdict
, ['mds', 'rm']))
398 assert_equal({}, validate_command(sigdict
, ['mds', 'rm', '1', 'mds.42']))
400 def test_rmfailed(self
):
401 self
.assert_valid_command(['mds', 'rmfailed', '0'])
402 self
.assert_valid_command(['mds', 'rmfailed', '0', '--yes-i-really-mean-it'])
403 assert_equal({}, validate_command(sigdict
, ['mds', 'rmfailed', '0',
404 '--yes-i-really-mean-it',
407 def test_compat_rm_compat(self
):
408 self
.assert_valid_command(['mds', 'compat', 'rm_compat', '1'])
409 assert_equal({}, validate_command(sigdict
, ['mds',
412 assert_equal({}, validate_command(sigdict
, ['mds',
415 assert_equal({}, validate_command(sigdict
, ['mds',
417 'rm_compat', '1', '1']))
419 def test_incompat_rm_incompat(self
):
420 self
.assert_valid_command(['mds', 'compat', 'rm_incompat', '1'])
421 assert_equal({}, validate_command(sigdict
, ['mds',
424 assert_equal({}, validate_command(sigdict
, ['mds',
426 'rm_incompat', '-1']))
427 assert_equal({}, validate_command(sigdict
, ['mds',
429 'rm_incompat', '1', '1']))
432 class TestFS(TestArgparse
):
435 self
.check_0_or_1_natural_arg('fs', 'dump')
437 def test_fs_new(self
):
438 self
.assert_valid_command(['fs', 'new', 'default', 'metadata', 'data'])
440 def test_fs_set_max_mds(self
):
441 self
.assert_valid_command(['fs', 'set', 'default', 'max_mds', '1'])
442 self
.assert_valid_command(['fs', 'set', 'default', 'max_mds', '2'])
444 def test_fs_set_cluster_down(self
):
445 self
.assert_valid_command(['fs', 'set', 'default', 'down', 'true'])
447 def test_fs_set_cluster_up(self
):
448 self
.assert_valid_command(['fs', 'set', 'default', 'down', 'false'])
450 def test_fs_set_cluster_joinable(self
):
451 self
.assert_valid_command(['fs', 'set', 'default', 'joinable', 'true'])
453 def test_fs_set_cluster_not_joinable(self
):
454 self
.assert_valid_command(['fs', 'set', 'default', 'joinable', 'false'])
456 def test_fs_set(self
):
457 self
.assert_valid_command(['fs', 'set', 'default', 'max_file_size', '2'])
458 self
.assert_valid_command(['fs', 'set', 'default', 'allow_new_snaps', 'no'])
459 assert_equal({}, validate_command(sigdict
, ['fs',
463 def test_fs_add_data_pool(self
):
464 self
.assert_valid_command(['fs', 'add_data_pool', 'default', '1'])
465 self
.assert_valid_command(['fs', 'add_data_pool', 'default', 'foo'])
467 def test_fs_remove_data_pool(self
):
468 self
.assert_valid_command(['fs', 'rm_data_pool', 'default', '1'])
469 self
.assert_valid_command(['fs', 'rm_data_pool', 'default', 'foo'])
471 def test_fs_rm(self
):
472 self
.assert_valid_command(['fs', 'rm', 'default'])
473 self
.assert_valid_command(['fs', 'rm', 'default', '--yes-i-really-mean-it'])
474 assert_equal({}, validate_command(sigdict
, ['fs', 'rm', 'default', '--yes-i-really-mean-it', 'toomany']))
476 def test_fs_ls(self
):
477 self
.assert_valid_command(['fs', 'ls'])
478 assert_equal({}, validate_command(sigdict
, ['fs', 'ls', 'toomany']))
480 def test_fs_set_default(self
):
481 self
.assert_valid_command(['fs', 'set-default', 'cephfs'])
482 assert_equal({}, validate_command(sigdict
, ['fs', 'set-default']))
483 assert_equal({}, validate_command(sigdict
, ['fs', 'set-default', 'cephfs', 'toomany']))
486 class TestMon(TestArgparse
):
489 self
.check_0_or_1_natural_arg('mon', 'dump')
492 self
.check_no_arg('mon', 'stat')
494 def test_getmap(self
):
495 self
.check_0_or_1_natural_arg('mon', 'getmap')
498 self
.assert_valid_command(['mon', 'add', 'name', '1.2.3.4:1234'])
499 assert_equal({}, validate_command(sigdict
, ['mon', 'add']))
500 assert_equal({}, validate_command(sigdict
, ['mon', 'add', 'name']))
501 assert_equal({}, validate_command(sigdict
, ['mon', 'add',
504 assert_equal({}, validate_command(sigdict
, ['mon', 'add', 'name',
508 def test_remove(self
):
509 self
.assert_valid_command(['mon', 'remove', 'name'])
510 assert_equal({}, validate_command(sigdict
, ['mon', 'remove']))
511 assert_equal({}, validate_command(sigdict
, ['mon', 'remove',
515 class TestOSD(TestArgparse
):
518 self
.check_no_arg('osd', 'stat')
521 self
.check_0_or_1_natural_arg('osd', 'dump')
523 def test_osd_tree(self
):
524 self
.check_0_or_1_natural_arg('osd', 'tree')
526 def test_osd_ls(self
):
527 self
.check_0_or_1_natural_arg('osd', 'ls')
529 def test_osd_getmap(self
):
530 self
.check_0_or_1_natural_arg('osd', 'getmap')
532 def test_osd_getcrushmap(self
):
533 self
.check_0_or_1_natural_arg('osd', 'getcrushmap')
536 self
.check_no_arg('osd', 'perf')
538 def test_getmaxosd(self
):
539 self
.check_no_arg('osd', 'getmaxosd')
542 self
.check_1_natural_arg('osd', 'find')
545 self
.assert_valid_command(['osd', 'map', 'poolname', 'objectname'])
546 self
.assert_valid_command(['osd', 'map', 'poolname', 'objectname', 'nspace'])
547 assert_equal({}, validate_command(sigdict
, ['osd', 'map']))
548 assert_equal({}, validate_command(sigdict
, ['osd', 'map', 'poolname']))
549 assert_equal({}, validate_command(sigdict
, ['osd', 'map',
550 'poolname', 'objectname', 'nspace',
553 def test_metadata(self
):
554 self
.check_0_or_1_natural_arg('osd', 'metadata')
556 def test_scrub(self
):
557 self
.check_1_string_arg('osd', 'scrub')
559 def test_deep_scrub(self
):
560 self
.check_1_string_arg('osd', 'deep-scrub')
562 def test_repair(self
):
563 self
.check_1_string_arg('osd', 'repair')
565 def test_lspools(self
):
566 self
.assert_valid_command(['osd', 'lspools'])
567 assert_equal({}, validate_command(sigdict
, ['osd', 'lspools',
570 def test_blacklist_ls(self
):
571 self
.assert_valid_command(['osd', 'blacklist', 'ls'])
572 assert_equal({}, validate_command(sigdict
, ['osd', 'blacklist']))
573 assert_equal({}, validate_command(sigdict
, ['osd', 'blacklist',
576 def test_crush_rule(self
):
577 assert_equal({}, validate_command(sigdict
, ['osd', 'crush']))
578 assert_equal({}, validate_command(sigdict
, ['osd', 'crush', 'rule']))
579 for subcommand
in ('list', 'ls'):
580 self
.assert_valid_command(['osd', 'crush', 'rule', subcommand
])
581 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
585 def test_crush_rule_dump(self
):
586 self
.assert_valid_command(['osd', 'crush', 'rule', 'dump'])
587 self
.assert_valid_command(['osd', 'crush', 'rule', 'dump', 'RULE'])
588 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
593 def test_crush_dump(self
):
594 self
.assert_valid_command(['osd', 'crush', 'dump'])
595 assert_equal({}, validate_command(sigdict
, ['osd', 'crush']))
596 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
600 def test_setcrushmap(self
):
601 self
.check_no_arg('osd', 'setcrushmap')
603 def test_crush_add_bucket(self
):
604 self
.assert_valid_command(['osd', 'crush', 'add-bucket',
606 self
.assert_valid_command(['osd', 'crush', 'add-bucket',
607 'name', 'type', 'root=foo-root', 'host=foo-host'])
608 assert_equal({}, validate_command(sigdict
, ['osd', 'crush']))
609 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
611 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
615 def test_crush_rename_bucket(self
):
616 self
.assert_valid_command(['osd', 'crush', 'rename-bucket',
617 'srcname', 'dstname'])
618 assert_equal({}, validate_command(sigdict
, ['osd', 'crush']))
619 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
621 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
624 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
625 'rename-bucket', 'srcname',
628 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
629 'rename-bucket', '^^^',
631 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
632 'rename-bucket', 'srcname',
635 def check_crush_setter(self
, setter
):
636 self
.assert_valid_command(['osd', 'crush', setter
,
637 '*', '2.3', 'AZaz09-_.='])
638 self
.assert_valid_command(['osd', 'crush', setter
,
639 'osd.0', '2.3', 'AZaz09-_.='])
640 self
.assert_valid_command(['osd', 'crush', setter
,
641 '0', '2.3', 'AZaz09-_.='])
642 self
.assert_valid_command(['osd', 'crush', setter
,
643 '0', '2.3', 'AZaz09-_.=', 'AZaz09-_.='])
644 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
647 ret
= validate_command(sigdict
, ['osd', 'crush',
651 assert ret
in [None, {}]
652 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
658 def test_crush_set(self
):
659 assert_equal({}, validate_command(sigdict
, ['osd', 'crush']))
660 self
.check_crush_setter('set')
662 def test_crush_add(self
):
663 assert_equal({}, validate_command(sigdict
, ['osd', 'crush']))
664 self
.check_crush_setter('add')
666 def test_crush_create_or_move(self
):
667 assert_equal({}, validate_command(sigdict
, ['osd', 'crush']))
668 self
.check_crush_setter('create-or-move')
670 def test_crush_move(self
):
671 self
.assert_valid_command(['osd', 'crush', 'move',
672 'AZaz09-_.', 'AZaz09-_.='])
673 self
.assert_valid_command(['osd', 'crush', 'move',
674 '0', 'AZaz09-_.=', 'AZaz09-_.='])
675 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
677 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
678 'move', 'AZaz09-_.']))
679 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
682 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
686 def test_crush_link(self
):
687 self
.assert_valid_command(['osd', 'crush', 'link',
688 'name', 'AZaz09-_.='])
689 self
.assert_valid_command(['osd', 'crush', 'link',
690 'name', 'AZaz09-_.=', 'AZaz09-_.='])
691 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
693 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
697 def test_crush_rm(self
):
698 for alias
in ('rm', 'remove', 'unlink'):
699 self
.assert_valid_command(['osd', 'crush', alias
, 'AZaz09-_.'])
700 self
.assert_valid_command(['osd', 'crush', alias
,
701 'AZaz09-_.', 'AZaz09-_.'])
702 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
704 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
710 def test_crush_reweight(self
):
711 self
.assert_valid_command(['osd', 'crush', 'reweight',
713 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
715 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
718 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
722 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
727 def test_crush_tunables(self
):
728 for tunable
in ('legacy', 'argonaut', 'bobtail', 'firefly',
729 'optimal', 'default'):
730 self
.assert_valid_command(['osd', 'crush', 'tunables',
732 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
734 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
736 'default', 'toomany']))
738 def test_crush_rule_create_simple(self
):
739 self
.assert_valid_command(['osd', 'crush', 'rule', 'create-simple',
740 'AZaz09-_.', 'AZaz09-_.', 'AZaz09-_.'])
741 assert_equal({}, validate_command(sigdict
, ['osd', 'crush', 'rule',
743 assert_equal({}, validate_command(sigdict
, ['osd', 'crush', 'rule',
746 assert_equal({}, validate_command(sigdict
, ['osd', 'crush', 'rule',
750 assert_equal({}, validate_command(sigdict
, ['osd', 'crush', 'rule',
755 assert_equal({}, validate_command(sigdict
, ['osd', 'crush', 'rule',
760 assert_equal({}, validate_command(sigdict
, ['osd', 'crush', 'rule',
765 assert_equal({}, validate_command(sigdict
, ['osd', 'crush', 'rule',
772 def test_crush_rule_create_erasure(self
):
773 self
.assert_valid_command(['osd', 'crush', 'rule', 'create-erasure',
775 self
.assert_valid_command(['osd', 'crush', 'rule', 'create-erasure',
776 'AZaz09-_.', 'whatever'])
777 assert_equal({}, validate_command(sigdict
, ['osd', 'crush', 'rule',
779 assert_equal({}, validate_command(sigdict
, ['osd', 'crush', 'rule',
782 assert_equal({}, validate_command(sigdict
, ['osd', 'crush', 'rule',
786 def test_crush_rule_rm(self
):
787 self
.assert_valid_command(['osd', 'crush', 'rule', 'rm', 'AZaz09-_.'])
788 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
790 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
793 assert_equal({}, validate_command(sigdict
, ['osd', 'crush',
798 def test_setmaxosd(self
):
799 self
.check_1_natural_arg('osd', 'setmaxosd')
801 def test_pause(self
):
802 self
.check_no_arg('osd', 'pause')
804 def test_unpause(self
):
805 self
.check_no_arg('osd', 'unpause')
807 def test_erasure_code_profile_set(self
):
808 self
.assert_valid_command(['osd', 'erasure-code-profile', 'set',
810 self
.assert_valid_command(['osd', 'erasure-code-profile', 'set',
812 self
.assert_valid_command(['osd', 'erasure-code-profile', 'set',
813 'name', 'A=B', 'C=D'])
814 assert_equal({}, validate_command(sigdict
, ['osd',
815 'erasure-code-profile',
817 assert_equal({}, validate_command(sigdict
, ['osd',
818 'erasure-code-profile',
822 def test_erasure_code_profile_get(self
):
823 self
.assert_valid_command(['osd', 'erasure-code-profile', 'get',
825 assert_equal({}, validate_command(sigdict
, ['osd',
826 'erasure-code-profile',
828 assert_equal({}, validate_command(sigdict
, ['osd',
829 'erasure-code-profile',
833 def test_erasure_code_profile_rm(self
):
834 self
.assert_valid_command(['osd', 'erasure-code-profile', 'rm',
836 assert_equal({}, validate_command(sigdict
, ['osd',
837 'erasure-code-profile',
839 assert_equal({}, validate_command(sigdict
, ['osd',
840 'erasure-code-profile',
844 def test_erasure_code_profile_ls(self
):
845 self
.assert_valid_command(['osd', 'erasure-code-profile', 'ls'])
846 assert_equal({}, validate_command(sigdict
, ['osd',
847 'erasure-code-profile',
851 def test_set_unset(self
):
852 for action
in ('set', 'unset'):
853 for flag
in ('pause', 'noup', 'nodown', 'noout', 'noin',
854 'nobackfill', 'norecover', 'noscrub', 'nodeep-scrub'):
855 self
.assert_valid_command(['osd', action
, flag
])
856 assert_equal({}, validate_command(sigdict
, ['osd', action
]))
857 assert_equal({}, validate_command(sigdict
, ['osd', action
,
859 assert_equal({}, validate_command(sigdict
, ['osd', action
,
860 'pause', 'toomany']))
863 self
.check_1_or_more_string_args('osd', 'down')
866 self
.check_1_or_more_string_args('osd', 'out')
869 self
.check_1_or_more_string_args('osd', 'in')
872 self
.check_1_or_more_string_args('osd', 'rm')
874 def test_reweight(self
):
875 self
.assert_valid_command(['osd', 'reweight', '1', '0.1'])
876 assert_equal({}, validate_command(sigdict
, ['osd', 'reweight']))
877 assert_equal({}, validate_command(sigdict
, ['osd', 'reweight',
879 assert_equal({}, validate_command(sigdict
, ['osd', 'reweight',
881 assert_equal({}, validate_command(sigdict
, ['osd', 'reweight',
883 assert_equal({}, validate_command(sigdict
, ['osd', 'reweight',
888 self
.assert_valid_command(['osd', 'lost', '1',
889 '--yes-i-really-mean-it'])
890 self
.assert_valid_command(['osd', 'lost', '1'])
891 assert_equal({}, validate_command(sigdict
, ['osd', 'lost']))
892 assert_equal({}, validate_command(sigdict
, ['osd', 'lost',
895 assert_equal({}, validate_command(sigdict
, ['osd', 'lost',
897 '--yes-i-really-mean-it']))
898 assert_equal({}, validate_command(sigdict
, ['osd', 'lost',
900 '--yes-i-really-mean-it',
903 def test_create(self
):
904 uuid
= '12345678123456781234567812345678'
905 self
.assert_valid_command(['osd', 'create'])
906 self
.assert_valid_command(['osd', 'create',
908 assert_equal({}, validate_command(sigdict
, ['osd', 'create',
910 assert_equal({}, validate_command(sigdict
, ['osd', 'create',
914 def test_blacklist(self
):
915 for action
in ('add', 'rm'):
916 self
.assert_valid_command(['osd', 'blacklist', action
,
918 self
.assert_valid_command(['osd', 'blacklist', action
,
920 self
.assert_valid_command(['osd', 'blacklist', action
,
921 '1.2.3.4/567', '600.40'])
922 self
.assert_valid_command(['osd', 'blacklist', action
,
923 '1.2.3.4', '600.40'])
924 assert_equal({}, validate_command(sigdict
, ['osd', 'blacklist',
928 assert_equal({}, validate_command(sigdict
, ['osd', 'blacklist',
932 assert_equal({}, validate_command(sigdict
, ['osd', 'blacklist',
938 def test_pool_mksnap(self
):
939 self
.assert_valid_command(['osd', 'pool', 'mksnap',
940 'poolname', 'snapname'])
941 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'mksnap']))
942 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'mksnap',
944 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'mksnap',
945 'poolname', 'snapname',
948 def test_pool_rmsnap(self
):
949 self
.assert_valid_command(['osd', 'pool', 'rmsnap',
950 'poolname', 'snapname'])
951 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'rmsnap']))
952 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'rmsnap',
954 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'rmsnap',
955 'poolname', 'snapname',
958 def test_pool_kwargs(self
):
960 Use the pool creation command to exercise keyword-style arguments
961 since it has lots of parameters
963 # Simply use a keyword arg instead of a positional arg, in its
964 # normal order (pgp_num after pg_num)
967 "prefix": "osd pool create",
971 }, validate_command(sigdict
, [
972 'osd', 'pool', 'create', "foo", "8", "--pgp_num", "16"]))
974 # Again, but using the "--foo=bar" style
977 "prefix": "osd pool create",
981 }, validate_command(sigdict
, [
982 'osd', 'pool', 'create', "foo", "8", "--pgp_num=16"]))
984 # Specify keyword args in a different order than their definitions
985 # (pgp_num after pool_type)
988 "prefix": "osd pool create",
992 "pool_type": "replicated"
993 }, validate_command(sigdict
, [
994 'osd', 'pool', 'create', "foo", "8",
995 "--pool_type", "replicated",
998 # Use a keyword argument that doesn't exist, should fail validation
999 assert_equal({}, validate_command(sigdict
,
1000 ['osd', 'pool', 'create', "foo", "8", "--foo=bar"]))
1003 # Long form of a boolean argument (--foo=true)
1006 "prefix": "osd pool delete",
1009 "yes_i_really_really_mean_it": True
1010 }, validate_command(sigdict
, [
1011 'osd', 'pool', 'delete', "foo", "foo",
1012 "--yes-i-really-really-mean-it=true"]))
1014 def test_pool_bool_args(self
):
1016 Use pool deletion to exercise boolean arguments since it has
1017 the --yes-i-really-really-mean-it flags
1020 # Short form of a boolean argument (--foo)
1023 "prefix": "osd pool delete",
1026 "yes_i_really_really_mean_it": True
1027 }, validate_command(sigdict
, [
1028 'osd', 'pool', 'delete', "foo", "foo",
1029 "--yes-i-really-really-mean-it"]))
1031 # Long form of a boolean argument (--foo=true)
1034 "prefix": "osd pool delete",
1037 "yes_i_really_really_mean_it": True
1038 }, validate_command(sigdict
, [
1039 'osd', 'pool', 'delete', "foo", "foo",
1040 "--yes-i-really-really-mean-it=true"]))
1042 # Negative form of a boolean argument (--foo=false)
1045 "prefix": "osd pool delete",
1048 "yes_i_really_really_mean_it": False
1049 }, validate_command(sigdict
, [
1050 'osd', 'pool', 'delete', "foo", "foo",
1051 "--yes-i-really-really-mean-it=false"]))
1053 # Invalid value boolean argument (--foo=somethingelse)
1054 assert_equal({}, validate_command(sigdict
, [
1055 'osd', 'pool', 'delete', "foo", "foo",
1056 "--yes-i-really-really-mean-it=rhubarb"]))
1058 def test_pool_create(self
):
1059 self
.assert_valid_command(['osd', 'pool', 'create',
1061 self
.assert_valid_command(['osd', 'pool', 'create',
1062 'poolname', '128', '128'])
1063 self
.assert_valid_command(['osd', 'pool', 'create',
1064 'poolname', '128', '128',
1066 self
.assert_valid_command(['osd', 'pool', 'create',
1067 'poolname', '128', '128',
1068 'erasure', 'A-Za-z0-9-_.', 'ruleset^^'])
1069 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'create']))
1070 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'create',
1072 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'create',
1074 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'create',
1079 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'create',
1082 'erasure', 'profile',
1085 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'create',
1088 'INVALID', 'profile',
1091 def test_pool_delete(self
):
1092 self
.assert_valid_command(['osd', 'pool', 'delete',
1093 'poolname', 'poolname',
1094 '--yes-i-really-really-mean-it'])
1095 self
.assert_valid_command(['osd', 'pool', 'delete',
1096 'poolname', 'poolname'])
1097 self
.assert_valid_command(['osd', 'pool', 'delete',
1099 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'delete']))
1100 assert_equal({}, validate_command(sigdict
,
1101 ['osd', 'pool', 'delete',
1102 'poolname', 'poolname',
1103 '--yes-i-really-really-mean-it',
1106 def test_pool_rename(self
):
1107 self
.assert_valid_command(['osd', 'pool', 'rename',
1108 'poolname', 'othername'])
1109 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'rename']))
1110 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'rename',
1112 assert_equal({}, validate_command(sigdict
, ['osd', 'pool', 'rename',
1113 'poolname', 'othername',
1116 def test_pool_get(self
):
1117 for var
in ('size', 'min_size',
1118 'pg_num', 'pgp_num', 'crush_rule', 'fast_read',
1119 'scrub_min_interval', 'scrub_max_interval',
1120 'deep_scrub_interval', 'recovery_priority',
1121 'recovery_op_priority'):
1122 self
.assert_valid_command(['osd', 'pool', 'get', 'poolname', var
])
1123 assert_equal({}, validate_command(sigdict
, ['osd', 'pool']))
1124 assert_equal({}, validate_command(sigdict
, ['osd', 'pool',
1126 assert_equal({}, validate_command(sigdict
, ['osd', 'pool',
1127 'get', 'poolname']))
1128 assert_equal({}, validate_command(sigdict
, ['osd', 'pool',
1130 'size', 'toomany']))
1131 assert_equal({}, validate_command(sigdict
, ['osd', 'pool',
1135 def test_pool_set(self
):
1136 for var
in ('size', 'min_size',
1137 'pg_num', 'pgp_num', 'crush_rule',
1138 'hashpspool', 'fast_read',
1139 'scrub_min_interval', 'scrub_max_interval',
1140 'deep_scrub_interval', 'recovery_priority',
1141 'recovery_op_priority'):
1142 self
.assert_valid_command(['osd', 'pool',
1143 'set', 'poolname', var
, 'value'])
1144 assert_equal({}, validate_command(sigdict
, ['osd', 'pool',
1146 assert_equal({}, validate_command(sigdict
, ['osd', 'pool',
1147 'set', 'poolname']))
1148 assert_equal({}, validate_command(sigdict
, ['osd', 'pool',
1153 def test_pool_set_quota(self
):
1154 for field
in ('max_objects', 'max_bytes'):
1155 self
.assert_valid_command(['osd', 'pool', 'set-quota',
1156 'poolname', field
, '10K'])
1157 assert_equal({}, validate_command(sigdict
, ['osd', 'pool',
1159 assert_equal({}, validate_command(sigdict
, ['osd', 'pool',
1162 assert_equal({}, validate_command(sigdict
, ['osd', 'pool',
1166 assert_equal({}, validate_command(sigdict
, ['osd', 'pool',
1171 assert_equal({}, validate_command(sigdict
, ['osd', 'pool',
1178 def test_reweight_by_utilization(self
):
1179 self
.assert_valid_command(['osd', 'reweight-by-utilization'])
1180 self
.assert_valid_command(['osd', 'reweight-by-utilization', '100'])
1181 self
.assert_valid_command(['osd', 'reweight-by-utilization', '100', '.1'])
1182 assert_equal({}, validate_command(sigdict
, ['osd',
1183 'reweight-by-utilization',
1187 def test_tier_op(self
):
1188 for op
in ('add', 'remove', 'set-overlay'):
1189 self
.assert_valid_command(['osd', 'tier', op
,
1190 'poolname', 'othername'])
1191 assert_equal({}, validate_command(sigdict
, ['osd', 'tier', op
]))
1192 assert_equal({}, validate_command(sigdict
, ['osd', 'tier', op
,
1194 assert_equal({}, validate_command(sigdict
, ['osd', 'tier', op
,
1199 def test_tier_cache_mode(self
):
1200 for mode
in ('none', 'writeback', 'forward', 'readonly', 'readforward', 'readproxy'):
1201 self
.assert_valid_command(['osd', 'tier', 'cache-mode',
1203 assert_equal({}, validate_command(sigdict
, ['osd', 'tier',
1205 assert_equal({}, validate_command(sigdict
, ['osd', 'tier',
1209 def test_tier_remove_overlay(self
):
1210 self
.assert_valid_command(['osd', 'tier', 'remove-overlay',
1212 assert_equal({}, validate_command(sigdict
, ['osd', 'tier',
1214 assert_equal({}, validate_command(sigdict
, ['osd', 'tier',
1219 def set_ratio(self
, command
):
1220 self
.assert_valid_command(['osd',
1223 assert_equal({}, validate_command(sigdict
, ['osd', command
]))
1224 assert_equal({}, validate_command(sigdict
, ['osd',
1228 def test_set_full_ratio(self
):
1229 self
.set_ratio('set-full-ratio')
1231 def test_set_backfillfull_ratio(self
):
1232 self
.set_ratio('set-backfillfull-ratio')
1234 def test_set_nearfull_ratio(self
):
1235 self
.set_ratio('set-nearfull-ratio')
1238 class TestConfigKey(TestArgparse
):
1241 self
.check_1_string_arg('config-key', 'get')
1244 self
.assert_valid_command(['config-key', 'put',
1246 self
.assert_valid_command(['config-key', 'put',
1248 assert_equal({}, validate_command(sigdict
, ['config-key', 'put']))
1249 assert_equal({}, validate_command(sigdict
, ['config-key', 'put',
1254 self
.check_1_string_arg('config-key', 'del')
1256 def test_exists(self
):
1257 self
.check_1_string_arg('config-key', 'exists')
1259 def test_dump(self
):
1260 self
.check_0_or_1_string_arg('config-key', 'dump')
1262 def test_list(self
):
1263 self
.check_no_arg('config-key', 'list')
1265 # compile-command: "cd ../.. ; make -j4 &&
1266 # PYTHONPATH=pybind nosetests --stop \
1267 # test/pybind/test_ceph_argparse.py # test_ceph_argparse.py:TestOSD.test_rm"