]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/pybind/test_ceph_argparse.py
update sources to 12.2.8
[ceph.git] / 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
4 #
5 # Ceph - scalable distributed file system
6 #
7 # Copyright (C) 2013,2014 Cloudwatt <libre.licensing@cloudwatt.com>
8 # Copyright (C) 2014 Red Hat <contact@redhat.com>
9 #
10 # Author: Loic Dachary <loic@dachary.org>
11 #
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.
16 #
17
18 from nose.tools import eq_ as eq
19 from nose.tools import *
20
21 from ceph_argparse import validate_command, parse_json_funcsigs
22
23 import os
24 import re
25 import sys
26 import json
27 try:
28 from StringIO import StringIO
29 except ImportError:
30 from io import StringIO
31
32 def get_command_descriptions(what):
33 CEPH_BIN = os.environ['CEPH_BIN']
34 if CEPH_BIN == "":
35 CEPH_BIN = "."
36 return os.popen(CEPH_BIN + "/get_command_descriptions " + "--" + what).read()
37
38 def test_parse_json_funcsigs():
39 commands = get_command_descriptions("all")
40 cmd_json = parse_json_funcsigs(commands, 'cli')
41
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')
45
46 sigdict = parse_json_funcsigs(get_command_descriptions("all"), 'cli')
47
48
49 class TestArgparse:
50
51 def assert_valid_command(self, args):
52 result = validate_command(sigdict, args)
53 assert_not_in(result, [{}, None])
54
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',
60 '1']))
61
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',
67 '1']))
68
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,
73 command,
74 'string',
75 'toomany']))
76
77 def check_1_or_more_string_args(self, prefix, command):
78 assert_equal({}, validate_command(sigdict, [prefix,
79 command]))
80 self.assert_valid_command([prefix,
81 command,
82 'string'])
83 self.assert_valid_command([prefix,
84 command,
85 'string',
86 'more string'])
87
88 def check_no_arg(self, prefix, command):
89 self.assert_valid_command([prefix,
90 command])
91 assert_equal({}, validate_command(sigdict, [prefix,
92 command,
93 'toomany']))
94
95 def capture_output(self, args, stdout=None, stderr=None):
96 if stdout:
97 stdout = StringIO()
98 sys.stdout = stdout
99 if stderr:
100 stderr = StringIO()
101 sys.stderr = stderr
102 ret = validate_command(sigdict, args)
103 if stdout:
104 stdout = stdout.getvalue().strip()
105 if stderr:
106 stderr = stderr.getvalue().strip()
107 return ret, stdout, stderr
108
109
110 class TestBasic:
111
112 def test_non_ascii_in_non_options(self):
113 # ArgumentPrefix("no match for {0}".format(s)) is not able to convert
114 # unicode str parameter into str. and validate_command() should not
115 # choke on it.
116 assert_equal({}, validate_command(sigdict, [u'章鱼和鱿鱼']))
117 assert_equal({}, validate_command(sigdict, [u'–w']))
118 # actually we always pass unicode strings to validate_command() in "ceph"
119 # CLI, but we also use bytestrings in our tests, so make sure it does not
120 # break.
121 assert_equal({}, validate_command(sigdict, ['章鱼和鱿鱼']))
122 assert_equal({}, validate_command(sigdict, ['–w']))
123
124
125 class TestPG(TestArgparse):
126
127 def test_stat(self):
128 self.assert_valid_command(['pg', 'stat'])
129
130 def test_getmap(self):
131 self.assert_valid_command(['pg', 'getmap'])
132
133 def test_dump(self):
134 self.assert_valid_command(['pg', 'dump'])
135 self.assert_valid_command(['pg', 'dump',
136 'all',
137 'summary',
138 'sum',
139 'delta',
140 'pools',
141 'osds',
142 'pgs',
143 'pgs_brief'])
144 assert_equal({}, validate_command(sigdict, ['pg', 'dump', 'invalid']))
145
146 def test_dump_json(self):
147 self.assert_valid_command(['pg', 'dump_json'])
148 self.assert_valid_command(['pg', 'dump_json',
149 'all',
150 'summary',
151 'sum',
152 'pools',
153 'osds',
154 'pgs'])
155 assert_equal({}, validate_command(sigdict, ['pg', 'dump_json',
156 'invalid']))
157
158 def test_dump_pools_json(self):
159 self.assert_valid_command(['pg', 'dump_pools_json'])
160
161 def test_dump_pools_stuck(self):
162 self.assert_valid_command(['pg', 'dump_stuck'])
163 self.assert_valid_command(['pg', 'dump_stuck',
164 'inactive',
165 'unclean',
166 'stale'])
167 assert_equal({}, validate_command(sigdict, ['pg', 'dump_stuck',
168 'invalid']))
169 self.assert_valid_command(['pg', 'dump_stuck',
170 'inactive',
171 '1234'])
172
173 def one_pgid(self, command):
174 self.assert_valid_command(['pg', command, '1.1'])
175 assert_equal({}, validate_command(sigdict, ['pg', command]))
176 assert_equal({}, validate_command(sigdict, ['pg', command, '1']))
177
178 def test_map(self):
179 self.one_pgid('map')
180
181 def test_scrub(self):
182 self.one_pgid('scrub')
183
184 def test_deep_scrub(self):
185 self.one_pgid('deep-scrub')
186
187 def test_repair(self):
188 self.one_pgid('repair')
189
190 def test_debug(self):
191 self.assert_valid_command(['pg',
192 'debug',
193 'unfound_objects_exist'])
194 self.assert_valid_command(['pg',
195 'debug',
196 'degraded_pgs_exist'])
197 assert_equal({}, validate_command(sigdict, ['pg', 'debug']))
198 assert_equal({}, validate_command(sigdict, ['pg', 'debug',
199 'invalid']))
200
201 def test_pg_missing_args_output(self):
202 ret, _, stderr = self.capture_output(['pg'], stderr=True)
203 assert_equal({}, ret)
204 assert_regexp_matches(stderr, re.compile('no valid command found.* closest matches'))
205
206 def test_pg_wrong_arg_output(self):
207 ret, _, stderr = self.capture_output(['pg', 'map', 'bad-pgid'],
208 stderr=True)
209 assert_equal({}, ret)
210 assert_in("Invalid command", stderr)
211
212
213 class TestAuth(TestArgparse):
214
215 def test_export(self):
216 self.assert_valid_command(['auth', 'export'])
217 self.assert_valid_command(['auth',
218 'export',
219 'string'])
220 assert_equal({}, validate_command(sigdict, ['auth',
221 'export',
222 'string',
223 'toomany']))
224
225 def test_get(self):
226 self.check_1_string_arg('auth', 'get')
227
228 def test_get_key(self):
229 self.check_1_string_arg('auth', 'get-key')
230
231 def test_print_key(self):
232 self.check_1_string_arg('auth', 'print-key')
233 self.check_1_string_arg('auth', 'print_key')
234
235 def test_list(self):
236 self.check_no_arg('auth', 'list')
237
238 def test_import(self):
239 self.check_no_arg('auth', 'import')
240
241 def test_add(self):
242 self.check_1_or_more_string_args('auth', 'add')
243
244 def test_get_or_create_key(self):
245 self.check_1_or_more_string_args('auth', 'get-or-create-key')
246
247 def test_get_or_create(self):
248 self.check_1_or_more_string_args('auth', 'get-or-create')
249
250 def test_caps(self):
251 assert_equal({}, validate_command(sigdict, ['auth',
252 'caps']))
253 assert_equal({}, validate_command(sigdict, ['auth',
254 'caps',
255 'string']))
256 self.assert_valid_command(['auth',
257 'caps',
258 'string',
259 'more string'])
260
261 def test_del(self):
262 self.check_1_string_arg('auth', 'del')
263
264
265 class TestMonitor(TestArgparse):
266
267 def test_compact(self):
268 self.assert_valid_command(['compact'])
269
270 def test_scrub(self):
271 self.assert_valid_command(['scrub'])
272
273 def test_fsid(self):
274 self.assert_valid_command(['fsid'])
275
276 def test_log(self):
277 assert_equal({}, validate_command(sigdict, ['log']))
278 self.assert_valid_command(['log', 'a logtext'])
279 self.assert_valid_command(['log', 'a logtext', 'and another'])
280
281 def test_injectargs(self):
282 assert_equal({}, validate_command(sigdict, ['injectargs']))
283 self.assert_valid_command(['injectargs', 'one'])
284 self.assert_valid_command(['injectargs', 'one', 'two'])
285
286 def test_status(self):
287 self.assert_valid_command(['status'])
288
289 def test_health(self):
290 self.assert_valid_command(['health'])
291 self.assert_valid_command(['health', 'detail'])
292 assert_equal({}, validate_command(sigdict, ['health', 'invalid']))
293 assert_equal({}, validate_command(sigdict, ['health', 'detail',
294 'toomany']))
295
296 def test_df(self):
297 self.assert_valid_command(['df'])
298 self.assert_valid_command(['df', 'detail'])
299 assert_equal({}, validate_command(sigdict, ['df', 'invalid']))
300 assert_equal({}, validate_command(sigdict, ['df', 'detail',
301 'toomany']))
302
303 def test_report(self):
304 self.assert_valid_command(['report'])
305 self.assert_valid_command(['report', 'tag1'])
306 self.assert_valid_command(['report', 'tag1', 'tag2'])
307
308 def test_quorum_status(self):
309 self.assert_valid_command(['quorum_status'])
310
311 def test_mon_status(self):
312 self.assert_valid_command(['mon_status'])
313
314 def test_sync_force(self):
315 self.assert_valid_command(['sync',
316 'force',
317 '--yes-i-really-mean-it',
318 '--i-know-what-i-am-doing'])
319 self.assert_valid_command(['sync',
320 'force',
321 '--yes-i-really-mean-it'])
322 self.assert_valid_command(['sync',
323 'force'])
324 assert_equal({}, validate_command(sigdict, ['sync']))
325 assert_equal({}, validate_command(sigdict, ['sync',
326 'force',
327 '--yes-i-really-mean-it',
328 '--i-know-what-i-am-doing',
329 'toomany']))
330
331 def test_heap(self):
332 assert_equal({}, validate_command(sigdict, ['heap']))
333 assert_equal({}, validate_command(sigdict, ['heap', 'invalid']))
334 self.assert_valid_command(['heap', 'dump'])
335 self.assert_valid_command(['heap', 'start_profiler'])
336 self.assert_valid_command(['heap', 'stop_profiler'])
337 self.assert_valid_command(['heap', 'release'])
338 self.assert_valid_command(['heap', 'stats'])
339
340 def test_quorum(self):
341 assert_equal({}, validate_command(sigdict, ['quorum']))
342 assert_equal({}, validate_command(sigdict, ['quorum', 'invalid']))
343 self.assert_valid_command(['quorum', 'enter'])
344 self.assert_valid_command(['quorum', 'exit'])
345 assert_equal({}, validate_command(sigdict, ['quorum',
346 'enter',
347 'toomany']))
348
349 def test_tell(self):
350 assert_equal({}, validate_command(sigdict, ['tell']))
351 assert_equal({}, validate_command(sigdict, ['tell', 'invalid']))
352 for name in ('osd', 'mon', 'client', 'mds'):
353 assert_equal({}, validate_command(sigdict, ['tell', name]))
354 assert_equal({}, validate_command(sigdict, ['tell',
355 name + ".42"]))
356 self.assert_valid_command(['tell', name + ".42", 'something'])
357 self.assert_valid_command(['tell', name + ".42",
358 'something',
359 'something else'])
360
361
362 class TestMDS(TestArgparse):
363
364 def test_stat(self):
365 self.check_no_arg('mds', 'stat')
366
367 def test_dump(self):
368 self.check_0_or_1_natural_arg('mds', 'dump')
369
370 def test_tell(self):
371 self.assert_valid_command(['mds', 'tell',
372 'someone',
373 'something'])
374 self.assert_valid_command(['mds', 'tell',
375 'someone',
376 'something',
377 'something else'])
378 assert_equal({}, validate_command(sigdict, ['mds', 'tell']))
379 assert_equal({}, validate_command(sigdict, ['mds', 'tell',
380 'someone']))
381
382 def test_compat_show(self):
383 self.assert_valid_command(['mds', 'compat', 'show'])
384 assert_equal({}, validate_command(sigdict, ['mds', 'compat']))
385 assert_equal({}, validate_command(sigdict, ['mds', 'compat',
386 'show', 'toomany']))
387
388 def test_stop(self):
389 self.assert_valid_command(['mds', 'stop', 'someone'])
390 assert_equal({}, validate_command(sigdict, ['mds', 'stop']))
391 assert_equal({}, validate_command(sigdict, ['mds', 'stop',
392 'someone', 'toomany']))
393
394 def test_deactivate(self):
395 self.assert_valid_command(['mds', 'deactivate', 'someone'])
396 assert_equal({}, validate_command(sigdict, ['mds', 'deactivate']))
397 assert_equal({}, validate_command(sigdict, ['mds', 'deactivate',
398 'someone', 'toomany']))
399
400 def test_set_max_mds(self):
401 self.check_1_natural_arg('mds', 'set_max_mds')
402
403 def test_set_state(self):
404 self.assert_valid_command(['mds', 'set_state', '1', '2'])
405 assert_equal({}, validate_command(sigdict, ['mds', 'set_state']))
406 assert_equal({}, validate_command(sigdict, ['mds', 'set_state', '-1']))
407 assert_equal({}, validate_command(sigdict, ['mds', 'set_state',
408 '1', '-1']))
409 assert_equal({}, validate_command(sigdict, ['mds', 'set_state',
410 '1', '21']))
411
412 def test_fail(self):
413 self.check_1_string_arg('mds', 'fail')
414
415 def test_rm(self):
416 # Valid: single GID argument present
417 self.assert_valid_command(['mds', 'rm', '1'])
418
419 # Missing GID arg: invalid
420 assert_equal({}, validate_command(sigdict, ['mds', 'rm']))
421 # Extra arg: invalid
422 assert_equal({}, validate_command(sigdict, ['mds', 'rm', '1', 'mds.42']))
423
424 def test_rmfailed(self):
425 self.assert_valid_command(['mds', 'rmfailed', '0'])
426 self.assert_valid_command(['mds', 'rmfailed', '0', '--yes-i-really-mean-it'])
427 assert_equal({}, validate_command(sigdict, ['mds', 'rmfailed', '0',
428 '--yes-i-really-mean-it',
429 'toomany']))
430
431 def test_cluster_down(self):
432 self.check_no_arg('mds', 'cluster_down')
433
434 def test_cluster_up(self):
435 self.check_no_arg('mds', 'cluster_up')
436
437 def test_compat_rm_compat(self):
438 self.assert_valid_command(['mds', 'compat', 'rm_compat', '1'])
439 assert_equal({}, validate_command(sigdict, ['mds',
440 'compat',
441 'rm_compat']))
442 assert_equal({}, validate_command(sigdict, ['mds',
443 'compat',
444 'rm_compat', '-1']))
445 assert_equal({}, validate_command(sigdict, ['mds',
446 'compat',
447 'rm_compat', '1', '1']))
448
449 def test_incompat_rm_incompat(self):
450 self.assert_valid_command(['mds', 'compat', 'rm_incompat', '1'])
451 assert_equal({}, validate_command(sigdict, ['mds',
452 'compat',
453 'rm_incompat']))
454 assert_equal({}, validate_command(sigdict, ['mds',
455 'compat',
456 'rm_incompat', '-1']))
457 assert_equal({}, validate_command(sigdict, ['mds',
458 'compat',
459 'rm_incompat', '1', '1']))
460
461 def test_mds_set(self):
462 self.assert_valid_command(['mds', 'set', 'max_mds', '2'])
463 self.assert_valid_command(['mds', 'set', 'max_file_size', '2'])
464 self.assert_valid_command(['mds', 'set', 'allow_new_snaps', 'no'])
465 assert_equal({}, validate_command(sigdict, ['mds',
466 'set',
467 'invalid']))
468
469 def test_add_data_pool(self):
470 self.assert_valid_command(['mds', 'add_data_pool', '1'])
471 self.assert_valid_command(['mds', 'add_data_pool', 'foo'])
472
473 def test_remove_data_pool(self):
474 self.assert_valid_command(['mds', 'remove_data_pool', '1'])
475 self.assert_valid_command(['mds', 'remove_data_pool', 'foo'])
476
477 def test_newfs(self):
478 self.assert_valid_command(['mds', 'newfs', '1', '2',
479 '--yes-i-really-mean-it'])
480 self.assert_valid_command(['mds', 'newfs', '1', '2'])
481 assert_equal({}, validate_command(sigdict, ['mds', 'newfs']))
482 assert_equal({}, validate_command(sigdict, ['mds', 'newfs', '1']))
483 assert_equal({}, validate_command(sigdict, ['mds',
484 'newfs',
485 '1',
486 '2',
487 '--yes-i-really-mean-it',
488 'toomany']))
489 assert_equal({}, validate_command(sigdict, ['mds',
490 'newfs',
491 '-1',
492 '2',
493 '--yes-i-really-mean-it']))
494 assert_equal({}, validate_command(sigdict, ['mds',
495 'newfs',
496 '1',
497 '-1',
498 '--yes-i-really-mean-it']))
499
500
501 class TestFS(TestArgparse):
502
503 def test_dump(self):
504 self.check_0_or_1_natural_arg('fs', 'dump')
505
506 def test_fs_new(self):
507 self.assert_valid_command(['fs', 'new', 'default', 'metadata', 'data'])
508
509 def test_fs_rm(self):
510 self.assert_valid_command(['fs', 'rm', 'default'])
511 self.assert_valid_command(['fs', 'rm', 'default', '--yes-i-really-mean-it'])
512 assert_equal({}, validate_command(sigdict, ['fs', 'rm', 'default', '--yes-i-really-mean-it', 'toomany']))
513
514 def test_fs_ls(self):
515 self.assert_valid_command(['fs', 'ls'])
516 assert_equal({}, validate_command(sigdict, ['fs', 'ls', 'toomany']))
517
518 def test_fs_set_default(self):
519 self.assert_valid_command(['fs', 'set-default', 'cephfs'])
520 assert_equal({}, validate_command(sigdict, ['fs', 'set-default']))
521 assert_equal({}, validate_command(sigdict, ['fs', 'set-default', 'cephfs', 'toomany']))
522
523 class TestMon(TestArgparse):
524
525 def test_dump(self):
526 self.check_0_or_1_natural_arg('mon', 'dump')
527
528 def test_stat(self):
529 self.check_no_arg('mon', 'stat')
530
531 def test_getmap(self):
532 self.check_0_or_1_natural_arg('mon', 'getmap')
533
534 def test_add(self):
535 self.assert_valid_command(['mon', 'add', 'name', '1.2.3.4:1234'])
536 assert_equal({}, validate_command(sigdict, ['mon', 'add']))
537 assert_equal({}, validate_command(sigdict, ['mon', 'add', 'name']))
538 assert_equal({}, validate_command(sigdict, ['mon', 'add',
539 'name',
540 '400.500.600.700']))
541 assert_equal({}, validate_command(sigdict, ['mon', 'add', 'name',
542 '1.2.3.4:1234',
543 'toomany']))
544
545 def test_remove(self):
546 self.assert_valid_command(['mon', 'remove', 'name'])
547 assert_equal({}, validate_command(sigdict, ['mon', 'remove']))
548 assert_equal({}, validate_command(sigdict, ['mon', 'remove',
549 'name', 'toomany']))
550
551
552 class TestOSD(TestArgparse):
553
554 def test_stat(self):
555 self.check_no_arg('osd', 'stat')
556
557 def test_dump(self):
558 self.check_0_or_1_natural_arg('osd', 'dump')
559
560 def test_osd_tree(self):
561 self.check_0_or_1_natural_arg('osd', 'tree')
562
563 def test_osd_ls(self):
564 self.check_0_or_1_natural_arg('osd', 'ls')
565
566 def test_osd_getmap(self):
567 self.check_0_or_1_natural_arg('osd', 'getmap')
568
569 def test_osd_getcrushmap(self):
570 self.check_0_or_1_natural_arg('osd', 'getcrushmap')
571
572 def test_perf(self):
573 self.check_no_arg('osd', 'perf')
574
575 def test_getmaxosd(self):
576 self.check_no_arg('osd', 'getmaxosd')
577
578 def test_find(self):
579 self.check_1_natural_arg('osd', 'find')
580
581 def test_map(self):
582 self.assert_valid_command(['osd', 'map', 'poolname', 'objectname'])
583 self.assert_valid_command(['osd', 'map', 'poolname', 'objectname', 'nspace'])
584 assert_equal({}, validate_command(sigdict, ['osd', 'map']))
585 assert_equal({}, validate_command(sigdict, ['osd', 'map', 'poolname']))
586 assert_equal({}, validate_command(sigdict, ['osd', 'map',
587 'poolname', 'objectname', 'nspace',
588 'toomany']))
589
590 def test_metadata(self):
591 self.check_0_or_1_natural_arg('osd', 'metadata')
592
593 def test_scrub(self):
594 self.check_1_string_arg('osd', 'scrub')
595
596 def test_deep_scrub(self):
597 self.check_1_string_arg('osd', 'deep-scrub')
598
599 def test_repair(self):
600 self.check_1_string_arg('osd', 'repair')
601
602 def test_lspools(self):
603 self.assert_valid_command(['osd', 'lspools'])
604 self.assert_valid_command(['osd', 'lspools', '1'])
605 self.assert_valid_command(['osd', 'lspools', '-1'])
606 assert_equal({}, validate_command(sigdict, ['osd', 'lspools',
607 '1', 'toomany']))
608
609 def test_blacklist_ls(self):
610 self.assert_valid_command(['osd', 'blacklist', 'ls'])
611 assert_equal({}, validate_command(sigdict, ['osd', 'blacklist']))
612 assert_equal({}, validate_command(sigdict, ['osd', 'blacklist',
613 'ls', 'toomany']))
614
615 def test_crush_rule(self):
616 assert_equal({}, validate_command(sigdict, ['osd', 'crush']))
617 assert_equal({}, validate_command(sigdict, ['osd', 'crush', 'rule']))
618 for subcommand in ('list', 'ls'):
619 self.assert_valid_command(['osd', 'crush', 'rule', subcommand])
620 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
621 'rule', subcommand,
622 'toomany']))
623
624 def test_crush_rule_dump(self):
625 self.assert_valid_command(['osd', 'crush', 'rule', 'dump'])
626 self.assert_valid_command(['osd', 'crush', 'rule', 'dump', 'RULE'])
627 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
628 'rule', 'dump',
629 'RULE',
630 'toomany']))
631
632 def test_crush_dump(self):
633 self.assert_valid_command(['osd', 'crush', 'dump'])
634 assert_equal({}, validate_command(sigdict, ['osd', 'crush']))
635 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
636 'dump',
637 'toomany']))
638
639 def test_setcrushmap(self):
640 self.check_no_arg('osd', 'setcrushmap')
641
642 def test_crush_add_bucket(self):
643 self.assert_valid_command(['osd', 'crush', 'add-bucket',
644 'name', 'type'])
645 assert_equal({}, validate_command(sigdict, ['osd', 'crush']))
646 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
647 'add-bucket']))
648 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
649 'add-bucket', 'name',
650 'type',
651 'toomany']))
652 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
653 'add-bucket', '^^^',
654 'type']))
655
656 def test_crush_rename_bucket(self):
657 self.assert_valid_command(['osd', 'crush', 'rename-bucket',
658 'srcname', 'dstname'])
659 assert_equal({}, validate_command(sigdict, ['osd', 'crush']))
660 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
661 'rename-bucket']))
662 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
663 'rename-bucket',
664 'srcname']))
665 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
666 'rename-bucket', 'srcname',
667 'dstname',
668 'toomany']))
669 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
670 'rename-bucket', '^^^',
671 'dstname']))
672 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
673 'rename-bucket', 'srcname',
674 '^^^^']))
675
676 def check_crush_setter(self, setter):
677 self.assert_valid_command(['osd', 'crush', setter,
678 '*', '2.3', 'AZaz09-_.='])
679 self.assert_valid_command(['osd', 'crush', setter,
680 'osd.0', '2.3', 'AZaz09-_.='])
681 self.assert_valid_command(['osd', 'crush', setter,
682 '0', '2.3', 'AZaz09-_.='])
683 self.assert_valid_command(['osd', 'crush', setter,
684 '0', '2.3', 'AZaz09-_.=', 'AZaz09-_.='])
685 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
686 setter,
687 'osd.0']))
688 ret = validate_command(sigdict, ['osd', 'crush',
689 setter,
690 'osd.0',
691 '-1.0'])
692 assert ret in [None, {}]
693 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
694 setter,
695 'osd.0',
696 '1.0',
697 '^^^']))
698
699 def test_crush_set(self):
700 assert_equal({}, validate_command(sigdict, ['osd', 'crush']))
701 self.check_crush_setter('set')
702
703 def test_crush_add(self):
704 assert_equal({}, validate_command(sigdict, ['osd', 'crush']))
705 self.check_crush_setter('add')
706
707 def test_crush_create_or_move(self):
708 assert_equal({}, validate_command(sigdict, ['osd', 'crush']))
709 self.check_crush_setter('create-or-move')
710
711 def test_crush_move(self):
712 self.assert_valid_command(['osd', 'crush', 'move',
713 'AZaz09-_.', 'AZaz09-_.='])
714 self.assert_valid_command(['osd', 'crush', 'move',
715 '0', 'AZaz09-_.=', 'AZaz09-_.='])
716 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
717 'move']))
718 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
719 'move', 'AZaz09-_.']))
720 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
721 'move', '^^^',
722 'AZaz09-_.=']))
723 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
724 'move', 'AZaz09-_.',
725 '^^^']))
726
727 def test_crush_link(self):
728 self.assert_valid_command(['osd', 'crush', 'link',
729 'name', 'AZaz09-_.='])
730 self.assert_valid_command(['osd', 'crush', 'link',
731 'name', 'AZaz09-_.=', 'AZaz09-_.='])
732 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
733 'link']))
734 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
735 'link',
736 'name']))
737
738 def test_crush_rm(self):
739 for alias in ('rm', 'remove', 'unlink'):
740 self.assert_valid_command(['osd', 'crush', alias, 'AZaz09-_.'])
741 self.assert_valid_command(['osd', 'crush', alias,
742 'AZaz09-_.', 'AZaz09-_.'])
743 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
744 alias]))
745 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
746 alias,
747 'AZaz09-_.',
748 'AZaz09-_.',
749 'toomany']))
750
751 def test_crush_reweight(self):
752 self.assert_valid_command(['osd', 'crush', 'reweight',
753 'AZaz09-_.', '2.3'])
754 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
755 'reweight']))
756 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
757 'reweight',
758 'AZaz09-_.']))
759 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
760 'reweight',
761 'AZaz09-_.',
762 '-1.0']))
763 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
764 'reweight',
765 '^^^',
766 '2.3']))
767
768 def test_crush_tunables(self):
769 for tunable in ('legacy', 'argonaut', 'bobtail', 'firefly',
770 'optimal', 'default'):
771 self.assert_valid_command(['osd', 'crush', 'tunables',
772 tunable])
773 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
774 'tunables']))
775 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
776 'tunables',
777 'default', 'toomany']))
778
779 def test_crush_rule_create_simple(self):
780 self.assert_valid_command(['osd', 'crush', 'rule', 'create-simple',
781 'AZaz09-_.', 'AZaz09-_.', 'AZaz09-_.'])
782 assert_equal({}, validate_command(sigdict, ['osd', 'crush', 'rule',
783 'create-simple']))
784 assert_equal({}, validate_command(sigdict, ['osd', 'crush', 'rule',
785 'create-simple',
786 'AZaz09-_.']))
787 assert_equal({}, validate_command(sigdict, ['osd', 'crush', 'rule',
788 'create-simple',
789 'AZaz09-_.',
790 'AZaz09-_.']))
791 assert_equal({}, validate_command(sigdict, ['osd', 'crush', 'rule',
792 'create-simple',
793 '^^^',
794 'AZaz09-_.',
795 'AZaz09-_.']))
796 assert_equal({}, validate_command(sigdict, ['osd', 'crush', 'rule',
797 'create-simple',
798 'AZaz09-_.',
799 '|||',
800 'AZaz09-_.']))
801 assert_equal({}, validate_command(sigdict, ['osd', 'crush', 'rule',
802 'create-simple',
803 'AZaz09-_.',
804 'AZaz09-_.',
805 '+++']))
806 assert_equal({}, validate_command(sigdict, ['osd', 'crush', 'rule',
807 'create-simple',
808 'AZaz09-_.',
809 'AZaz09-_.',
810 'AZaz09-_.',
811 'toomany']))
812
813 def test_crush_rule_create_erasure(self):
814 self.assert_valid_command(['osd', 'crush', 'rule', 'create-erasure',
815 'AZaz09-_.'])
816 self.assert_valid_command(['osd', 'crush', 'rule', 'create-erasure',
817 'AZaz09-_.', 'whatever'])
818 assert_equal({}, validate_command(sigdict, ['osd', 'crush', 'rule',
819 'create-erasure']))
820 assert_equal({}, validate_command(sigdict, ['osd', 'crush', 'rule',
821 'create-erasure',
822 '^^^']))
823 assert_equal({}, validate_command(sigdict, ['osd', 'crush', 'rule',
824 'create-erasure',
825 'name', '^^^']))
826
827 def test_crush_rule_rm(self):
828 self.assert_valid_command(['osd', 'crush', 'rule', 'rm', 'AZaz09-_.'])
829 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
830 'rule', 'rm']))
831 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
832 'rule', 'rm',
833 '^^^^']))
834 assert_equal({}, validate_command(sigdict, ['osd', 'crush',
835 'rule', 'rm',
836 'AZaz09-_.',
837 'toomany']))
838
839 def test_setmaxosd(self):
840 self.check_1_natural_arg('osd', 'setmaxosd')
841
842 def test_pause(self):
843 self.check_no_arg('osd', 'pause')
844
845 def test_unpause(self):
846 self.check_no_arg('osd', 'unpause')
847
848 def test_erasure_code_profile_set(self):
849 self.assert_valid_command(['osd', 'erasure-code-profile', 'set',
850 'name'])
851 self.assert_valid_command(['osd', 'erasure-code-profile', 'set',
852 'name', 'A=B'])
853 self.assert_valid_command(['osd', 'erasure-code-profile', 'set',
854 'name', 'A=B', 'C=D'])
855 assert_equal({}, validate_command(sigdict, ['osd',
856 'erasure-code-profile',
857 'set']))
858 assert_equal({}, validate_command(sigdict, ['osd',
859 'erasure-code-profile',
860 'set',
861 '^^^^']))
862
863 def test_erasure_code_profile_get(self):
864 self.assert_valid_command(['osd', 'erasure-code-profile', 'get',
865 'name'])
866 assert_equal({}, validate_command(sigdict, ['osd',
867 'erasure-code-profile',
868 'get']))
869 assert_equal({}, validate_command(sigdict, ['osd',
870 'erasure-code-profile',
871 'get',
872 '^^^^']))
873
874 def test_erasure_code_profile_rm(self):
875 self.assert_valid_command(['osd', 'erasure-code-profile', 'rm',
876 'name'])
877 assert_equal({}, validate_command(sigdict, ['osd',
878 'erasure-code-profile',
879 'rm']))
880 assert_equal({}, validate_command(sigdict, ['osd',
881 'erasure-code-profile',
882 'rm',
883 '^^^^']))
884
885 def test_erasure_code_profile_ls(self):
886 self.assert_valid_command(['osd', 'erasure-code-profile', 'ls'])
887 assert_equal({}, validate_command(sigdict, ['osd',
888 'erasure-code-profile',
889 'ls',
890 'toomany']))
891
892 def test_set_unset(self):
893 for action in ('set', 'unset'):
894 for flag in ('pause', 'noup', 'nodown', 'noout', 'noin',
895 'nobackfill', 'norecover', 'noscrub', 'nodeep-scrub'):
896 self.assert_valid_command(['osd', action, flag])
897 assert_equal({}, validate_command(sigdict, ['osd', action]))
898 assert_equal({}, validate_command(sigdict, ['osd', action,
899 'invalid']))
900 assert_equal({}, validate_command(sigdict, ['osd', action,
901 'pause', 'toomany']))
902
903 def test_cluster_snap(self):
904 assert_equal({}, validate_command(sigdict, ['osd', 'cluster_snap']))
905
906 def test_down(self):
907 self.check_1_or_more_string_args('osd', 'down')
908
909 def test_out(self):
910 self.check_1_or_more_string_args('osd', 'out')
911
912 def test_in(self):
913 self.check_1_or_more_string_args('osd', 'in')
914
915 def test_rm(self):
916 self.check_1_or_more_string_args('osd', 'rm')
917
918 def test_reweight(self):
919 self.assert_valid_command(['osd', 'reweight', '1', '0.1'])
920 assert_equal({}, validate_command(sigdict, ['osd', 'reweight']))
921 assert_equal({}, validate_command(sigdict, ['osd', 'reweight',
922 '1']))
923 assert_equal({}, validate_command(sigdict, ['osd', 'reweight',
924 '1', '2.0']))
925 assert_equal({}, validate_command(sigdict, ['osd', 'reweight',
926 '-1', '0.1']))
927 assert_equal({}, validate_command(sigdict, ['osd', 'reweight',
928 '1', '0.1',
929 'toomany']))
930
931 def test_lost(self):
932 self.assert_valid_command(['osd', 'lost', '1',
933 '--yes-i-really-mean-it'])
934 self.assert_valid_command(['osd', 'lost', '1'])
935 assert_equal({}, validate_command(sigdict, ['osd', 'lost']))
936 assert_equal({}, validate_command(sigdict, ['osd', 'lost',
937 '1',
938 'what?']))
939 assert_equal({}, validate_command(sigdict, ['osd', 'lost',
940 '-1',
941 '--yes-i-really-mean-it']))
942 assert_equal({}, validate_command(sigdict, ['osd', 'lost',
943 '1',
944 '--yes-i-really-mean-it',
945 'toomany']))
946
947 def test_create(self):
948 uuid = '12345678123456781234567812345678'
949 self.assert_valid_command(['osd', 'create'])
950 self.assert_valid_command(['osd', 'create',
951 uuid])
952 assert_equal({}, validate_command(sigdict, ['osd', 'create',
953 'invalid']))
954 assert_equal({}, validate_command(sigdict, ['osd', 'create',
955 uuid,
956 'toomany']))
957
958 def test_blacklist(self):
959 for action in ('add', 'rm'):
960 self.assert_valid_command(['osd', 'blacklist', action,
961 '1.2.3.4/567'])
962 self.assert_valid_command(['osd', 'blacklist', action,
963 '1.2.3.4'])
964 self.assert_valid_command(['osd', 'blacklist', action,
965 '1.2.3.4/567', '600.40'])
966 self.assert_valid_command(['osd', 'blacklist', action,
967 '1.2.3.4', '600.40'])
968 assert_equal({}, validate_command(sigdict, ['osd', 'blacklist',
969 action,
970 'invalid',
971 '600.40']))
972 assert_equal({}, validate_command(sigdict, ['osd', 'blacklist',
973 action,
974 '1.2.3.4/567',
975 '-1.0']))
976 assert_equal({}, validate_command(sigdict, ['osd', 'blacklist',
977 action,
978 '1.2.3.4/567',
979 '600.40',
980 'toomany']))
981
982 def test_pool_mksnap(self):
983 self.assert_valid_command(['osd', 'pool', 'mksnap',
984 'poolname', 'snapname'])
985 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'mksnap']))
986 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'mksnap',
987 'poolname']))
988 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'mksnap',
989 'poolname', 'snapname',
990 'toomany']))
991
992 def test_pool_rmsnap(self):
993 self.assert_valid_command(['osd', 'pool', 'rmsnap',
994 'poolname', 'snapname'])
995 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'rmsnap']))
996 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'rmsnap',
997 'poolname']))
998 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'rmsnap',
999 'poolname', 'snapname',
1000 'toomany']))
1001
1002 def test_pool_create(self):
1003 self.assert_valid_command(['osd', 'pool', 'create',
1004 'poolname', '128'])
1005 self.assert_valid_command(['osd', 'pool', 'create',
1006 'poolname', '128', '128'])
1007 self.assert_valid_command(['osd', 'pool', 'create',
1008 'poolname', '128', '128',
1009 'replicated'])
1010 self.assert_valid_command(['osd', 'pool', 'create',
1011 'poolname', '128', '128',
1012 'erasure', 'A-Za-z0-9-_.', 'ruleset^^'])
1013 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'create']))
1014 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'create',
1015 'poolname']))
1016 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'create',
1017 'poolname', '-1']))
1018 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'create',
1019 'poolname',
1020 '128', '128',
1021 'erasure', '^^^',
1022 'ruleset']))
1023 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'create',
1024 'poolname',
1025 '128', '128',
1026 'erasure', 'profile',
1027 'ruleset',
1028 'toomany']))
1029 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'create',
1030 'poolname',
1031 '128', '128',
1032 'INVALID', 'profile',
1033 'ruleset']))
1034
1035 def test_pool_delete(self):
1036 self.assert_valid_command(['osd', 'pool', 'delete',
1037 'poolname', 'poolname',
1038 '--yes-i-really-really-mean-it'])
1039 self.assert_valid_command(['osd', 'pool', 'delete',
1040 'poolname', 'poolname'])
1041 self.assert_valid_command(['osd', 'pool', 'delete',
1042 'poolname'])
1043 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'delete']))
1044 assert_equal({}, validate_command(sigdict,
1045 ['osd', 'pool', 'delete',
1046 'poolname', 'poolname',
1047 '--yes-i-really-really-mean-it',
1048 'toomany']))
1049
1050 def test_pool_rename(self):
1051 self.assert_valid_command(['osd', 'pool', 'rename',
1052 'poolname', 'othername'])
1053 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'rename']))
1054 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'rename',
1055 'poolname']))
1056 assert_equal({}, validate_command(sigdict, ['osd', 'pool', 'rename',
1057 'poolname', 'othername',
1058 'toomany']))
1059
1060 def test_pool_get(self):
1061 for var in ('size', 'min_size', 'crash_replay_interval',
1062 'pg_num', 'pgp_num', 'crush_rule', 'auid', 'fast_read',
1063 'scrub_min_interval', 'scrub_max_interval',
1064 'deep_scrub_interval', 'recovery_priority',
1065 'recovery_op_priority'):
1066 self.assert_valid_command(['osd', 'pool', 'get', 'poolname', var])
1067 assert_equal({}, validate_command(sigdict, ['osd', 'pool']))
1068 assert_equal({}, validate_command(sigdict, ['osd', 'pool',
1069 'get']))
1070 assert_equal({}, validate_command(sigdict, ['osd', 'pool',
1071 'get', 'poolname']))
1072 assert_equal({}, validate_command(sigdict, ['osd', 'pool',
1073 'get', 'poolname',
1074 'size', 'toomany']))
1075 assert_equal({}, validate_command(sigdict, ['osd', 'pool',
1076 'get', 'poolname',
1077 'invalid']))
1078
1079 def test_pool_set(self):
1080 for var in ('size', 'min_size', 'crash_replay_interval',
1081 'pg_num', 'pgp_num', 'crush_rule',
1082 'hashpspool', 'auid', 'fast_read',
1083 'scrub_min_interval', 'scrub_max_interval',
1084 'deep_scrub_interval', 'recovery_priority',
1085 'recovery_op_priority'):
1086 self.assert_valid_command(['osd', 'pool',
1087 'set', 'poolname', var, 'value'])
1088 assert_equal({}, validate_command(sigdict, ['osd', 'pool',
1089 'set']))
1090 assert_equal({}, validate_command(sigdict, ['osd', 'pool',
1091 'set', 'poolname']))
1092 assert_equal({}, validate_command(sigdict, ['osd', 'pool',
1093 'set', 'poolname',
1094 'size', 'value',
1095 'toomany']))
1096
1097 def test_pool_set_quota(self):
1098 for field in ('max_objects', 'max_bytes'):
1099 self.assert_valid_command(['osd', 'pool', 'set-quota',
1100 'poolname', field, '10K'])
1101 assert_equal({}, validate_command(sigdict, ['osd', 'pool',
1102 'set-quota']))
1103 assert_equal({}, validate_command(sigdict, ['osd', 'pool',
1104 'set-quota',
1105 'poolname']))
1106 assert_equal({}, validate_command(sigdict, ['osd', 'pool',
1107 'set-quota',
1108 'poolname',
1109 'max_objects']))
1110 assert_equal({}, validate_command(sigdict, ['osd', 'pool',
1111 'set-quota',
1112 'poolname',
1113 'invalid',
1114 '10K']))
1115 assert_equal({}, validate_command(sigdict, ['osd', 'pool',
1116 'set-quota',
1117 'poolname',
1118 'max_objects',
1119 '10K',
1120 'toomany']))
1121
1122 def test_reweight_by_utilization(self):
1123 self.assert_valid_command(['osd', 'reweight-by-utilization'])
1124 self.assert_valid_command(['osd', 'reweight-by-utilization', '100'])
1125 self.assert_valid_command(['osd', 'reweight-by-utilization', '100', '.1'])
1126 self.assert_valid_command(['osd', 'reweight-by-utilization', '--no-increasing'])
1127 assert_equal({}, validate_command(sigdict, ['osd',
1128 'reweight-by-utilization',
1129 '100',
1130 'toomany']))
1131
1132 def test_tier_op(self):
1133 for op in ('add', 'remove', 'set-overlay'):
1134 self.assert_valid_command(['osd', 'tier', op,
1135 'poolname', 'othername'])
1136 assert_equal({}, validate_command(sigdict, ['osd', 'tier', op]))
1137 assert_equal({}, validate_command(sigdict, ['osd', 'tier', op,
1138 'poolname']))
1139 assert_equal({}, validate_command(sigdict, ['osd', 'tier', op,
1140 'poolname',
1141 'othername',
1142 'toomany']))
1143
1144 def test_tier_cache_mode(self):
1145 for mode in ('none', 'writeback', 'forward', 'readonly', 'readforward', 'readproxy'):
1146 self.assert_valid_command(['osd', 'tier', 'cache-mode',
1147 'poolname', mode])
1148 assert_equal({}, validate_command(sigdict, ['osd', 'tier',
1149 'cache-mode']))
1150 assert_equal({}, validate_command(sigdict, ['osd', 'tier',
1151 'cache-mode',
1152 'invalid']))
1153
1154 def test_tier_remove_overlay(self):
1155 self.assert_valid_command(['osd', 'tier', 'remove-overlay',
1156 'poolname'])
1157 assert_equal({}, validate_command(sigdict, ['osd', 'tier',
1158 'remove-overlay']))
1159 assert_equal({}, validate_command(sigdict, ['osd', 'tier',
1160 'remove-overlay',
1161 'poolname',
1162 'toomany']))
1163
1164 def set_ratio(self, command):
1165 self.assert_valid_command(['osd',
1166 command,
1167 '0.0'])
1168 assert_equal({}, validate_command(sigdict, ['osd', command]))
1169 assert_equal({}, validate_command(sigdict, ['osd',
1170 command,
1171 '2.0']))
1172
1173 def test_set_full_ratio(self):
1174 self.set_ratio('set-full-ratio')
1175
1176 def test_set_backfillfull_ratio(self):
1177 self.set_ratio('set-backfillfull-ratio')
1178
1179 def test_set_nearfull_ratio(self):
1180 self.set_ratio('set-nearfull-ratio')
1181
1182
1183 class TestConfigKey(TestArgparse):
1184
1185 def test_get(self):
1186 self.check_1_string_arg('config-key', 'get')
1187
1188 def test_put(self):
1189 self.assert_valid_command(['config-key', 'put',
1190 'key'])
1191 self.assert_valid_command(['config-key', 'put',
1192 'key', 'value'])
1193 assert_equal({}, validate_command(sigdict, ['config-key', 'put']))
1194 assert_equal({}, validate_command(sigdict, ['config-key', 'put',
1195 'key', 'value',
1196 'toomany']))
1197
1198 def test_del(self):
1199 self.check_1_string_arg('config-key', 'del')
1200
1201 def test_exists(self):
1202 self.check_1_string_arg('config-key', 'exists')
1203
1204 def test_dump(self):
1205 self.check_no_arg('config-key', 'dump')
1206
1207 def test_list(self):
1208 self.check_no_arg('config-key', 'list')
1209 # Local Variables:
1210 # compile-command: "cd ../.. ; make -j4 &&
1211 # PYTHONPATH=pybind nosetests --stop \
1212 # test/pybind/test_ceph_argparse.py # test_ceph_argparse.py:TestOSD.test_rm"
1213 # End: