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