Add "start_version" and "end_version" support to argparse
Now, "cinder help subcommand" can not show whether an argument is supported for a specific microversion. With this change, developers only need to add a start_version or end_version in the utils.arg wrap, cinderclient will support the microversion for that arguement. @utils.arg( '--foo', start_version='3.1') @utils.arg( '--bar', start_version='3.2', end_version='3.5') def do_some_action(): ...... In previous example, an exception will be raised for such command: $ cinder --os-volume-api-version 3.6 --bar some-ation And only "--foo" will show up for such help command: $ cinder --os-volume-api-version 3.1 help some-ation Change-Id: I74137486992846bbf9fdff53c009851db2356eef Partial-Bug: #1600567 Co-Authored-By: Nate Potter <nathaniel.potter@intel.com>
This commit is contained in:
parent
0daa4aa023
commit
b76f594413
|
@ -28,6 +28,34 @@ class UnsupportedVersion(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class UnsupportedAttribute(AttributeError):
|
||||||
|
"""Indicates that the user is trying to transmit the argument to a method,
|
||||||
|
which is not supported by selected version.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, argument_name, start_version, end_version):
|
||||||
|
if not start_version.is_null() and not end_version.is_null():
|
||||||
|
self.message = (
|
||||||
|
"'%(name)s' argument is only allowed for microversions "
|
||||||
|
"%(start)s - %(end)s." % {"name": argument_name,
|
||||||
|
"start": start_version.get_string(),
|
||||||
|
"end": end_version.get_string()})
|
||||||
|
elif not start_version.is_null():
|
||||||
|
self.message = (
|
||||||
|
"'%(name)s' argument is only allowed since microversion "
|
||||||
|
"%(start)s." % {"name": argument_name,
|
||||||
|
"start": start_version.get_string()})
|
||||||
|
|
||||||
|
elif not end_version.is_null():
|
||||||
|
self.message = (
|
||||||
|
"'%(name)s' argument is not allowed after microversion "
|
||||||
|
"%(end)s." % {"name": argument_name,
|
||||||
|
"end": end_version.get_string()})
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.message
|
||||||
|
|
||||||
|
|
||||||
class InvalidAPIVersion(Exception):
|
class InvalidAPIVersion(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import logging
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
import six
|
||||||
|
|
||||||
from cinderclient import api_versions
|
from cinderclient import api_versions
|
||||||
from cinderclient import client
|
from cinderclient import client
|
||||||
|
@ -56,6 +57,8 @@ DEFAULT_CINDER_ENDPOINT_TYPE = 'publicURL'
|
||||||
V1_SHELL = 'cinderclient.v1.shell'
|
V1_SHELL = 'cinderclient.v1.shell'
|
||||||
V2_SHELL = 'cinderclient.v2.shell'
|
V2_SHELL = 'cinderclient.v2.shell'
|
||||||
V3_SHELL = 'cinderclient.v3.shell'
|
V3_SHELL = 'cinderclient.v3.shell'
|
||||||
|
HINT_HELP_MSG = (" [hint: use '--os-volume-api-version' flag to show help "
|
||||||
|
"message for proper version]")
|
||||||
|
|
||||||
logging.basicConfig()
|
logging.basicConfig()
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -395,24 +398,26 @@ class OpenStackCinderShell(object):
|
||||||
parser.set_defaults(insecure=utils.env('CINDERCLIENT_INSECURE',
|
parser.set_defaults(insecure=utils.env('CINDERCLIENT_INSECURE',
|
||||||
default=False))
|
default=False))
|
||||||
|
|
||||||
def get_subcommand_parser(self, version):
|
def get_subcommand_parser(self, version, do_help=False, input_args=None):
|
||||||
parser = self.get_base_parser()
|
parser = self.get_base_parser()
|
||||||
|
|
||||||
self.subcommands = {}
|
self.subcommands = {}
|
||||||
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||||
|
|
||||||
if version == '2':
|
if version.ver_major == 2:
|
||||||
actions_module = importutils.import_module(V2_SHELL)
|
actions_module = importutils.import_module(V2_SHELL)
|
||||||
elif version == '3':
|
elif version.ver_major == 3:
|
||||||
actions_module = importutils.import_module(V3_SHELL)
|
actions_module = importutils.import_module(V3_SHELL)
|
||||||
else:
|
else:
|
||||||
actions_module = importutils.import_module(V1_SHELL)
|
actions_module = importutils.import_module(V1_SHELL)
|
||||||
|
|
||||||
self._find_actions(subparsers, actions_module)
|
self._find_actions(subparsers, actions_module, version, do_help,
|
||||||
self._find_actions(subparsers, self)
|
input_args)
|
||||||
|
self._find_actions(subparsers, self, version, do_help, input_args)
|
||||||
|
|
||||||
for extension in self.extensions:
|
for extension in self.extensions:
|
||||||
self._find_actions(subparsers, extension.module)
|
self._find_actions(subparsers, extension.module, version, do_help,
|
||||||
|
input_args)
|
||||||
|
|
||||||
self._add_bash_completion_subparser(subparsers)
|
self._add_bash_completion_subparser(subparsers)
|
||||||
|
|
||||||
|
@ -427,18 +432,53 @@ class OpenStackCinderShell(object):
|
||||||
self.subcommands['bash_completion'] = subparser
|
self.subcommands['bash_completion'] = subparser
|
||||||
subparser.set_defaults(func=self.do_bash_completion)
|
subparser.set_defaults(func=self.do_bash_completion)
|
||||||
|
|
||||||
def _find_actions(self, subparsers, actions_module):
|
def _build_versioned_help_message(self, start_version, end_version):
|
||||||
|
if not start_version.is_null() and not end_version.is_null():
|
||||||
|
msg = (_(" (Supported by API versions %(start)s - %(end)s)")
|
||||||
|
% {"start": start_version.get_string(),
|
||||||
|
"end": end_version.get_string()})
|
||||||
|
elif not start_version.is_null():
|
||||||
|
msg = (_(" (Supported by API version %(start)s and later)")
|
||||||
|
% {"start": start_version.get_string()})
|
||||||
|
else:
|
||||||
|
msg = (_(" Supported until API version %(end)s)")
|
||||||
|
% {"end": end_version.get_string()})
|
||||||
|
return six.text_type(msg)
|
||||||
|
|
||||||
|
def _find_actions(self, subparsers, actions_module, version,
|
||||||
|
do_help, input_args):
|
||||||
for attr in (a for a in dir(actions_module) if a.startswith('do_')):
|
for attr in (a for a in dir(actions_module) if a.startswith('do_')):
|
||||||
# I prefer to be hyphen-separated instead of underscores.
|
# I prefer to be hyphen-separated instead of underscores.
|
||||||
command = attr[3:].replace('_', '-')
|
command = attr[3:].replace('_', '-')
|
||||||
callback = getattr(actions_module, attr)
|
callback = getattr(actions_module, attr)
|
||||||
desc = callback.__doc__ or ''
|
desc = callback.__doc__ or ''
|
||||||
help = desc.strip().split('\n')[0]
|
action_help = desc.strip().split('\n')[0]
|
||||||
|
if hasattr(callback, "versioned"):
|
||||||
|
additional_msg = ""
|
||||||
|
subs = api_versions.get_substitutions(
|
||||||
|
utils.get_function_name(callback))
|
||||||
|
if do_help:
|
||||||
|
additional_msg = self._build_versioned_help_message(
|
||||||
|
subs[0].start_version, subs[-1].end_version)
|
||||||
|
if version.is_latest():
|
||||||
|
additional_msg += HINT_HELP_MSG
|
||||||
|
subs = [versioned_method for versioned_method in subs
|
||||||
|
if version.matches(versioned_method.start_version,
|
||||||
|
versioned_method.end_version)]
|
||||||
|
if not subs:
|
||||||
|
# There is no proper versioned method.
|
||||||
|
continue
|
||||||
|
# Use the "latest" substitution.
|
||||||
|
callback = subs[-1].func
|
||||||
|
desc = callback.__doc__ or desc
|
||||||
|
action_help = desc.strip().split('\n')[0]
|
||||||
|
action_help += additional_msg
|
||||||
|
|
||||||
arguments = getattr(callback, 'arguments', [])
|
arguments = getattr(callback, 'arguments', [])
|
||||||
|
|
||||||
subparser = subparsers.add_parser(
|
subparser = subparsers.add_parser(
|
||||||
command,
|
command,
|
||||||
help=help,
|
help=action_help,
|
||||||
description=desc,
|
description=desc,
|
||||||
add_help=False,
|
add_help=False,
|
||||||
formatter_class=OpenStackHelpFormatter)
|
formatter_class=OpenStackHelpFormatter)
|
||||||
|
@ -448,8 +488,40 @@ class OpenStackCinderShell(object):
|
||||||
help=argparse.SUPPRESS,)
|
help=argparse.SUPPRESS,)
|
||||||
|
|
||||||
self.subcommands[command] = subparser
|
self.subcommands[command] = subparser
|
||||||
|
|
||||||
|
# NOTE(ntpttr): We get a counter for each argument in this
|
||||||
|
# command here because during the microversion check we only
|
||||||
|
# want to raise an exception if no version of the argument
|
||||||
|
# matches the current microversion. The exception will only
|
||||||
|
# be raised after the last instance of a particular argument
|
||||||
|
# fails the check.
|
||||||
|
arg_counter = dict()
|
||||||
for (args, kwargs) in arguments:
|
for (args, kwargs) in arguments:
|
||||||
subparser.add_argument(*args, **kwargs)
|
arg_counter[args[0]] = arg_counter.get(args[0], 0) + 1
|
||||||
|
|
||||||
|
for (args, kwargs) in arguments:
|
||||||
|
start_version = kwargs.get("start_version", None)
|
||||||
|
start_version = api_versions.APIVersion(start_version)
|
||||||
|
end_version = kwargs.get('end_version', None)
|
||||||
|
end_version = api_versions.APIVersion(end_version)
|
||||||
|
if do_help and not (start_version.is_null()
|
||||||
|
and end_version.is_null()):
|
||||||
|
kwargs["help"] = kwargs.get("help", "") + (
|
||||||
|
self._build_versioned_help_message(start_version,
|
||||||
|
end_version))
|
||||||
|
if not version.matches(start_version, end_version):
|
||||||
|
if args[0] in input_args and command == input_args[0]:
|
||||||
|
if arg_counter[args[0]] == 1:
|
||||||
|
# This is the last version of this argument,
|
||||||
|
# raise the exception.
|
||||||
|
raise exc.UnsupportedAttribute(args[0],
|
||||||
|
start_version, end_version)
|
||||||
|
arg_counter[args[0]] -= 1
|
||||||
|
continue
|
||||||
|
kw = kwargs.copy()
|
||||||
|
kw.pop("start_version", None)
|
||||||
|
kw.pop("end_version", None)
|
||||||
|
subparser.add_argument(*args, **kw)
|
||||||
subparser.set_defaults(func=callback)
|
subparser.set_defaults(func=callback)
|
||||||
|
|
||||||
def setup_debugging(self, debug):
|
def setup_debugging(self, debug):
|
||||||
|
@ -502,6 +574,9 @@ class OpenStackCinderShell(object):
|
||||||
api_version_input = True
|
api_version_input = True
|
||||||
self.options = options
|
self.options = options
|
||||||
|
|
||||||
|
do_help = ('help' in argv) or (
|
||||||
|
'--help' in argv) or ('-h' in argv) or not argv
|
||||||
|
|
||||||
if not options.os_volume_api_version:
|
if not options.os_volume_api_version:
|
||||||
api_version = api_versions.get_api_version(
|
api_version = api_versions.get_api_version(
|
||||||
DEFAULT_MAJOR_OS_VOLUME_API_VERSION)
|
DEFAULT_MAJOR_OS_VOLUME_API_VERSION)
|
||||||
|
@ -514,7 +589,8 @@ class OpenStackCinderShell(object):
|
||||||
self.extensions = client.discover_extensions(major_version_string)
|
self.extensions = client.discover_extensions(major_version_string)
|
||||||
self._run_extension_hooks('__pre_parse_args__')
|
self._run_extension_hooks('__pre_parse_args__')
|
||||||
|
|
||||||
subcommand_parser = self.get_subcommand_parser(major_version_string)
|
subcommand_parser = self.get_subcommand_parser(api_version,
|
||||||
|
do_help, args)
|
||||||
self.parser = subcommand_parser
|
self.parser = subcommand_parser
|
||||||
|
|
||||||
if options.help or not argv:
|
if options.help or not argv:
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
# Copyright 2016 FUJITSU LIMITED
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from cinderclient import api_versions
|
||||||
|
from cinderclient import utils
|
||||||
|
|
||||||
|
|
||||||
|
@api_versions.wraps("3.0", "3.1")
|
||||||
|
def do_fake_action():
|
||||||
|
"""help message
|
||||||
|
|
||||||
|
This will not show up in help message
|
||||||
|
"""
|
||||||
|
return "fake_action 3.0 to 3.1"
|
||||||
|
|
||||||
|
|
||||||
|
@api_versions.wraps("3.2", "3.3")
|
||||||
|
def do_fake_action():
|
||||||
|
return "fake_action 3.2 to 3.3"
|
||||||
|
|
||||||
|
|
||||||
|
@api_versions.wraps("3.6")
|
||||||
|
@utils.arg(
|
||||||
|
'--foo',
|
||||||
|
start_version='3.7')
|
||||||
|
def do_another_fake_action():
|
||||||
|
return "another_fake_action"
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg(
|
||||||
|
'--foo',
|
||||||
|
start_version='3.1',
|
||||||
|
end_version='3.2')
|
||||||
|
@utils.arg(
|
||||||
|
'--bar',
|
||||||
|
help='bar help',
|
||||||
|
start_version='3.3',
|
||||||
|
end_version='3.4')
|
||||||
|
def do_fake_action2():
|
||||||
|
return "fake_action2"
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg(
|
||||||
|
'--foo',
|
||||||
|
help='first foo',
|
||||||
|
start_version='3.6',
|
||||||
|
end_version='3.7')
|
||||||
|
@utils.arg(
|
||||||
|
'--foo',
|
||||||
|
help='second foo',
|
||||||
|
start_version='3.8')
|
||||||
|
def do_fake_action3():
|
||||||
|
return "fake_action3"
|
|
@ -27,9 +27,11 @@ from six import moves
|
||||||
from testtools import matchers
|
from testtools import matchers
|
||||||
|
|
||||||
import cinderclient
|
import cinderclient
|
||||||
|
from cinderclient import api_versions
|
||||||
from cinderclient import exceptions
|
from cinderclient import exceptions
|
||||||
from cinderclient import auth_plugin
|
from cinderclient import auth_plugin
|
||||||
from cinderclient import shell
|
from cinderclient import shell
|
||||||
|
from cinderclient.tests.unit import fake_actions_module
|
||||||
from cinderclient.tests.unit.test_auth_plugins import mock_http_request
|
from cinderclient.tests.unit.test_auth_plugins import mock_http_request
|
||||||
from cinderclient.tests.unit.test_auth_plugins import requested_headers
|
from cinderclient.tests.unit.test_auth_plugins import requested_headers
|
||||||
from cinderclient.tests.unit.fixture_data import keystone_client
|
from cinderclient.tests.unit.fixture_data import keystone_client
|
||||||
|
@ -304,3 +306,172 @@ class CinderClientArgumentParserTest(utils.TestCase):
|
||||||
help=argparse.SUPPRESS)
|
help=argparse.SUPPRESS)
|
||||||
|
|
||||||
self.assertRaises(SystemExit, parser.parse_args, ['--test'])
|
self.assertRaises(SystemExit, parser.parse_args, ['--test'])
|
||||||
|
|
||||||
|
|
||||||
|
class TestLoadVersionedActions(utils.TestCase):
|
||||||
|
|
||||||
|
def test_load_versioned_actions(self):
|
||||||
|
parser = cinderclient.shell.CinderClientArgumentParser()
|
||||||
|
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||||
|
shell = cinderclient.shell.OpenStackCinderShell()
|
||||||
|
shell.subcommands = {}
|
||||||
|
shell._find_actions(subparsers, fake_actions_module,
|
||||||
|
api_versions.APIVersion("3.0"), False, [])
|
||||||
|
self.assertIn('fake-action', shell.subcommands.keys())
|
||||||
|
self.assertEqual(
|
||||||
|
"fake_action 3.0 to 3.1",
|
||||||
|
shell.subcommands['fake-action'].get_default('func')())
|
||||||
|
|
||||||
|
shell.subcommands = {}
|
||||||
|
shell._find_actions(subparsers, fake_actions_module,
|
||||||
|
api_versions.APIVersion("3.2"), False, [])
|
||||||
|
self.assertIn('fake-action', shell.subcommands.keys())
|
||||||
|
self.assertEqual(
|
||||||
|
"fake_action 3.2 to 3.3",
|
||||||
|
shell.subcommands['fake-action'].get_default('func')())
|
||||||
|
|
||||||
|
self.assertIn('fake-action2', shell.subcommands.keys())
|
||||||
|
self.assertEqual(
|
||||||
|
"fake_action2",
|
||||||
|
shell.subcommands['fake-action2'].get_default('func')())
|
||||||
|
|
||||||
|
def test_load_versioned_actions_not_in_version_range(self):
|
||||||
|
parser = cinderclient.shell.CinderClientArgumentParser()
|
||||||
|
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||||
|
shell = cinderclient.shell.OpenStackCinderShell()
|
||||||
|
shell.subcommands = {}
|
||||||
|
shell._find_actions(subparsers, fake_actions_module,
|
||||||
|
api_versions.APIVersion('3.10000'), False, [])
|
||||||
|
self.assertNotIn('fake-action', shell.subcommands.keys())
|
||||||
|
self.assertIn('fake-action2', shell.subcommands.keys())
|
||||||
|
|
||||||
|
def test_load_versioned_actions_unsupported_input(self):
|
||||||
|
parser = cinderclient.shell.CinderClientArgumentParser()
|
||||||
|
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||||
|
shell = cinderclient.shell.OpenStackCinderShell()
|
||||||
|
shell.subcommands = {}
|
||||||
|
self.assertRaises(exceptions.UnsupportedAttribute,
|
||||||
|
shell._find_actions, subparsers, fake_actions_module,
|
||||||
|
api_versions.APIVersion('3.6'), False,
|
||||||
|
['another-fake-action', '--foo'])
|
||||||
|
|
||||||
|
def test_load_versioned_actions_with_help(self):
|
||||||
|
parser = cinderclient.shell.CinderClientArgumentParser()
|
||||||
|
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||||
|
shell = cinderclient.shell.OpenStackCinderShell()
|
||||||
|
shell.subcommands = {}
|
||||||
|
with mock.patch.object(subparsers, 'add_parser') as mock_add_parser:
|
||||||
|
shell._find_actions(subparsers, fake_actions_module,
|
||||||
|
api_versions.APIVersion("3.1"), True, [])
|
||||||
|
self.assertIn('fake-action', shell.subcommands.keys())
|
||||||
|
expected_help = ("help message (Supported by API versions "
|
||||||
|
"%(start)s - %(end)s)") % {
|
||||||
|
'start': '3.0', 'end': '3.3'}
|
||||||
|
expected_desc = ("help message\n\n "
|
||||||
|
"This will not show up in help message\n ")
|
||||||
|
mock_add_parser.assert_any_call(
|
||||||
|
'fake-action',
|
||||||
|
help=expected_help,
|
||||||
|
description=expected_desc,
|
||||||
|
add_help=False,
|
||||||
|
formatter_class=cinderclient.shell.OpenStackHelpFormatter)
|
||||||
|
|
||||||
|
def test_load_versioned_actions_with_help_on_latest(self):
|
||||||
|
parser = cinderclient.shell.CinderClientArgumentParser()
|
||||||
|
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||||
|
shell = cinderclient.shell.OpenStackCinderShell()
|
||||||
|
shell.subcommands = {}
|
||||||
|
with mock.patch.object(subparsers, 'add_parser') as mock_add_parser:
|
||||||
|
shell._find_actions(subparsers, fake_actions_module,
|
||||||
|
api_versions.APIVersion("3.latest"), True, [])
|
||||||
|
self.assertIn('another-fake-action', shell.subcommands.keys())
|
||||||
|
expected_help = (" (Supported by API versions %(start)s - "
|
||||||
|
"%(end)s)%(hint)s") % {
|
||||||
|
'start': '3.6', 'end': '3.latest',
|
||||||
|
'hint': cinderclient.shell.HINT_HELP_MSG}
|
||||||
|
mock_add_parser.assert_any_call(
|
||||||
|
'another-fake-action',
|
||||||
|
help=expected_help,
|
||||||
|
description='',
|
||||||
|
add_help=False,
|
||||||
|
formatter_class=cinderclient.shell.OpenStackHelpFormatter)
|
||||||
|
|
||||||
|
@mock.patch.object(cinderclient.shell.CinderClientArgumentParser,
|
||||||
|
'add_argument')
|
||||||
|
def test_load_versioned_actions_with_args(self, mock_add_arg):
|
||||||
|
parser = cinderclient.shell.CinderClientArgumentParser(add_help=False)
|
||||||
|
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||||
|
shell = cinderclient.shell.OpenStackCinderShell()
|
||||||
|
shell.subcommands = {}
|
||||||
|
shell._find_actions(subparsers, fake_actions_module,
|
||||||
|
api_versions.APIVersion("3.1"), False, [])
|
||||||
|
self.assertIn('fake-action2', shell.subcommands.keys())
|
||||||
|
mock_add_arg.assert_has_calls([
|
||||||
|
mock.call('-h', '--help', action='help', help='==SUPPRESS=='),
|
||||||
|
mock.call('--foo')])
|
||||||
|
|
||||||
|
@mock.patch.object(cinderclient.shell.CinderClientArgumentParser,
|
||||||
|
'add_argument')
|
||||||
|
def test_load_versioned_actions_with_args2(self, mock_add_arg):
|
||||||
|
parser = cinderclient.shell.CinderClientArgumentParser(add_help=False)
|
||||||
|
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||||
|
shell = cinderclient.shell.OpenStackCinderShell()
|
||||||
|
shell.subcommands = {}
|
||||||
|
shell._find_actions(subparsers, fake_actions_module,
|
||||||
|
api_versions.APIVersion("3.4"), False, [])
|
||||||
|
self.assertIn('fake-action2', shell.subcommands.keys())
|
||||||
|
mock_add_arg.assert_has_calls([
|
||||||
|
mock.call('-h', '--help', action='help', help='==SUPPRESS=='),
|
||||||
|
mock.call('--bar', help="bar help")])
|
||||||
|
|
||||||
|
@mock.patch.object(cinderclient.shell.CinderClientArgumentParser,
|
||||||
|
'add_argument')
|
||||||
|
def test_load_versioned_actions_with_args_not_in_version_range(
|
||||||
|
self, mock_add_arg):
|
||||||
|
parser = cinderclient.shell.CinderClientArgumentParser(add_help=False)
|
||||||
|
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||||
|
shell = cinderclient.shell.OpenStackCinderShell()
|
||||||
|
shell.subcommands = {}
|
||||||
|
shell._find_actions(subparsers, fake_actions_module,
|
||||||
|
api_versions.APIVersion("3.10000"), False, [])
|
||||||
|
self.assertIn('fake-action2', shell.subcommands.keys())
|
||||||
|
mock_add_arg.assert_has_calls([
|
||||||
|
mock.call('-h', '--help', action='help', help='==SUPPRESS==')])
|
||||||
|
|
||||||
|
@mock.patch.object(cinderclient.shell.CinderClientArgumentParser,
|
||||||
|
'add_argument')
|
||||||
|
def test_load_versioned_actions_with_args_and_help(self, mock_add_arg):
|
||||||
|
parser = cinderclient.shell.CinderClientArgumentParser(add_help=False)
|
||||||
|
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||||
|
shell = cinderclient.shell.OpenStackCinderShell()
|
||||||
|
shell.subcommands = {}
|
||||||
|
shell._find_actions(subparsers, fake_actions_module,
|
||||||
|
api_versions.APIVersion("3.4"), True, [])
|
||||||
|
mock_add_arg.assert_has_calls([
|
||||||
|
mock.call('-h', '--help', action='help', help='==SUPPRESS=='),
|
||||||
|
mock.call('--bar',
|
||||||
|
help="bar help (Supported by API versions"
|
||||||
|
" 3.3 - 3.4)")])
|
||||||
|
|
||||||
|
@mock.patch.object(cinderclient.shell.CinderClientArgumentParser,
|
||||||
|
'add_argument')
|
||||||
|
def test_load_actions_with_versioned_args(self, mock_add_arg):
|
||||||
|
parser = cinderclient.shell.CinderClientArgumentParser(add_help=False)
|
||||||
|
subparsers = parser.add_subparsers(metavar='<subcommand>')
|
||||||
|
shell = cinderclient.shell.OpenStackCinderShell()
|
||||||
|
shell.subcommands = {}
|
||||||
|
shell._find_actions(subparsers, fake_actions_module,
|
||||||
|
api_versions.APIVersion("3.6"), False, [])
|
||||||
|
self.assertIn(mock.call('--foo', help="first foo"),
|
||||||
|
mock_add_arg.call_args_list)
|
||||||
|
self.assertNotIn(mock.call('--foo', help="second foo"),
|
||||||
|
mock_add_arg.call_args_list)
|
||||||
|
|
||||||
|
mock_add_arg.reset_mock()
|
||||||
|
|
||||||
|
shell._find_actions(subparsers, fake_actions_module,
|
||||||
|
api_versions.APIVersion("3.9"), False, [])
|
||||||
|
self.assertNotIn(mock.call('--foo', help="first foo"),
|
||||||
|
mock_add_arg.call_args_list)
|
||||||
|
self.assertIn(mock.call('--foo', help="second foo"),
|
||||||
|
mock_add_arg.call_args_list)
|
||||||
|
|
|
@ -129,7 +129,7 @@ class ShellTest(utils.TestCase):
|
||||||
'--os-volume-api-version 3.9 backup-update 1234')
|
'--os-volume-api-version 3.9 backup-update 1234')
|
||||||
|
|
||||||
def test_backup_update_wrong_version(self):
|
def test_backup_update_wrong_version(self):
|
||||||
self.assertRaises(exceptions.VersionNotFoundForAPIMethod,
|
self.assertRaises(SystemExit,
|
||||||
self.run_command,
|
self.run_command,
|
||||||
'--os-volume-api-version 3.8 '
|
'--os-volume-api-version 3.8 '
|
||||||
'backup-update --name new-name 1234')
|
'backup-update --name new-name 1234')
|
||||||
|
|
|
@ -1602,14 +1602,14 @@ def do_backup_reset_state(cs, args):
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.service_type('volumev3')
|
||||||
|
@api_versions.wraps('3.9')
|
||||||
@utils.arg('backup', metavar='<backup>',
|
@utils.arg('backup', metavar='<backup>',
|
||||||
help='Name or ID of backup to rename.')
|
help='Name or ID of backup to rename.')
|
||||||
@utils.arg('--name', nargs='?', metavar='<name>',
|
@utils.arg('--name', nargs='?', metavar='<name>',
|
||||||
help='New name for backup.')
|
help='New name for backup.')
|
||||||
@utils.arg('--description', metavar='<description>',
|
@utils.arg('--description', metavar='<description>',
|
||||||
help='Backup description. Default=None.')
|
help='Backup description. Default=None.')
|
||||||
@utils.service_type('volumev3')
|
|
||||||
@api_versions.wraps('3.9')
|
|
||||||
def do_backup_update(cs, args):
|
def do_backup_update(cs, args):
|
||||||
"""Renames a backup."""
|
"""Renames a backup."""
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
|
|
Loading…
Reference in New Issue