diff options
Diffstat (limited to 'openstackclient')
107 files changed, 3755 insertions, 658 deletions
diff --git a/openstackclient/api/api.py b/openstackclient/api/api.py index 97eb7e4a..6a88e7f7 100644 --- a/openstackclient/api/api.py +++ b/openstackclient/api/api.py @@ -243,14 +243,14 @@ class BaseAPI(KeystoneSession): def getlist(kw): """Do list call, unwrap resource dict if present""" ret = self.list(path, **kw) - if type(ret) == dict and resource in ret: + if isinstance(ret, dict) and resource in ret: ret = ret[resource] return ret # Search by attribute kwargs = {attr: value} data = getlist(kwargs) - if type(data) == dict: + if isinstance(data, dict): return data if len(data) == 1: return data[0] @@ -283,7 +283,7 @@ class BaseAPI(KeystoneSession): """ items = self.list(path) - if type(items) == dict: + if isinstance(items, dict): # strip off the enclosing dict key = list(items.keys())[0] items = items[key] diff --git a/openstackclient/api/auth.py b/openstackclient/api/auth.py index 66272e42..3d6f7bcf 100644 --- a/openstackclient/api/auth.py +++ b/openstackclient/api/auth.py @@ -80,13 +80,13 @@ def select_auth_plugin(options): # Do the token/url check first as this must override the default # 'password' set by os-client-config # Also, url and token are not copied into o-c-c's auth dict (yet?) - if options.auth.get('url', None) and options.auth.get('token', None): + if options.auth.get('url') and options.auth.get('token'): # service token authentication auth_plugin_name = 'token_endpoint' elif options.auth_type in [plugin.name for plugin in PLUGIN_LIST]: # A direct plugin name was given, use it auth_plugin_name = options.auth_type - elif options.auth.get('username', None): + elif options.auth.get('username'): if options.identity_api_version == '3': auth_plugin_name = 'v3password' elif options.identity_api_version.startswith('2'): @@ -94,7 +94,7 @@ def select_auth_plugin(options): else: # let keystoneclient figure it out itself auth_plugin_name = 'osc_password' - elif options.auth.get('token', None): + elif options.auth.get('token'): if options.identity_api_version == '3': auth_plugin_name = 'v3token' elif options.identity_api_version.startswith('2'): @@ -106,7 +106,7 @@ def select_auth_plugin(options): # The ultimate default is similar to the original behaviour, # but this time with version discovery auth_plugin_name = 'osc_password' - LOG.debug("Auth plugin %s selected" % auth_plugin_name) + LOG.debug("Auth plugin %s selected", auth_plugin_name) return auth_plugin_name @@ -130,42 +130,47 @@ def build_auth_params(auth_plugin_name, cmd_options): auth_plugin_class = None plugin_options = set([o.replace('-', '_') for o in get_options_list()]) for option in plugin_options: - LOG.debug('fetching option %s' % option) + LOG.debug('fetching option %s', option) auth_params[option] = getattr(cmd_options.auth, option, None) return (auth_plugin_class, auth_params) -def check_valid_auth_options(options, auth_plugin_name): - """Perform basic option checking, provide helpful error messages""" +def check_valid_auth_options(options, auth_plugin_name, required_scope=True): + """Perform basic option checking, provide helpful error messages. + + :param required_scope: indicate whether a scoped token is required + + """ msg = '' if auth_plugin_name.endswith('password'): - if not options.auth.get('username', None): + if not options.auth.get('username'): msg += _('Set a username with --os-username, OS_USERNAME,' ' or auth.username\n') - if not options.auth.get('auth_url', None): + if not options.auth.get('auth_url'): msg += _('Set an authentication URL, with --os-auth-url,' ' OS_AUTH_URL or auth.auth_url\n') - if (not options.auth.get('project_id', None) and not - options.auth.get('domain_id', None) and not - options.auth.get('domain_name', None) and not - options.auth.get('project_name', None) and not - options.auth.get('tenant_id', None) and not - options.auth.get('tenant_name', None)): + if (required_scope and not + options.auth.get('project_id') and not + options.auth.get('domain_id') and not + options.auth.get('domain_name') and not + options.auth.get('project_name') and not + options.auth.get('tenant_id') and not + options.auth.get('tenant_name')): msg += _('Set a scope, such as a project or domain, set a ' 'project scope with --os-project-name, OS_PROJECT_NAME ' 'or auth.project_name, set a domain scope with ' '--os-domain-name, OS_DOMAIN_NAME or auth.domain_name') elif auth_plugin_name.endswith('token'): - if not options.auth.get('token', None): + if not options.auth.get('token'): msg += _('Set a token with --os-token, OS_TOKEN or auth.token\n') - if not options.auth.get('auth_url', None): + if not options.auth.get('auth_url'): msg += _('Set a service AUTH_URL, with --os-auth-url, ' 'OS_AUTH_URL or auth.auth_url\n') elif auth_plugin_name == 'token_endpoint': - if not options.auth.get('token', None): + if not options.auth.get('token'): msg += _('Set a token with --os-token, OS_TOKEN or auth.token\n') - if not options.auth.get('url', None): + if not options.auth.get('url'): msg += _('Set a service URL, with --os-url, OS_URL or auth.url\n') if msg: diff --git a/openstackclient/api/auth_plugin.py b/openstackclient/api/auth_plugin.py index deddfcc4..cff0b75d 100644 --- a/openstackclient/api/auth_plugin.py +++ b/openstackclient/api/auth_plugin.py @@ -97,7 +97,7 @@ class OSCGenericPassword(ksc_password.Password): ver_u.query, ver_u.fragment, )) - LOG.debug('Version URL updated: %s' % url) + LOG.debug('Version URL updated: %s', url) return super(OSCGenericPassword, self).create_plugin( session=session, diff --git a/openstackclient/api/object_store_v1.py b/openstackclient/api/object_store_v1.py index d9f130bc..10139ea1 100644 --- a/openstackclient/api/object_store_v1.py +++ b/openstackclient/api/object_store_v1.py @@ -50,7 +50,7 @@ class APIv1(api.BaseAPI): data = { 'account': self._find_account_id(), 'container': container, - 'x-trans-id': response.headers.get('x-trans-id', None), + 'x-trans-id': response.headers.get('x-trans-id'), } return data @@ -176,21 +176,19 @@ class APIv1(api.BaseAPI): 'account': self._find_account_id(), 'container': container, 'object_count': response.headers.get( - 'x-container-object-count', - None, + 'x-container-object-count' ), - 'bytes_used': response.headers.get('x-container-bytes-used', None) + 'bytes_used': response.headers.get('x-container-bytes-used') } if 'x-container-read' in response.headers: - data['read_acl'] = response.headers.get('x-container-read', None) + data['read_acl'] = response.headers.get('x-container-read') if 'x-container-write' in response.headers: - data['write_acl'] = response.headers.get('x-container-write', None) + data['write_acl'] = response.headers.get('x-container-write') if 'x-container-sync-to' in response.headers: - data['sync_to'] = response.headers.get('x-container-sync-to', None) + data['sync_to'] = response.headers.get('x-container-sync-to') if 'x-container-sync-key' in response.headers: - data['sync_key'] = response.headers.get('x-container-sync-key', - None) + data['sync_key'] = response.headers.get('x-container-sync-key') properties = self._get_properties(response.headers, 'x-container-meta-') @@ -248,8 +246,8 @@ class APIv1(api.BaseAPI): 'account': self._find_account_id(), 'container': container, 'object': object, - 'x-trans-id': response.headers.get('X-Trans-Id', None), - 'etag': response.headers.get('Etag', None), + 'x-trans-id': response.headers.get('X-Trans-Id'), + 'etag': response.headers.get('Etag'), } return data @@ -453,21 +451,19 @@ class APIv1(api.BaseAPI): 'account': self._find_account_id(), 'container': container, 'object': object, - 'content-type': response.headers.get('content-type', None), + 'content-type': response.headers.get('content-type'), } if 'content-length' in response.headers: data['content-length'] = response.headers.get( - 'content-length', - None, + 'content-length' ) if 'last-modified' in response.headers: - data['last-modified'] = response.headers.get('last-modified', None) + data['last-modified'] = response.headers.get('last-modified') if 'etag' in response.headers: - data['etag'] = response.headers.get('etag', None) + data['etag'] = response.headers.get('etag') if 'x-object-manifest' in response.headers: data['x-object-manifest'] = response.headers.get( - 'x-object-manifest', - None, + 'x-object-manifest' ) properties = self._get_properties(response.headers, 'x-object-meta-') @@ -506,10 +502,9 @@ class APIv1(api.BaseAPI): data['properties'] = properties # Map containers, bytes and objects a bit nicer - data['Containers'] = response.headers.get('x-account-container-count', - None) - data['Objects'] = response.headers.get('x-account-object-count', None) - data['Bytes'] = response.headers.get('x-account-bytes-used', None) + data['Containers'] = response.headers.get('x-account-container-count') + data['Objects'] = response.headers.get('x-account-object-count') + data['Bytes'] = response.headers.get('x-account-bytes-used') # Add in Account info too data['Account'] = self._find_account_id() return data @@ -556,7 +551,7 @@ class APIv1(api.BaseAPI): log = logging.getLogger(__name__ + '._set_properties') headers = {} - for k, v in properties.iteritems(): + for k, v in six.iteritems(properties): if not utils.is_ascii(k) or not utils.is_ascii(v): log.error('Cannot set property %s to non-ascii value', k) continue diff --git a/openstackclient/api/utils.py b/openstackclient/api/utils.py index fa759cd3..ab0e23c2 100644 --- a/openstackclient/api/utils.py +++ b/openstackclient/api/utils.py @@ -61,7 +61,7 @@ def simple_filter( # Searching data fields search_value = d[attr] elif (property_field and property_field in d and - type(d[property_field]) is dict): + isinstance(d[property_field], dict)): # Searching a properties field - do this separately because # we don't want to fail over to checking the fields if a # property name is given. diff --git a/openstackclient/common/availability_zone.py b/openstackclient/common/availability_zone.py index a941418b..a6d11b78 100644 --- a/openstackclient/common/availability_zone.py +++ b/openstackclient/common/availability_zone.py @@ -146,21 +146,20 @@ class ListAvailabilityZone(command.Lister): def _get_network_availability_zones(self, parsed_args): network_client = self.app.client_manager.network - data = [] try: # Verify that the extension exists. network_client.find_extension('Availability Zone', ignore_missing=False) - data = network_client.availability_zones() except Exception as e: self.log.debug('Network availability zone exception: ' + str(e)) if parsed_args.network: message = "Availability zones list not supported by " \ "Network API" self.log.warning(message) + return [] result = [] - for zone in data: + for zone in network_client.availability_zones(): result += _xform_network_availability_zone(zone) return result diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py index dce19725..938dd05c 100644 --- a/openstackclient/common/clientmanager.py +++ b/openstackclient/common/clientmanager.py @@ -37,6 +37,7 @@ USER_AGENT = 'python-openstackclient' class ClientCache(object): """Descriptor class for caching created client handles.""" + def __init__(self, factory): self.factory = factory self._handle = None @@ -90,7 +91,7 @@ class ClientManager(object): self._cli_options = cli_options self._api_version = api_version self._pw_callback = pw_func - self._url = self._cli_options.auth.get('url', None) + self._url = self._cli_options.auth.get('url') self._region_name = self._cli_options.region_name self._interface = self._cli_options.interface @@ -113,24 +114,40 @@ class ClientManager(object): root_logger = logging.getLogger('') LOG.setLevel(root_logger.getEffectiveLevel()) - def setup_auth(self): + # NOTE(gyee): use this flag to indicate whether auth setup has already + # been completed. If so, do not perform auth setup again. The reason + # we need this flag is that we want to be able to perform auth setup + # outside of auth_ref as auth_ref itself is a property. We can not + # retrofit auth_ref to optionally skip scope check. Some operations + # do not require a scoped token. In those cases, we call setup_auth + # prior to dereferrencing auth_ref. + self._auth_setup_completed = False + + def setup_auth(self, required_scope=True): """Set up authentication + :param required_scope: indicate whether a scoped token is required + This is deferred until authentication is actually attempted because it gets in the way of things that do not require auth. """ + if self._auth_setup_completed: + return + # If no auth type is named by the user, select one based on # the supplied options self.auth_plugin_name = auth.select_auth_plugin(self._cli_options) # Basic option checking to avoid unhelpful error messages - auth.check_valid_auth_options(self._cli_options, self.auth_plugin_name) + auth.check_valid_auth_options(self._cli_options, + self.auth_plugin_name, + required_scope=required_scope) # Horrible hack alert...must handle prompt for null password if # password auth is requested. if (self.auth_plugin_name.endswith('password') and - not self._cli_options.auth.get('password', None)): + not self._cli_options.auth.get('password')): self._cli_options.auth['password'] = self._pw_callback() (auth_plugin, self._auth_params) = auth.build_auth_params( @@ -146,9 +163,9 @@ class ClientManager(object): # PROJECT_DOMAIN_ID to 'OS_DEFAULT_DOMAIN' for better usability. if (self._api_version.get('identity') == '3' and self.auth_plugin_name.endswith('password') and - not self._auth_params.get('project_domain_id', None) and + not self._auth_params.get('project_domain_id') and not self.auth_plugin_name.startswith('v2') and - not self._auth_params.get('project_domain_name', None)): + not self._auth_params.get('project_domain_name')): self._auth_params['project_domain_id'] = default_domain # NOTE(stevemar): If USER_DOMAIN_ID or USER_DOMAIN_NAME is present, @@ -157,8 +174,8 @@ class ClientManager(object): if (self._api_version.get('identity') == '3' and self.auth_plugin_name.endswith('password') and not self.auth_plugin_name.startswith('v2') and - not self._auth_params.get('user_domain_id', None) and - not self._auth_params.get('user_domain_name', None)): + not self._auth_params.get('user_domain_id') and + not self._auth_params.get('user_domain_name')): self._auth_params['user_domain_id'] = default_domain # For compatibility until all clients can be updated @@ -167,8 +184,8 @@ class ClientManager(object): elif 'tenant_name' in self._auth_params: self._project_name = self._auth_params['tenant_name'] - LOG.info('Using auth plugin: %s' % self.auth_plugin_name) - LOG.debug('Using parameters %s' % + LOG.info('Using auth plugin: %s', self.auth_plugin_name) + LOG.debug('Using parameters %s', strutils.mask_password(self._auth_params)) self.auth = auth_plugin.load_from_options(**self._auth_params) # needed by SAML authentication @@ -180,6 +197,8 @@ class ClientManager(object): user_agent=USER_AGENT, ) + self._auth_setup_completed = True + return @property diff --git a/openstackclient/common/command.py b/openstackclient/common/command.py index 13b0bcc2..fee4559e 100644 --- a/openstackclient/common/command.py +++ b/openstackclient/common/command.py @@ -22,6 +22,7 @@ import six class CommandMeta(abc.ABCMeta): + def __new__(mcs, name, bases, cls_dict): if 'log' not in cls_dict: cls_dict['log'] = logging.getLogger( diff --git a/openstackclient/common/exceptions.py b/openstackclient/common/exceptions.py index ab043db0..5f5f5ab1 100644 --- a/openstackclient/common/exceptions.py +++ b/openstackclient/common/exceptions.py @@ -41,6 +41,7 @@ class UnsupportedVersion(Exception): class ClientException(Exception): """The base exception class for all exceptions this library raises.""" + def __init__(self, code, message=None, details=None): self.code = code self.message = message or self.__class__.message @@ -122,8 +123,8 @@ def from_response(response, body): if body: if hasattr(body, 'keys'): error = body[body.keys()[0]] - message = error.get('message', None) - details = error.get('details', None) + message = error.get('message') + details = error.get('details') else: # If we didn't get back a properly formed error message we # probably couldn't communicate with Keystone at all. diff --git a/openstackclient/common/logs.py b/openstackclient/common/logs.py index 6d1aec13..221c5997 100644 --- a/openstackclient/common/logs.py +++ b/openstackclient/common/logs.py @@ -18,6 +18,13 @@ import sys import warnings +def get_loggers(): + loggers = {} + for logkey in logging.Logger.manager.loggerDict.keys(): + loggers[logkey] = logging.getLevelName(logging.getLogger(logkey).level) + return loggers + + def log_level_from_options(options): # if --debug, --quiet or --verbose is not specified, # the default logging level is warning @@ -34,6 +41,17 @@ def log_level_from_options(options): return log_level +def log_level_from_string(level_string): + log_level = { + 'critical': logging.CRITICAL, + 'error': logging.ERROR, + 'warning': logging.WARNING, + 'info': logging.INFO, + 'debug': logging.DEBUG, + }.get(level_string, logging.WARNING) + return log_level + + def log_level_from_config(config): # Check the command line option verbose_level = config.get('verbose_level') @@ -49,15 +67,7 @@ def log_level_from_config(config): verbose_level = 'info' else: verbose_level = 'debug' - - log_level = { - 'critical': logging.CRITICAL, - 'error': logging.ERROR, - 'warning': logging.WARNING, - 'info': logging.INFO, - 'debug': logging.DEBUG, - }.get(verbose_level, logging.WARNING) - return log_level + return log_level_from_string(verbose_level) def set_warning_filter(log_level): @@ -159,7 +169,7 @@ class LogConfigurator(object): self.dump_trace = cloud_config.config.get('debug', self.dump_trace) self.console_logger.setLevel(log_level) - log_file = cloud_config.config.get('log_file', None) + log_file = cloud_config.config.get('log_file') if log_file: if not self.file_logger: self.file_logger = logging.FileHandler(filename=log_file) @@ -168,3 +178,21 @@ class LogConfigurator(object): self.file_logger.setFormatter(_FileFormatter(config=cloud_config)) self.file_logger.setLevel(log_level) self.root_logger.addHandler(self.file_logger) + + logconfig = cloud_config.config.get('logging') + if logconfig: + highest_level = logging.NOTSET + for k in logconfig.keys(): + level = log_level_from_string(logconfig[k]) + logging.getLogger(k).setLevel(level) + if (highest_level < level): + highest_level = level + self.console_logger.setLevel(highest_level) + if self.file_logger: + self.file_logger.setLevel(highest_level) + # loggers that are not set will use the handler level, so we + # need to set the global level for all the loggers + for logkey in logging.Logger.manager.loggerDict.keys(): + logger = logging.getLogger(logkey) + if logger.level == logging.NOTSET: + logger.setLevel(log_level) diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py index f208948e..b3d4c3b6 100644 --- a/openstackclient/common/quota.py +++ b/openstackclient/common/quota.py @@ -169,7 +169,7 @@ class ShowQuota(command.ShowOne): project = utils.find_resource( identity_client.projects, parsed_args.project, - ).id + ).id try: if parsed_args.quota_class: @@ -193,7 +193,7 @@ class ShowQuota(command.ShowOne): project = utils.find_resource( identity_client.projects, parsed_args.project, - ).id + ).id return self.app.client_manager.network.get_quota(project) else: return {} diff --git a/openstackclient/common/timing.py b/openstackclient/common/timing.py index 5f628759..71c2fec7 100644 --- a/openstackclient/common/timing.py +++ b/openstackclient/common/timing.py @@ -30,7 +30,8 @@ class Timing(command.Lister): for url, td in self.app.timing_data: # NOTE(dtroyer): Take the long way here because total_seconds() # was added in py27. - sec = (td.microseconds + (td.seconds + td.days*86400) * 1e6) / 1e6 + sec = (td.microseconds + (td.seconds + td.days * + 86400) * 1e6) / 1e6 total += sec results.append((url, sec)) results.append(('Total', total)) diff --git a/openstackclient/common/utils.py b/openstackclient/common/utils.py index 4142f830..840da402 100644 --- a/openstackclient/common/utils.py +++ b/openstackclient/common/utils.py @@ -163,7 +163,7 @@ def get_field(item, field): raise exceptions.CommandError(msg) -def get_item_properties(item, fields, mixed_case_fields=[], formatters={}): +def get_item_properties(item, fields, mixed_case_fields=None, formatters=None): """Return a tuple containing the item properties. :param item: a single item resource (e.g. Server, Project, etc) @@ -172,6 +172,11 @@ def get_item_properties(item, fields, mixed_case_fields=[], formatters={}): :param formatters: dictionary mapping field names to callables to format the values """ + if mixed_case_fields is None: + mixed_case_fields = [] + if formatters is None: + formatters = {} + row = [] for field in fields: @@ -187,7 +192,7 @@ def get_item_properties(item, fields, mixed_case_fields=[], formatters={}): return tuple(row) -def get_dict_properties(item, fields, mixed_case_fields=[], formatters={}): +def get_dict_properties(item, fields, mixed_case_fields=None, formatters=None): """Return a tuple containing the item properties. :param item: a single dict resource @@ -196,6 +201,11 @@ def get_dict_properties(item, fields, mixed_case_fields=[], formatters={}): :param formatters: dictionary mapping field names to callables to format the values """ + if mixed_case_fields is None: + mixed_case_fields = [] + if formatters is None: + formatters = {} + row = [] for field in fields: diff --git a/openstackclient/compute/client.py b/openstackclient/compute/client.py index 23a4deca..1481ed65 100644 --- a/openstackclient/compute/client.py +++ b/openstackclient/compute/client.py @@ -42,7 +42,7 @@ def make_client(instance): else: version = instance._api_version[API_NAME] - LOG.debug('Instantiating compute client for V%s' % version) + LOG.debug('Instantiating compute client for V%s', version) # Set client http_log_debug to True if verbosity level is high enough http_log_debug = utils.get_effective_log_level() <= logging.DEBUG diff --git a/openstackclient/compute/v2/flavor.py b/openstackclient/compute/v2/flavor.py index 093592cd..0308d940 100644 --- a/openstackclient/compute/v2/flavor.py +++ b/openstackclient/compute/v2/flavor.py @@ -149,20 +149,20 @@ class ListFlavor(command.Lister): action="store_true", default=True, help="List only public flavors (default)", - ) + ) public_group.add_argument( "--private", dest="public", action="store_false", help="List only private flavors", - ) + ) public_group.add_argument( "--all", dest="all", action="store_true", default=False, help="List all flavors, whether public or private", - ) + ) parser.add_argument( '--long', action='store_true', diff --git a/openstackclient/compute/v2/floatingip.py b/openstackclient/compute/v2/floatingip.py index 29ecbc90..6212989f 100644 --- a/openstackclient/compute/v2/floatingip.py +++ b/openstackclient/compute/v2/floatingip.py @@ -68,46 +68,6 @@ class CreateFloatingIP(command.ShowOne): return zip(*sorted(six.iteritems(info))) -class DeleteFloatingIP(command.Command): - """Delete a floating IP address""" - - def get_parser(self, prog_name): - parser = super(DeleteFloatingIP, self).get_parser(prog_name) - parser.add_argument( - "ip_address", - metavar="<ip-address>", - help="IP address to delete (ID only)", - ) - return parser - - def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute - - floating_ip = utils.find_resource( - compute_client.floating_ips, - parsed_args.ip_address, - ) - - compute_client.floating_ips.delete(floating_ip) - - -class ListFloatingIP(command.Lister): - """List floating IP addresses""" - - def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute - - columns = ('ID', 'Pool', 'IP', 'Fixed IP', 'Instance ID') - - data = compute_client.floating_ips.list() - - return (columns, - (utils.get_item_properties( - s, columns, - formatters={}, - ) for s in data)) - - class RemoveFloatingIP(command.Command): """Remove floating IP address from server""" diff --git a/openstackclient/compute/v2/security_group.py b/openstackclient/compute/v2/security_group.py index 2a8908d7..6f2e1a52 100644 --- a/openstackclient/compute/v2/security_group.py +++ b/openstackclient/compute/v2/security_group.py @@ -169,24 +169,6 @@ class CreateSecurityGroupRule(command.ShowOne): return zip(*sorted(six.iteritems(info))) -class DeleteSecurityGroupRule(command.Command): - """Delete a security group rule""" - - def get_parser(self, prog_name): - parser = super(DeleteSecurityGroupRule, self).get_parser(prog_name) - parser.add_argument( - 'rule', - metavar='<rule>', - help='Security group rule to delete (ID only)', - ) - return parser - - def take_action(self, parsed_args): - - compute_client = self.app.client_manager.compute - compute_client.security_group_rules.delete(parsed_args.rule) - - class ListSecurityGroup(command.Lister): """List security groups""" diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py index 4cb94822..ca239c51 100644 --- a/openstackclient/compute/v2/server.py +++ b/openstackclient/compute/v2/server.py @@ -1206,7 +1206,7 @@ class RescueServer(command.ShowOne): _, body = utils.find_resource( compute_client.servers, parsed_args.server, - ).rescue() + ).rescue() return zip(*sorted(six.iteritems(body))) diff --git a/openstackclient/identity/client.py b/openstackclient/identity/client.py index bd882ce8..c166e66a 100644 --- a/openstackclient/identity/client.py +++ b/openstackclient/identity/client.py @@ -53,7 +53,7 @@ def make_client(instance): session=instance.session, region_name=instance._region_name, **kwargs - ) + ) return client @@ -72,6 +72,7 @@ def build_option_parser(parser): class IdentityClientv2(identity_client_v2.Client): """Tweak the earlier client class to deal with some changes""" + def __getattr__(self, name): # Map v3 'projects' back to v2 'tenants' if name == "projects": diff --git a/openstackclient/identity/v2_0/token.py b/openstackclient/identity/v2_0/token.py index db38fae8..6a66a1c6 100644 --- a/openstackclient/identity/v2_0/token.py +++ b/openstackclient/identity/v2_0/token.py @@ -24,6 +24,9 @@ from openstackclient.i18n import _ # noqa class IssueToken(command.ShowOne): """Issue new token""" + # scoped token is optional + required_scope = False + def get_parser(self, prog_name): parser = super(IssueToken, self).get_parser(prog_name) return parser @@ -31,7 +34,8 @@ class IssueToken(command.ShowOne): def take_action(self, parsed_args): token = self.app.client_manager.auth_ref.service_catalog.get_token() - token['project_id'] = token.pop('tenant_id') + if 'tenant_id' in token: + token['project_id'] = token.pop('tenant_id') return zip(*sorted(six.iteritems(token))) diff --git a/openstackclient/identity/v3/role_assignment.py b/openstackclient/identity/v3/role_assignment.py index d766be68..a1418a82 100644 --- a/openstackclient/identity/v3/role_assignment.py +++ b/openstackclient/identity/v3/role_assignment.py @@ -34,6 +34,11 @@ class ListRoleAssignment(command.Lister): metavar='<role>', help='Role to filter (name or ID)', ) + parser.add_argument( + '--names', + action="store_true", + help='Display names instead of IDs', + ) user_or_group = parser.add_mutually_exclusive_group() user_or_group.add_argument( '--user', @@ -107,6 +112,7 @@ class ListRoleAssignment(command.Lister): parsed_args.group_domain, ) + include_names = True if parsed_args.names else False effective = True if parsed_args.effective else False columns = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited') @@ -118,17 +124,26 @@ class ListRoleAssignment(command.Lister): project=project, role=role, effective=effective, - os_inherit_extension_inherited_to=inherited_to) + os_inherit_extension_inherited_to=inherited_to, + include_names=include_names) data_parsed = [] for assignment in data: # Removing the extra "scope" layer in the assignment json scope = assignment.scope if 'project' in scope: - setattr(assignment, 'project', scope['project']['id']) + if include_names: + prj = '@'.join([scope['project']['name'], + scope['project']['domain']['name']]) + setattr(assignment, 'project', prj) + else: + setattr(assignment, 'project', scope['project']['id']) assignment.domain = '' elif 'domain' in scope: - setattr(assignment, 'domain', scope['domain']['id']) + if include_names: + setattr(assignment, 'domain', scope['domain']['name']) + else: + setattr(assignment, 'domain', scope['domain']['id']) assignment.project = '' else: @@ -141,17 +156,30 @@ class ListRoleAssignment(command.Lister): del assignment.scope if hasattr(assignment, 'user'): - setattr(assignment, 'user', assignment.user['id']) + if include_names: + usr = '@'.join([assignment.user['name'], + assignment.user['domain']['name']]) + setattr(assignment, 'user', usr) + else: + setattr(assignment, 'user', assignment.user['id']) assignment.group = '' elif hasattr(assignment, 'group'): - setattr(assignment, 'group', assignment.group['id']) + if include_names: + grp = '@'.join([assignment.group['name'], + assignment.group['domain']['name']]) + setattr(assignment, 'group', grp) + else: + setattr(assignment, 'group', assignment.group['id']) assignment.user = '' else: assignment.user = '' assignment.group = '' if hasattr(assignment, 'role'): - setattr(assignment, 'role', assignment.role['id']) + if include_names: + setattr(assignment, 'role', assignment.role['name']) + else: + setattr(assignment, 'role', assignment.role['id']) else: assignment.role = '' diff --git a/openstackclient/identity/v3/token.py b/openstackclient/identity/v3/token.py index 588c5218..5f131939 100644 --- a/openstackclient/identity/v3/token.py +++ b/openstackclient/identity/v3/token.py @@ -164,6 +164,9 @@ class CreateRequestToken(command.ShowOne): class IssueToken(command.ShowOne): """Issue new token""" + # scoped token is optional + required_scope = False + def get_parser(self, prog_name): parser = super(IssueToken, self).get_parser(prog_name) return parser @@ -173,3 +176,22 @@ class IssueToken(command.ShowOne): if 'tenant_id' in token: token['project_id'] = token.pop('tenant_id') return zip(*sorted(six.iteritems(token))) + + +class RevokeToken(command.Command): + """Revoke existing token""" + + def get_parser(self, prog_name): + parser = super(RevokeToken, self).get_parser(prog_name) + parser.add_argument( + 'token', + metavar='<token>', + help='Token to be deleted', + ) + return parser + + def take_action(self, parsed_args): + identity_client = self.app.client_manager.identity + + identity_client.tokens.revoke_token(parsed_args.token) + return diff --git a/openstackclient/identity/v3/unscoped_saml.py b/openstackclient/identity/v3/unscoped_saml.py index a42637dd..8e2616a6 100644 --- a/openstackclient/identity/v3/unscoped_saml.py +++ b/openstackclient/identity/v3/unscoped_saml.py @@ -27,6 +27,7 @@ UNSCOPED_AUTH_PLUGINS = ['v3unscopedsaml', 'v3unscopedadfs', 'v3oidc'] def auth_with_unscoped_saml(func): """Check the unscoped federated context""" + def _decorated(self, parsed_args): auth_plugin_name = self.app.client_manager.auth_plugin_name if auth_plugin_name in UNSCOPED_AUTH_PLUGINS: diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py index 9cc5facd..6e172bce 100644 --- a/openstackclient/image/v1/image.py +++ b/openstackclient/image/v1/image.py @@ -265,8 +265,8 @@ class CreateImage(command.ShowOne): finally: # Clean up open files - make sure data isn't a string if ('data' in kwargs and hasattr(kwargs['data'], 'close') and - kwargs['data'] != sys.stdin): - kwargs['data'].close() + kwargs['data'] != sys.stdin): + kwargs['data'].close() info.update(image._info) info['properties'] = utils.format_dict(info.get('properties', {})) @@ -697,8 +697,8 @@ class SetImage(command.Command): finally: # Clean up open files - make sure data isn't a string if ('data' in kwargs and hasattr(kwargs['data'], 'close') and - kwargs['data'] != sys.stdin): - kwargs['data'].close() + kwargs['data'] != sys.stdin): + kwargs['data'].close() class ShowImage(command.ShowOne): diff --git a/openstackclient/network/common.py b/openstackclient/network/common.py index c539dd05..1e2c4cce 100644 --- a/openstackclient/network/common.py +++ b/openstackclient/network/common.py @@ -19,7 +19,13 @@ from openstackclient.common import command @six.add_metaclass(abc.ABCMeta) class NetworkAndComputeCommand(command.Command): - """Network and Compute Command""" + """Network and Compute Command + + Command class for commands that support implementation via + the network or compute endpoint. Such commands have different + implementations for take_action() and may even have different + arguments. + """ def take_action(self, parsed_args): if self.app.client_manager.is_network_endpoint_enabled(): @@ -60,3 +66,105 @@ class NetworkAndComputeCommand(command.Command): def take_action_compute(self, client, parsed_args): """Override to do something useful.""" pass + + +@six.add_metaclass(abc.ABCMeta) +class NetworkAndComputeLister(command.Lister): + """Network and Compute Lister + + Lister class for commands that support implementation via + the network or compute endpoint. Such commands have different + implementations for take_action() and may even have different + arguments. + """ + + def take_action(self, parsed_args): + if self.app.client_manager.is_network_endpoint_enabled(): + return self.take_action_network(self.app.client_manager.network, + parsed_args) + else: + return self.take_action_compute(self.app.client_manager.compute, + parsed_args) + + def get_parser(self, prog_name): + self.log.debug('get_parser(%s)', prog_name) + parser = super(NetworkAndComputeLister, self).get_parser(prog_name) + parser = self.update_parser_common(parser) + self.log.debug('common parser: %s', parser) + if self.app.client_manager.is_network_endpoint_enabled(): + return self.update_parser_network(parser) + else: + return self.update_parser_compute(parser) + + def update_parser_common(self, parser): + """Default is no updates to parser.""" + return parser + + def update_parser_network(self, parser): + """Default is no updates to parser.""" + return parser + + def update_parser_compute(self, parser): + """Default is no updates to parser.""" + return parser + + @abc.abstractmethod + def take_action_network(self, client, parsed_args): + """Override to do something useful.""" + pass + + @abc.abstractmethod + def take_action_compute(self, client, parsed_args): + """Override to do something useful.""" + pass + + +@six.add_metaclass(abc.ABCMeta) +class NetworkAndComputeShowOne(command.ShowOne): + """Network and Compute ShowOne + + ShowOne class for commands that support implementation via + the network or compute endpoint. Such commands have different + implementations for take_action() and may even have different + arguments. + """ + + def take_action(self, parsed_args): + if self.app.client_manager.is_network_endpoint_enabled(): + return self.take_action_network(self.app.client_manager.network, + parsed_args) + else: + return self.take_action_compute(self.app.client_manager.compute, + parsed_args) + + def get_parser(self, prog_name): + self.log.debug('get_parser(%s)', prog_name) + parser = super(NetworkAndComputeShowOne, self).get_parser(prog_name) + parser = self.update_parser_common(parser) + self.log.debug('common parser: %s', parser) + if self.app.client_manager.is_network_endpoint_enabled(): + return self.update_parser_network(parser) + else: + return self.update_parser_compute(parser) + + def update_parser_common(self, parser): + """Default is no updates to parser.""" + return parser + + def update_parser_network(self, parser): + """Default is no updates to parser.""" + return parser + + def update_parser_compute(self, parser): + """Default is no updates to parser.""" + return parser + + @abc.abstractmethod + def take_action_network(self, client, parsed_args): + """Override to do something useful.""" + pass + + @abc.abstractmethod + def take_action_compute(self, client, parsed_args): + """Override to do something useful.""" + pass diff --git a/openstackclient/network/v2/floating_ip.py b/openstackclient/network/v2/floating_ip.py new file mode 100644 index 00000000..e0a65a48 --- /dev/null +++ b/openstackclient/network/v2/floating_ip.py @@ -0,0 +1,126 @@ +# 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. +# + +"""IP Floating action implementations""" + +from openstackclient.common import utils +from openstackclient.network import common + + +def _get_columns(item): + columns = item.keys() + if 'tenant_id' in columns: + columns.remove('tenant_id') + columns.append('project_id') + return tuple(sorted(columns)) + + +class DeleteFloatingIP(common.NetworkAndComputeCommand): + """Delete floating IP""" + + def update_parser_common(self, parser): + parser.add_argument( + 'floating_ip', + metavar="<floating-ip>", + help=("Floating IP to delete (IP address or ID)") + ) + return parser + + def take_action_network(self, client, parsed_args): + obj = client.find_ip(parsed_args.floating_ip) + client.delete_ip(obj) + + def take_action_compute(self, client, parsed_args): + obj = utils.find_resource( + client.floating_ips, + parsed_args.floating_ip, + ) + client.floating_ips.delete(obj.id) + + +class ListFloatingIP(common.NetworkAndComputeLister): + """List floating IP(s)""" + + def take_action_network(self, client, parsed_args): + columns = ( + 'id', + 'floating_ip_address', + 'fixed_ip_address', + 'port_id', + ) + headers = ( + 'ID', + 'Floating IP Address', + 'Fixed IP Address', + 'Port', + ) + + query = {} + data = client.ips(**query) + + return (headers, + (utils.get_item_properties( + s, columns, + formatters={}, + ) for s in data)) + + def take_action_compute(self, client, parsed_args): + columns = ( + 'ID', + 'IP', + 'Fixed IP', + 'Instance ID', + 'Pool', + ) + headers = ( + 'ID', + 'Floating IP Address', + 'Fixed IP Address', + 'Server', + 'Pool', + ) + + data = client.floating_ips.list() + + return (headers, + (utils.get_item_properties( + s, columns, + formatters={}, + ) for s in data)) + + +class ShowFloatingIP(common.NetworkAndComputeShowOne): + """Show floating IP details""" + + def update_parser_common(self, parser): + parser.add_argument( + 'floating_ip', + metavar="<floating-ip>", + help=("Floating IP to display (IP address or ID)") + ) + return parser + + def take_action_network(self, client, parsed_args): + obj = client.find_ip(parsed_args.floating_ip, ignore_missing=False) + columns = _get_columns(obj) + data = utils.get_item_properties(obj, columns) + return (columns, data) + + def take_action_compute(self, client, parsed_args): + obj = utils.find_resource( + client.floating_ips, + parsed_args.floating_ip, + ) + columns = _get_columns(obj._info) + data = utils.get_dict_properties(obj._info, columns) + return (columns, data) diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py index 61237219..fd7ab8fb 100644 --- a/openstackclient/network/v2/network.py +++ b/openstackclient/network/v2/network.py @@ -17,6 +17,7 @@ from openstackclient.common import command from openstackclient.common import exceptions from openstackclient.common import utils from openstackclient.identity import common as identity_common +from openstackclient.network import common def _format_admin_state(item): @@ -141,11 +142,10 @@ class CreateNetwork(command.ShowOne): return (columns, data) -class DeleteNetwork(command.Command): +class DeleteNetwork(common.NetworkAndComputeCommand): """Delete network(s)""" - def get_parser(self, prog_name): - parser = super(DeleteNetwork, self).get_parser(prog_name) + def update_parser_common(self, parser): parser.add_argument( 'network', metavar="<network>", @@ -154,18 +154,24 @@ class DeleteNetwork(command.Command): ) return parser - def take_action(self, parsed_args): - client = self.app.client_manager.network + def take_action_network(self, client, parsed_args): for network in parsed_args.network: obj = client.find_network(network) client.delete_network(obj) + def take_action_compute(self, client, parsed_args): + for network in parsed_args.network: + network = utils.find_resource( + client.networks, + network, + ) + client.networks.delete(network.id) + -class ListNetwork(command.Lister): +class ListNetwork(common.NetworkAndComputeLister): """List networks""" - def get_parser(self, prog_name): - parser = super(ListNetwork, self).get_parser(prog_name) + def update_parser_common(self, parser): parser.add_argument( '--external', action='store_true', @@ -180,9 +186,7 @@ class ListNetwork(command.Lister): ) return parser - def take_action(self, parsed_args): - client = self.app.client_manager.network - + def take_action_network(self, client, parsed_args): if parsed_args.long: columns = ( 'id', @@ -224,7 +228,29 @@ class ListNetwork(command.Lister): args = {'router:external': True} else: args = {} + data = client.networks(**args) + + return (column_headers, + (utils.get_item_properties( + s, columns, + formatters=_formatters, + ) for s in data)) + + def take_action_compute(self, client, parsed_args): + columns = ( + 'id', + 'label', + 'cidr', + ) + column_headers = ( + 'ID', + 'Name', + 'Subnet', + ) + + data = client.networks.list() + return (column_headers, (utils.get_item_properties( s, columns, @@ -238,7 +264,7 @@ class SetNetwork(command.Command): def get_parser(self, prog_name): parser = super(SetNetwork, self).get_parser(prog_name) parser.add_argument( - 'identifier', + 'network', metavar="<network>", help=("Network to modify (name or ID)") ) @@ -279,7 +305,7 @@ class SetNetwork(command.Command): def take_action(self, parsed_args): client = self.app.client_manager.network - obj = client.find_network(parsed_args.identifier, ignore_missing=False) + obj = client.find_network(parsed_args.network, ignore_missing=False) attrs = _get_attrs(self.app.client_manager, parsed_args) if attrs == {}: @@ -290,21 +316,28 @@ class SetNetwork(command.Command): return -class ShowNetwork(command.ShowOne): +class ShowNetwork(common.NetworkAndComputeShowOne): """Show network details""" - def get_parser(self, prog_name): - parser = super(ShowNetwork, self).get_parser(prog_name) + def update_parser_common(self, parser): parser.add_argument( - 'identifier', + 'network', metavar="<network>", help=("Network to display (name or ID)") ) return parser - def take_action(self, parsed_args): - client = self.app.client_manager.network - obj = client.find_network(parsed_args.identifier, ignore_missing=False) + def take_action_network(self, client, parsed_args): + obj = client.find_network(parsed_args.network, ignore_missing=False) columns = _get_columns(obj) data = utils.get_item_properties(obj, columns, formatters=_formatters) return (columns, data) + + def take_action_compute(self, client, parsed_args): + network = utils.find_resource( + client.networks, + parsed_args.network, + ) + columns = sorted(network._info.keys()) + data = utils.get_dict_properties(network._info, columns) + return (columns, data) diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py index 46cb031f..19b3701d 100644 --- a/openstackclient/network/v2/port.py +++ b/openstackclient/network/v2/port.py @@ -26,9 +26,9 @@ _formatters = { 'allowed_address_pairs': utils.format_list_of_dicts, 'binding_profile': utils.format_dict, 'binding_vif_details': utils.format_dict, - 'dns_assignment': utils.format_list_of_dicts, + 'dns_assignment': utils.format_list_of_dicts, 'extra_dhcp_opts': utils.format_list_of_dicts, - 'fixed_ips': utils.format_list_of_dicts, + 'fixed_ips': utils.format_list_of_dicts, 'security_groups': utils.format_list, } diff --git a/openstackclient/network/v2/security_group_rule.py b/openstackclient/network/v2/security_group_rule.py new file mode 100644 index 00000000..a61e3233 --- /dev/null +++ b/openstackclient/network/v2/security_group_rule.py @@ -0,0 +1,121 @@ +# 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. +# + +"""Security Group Rule action implementations""" + +import six + +from openstackclient.common import exceptions +from openstackclient.common import utils +from openstackclient.network import common + + +def _xform_security_group_rule(sgroup): + info = {} + info.update(sgroup) + from_port = info.pop('from_port') + to_port = info.pop('to_port') + if isinstance(from_port, int) and isinstance(to_port, int): + port_range = {'port_range': "%u:%u" % (from_port, to_port)} + elif from_port is None and to_port is None: + port_range = {'port_range': ""} + else: + port_range = {'port_range': "%s:%s" % (from_port, to_port)} + info.update(port_range) + if 'cidr' in info['ip_range']: + info['ip_range'] = info['ip_range']['cidr'] + else: + info['ip_range'] = '' + if info['ip_protocol'] is None: + info['ip_protocol'] = '' + elif info['ip_protocol'].lower() == 'icmp': + info['port_range'] = '' + group = info.pop('group') + if 'name' in group: + info['remote_security_group'] = group['name'] + else: + info['remote_security_group'] = '' + return info + + +def _format_security_group_rule_show(obj): + data = _xform_security_group_rule(obj) + return zip(*sorted(six.iteritems(data))) + + +def _get_columns(item): + columns = item.keys() + if 'tenant_id' in columns: + columns.remove('tenant_id') + columns.append('project_id') + return tuple(sorted(columns)) + + +class DeleteSecurityGroupRule(common.NetworkAndComputeCommand): + """Delete a security group rule""" + + def update_parser_common(self, parser): + parser.add_argument( + 'rule', + metavar='<rule>', + help='Security group rule to delete (ID only)', + ) + return parser + + def take_action_network(self, client, parsed_args): + obj = client.find_security_group_rule(parsed_args.rule) + client.delete_security_group_rule(obj) + + def take_action_compute(self, client, parsed_args): + client.security_group_rules.delete(parsed_args.rule) + + +class ShowSecurityGroupRule(common.NetworkAndComputeShowOne): + """Display security group rule details""" + + def update_parser_common(self, parser): + parser.add_argument( + 'rule', + metavar="<rule>", + help="Security group rule to display (ID only)" + ) + return parser + + def take_action_network(self, client, parsed_args): + obj = client.find_security_group_rule(parsed_args.rule, + ignore_missing=False) + columns = _get_columns(obj) + data = utils.get_item_properties(obj, columns) + return (columns, data) + + def take_action_compute(self, client, parsed_args): + # NOTE(rtheis): Unfortunately, compute does not have an API + # to get or list security group rules so parse through the + # security groups to find all accessible rules in search of + # the requested rule. + obj = None + security_group_rules = [] + for security_group in client.security_groups.list(): + security_group_rules.extend(security_group.rules) + for security_group_rule in security_group_rules: + if parsed_args.rule == str(security_group_rule.get('id')): + obj = security_group_rule + break + + if obj is None: + msg = "Could not find security group rule " \ + "with ID %s" % parsed_args.rule + raise exceptions.CommandError(msg) + + # NOTE(rtheis): Format security group rule + return _format_security_group_rule_show(obj) diff --git a/openstackclient/network/v2/subnet.py b/openstackclient/network/v2/subnet.py index b948c656..7ed02a3a 100644 --- a/openstackclient/network/v2/subnet.py +++ b/openstackclient/network/v2/subnet.py @@ -30,6 +30,14 @@ _formatters = { } +def _get_columns(item): + columns = item.keys() + if 'tenant_id' in columns: + columns.remove('tenant_id') + columns.append('project_id') + return tuple(sorted(columns)) + + class ListSubnet(command.Lister): """List subnets""" @@ -61,3 +69,23 @@ class ListSubnet(command.Lister): s, columns, formatters=_formatters, ) for s in data)) + + +class ShowSubnet(command.ShowOne): + """Show subnet details""" + + def get_parser(self, prog_name): + parser = super(ShowSubnet, self).get_parser(prog_name) + parser.add_argument( + 'subnet', + metavar="<subnet>", + help="Subnet to show (name or ID)" + ) + return parser + + def take_action(self, parsed_args): + obj = self.app.client_manager.network.find_subnet(parsed_args.subnet, + ignore_missing=False) + columns = _get_columns(obj) + data = utils.get_item_properties(obj, columns, formatters=_formatters) + return (columns, data) diff --git a/openstackclient/network/v2/subnet_pool.py b/openstackclient/network/v2/subnet_pool.py new file mode 100644 index 00000000..5bb45c12 --- /dev/null +++ b/openstackclient/network/v2/subnet_pool.py @@ -0,0 +1,121 @@ +# 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. +# + +"""Subnet pool action implementations""" + +from openstackclient.common import command +from openstackclient.common import utils + + +def _get_columns(item): + columns = item.keys() + if 'tenant_id' in columns: + columns.remove('tenant_id') + columns.append('project_id') + return tuple(sorted(columns)) + + +_formatters = { + 'prefixes': utils.format_list, +} + + +class DeleteSubnetPool(command.Command): + """Delete subnet pool""" + + def get_parser(self, prog_name): + parser = super(DeleteSubnetPool, self).get_parser(prog_name) + parser.add_argument( + 'subnet_pool', + metavar="<subnet-pool>", + help=("Subnet pool to delete (name or ID)") + ) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + obj = client.find_subnet_pool(parsed_args.subnet_pool) + client.delete_subnet_pool(obj) + + +class ListSubnetPool(command.Lister): + """List subnet pools""" + + def get_parser(self, prog_name): + parser = super(ListSubnetPool, self).get_parser(prog_name) + parser.add_argument( + '--long', + action='store_true', + default=False, + help='List additional fields in output', + ) + return parser + + def take_action(self, parsed_args): + data = self.app.client_manager.network.subnet_pools() + + if parsed_args.long: + headers = ( + 'ID', + 'Name', + 'Prefixes', + 'Default Prefix Length', + 'Address Scope', + ) + columns = ( + 'id', + 'name', + 'prefixes', + 'default_prefixlen', + 'address_scope_id', + ) + else: + headers = ( + 'ID', + 'Name', + 'Prefixes', + ) + columns = ( + 'id', + 'name', + 'prefixes', + ) + + return (headers, + (utils.get_item_properties( + s, columns, + formatters={}, + ) for s in data)) + + +class ShowSubnetPool(command.ShowOne): + """Display subnet pool details""" + + def get_parser(self, prog_name): + parser = super(ShowSubnetPool, self).get_parser(prog_name) + parser.add_argument( + 'subnet_pool', + metavar="<subnet-pool>", + help=("Subnet pool to display (name or ID)") + ) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + obj = client.find_subnet_pool( + parsed_args.subnet_pool, + ignore_missing=False + ) + columns = _get_columns(obj) + data = utils.get_item_properties(obj, columns, formatters=_formatters) + return (columns, data) diff --git a/openstackclient/shell.py b/openstackclient/shell.py index bd13fbb5..659bbee7 100644 --- a/openstackclient/shell.py +++ b/openstackclient/shell.py @@ -285,12 +285,17 @@ class OpenStackShell(app.App): # Do configuration file handling # Ignore the default value of interface. Only if it is set later # will it be used. - cc = cloud_config.OpenStackConfig( - override_defaults={ - 'interface': None, - 'auth_type': auth_type, + try: + cc = cloud_config.OpenStackConfig( + override_defaults={ + 'interface': None, + 'auth_type': auth_type, }, ) + except (IOError, OSError) as e: + self.log.critical("Could not read clouds.yaml configuration file") + self.print_help_if_requested() + raise e # TODO(thowe): Change cliff so the default value for debug # can be set to None. @@ -399,6 +404,9 @@ class OpenStackShell(app.App): cmd.__class__.__name__, ) if cmd.auth_required: + if hasattr(cmd, 'required_scope'): + # let the command decide whether we need a scoped token + self.client_manager.setup_auth(cmd.required_scope) # Trigger the Identity client to initialize self.client_manager.auth_ref return diff --git a/openstackclient/tests/common/test_availability_zone.py b/openstackclient/tests/common/test_availability_zone.py index e44455c7..feecaf55 100644 --- a/openstackclient/tests/common/test_availability_zone.py +++ b/openstackclient/tests/common/test_availability_zone.py @@ -144,7 +144,9 @@ class TestAvailabilityZoneList(TestAvailabilityZone): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.compute_azs_mock.list.assert_called_with() @@ -170,7 +172,9 @@ class TestAvailabilityZoneList(TestAvailabilityZone): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.compute_azs_mock.list.assert_called_with() @@ -199,7 +203,9 @@ class TestAvailabilityZoneList(TestAvailabilityZone): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.compute_azs_mock.list.assert_called_with() @@ -221,7 +227,9 @@ class TestAvailabilityZoneList(TestAvailabilityZone): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.compute_azs_mock.list.assert_not_called() @@ -243,7 +251,9 @@ class TestAvailabilityZoneList(TestAvailabilityZone): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.compute_azs_mock.list.assert_not_called() diff --git a/openstackclient/tests/common/test_clientmanager.py b/openstackclient/tests/common/test_clientmanager.py index 523f79a3..2bd9e783 100644 --- a/openstackclient/tests/common/test_clientmanager.py +++ b/openstackclient/tests/common/test_clientmanager.py @@ -47,6 +47,7 @@ class Container(object): class FakeOptions(object): + def __init__(self, **kwargs): for option in auth.OPTIONS_LIST: setattr(self, option.replace('-', '_'), None) @@ -71,6 +72,7 @@ class TestClientCache(utils.TestCase): class TestClientManager(utils.TestCase): + def setUp(self): super(TestClientManager, self).setUp() self.mock = mock.Mock() @@ -325,3 +327,28 @@ class TestClientManager(utils.TestCase): exc.CommandError, client_manager.setup_auth, ) + + @mock.patch('openstackclient.api.auth.check_valid_auth_options') + def test_client_manager_auth_setup_once(self, check_auth_options_func): + client_manager = clientmanager.ClientManager( + cli_options=FakeOptions( + auth=dict( + auth_url=fakes.AUTH_URL, + username=fakes.USERNAME, + password=fakes.PASSWORD, + project_name=fakes.PROJECT_NAME, + ), + ), + api_version=API_VERSION, + verify=False, + ) + self.assertFalse(client_manager._auth_setup_completed) + client_manager.setup_auth() + self.assertTrue(check_auth_options_func.called) + self.assertTrue(client_manager._auth_setup_completed) + + # now make sure we don't do auth setup the second time around + # by checking whether check_valid_auth_options() gets called again + check_auth_options_func.reset_mock() + client_manager.auth_ref + check_auth_options_func.assert_not_called() diff --git a/openstackclient/tests/common/test_command.py b/openstackclient/tests/common/test_command.py index 1b2584bd..7467d9eb 100644 --- a/openstackclient/tests/common/test_command.py +++ b/openstackclient/tests/common/test_command.py @@ -19,6 +19,7 @@ from openstackclient.tests import utils as test_utils class FakeCommand(command.Command): + def take_action(self, parsed_args): pass diff --git a/openstackclient/tests/common/test_commandmanager.py b/openstackclient/tests/common/test_commandmanager.py index 056b637d..e2b274dc 100644 --- a/openstackclient/tests/common/test_commandmanager.py +++ b/openstackclient/tests/common/test_commandmanager.py @@ -20,6 +20,7 @@ from openstackclient.tests import utils class FakeCommand(object): + @classmethod def load(cls): return cls @@ -48,6 +49,7 @@ class FakeCommandManager(commandmanager.CommandManager): class TestCommandManager(utils.TestCase): + def test_add_command_group(self): mgr = FakeCommandManager('test') @@ -100,6 +102,6 @@ class TestCommandManager(utils.TestCase): mock_pkg_resources, ) as iter_entry_points: mgr = commandmanager.CommandManager('test') - assert iter_entry_points.called_once_with('test') + iter_entry_points.assert_called_once_with('test') cmds = mgr.get_command_names('test') self.assertEqual(['one', 'cmd two'], cmds) diff --git a/openstackclient/tests/common/test_extension.py b/openstackclient/tests/common/test_extension.py index 21c2cc24..66532827 100644 --- a/openstackclient/tests/common/test_extension.py +++ b/openstackclient/tests/common/test_extension.py @@ -63,7 +63,9 @@ class TestExtensionList(TestExtension): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # no args should output from all services @@ -93,7 +95,9 @@ class TestExtensionList(TestExtension): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # no args should output from all services @@ -131,7 +135,9 @@ class TestExtensionList(TestExtension): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.identity_extensions_mock.list.assert_called_with() diff --git a/openstackclient/tests/common/test_logs.py b/openstackclient/tests/common/test_logs.py index a319533a..0386cdfd 100644 --- a/openstackclient/tests/common/test_logs.py +++ b/openstackclient/tests/common/test_logs.py @@ -66,6 +66,7 @@ class TestContext(utils.TestCase): class TestFileFormatter(utils.TestCase): + def test_nothing(self): formatter = logs._FileFormatter() self.assertEqual(('%(asctime)s.%(msecs)03d %(process)d %(levelname)s ' @@ -93,6 +94,7 @@ class TestFileFormatter(utils.TestCase): class TestLogConfigurator(utils.TestCase): + def setUp(self): super(TestLogConfigurator, self).setUp() self.options = mock.Mock() diff --git a/openstackclient/tests/common/test_module.py b/openstackclient/tests/common/test_module.py index 6918c1b4..2821da9e 100644 --- a/openstackclient/tests/common/test_module.py +++ b/openstackclient/tests/common/test_module.py @@ -62,7 +62,9 @@ class TestCommandList(utils.TestCommand): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) collist = ('Command Group', 'Commands') @@ -94,7 +96,9 @@ class TestModuleList(utils.TestCommand): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Additional modules may be present, just check our additions @@ -110,7 +114,9 @@ class TestModuleList(utils.TestCommand): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Additional modules may be present, just check our additions diff --git a/openstackclient/tests/common/test_timing.py b/openstackclient/tests/common/test_timing.py index e7b9a040..e33bb7ae 100644 --- a/openstackclient/tests/common/test_timing.py +++ b/openstackclient/tests/common/test_timing.py @@ -61,7 +61,9 @@ class TestTiming(utils.TestCommand): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) @@ -73,14 +75,16 @@ class TestTiming(utils.TestCommand): def test_timing_list(self): self.app.timing_data = [( timing_url, - datetime.timedelta(microseconds=timing_elapsed*1000000), + datetime.timedelta(microseconds=timing_elapsed * 1000000), )] arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) datalist = [ diff --git a/openstackclient/tests/common/test_utils.py b/openstackclient/tests/common/test_utils.py index da7ce063..95bce458 100644 --- a/openstackclient/tests/common/test_utils.py +++ b/openstackclient/tests/common/test_utils.py @@ -250,6 +250,7 @@ class NoUniqueMatch(Exception): class TestFindResource(test_utils.TestCase): + def setUp(self): super(TestFindResource, self).setUp() self.name = 'legos' diff --git a/openstackclient/tests/compute/v2/fakes.py b/openstackclient/tests/compute/v2/fakes.py index 68a66740..f4d79ff7 100644 --- a/openstackclient/tests/compute/v2/fakes.py +++ b/openstackclient/tests/compute/v2/fakes.py @@ -87,9 +87,11 @@ SERVICE = { class FakeComputev2Client(object): + def __init__(self, **kwargs): self.aggregates = mock.Mock() self.aggregates.resource_class = fakes.FakeResource(None, {}) + self.availability_zones = mock.Mock() self.availability_zones.resource_class = fakes.FakeResource(None, {}) @@ -120,18 +122,28 @@ class FakeComputev2Client(object): self.hypervisors = mock.Mock() self.hypervisors.resource_class = fakes.FakeResource(None, {}) + self.hypervisors_stats = mock.Mock() + self.hypervisors_stats.resource_class = fakes.FakeResource(None, {}) + self.security_groups = mock.Mock() self.security_groups.resource_class = fakes.FakeResource(None, {}) self.security_group_rules = mock.Mock() self.security_group_rules.resource_class = fakes.FakeResource(None, {}) + self.floating_ips = mock.Mock() + self.floating_ips.resource_class = fakes.FakeResource(None, {}) + + self.networks = mock.Mock() + self.networks.resource_class = fakes.FakeResource(None, {}) + self.auth_token = kwargs['token'] self.management_url = kwargs['endpoint'] class TestComputev2(utils.TestCommand): + def setUp(self): super(TestComputev2, self).setUp() @@ -228,6 +240,126 @@ class FakeHypervisor(object): return hypervisors +class FakehypervisorStats(object): + """Fake one or more hypervisor stats.""" + + @staticmethod + def create_one_hypervisor_stats(attrs={}, methods={}): + """Create a fake hypervisor stats. + + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeResource object, with id, hypervisor_hostname, and so on + """ + # Set default attributes. + stats_info = { + 'count': 2, + 'current_workload': 0, + 'disk_available_least': 50, + 'free_disk_gb': 100, + 'free_ram_mb': 23000, + 'local_gb': 100, + 'local_gb_used': 0, + 'memory_mb': 23800, + 'memory_mb_used': 1400, + 'running_vms': 3, + 'vcpus': 8, + 'vcpus_used': 3, + } + stats_info.update(attrs) + + # Set default method. + hypervisor_stats_method = {'to_dict': stats_info} + hypervisor_stats_method.update(methods) + + hypervisor_stats = fakes.FakeResource( + info=copy.deepcopy(stats_info), + methods=copy.deepcopy(hypervisor_stats_method), + loaded=True) + return hypervisor_stats + + @staticmethod + def create_hypervisors_stats(attrs={}, count=2): + """Create multiple fake hypervisors stats. + + :param Dictionary attrs: + A dictionary with all attributes + :param int count: + The number of hypervisors to fake + :return: + A list of FakeResource objects faking the hypervisors + """ + hypervisors = [] + for i in range(0, count): + hypervisors.append( + FakehypervisorStats.create_one_hypervisor_stats(attrs)) + + return hypervisors + + +class FakeSecurityGroupRule(object): + """Fake one or more security group rules.""" + + @staticmethod + def create_one_security_group_rule(attrs={}, methods={}): + """Create a fake security group rule. + + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods + :return: + A FakeResource object, with id, etc. + """ + # Set default attributes. + security_group_rule_attrs = { + 'from_port': -1, + 'group': {}, + 'id': 'security-group-rule-id-' + uuid.uuid4().hex, + 'ip_protocol': 'icmp', + 'ip_range': {'cidr': '0.0.0.0/0'}, + 'parent_group_id': 'security-group-id-' + uuid.uuid4().hex, + 'to_port': -1, + } + + # Overwrite default attributes. + security_group_rule_attrs.update(attrs) + + # Set default methods. + security_group_rule_methods = {} + + # Overwrite default methods. + security_group_rule_methods.update(methods) + + security_group_rule = fakes.FakeResource( + info=copy.deepcopy(security_group_rule_attrs), + methods=copy.deepcopy(security_group_rule_methods), + loaded=True) + return security_group_rule + + @staticmethod + def create_security_group_rules(attrs={}, methods={}, count=2): + """Create multiple fake security group rules. + + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods + :param int count: + The number of security group rules to fake + :return: + A list of FakeResource objects faking the security group rules + """ + security_group_rules = [] + for i in range(0, count): + security_group_rules.append( + FakeSecurityGroupRule.create_one_security_group_rule( + attrs, methods)) + + return security_group_rules + + class FakeServer(object): """Fake one or more compute servers.""" @@ -247,6 +379,12 @@ class FakeServer(object): 'id': 'server-id-' + uuid.uuid4().hex, 'name': 'server-name-' + uuid.uuid4().hex, 'metadata': {}, + 'image': { + 'id': 'image-id-' + uuid.uuid4().hex, + }, + 'flavor': { + 'id': 'flavor-id-' + uuid.uuid4().hex, + } } # Overwrite default attributes. @@ -303,8 +441,11 @@ class FakeFlavorResource(fakes.FakeResource): Need to fake them, otherwise the functions to be tested won't run properly. """ - # Fake properties. - _keys = {'property': 'value'} + def __init__(self, manager=None, info={}, loaded=False, methods={}): + super(FakeFlavorResource, self).__init__(manager, info, + loaded, methods) + # Fake properties. + self._keys = {'property': 'value'} def set_keys(self, args): self._keys.update(args) @@ -335,6 +476,12 @@ class FakeFlavor(object): 'name': 'flavor-name-' + uuid.uuid4().hex, 'ram': 8192, 'vcpus': 4, + 'disk': 128, + 'swap': '', + 'rxtx_factor': '1.0', + 'OS-FLV-DISABLED:disabled': False, + 'os-flavor-access:is_public': True, + 'OS-FLV-EXT-DATA:ephemeral': 0, } # Overwrite default attributes. @@ -342,6 +489,12 @@ class FakeFlavor(object): flavor = FakeFlavorResource(info=copy.deepcopy(flavor_info), loaded=True) + + # Set attributes with special mappings in nova client. + flavor.disabled = flavor_info['OS-FLV-DISABLED:disabled'] + flavor.is_public = flavor_info['os-flavor-access:is_public'] + flavor.ephemeral = flavor_info['OS-FLV-EXT-DATA:ephemeral'] + return flavor @staticmethod @@ -439,3 +592,170 @@ class FakeAvailabilityZone(object): availability_zones.append(availability_zone) return availability_zones + + +class FakeFloatingIP(object): + """Fake one or more floating ip.""" + + @staticmethod + def create_one_floating_ip(attrs={}, methods={}): + """Create a fake floating ip. + + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods + :return: + A FakeResource object, with id, ip, and so on + """ + # Set default attributes. + floating_ip_attrs = { + 'id': 'floating-ip-id-' + uuid.uuid4().hex, + 'ip': '1.0.9.0', + 'fixed_ip': '2.0.9.0', + 'instance_id': 'server-id-' + uuid.uuid4().hex, + 'pool': 'public', + } + + # Overwrite default attributes. + floating_ip_attrs.update(attrs) + + # Set default methods. + floating_ip_methods = {} + + # Overwrite default methods. + floating_ip_methods.update(methods) + + floating_ip = fakes.FakeResource( + info=copy.deepcopy(floating_ip_attrs), + methods=copy.deepcopy(floating_ip_methods), + loaded=True) + + return floating_ip + + @staticmethod + def create_floating_ips(attrs={}, methods={}, count=2): + """Create multiple fake floating ips. + + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods + :param int count: + The number of floating ips to fake + :return: + A list of FakeResource objects faking the floating ips + """ + floating_ips = [] + for i in range(0, count): + floating_ips.append(FakeFloatingIP.create_one_floating_ip( + attrs, + methods + )) + return floating_ips + + @staticmethod + def get_floating_ips(floating_ips=None, count=2): + """Get an iterable MagicMock object with a list of faked floating ips. + + If floating_ips list is provided, then initialize the Mock object + with the list. Otherwise create one. + + :param List floating ips: + A list of FakeResource objects faking floating ips + :param int count: + The number of floating ips to fake + :return: + An iterable Mock object with side_effect set to a list of faked + floating ips + """ + if floating_ips is None: + floating_ips = FakeFloatingIP.create_floating_ips(count) + return mock.MagicMock(side_effect=floating_ips) + + +class FakeNetwork(object): + """Fake one or more networks.""" + + @staticmethod + def create_one_network(attrs={}, methods={}): + """Create a fake network. + + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods + :return: + A FakeResource object, with id, label, cidr and so on + """ + # Set default attributes. + network_attrs = { + 'bridge': 'br100', + 'bridge_interface': None, + 'broadcast': '10.0.0.255', + 'cidr': '10.0.0.0/24', + 'cidr_v6': None, + 'created_at': '2016-02-11T11:17:37.000000', + 'deleted': False, + 'deleted_at': None, + 'dhcp_server': '10.0.0.1', + 'dhcp_start': '10.0.0.2', + 'dns1': '8.8.4.4', + 'dns2': None, + 'enable_dhcp': True, + 'gateway': '10.0.0.1', + 'gateway_v6': None, + 'host': None, + 'id': 'network-id-' + uuid.uuid4().hex, + 'injected': False, + 'label': 'network-label-' + uuid.uuid4().hex, + 'mtu': None, + 'multi_host': False, + 'netmask': '255.255.255.0', + 'netmask_v6': None, + 'priority': None, + 'project_id': 'project-id-' + uuid.uuid4().hex, + 'rxtx_base': None, + 'share_address': False, + 'updated_at': None, + 'vlan': None, + 'vpn_private_address': None, + 'vpn_public_address': None, + 'vpn_public_port': None, + } + + # Overwrite default attributes. + network_attrs.update(attrs) + + # Set default methods. + network_methods = { + 'keys': ['id', 'label', 'cidr'], + } + + # Overwrite default methods. + network_methods.update(methods) + + network = fakes.FakeResource(info=copy.deepcopy(network_attrs), + methods=copy.deepcopy(network_methods), + loaded=True) + + return network + + @staticmethod + def create_networks(attrs={}, methods={}, count=2): + """Create multiple fake networks. + + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods + :param int count: + The number of networks to fake + :return: + A list of FakeResource objects faking the networks + """ + networks = [] + for i in range(0, count): + networks.append(FakeNetwork.create_one_network(attrs, methods)) + + return networks diff --git a/openstackclient/tests/compute/v2/test_flavor.py b/openstackclient/tests/compute/v2/test_flavor.py index 9ae26962..781e3068 100644 --- a/openstackclient/tests/compute/v2/test_flavor.py +++ b/openstackclient/tests/compute/v2/test_flavor.py @@ -14,8 +14,10 @@ # from openstackclient.common import exceptions +from openstackclient.common import utils from openstackclient.compute.v2 import flavor from openstackclient.tests.compute.v2 import fakes as compute_fakes +from openstackclient.tests import utils as tests_utils class TestFlavor(compute_fakes.TestComputev2): @@ -97,15 +99,15 @@ class TestFlavorList(TestFlavor): flavors[0].id, flavors[0].name, flavors[0].ram, - '', - '', + flavors[0].disk, + flavors[0].ephemeral, flavors[0].vcpus, - '' + flavors[0].is_public, ), ) data_long = (data[0] + ( - '', - '', - 'property=\'value\'' + flavors[0].swap, + flavors[0].rxtx_factor, + u'property=\'value\'' ), ) def setUp(self): @@ -126,7 +128,7 @@ class TestFlavorList(TestFlavor): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class Lister in cliff, abstractmethod take_action() + # In base command class Lister in cliff, abstract method take_action() # returns a tuple containing the column names and an iterable # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) @@ -155,7 +157,7 @@ class TestFlavorList(TestFlavor): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class Lister in cliff, abstractmethod take_action() + # In base command class Lister in cliff, abstract method take_action() # returns a tuple containing the column names and an iterable # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) @@ -184,7 +186,7 @@ class TestFlavorList(TestFlavor): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class Lister in cliff, abstractmethod take_action() + # In base command class Lister in cliff, abstract method take_action() # returns a tuple containing the column names and an iterable # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) @@ -213,7 +215,7 @@ class TestFlavorList(TestFlavor): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class Lister in cliff, abstractmethod take_action() + # In base command class Lister in cliff, abstract method take_action() # returns a tuple containing the column names and an iterable # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) @@ -242,7 +244,7 @@ class TestFlavorList(TestFlavor): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class Lister in cliff, abstractmethod take_action() + # In base command class Lister in cliff, abstract method take_action() # returns a tuple containing the column names and an iterable # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) @@ -290,8 +292,73 @@ class TestFlavorSet(TestFlavor): self.flavors_mock.find.assert_called_with(name='baremetal') - self.assertEqual('properties', columns[2]) - self.assertIn('FOO=\'"B A R"\'', data[2]) + self.assertEqual('properties', columns[6]) + self.assertIn('FOO=\'"B A R"\'', data[6]) + + +class TestFlavorShow(TestFlavor): + + # Return value of self.flavors_mock.find(). + flavor = compute_fakes.FakeFlavor.create_one_flavor() + + columns = ( + 'OS-FLV-DISABLED:disabled', + 'OS-FLV-EXT-DATA:ephemeral', + 'disk', + 'id', + 'name', + 'os-flavor-access:is_public', + 'properties', + 'ram', + 'rxtx_factor', + 'swap', + 'vcpus', + ) + + data = ( + flavor.disabled, + flavor.ephemeral, + flavor.disk, + flavor.id, + flavor.name, + flavor.is_public, + utils.format_dict(flavor.get_keys()), + flavor.ram, + flavor.rxtx_factor, + flavor.swap, + flavor.vcpus, + ) + + def setUp(self): + super(TestFlavorShow, self).setUp() + + # Return value of utils.find_resource() + self.flavors_mock.get.return_value = self.flavor + + self.cmd = flavor.ShowFlavor(self.app, None) + + def test_show_no_options(self): + arglist = [] + verifylist = [] + + # Missing required args should boil here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_flavor_show(self): + arglist = [ + self.flavor.name, + ] + verifylist = [ + ('flavor', self.flavor.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) class TestFlavorUnset(TestFlavor): @@ -322,5 +389,5 @@ class TestFlavorUnset(TestFlavor): self.flavors_mock.find.assert_called_with(name='baremetal') - self.assertEqual('properties', columns[2]) - self.assertNotIn('property', data[2]) + self.assertEqual('properties', columns[6]) + self.assertNotIn('property', data[6]) diff --git a/openstackclient/tests/compute/v2/test_hypervisor.py b/openstackclient/tests/compute/v2/test_hypervisor.py index a11f59d2..8d717ba7 100644 --- a/openstackclient/tests/compute/v2/test_hypervisor.py +++ b/openstackclient/tests/compute/v2/test_hypervisor.py @@ -67,7 +67,7 @@ class TestHypervisorList(TestHypervisor): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class Lister in cliff, abstractmethod take_action() + # In base command class Lister in cliff, abstract method take_action() # returns a tuple containing the column names and an iterable # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) @@ -94,7 +94,7 @@ class TestHypervisorList(TestHypervisor): ), ) - # In base command class Lister in cliff, abstractmethod take_action() + # In base command class Lister in cliff, abstract method take_action() # returns a tuple containing the column names and an iterable # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) @@ -211,7 +211,7 @@ class TestHypervisorShow(TestHypervisor): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) diff --git a/openstackclient/tests/compute/v2/test_hypervisor_stats.py b/openstackclient/tests/compute/v2/test_hypervisor_stats.py new file mode 100644 index 00000000..39e303a8 --- /dev/null +++ b/openstackclient/tests/compute/v2/test_hypervisor_stats.py @@ -0,0 +1,79 @@ +# Copyright 2016 EasyStack Corporation +# +# 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 openstackclient.compute.v2 import hypervisor_stats +from openstackclient.tests.compute.v2 import fakes as compute_fakes + + +class TestHypervisorStats(compute_fakes.TestComputev2): + + def setUp(self): + super(TestHypervisorStats, self).setUp() + + # Get a shortcut to the compute client hypervisors mock + self.hypervisors_mock = self.app.client_manager.compute.hypervisors + self.hypervisors_mock.reset_mock() + + +class TestHypervisorStatsShow(TestHypervisorStats): + + def setUp(self): + super(TestHypervisorStatsShow, self).setUp() + + self.hypervisor_stats = \ + compute_fakes.FakehypervisorStats.create_one_hypervisor_stats() + + self.hypervisors_mock.statistics.return_value =\ + self.hypervisor_stats + + self.cmd = hypervisor_stats.ShowHypervisorStats(self.app, None) + + self.columns = ( + 'count', + 'current_workload', + 'disk_available_least', + 'free_disk_gb', + 'free_ram_mb', + 'local_gb', + 'local_gb_used', + 'memory_mb', + 'memory_mb_used', + 'running_vms', + 'vcpus', + 'vcpus_used', + ) + + self.data = ( + 2, + 0, + 50, + 100, + 23000, + 100, + 0, + 23800, + 1400, + 3, + 8, + 3, + ) + + def test_hypervisor_show_stats(self): + arglist = [] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) diff --git a/openstackclient/tests/compute/v2/test_security_group.py b/openstackclient/tests/compute/v2/test_security_group.py index 79eefe6c..c6998cb5 100644 --- a/openstackclient/tests/compute/v2/test_security_group.py +++ b/openstackclient/tests/compute/v2/test_security_group.py @@ -87,7 +87,7 @@ class TestSecurityGroupCreate(TestSecurityGroup): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) @@ -112,7 +112,7 @@ class TestSecurityGroupCreate(TestSecurityGroup): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) @@ -159,7 +159,7 @@ class TestSecurityGroupList(TestSecurityGroup): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class Lister in cliff, abstractmethod take_action() + # In base command class Lister in cliff, abstract method take_action() # returns a tuple containing the column names and an iterable # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) diff --git a/openstackclient/tests/compute/v2/test_security_group_rule.py b/openstackclient/tests/compute/v2/test_security_group_rule.py index d211ee4e..9a8003f3 100644 --- a/openstackclient/tests/compute/v2/test_security_group_rule.py +++ b/openstackclient/tests/compute/v2/test_security_group_rule.py @@ -149,7 +149,7 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) @@ -195,7 +195,7 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) @@ -245,7 +245,7 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) @@ -290,7 +290,7 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) @@ -338,7 +338,7 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) @@ -411,7 +411,7 @@ class TestSecurityGroupRuleList(TestSecurityGroupRule): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class Lister in cliff, abstractmethod take_action() + # In base command class Lister in cliff, abstract method take_action() # returns a tuple containing the column names and an iterable # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) @@ -449,7 +449,7 @@ class TestSecurityGroupRuleList(TestSecurityGroupRule): parsed_args = self.check_parser(self.cmd, [], []) - # In base command class Lister in cliff, abstractmethod take_action() + # In base command class Lister in cliff, abstract method take_action() # returns a tuple containing the column names and an iterable # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) diff --git a/openstackclient/tests/compute/v2/test_server.py b/openstackclient/tests/compute/v2/test_server.py index 84402ea5..d379b173 100644 --- a/openstackclient/tests/compute/v2/test_server.py +++ b/openstackclient/tests/compute/v2/test_server.py @@ -12,7 +12,6 @@ # License for the specific language governing permissions and limitations # under the License. # - import mock from mock import call @@ -92,6 +91,7 @@ class TestServerCreate(TestServer): 'addresses', 'flavor', 'id', + 'image', 'name', 'networks', 'properties', @@ -100,8 +100,9 @@ class TestServerCreate(TestServer): def datalist(self): datalist = ( '', - self.flavor.name + ' ()', + self.flavor.name + ' (' + self.new_server.flavor.get('id') + ')', self.new_server.id, + self.image.name + ' (' + self.new_server.image.get('id') + ')', self.new_server.name, self.new_server.networks, '', @@ -143,11 +144,10 @@ class TestServerCreate(TestServer): verifylist = [ ('server_name', self.new_server.name), ] - try: - # Missing required args should bail here - self.check_parser(self.cmd, arglist, verifylist) - except utils.ParserException: - pass + + # Missing required args should bail here + self.assertRaises(utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) def test_server_create_minimal(self): arglist = [ @@ -163,7 +163,7 @@ class TestServerCreate(TestServer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) @@ -243,7 +243,7 @@ class TestServerCreate(TestServer): self.app.client_manager.network.find_network = find_network self.app.client_manager.network.find_port = find_port - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) @@ -303,7 +303,7 @@ class TestServerCreate(TestServer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) @@ -557,7 +557,7 @@ class TestServerImageCreate(TestServer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) @@ -582,7 +582,7 @@ class TestServerImageCreate(TestServer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class ShowOne in cliff, abstractmethod take_action() + # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) @@ -618,33 +618,32 @@ class TestServerList(TestServer): 'Properties', ) - # Default search options, in the case of no commandline option specified. - search_opts = { - 'reservation_id': None, - 'ip': None, - 'ip6': None, - 'name': None, - 'instance_name': None, - 'status': None, - 'flavor': None, - 'image': None, - 'host': None, - 'tenant_id': None, - 'all_tenants': False, - 'user_id': None, - } - - # Default params of the core function of the command in the case of no - # commandline option specified. - kwargs = { - 'search_opts': search_opts, - 'marker': None, - 'limit': None, - } - def setUp(self): super(TestServerList, self).setUp() + self.search_opts = { + 'reservation_id': None, + 'ip': None, + 'ip6': None, + 'name': None, + 'instance_name': None, + 'status': None, + 'flavor': None, + 'image': None, + 'host': None, + 'tenant_id': None, + 'all_tenants': False, + 'user_id': None, + } + + # Default params of the core function of the command in the case of no + # commandline option specified. + self.kwargs = { + 'search_opts': self.search_opts, + 'marker': None, + 'limit': None, + } + # The fake servers' attributes. Use the original attributes names in # nova, not the ones printed by "server list" command. self.attrs = { @@ -661,9 +660,14 @@ class TestServerList(TestServer): # The servers to be listed. self.servers = self.setup_servers_mock(3) - self.servers_mock.list.return_value = self.servers + self.image = image_fakes.FakeImage.create_one_image() + self.cimages_mock.get.return_value = self.image + + self.flavor = compute_fakes.FakeFlavor.create_one_flavor() + self.flavors_mock.get.return_value = self.flavor + # Get the command object to test self.cmd = server.ListServer(self.app, None) @@ -722,6 +726,46 @@ class TestServerList(TestServer): self.assertEqual(self.columns_long, columns) self.assertEqual(tuple(self.data_long), tuple(data)) + def test_server_list_with_image(self): + + arglist = [ + '--image', self.image.id + ] + verifylist = [ + ('image', self.image.id) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.cimages_mock.get.assert_called_with(self.image.id) + + self.search_opts['image'] = self.image.id + self.servers_mock.list.assert_called_with(**self.kwargs) + + self.assertEqual(self.columns, columns) + self.assertEqual(tuple(self.data), tuple(data)) + + def test_server_list_with_flavor(self): + + arglist = [ + '--flavor', self.flavor.id + ] + verifylist = [ + ('flavor', self.flavor.id) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.flavors_mock.get.assert_called_with(self.flavor.id) + + self.search_opts['flavor'] = self.flavor.id + self.servers_mock.list.assert_called_with(**self.kwargs) + + self.assertEqual(self.columns, columns) + self.assertEqual(tuple(self.data), tuple(data)) + class TestServerLock(TestServer): diff --git a/openstackclient/tests/compute/v2/test_service.py b/openstackclient/tests/compute/v2/test_service.py index 71700aa8..54adaab3 100644 --- a/openstackclient/tests/compute/v2/test_service.py +++ b/openstackclient/tests/compute/v2/test_service.py @@ -81,7 +81,7 @@ class TestServiceList(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # In base command class Lister in cliff, abstractmethod take_action() + # In base command class Lister in cliff, abstract method take_action() # returns a tuple containing the column names and an iterable # containing the data to be listed. self.cmd.take_action(parsed_args) diff --git a/openstackclient/tests/fakes.py b/openstackclient/tests/fakes.py index 718dff69..9fdcc7e9 100644 --- a/openstackclient/tests/fakes.py +++ b/openstackclient/tests/fakes.py @@ -51,6 +51,7 @@ TEST_VERSIONS = fixture.DiscoveryList(href=AUTH_URL) class FakeStdout(object): + def __init__(self): self.content = [] @@ -65,6 +66,7 @@ class FakeStdout(object): class FakeLog(object): + def __init__(self): self.messages = {} @@ -85,6 +87,7 @@ class FakeLog(object): class FakeApp(object): + def __init__(self, _stdout, _log): self.stdout = _stdout self.client_manager = None @@ -95,12 +98,14 @@ class FakeApp(object): class FakeClient(object): + def __init__(self, **kwargs): self.endpoint = kwargs['endpoint'] self.token = kwargs['token'] class FakeClientManager(object): + def __init__(self): self.compute = None self.identity = None @@ -129,12 +134,14 @@ class FakeClientManager(object): class FakeModule(object): + def __init__(self, name, version): self.name = name self.__version__ = version class FakeResource(object): + def __init__(self, manager=None, info={}, loaded=False, methods={}): """Set attributes and methods for a resource. @@ -178,6 +185,7 @@ class FakeResource(object): class FakeResponse(requests.Response): + def __init__(self, headers={}, status_code=200, data=None, encoding=None): super(FakeResponse, self).__init__() @@ -190,6 +198,7 @@ class FakeResponse(requests.Response): class FakeModel(dict): + def __getattr__(self, key): try: return self[key] diff --git a/openstackclient/tests/identity/v2_0/fakes.py b/openstackclient/tests/identity/v2_0/fakes.py index 6688606a..b37bd9da 100644 --- a/openstackclient/tests/identity/v2_0/fakes.py +++ b/openstackclient/tests/identity/v2_0/fakes.py @@ -80,6 +80,12 @@ TOKEN = { 'user_id': user_id, } +UNSCOPED_TOKEN = { + 'expires': token_expires, + 'id': token_id, + 'user_id': user_id, +} + endpoint_name = service_name endpoint_adminurl = 'https://admin.example.com/v2/UUID' endpoint_region = 'RegionOne' @@ -122,6 +128,7 @@ EXTENSION = { class FakeIdentityv2Client(object): + def __init__(self, **kwargs): self.roles = mock.Mock() self.roles.resource_class = fakes.FakeResource(None, {}) @@ -151,6 +158,7 @@ class FakeIdentityv2Client(object): class TestIdentityv2(utils.TestCommand): + def setUp(self): super(TestIdentityv2, self).setUp() diff --git a/openstackclient/tests/identity/v2_0/test_catalog.py b/openstackclient/tests/identity/v2_0/test_catalog.py index ff1d993e..1e27bb3c 100644 --- a/openstackclient/tests/identity/v2_0/test_catalog.py +++ b/openstackclient/tests/identity/v2_0/test_catalog.py @@ -72,7 +72,9 @@ class TestCatalogList(TestCatalog): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.sc_mock.service_catalog.get_data.assert_called_with() @@ -114,7 +116,9 @@ class TestCatalogList(TestCatalog): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.sc_mock.service_catalog.get_data.assert_called_with() @@ -146,7 +150,9 @@ class TestCatalogShow(TestCatalog): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.sc_mock.service_catalog.get_data.assert_called_with() diff --git a/openstackclient/tests/identity/v2_0/test_endpoint.py b/openstackclient/tests/identity/v2_0/test_endpoint.py index 354b1e40..088fdcd1 100644 --- a/openstackclient/tests/identity/v2_0/test_endpoint.py +++ b/openstackclient/tests/identity/v2_0/test_endpoint.py @@ -69,7 +69,9 @@ class TestEndpointCreate(TestEndpoint): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # EndpointManager.create(region, service_id, publicurl, adminurl, @@ -130,7 +132,6 @@ class TestEndpointDelete(TestEndpoint): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) self.endpoints_mock.delete.assert_called_with( @@ -165,7 +166,9 @@ class TestEndpointList(TestEndpoint): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.endpoints_mock.list.assert_called_with() @@ -189,7 +192,9 @@ class TestEndpointList(TestEndpoint): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.endpoints_mock.list.assert_called_with() @@ -240,7 +245,9 @@ class TestEndpointShow(TestEndpoint): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # EndpointManager.list() diff --git a/openstackclient/tests/identity/v2_0/test_project.py b/openstackclient/tests/identity/v2_0/test_project.py index 69b29268..669c3eab 100644 --- a/openstackclient/tests/identity/v2_0/test_project.py +++ b/openstackclient/tests/identity/v2_0/test_project.py @@ -70,7 +70,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -96,7 +98,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -124,7 +128,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -152,7 +158,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -180,7 +188,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -221,7 +231,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ProjectManager.create(name, description, enabled) @@ -251,7 +263,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -322,7 +336,9 @@ class TestProjectList(TestProject): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.projects_mock.list.assert_called_with() @@ -343,7 +359,9 @@ class TestProjectList(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.projects_mock.list.assert_called_with() @@ -549,7 +567,9 @@ class TestProjectShow(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.projects_mock.get.assert_called_with( identity_fakes.project_id, diff --git a/openstackclient/tests/identity/v2_0/test_role.py b/openstackclient/tests/identity/v2_0/test_role.py index c2bacc52..03b7f924 100644 --- a/openstackclient/tests/identity/v2_0/test_role.py +++ b/openstackclient/tests/identity/v2_0/test_role.py @@ -86,7 +86,9 @@ class TestRoleAdd(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # RoleManager.add_user_role(user, role, tenant=None) @@ -137,7 +139,9 @@ class TestRoleCreate(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # RoleManager.create(name) @@ -171,7 +175,9 @@ class TestRoleCreate(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # RoleManager.get(name, description, enabled) @@ -196,7 +202,9 @@ class TestRoleCreate(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # RoleManager.create(name) @@ -232,7 +240,6 @@ class TestRoleDelete(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) self.roles_mock.delete.assert_called_with( @@ -261,7 +268,9 @@ class TestRoleList(TestRole): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.roles_mock.list.assert_called_with() @@ -331,7 +340,9 @@ class TestUserRoleList(TestRole): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.roles_mock.roles_for_user.assert_called_with( @@ -388,7 +399,9 @@ class TestUserRoleList(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.roles_mock.roles_for_user.assert_called_with( @@ -446,7 +459,6 @@ class TestRoleRemove(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # RoleManager.remove_user_role(user, role, tenant=None) @@ -480,7 +492,9 @@ class TestRoleShow(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # RoleManager.get(role) diff --git a/openstackclient/tests/identity/v2_0/test_service.py b/openstackclient/tests/identity/v2_0/test_service.py index b97786b4..606b1433 100644 --- a/openstackclient/tests/identity/v2_0/test_service.py +++ b/openstackclient/tests/identity/v2_0/test_service.py @@ -69,7 +69,9 @@ class TestServiceCreate(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ServiceManager.create(name, service_type, description) @@ -95,7 +97,9 @@ class TestServiceCreate(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ServiceManager.create(name, service_type, description) @@ -121,7 +125,9 @@ class TestServiceCreate(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ServiceManager.create(name, service_type, description) @@ -148,7 +154,9 @@ class TestServiceCreate(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ServiceManager.create(name, service_type, description) @@ -186,7 +194,6 @@ class TestServiceDelete(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) self.services_mock.delete.assert_called_with( @@ -215,7 +222,9 @@ class TestServiceList(TestService): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.services_mock.list.assert_called_with() @@ -238,7 +247,9 @@ class TestServiceList(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.services_mock.list.assert_called_with() @@ -277,7 +288,9 @@ class TestServiceShow(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ServiceManager.get(id) diff --git a/openstackclient/tests/identity/v2_0/test_token.py b/openstackclient/tests/identity/v2_0/test_token.py index ce2faef3..c90477f9 100644 --- a/openstackclient/tests/identity/v2_0/test_token.py +++ b/openstackclient/tests/identity/v2_0/test_token.py @@ -43,7 +43,9 @@ class TestTokenIssue(TestToken): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.sc_mock.get_token.assert_called_with() @@ -58,6 +60,28 @@ class TestTokenIssue(TestToken): ) self.assertEqual(datalist, data) + def test_token_issue_with_unscoped_token(self): + # make sure we return an unscoped token + self.sc_mock.get_token.return_value = identity_fakes.UNSCOPED_TOKEN + + arglist = [] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + self.sc_mock.get_token.assert_called_with() + + collist = ('expires', 'id', 'user_id') + self.assertEqual(collist, columns) + datalist = ( + identity_fakes.token_expires, + identity_fakes.token_id, + identity_fakes.user_id, + ) + self.assertEqual(datalist, data) + class TestTokenRevoke(TestToken): diff --git a/openstackclient/tests/identity/v2_0/test_user.py b/openstackclient/tests/identity/v2_0/test_user.py index a25def87..a7332e63 100644 --- a/openstackclient/tests/identity/v2_0/test_user.py +++ b/openstackclient/tests/identity/v2_0/test_user.py @@ -83,7 +83,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -114,7 +116,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -143,7 +147,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. mocker = mock.Mock() mocker.return_value = 'abc123' with mock.patch("openstackclient.common.utils.get_password", mocker): @@ -176,7 +182,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -221,7 +229,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -259,7 +269,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -290,7 +302,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -332,7 +346,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # UserManager.create(name, password, email, tenant_id=, enabled=) @@ -352,7 +368,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -396,7 +414,6 @@ class TestUserDelete(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) self.users_mock.delete.assert_called_with( @@ -449,7 +466,9 @@ class TestUserList(TestUser): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.users_mock.list.assert_called_with(tenant_id=None) @@ -467,7 +486,9 @@ class TestUserList(TestUser): parsed_args = self.check_parser(self.cmd, arglist, verifylist) project_id = identity_fakes.PROJECT_2['id'] - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.users_mock.list.assert_called_with(tenant_id=project_id) @@ -484,7 +505,9 @@ class TestUserList(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.users_mock.list.assert_called_with(tenant_id=None) @@ -554,7 +577,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -585,7 +607,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # UserManager.update_password(user, password) @@ -611,7 +632,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples mocker = mock.Mock() mocker.return_value = 'abc123' with mock.patch("openstackclient.common.utils.get_password", mocker): @@ -639,7 +659,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -669,7 +688,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # UserManager.update_tenant(user, tenant) @@ -694,7 +712,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -723,7 +740,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -760,7 +776,9 @@ class TestUserShow(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.users_mock.get.assert_called_with(identity_fakes.user_id) diff --git a/openstackclient/tests/identity/v3/fakes.py b/openstackclient/tests/identity/v3/fakes.py index 9fe341ed..1422166a 100644 --- a/openstackclient/tests/identity/v3/fakes.py +++ b/openstackclient/tests/identity/v3/fakes.py @@ -244,6 +244,12 @@ TRUST = { token_expires = '2014-01-01T00:00:00Z' token_id = 'tttttttt-tttt-tttt-tttt-tttttttttttt' +UNSCOPED_TOKEN = { + 'expires': token_expires, + 'id': token_id, + 'user_id': user_id, +} + TOKEN_WITH_PROJECT_ID = { 'expires': token_expires, 'id': token_id, @@ -314,6 +320,22 @@ ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID = { 'role': {'id': role_id}, } +ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID_INCLUDE_NAMES = { + 'scope': { + 'project': { + 'domain': {'id': domain_id, + 'name': domain_name}, + 'id': project_id, + 'name': project_name}}, + 'user': { + 'domain': {'id': domain_id, + 'name': domain_name}, + 'id': user_id, + 'name': user_name}, + 'role': {'id': role_id, + 'name': role_name}, +} + ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID_INHERITED = { 'scope': {'project': {'id': project_id}, 'OS-INHERIT:inherited_to': 'projects'}, @@ -333,6 +355,19 @@ ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID = { 'role': {'id': role_id}, } +ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID_INCLUDE_NAMES = { + 'scope': { + 'domain': {'id': domain_id, + 'name': domain_name}}, + 'user': { + 'domain': {'id': domain_id, + 'name': domain_name}, + 'id': user_id, + 'name': user_name}, + 'role': {'id': role_id, + 'name': role_name}, +} + ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID_INHERITED = { 'scope': {'domain': {'id': domain_id}, 'OS-INHERIT:inherited_to': 'projects'}, @@ -385,6 +420,7 @@ OAUTH_VERIFIER = { class FakeAuth(object): + def __init__(self, auth_method_class=None): self._auth_method_class = auth_method_class @@ -393,11 +429,13 @@ class FakeAuth(object): class FakeSession(object): + def __init__(self, **kwargs): self.auth = FakeAuth() class FakeIdentityv3Client(object): + def __init__(self, **kwargs): self.domains = mock.Mock() self.domains.resource_class = fakes.FakeResource(None, {}) @@ -420,6 +458,8 @@ class FakeIdentityv3Client(object): self.session = mock.Mock() self.session.auth.auth_ref.service_catalog.resource_class = \ fakes.FakeResource(None, {}) + self.tokens = mock.Mock() + self.tokens.resource_class = fakes.FakeResource(None, {}) self.trusts = mock.Mock() self.trusts.resource_class = fakes.FakeResource(None, {}) self.users = mock.Mock() @@ -431,6 +471,7 @@ class FakeIdentityv3Client(object): class FakeFederationManager(object): + def __init__(self, **kwargs): self.identity_providers = mock.Mock() self.identity_providers.resource_class = fakes.FakeResource(None, {}) @@ -447,12 +488,14 @@ class FakeFederationManager(object): class FakeFederatedClient(FakeIdentityv3Client): + def __init__(self, **kwargs): super(FakeFederatedClient, self).__init__(**kwargs) self.federation = FakeFederationManager() class FakeOAuth1Client(FakeIdentityv3Client): + def __init__(self, **kwargs): super(FakeOAuth1Client, self).__init__(**kwargs) @@ -465,6 +508,7 @@ class FakeOAuth1Client(FakeIdentityv3Client): class TestIdentityv3(utils.TestCommand): + def setUp(self): super(TestIdentityv3, self).setUp() @@ -475,6 +519,7 @@ class TestIdentityv3(utils.TestCommand): class TestFederatedIdentity(utils.TestCommand): + def setUp(self): super(TestFederatedIdentity, self).setUp() @@ -485,6 +530,7 @@ class TestFederatedIdentity(utils.TestCommand): class TestOAuth1(utils.TestCommand): + def setUp(self): super(TestOAuth1, self).setUp() diff --git a/openstackclient/tests/identity/v3/test_catalog.py b/openstackclient/tests/identity/v3/test_catalog.py index 6bb962de..a03c9d3e 100644 --- a/openstackclient/tests/identity/v3/test_catalog.py +++ b/openstackclient/tests/identity/v3/test_catalog.py @@ -68,7 +68,9 @@ class TestCatalogList(TestCatalog): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.sc_mock.service_catalog.get_data.assert_called_with() @@ -101,7 +103,9 @@ class TestCatalogShow(TestCatalog): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.sc_mock.service_catalog.get_data.assert_called_with() diff --git a/openstackclient/tests/identity/v3/test_consumer.py b/openstackclient/tests/identity/v3/test_consumer.py index 4e807562..7f6af734 100644 --- a/openstackclient/tests/identity/v3/test_consumer.py +++ b/openstackclient/tests/identity/v3/test_consumer.py @@ -121,7 +121,9 @@ class TestConsumerList(TestOAuth1): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.consumers_mock.list.assert_called_with() diff --git a/openstackclient/tests/identity/v3/test_credential.py b/openstackclient/tests/identity/v3/test_credential.py index e2e690c3..afff7b6c 100644 --- a/openstackclient/tests/identity/v3/test_credential.py +++ b/openstackclient/tests/identity/v3/test_credential.py @@ -46,6 +46,7 @@ class TestCredential(identity_fakes.TestIdentityv3): class TestCredentialSet(TestCredential): + def setUp(self): super(TestCredentialSet, self).setUp() self.cmd = credential.SetCredential(self.app, None) diff --git a/openstackclient/tests/identity/v3/test_domain.py b/openstackclient/tests/identity/v3/test_domain.py index 969c2df7..9de6b26a 100644 --- a/openstackclient/tests/identity/v3/test_domain.py +++ b/openstackclient/tests/identity/v3/test_domain.py @@ -63,7 +63,9 @@ class TestDomainCreate(TestDomain): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -90,7 +92,9 @@ class TestDomainCreate(TestDomain): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -117,7 +121,9 @@ class TestDomainCreate(TestDomain): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -144,7 +150,9 @@ class TestDomainCreate(TestDomain): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -215,7 +223,9 @@ class TestDomainList(TestDomain): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.domains_mock.list.assert_called_with() @@ -380,7 +390,9 @@ class TestDomainShow(TestDomain): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.domains_mock.get.assert_called_with( identity_fakes.domain_id, diff --git a/openstackclient/tests/identity/v3/test_endpoint.py b/openstackclient/tests/identity/v3/test_endpoint.py index fb88e004..1c481930 100644 --- a/openstackclient/tests/identity/v3/test_endpoint.py +++ b/openstackclient/tests/identity/v3/test_endpoint.py @@ -81,7 +81,9 @@ class TestEndpointCreate(TestEndpoint): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -126,7 +128,9 @@ class TestEndpointCreate(TestEndpoint): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -170,7 +174,9 @@ class TestEndpointCreate(TestEndpoint): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -214,7 +220,9 @@ class TestEndpointCreate(TestEndpoint): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -315,7 +323,9 @@ class TestEndpointList(TestEndpoint): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.endpoints_mock.list.assert_called_with() @@ -342,7 +352,9 @@ class TestEndpointList(TestEndpoint): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -374,7 +386,9 @@ class TestEndpointList(TestEndpoint): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -406,7 +420,9 @@ class TestEndpointList(TestEndpoint): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -665,7 +681,9 @@ class TestEndpointShow(TestEndpoint): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.endpoints_mock.get.assert_called_with( identity_fakes.endpoint_id, diff --git a/openstackclient/tests/identity/v3/test_group.py b/openstackclient/tests/identity/v3/test_group.py index 59a36819..c5f5dbca 100644 --- a/openstackclient/tests/identity/v3/test_group.py +++ b/openstackclient/tests/identity/v3/test_group.py @@ -85,7 +85,9 @@ class TestGroupList(TestGroup): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -110,7 +112,9 @@ class TestGroupList(TestGroup): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -135,7 +139,9 @@ class TestGroupList(TestGroup): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -160,7 +166,9 @@ class TestGroupList(TestGroup): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values diff --git a/openstackclient/tests/identity/v3/test_identity_provider.py b/openstackclient/tests/identity/v3/test_identity_provider.py index 50a922b8..ddad6ffb 100644 --- a/openstackclient/tests/identity/v3/test_identity_provider.py +++ b/openstackclient/tests/identity/v3/test_identity_provider.py @@ -290,7 +290,9 @@ class TestIdentityProviderList(TestIdentityProvider): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.identity_providers_mock.list.assert_called_with() @@ -366,6 +368,7 @@ class TestIdentityProviderSet(TestIdentityProvider): def test_identity_provider_set_description(self): """Set Identity Provider's description. """ + def prepare(self): """Prepare fake return objects before the test is executed""" updated_idp = copy.deepcopy(identity_fakes.IDENTITY_PROVIDER) @@ -410,6 +413,7 @@ class TestIdentityProviderSet(TestIdentityProvider): Set Identity Provider's ``enabled`` attribute to False. """ + def prepare(self): """Prepare fake return objects before the test is executed""" updated_idp = copy.deepcopy(identity_fakes.IDENTITY_PROVIDER) @@ -457,6 +461,7 @@ class TestIdentityProviderSet(TestIdentityProvider): Set Identity Provider's ``enabled`` attribute to True. """ + def prepare(self): """Prepare fake return objects before the test is executed""" resources = fakes.FakeResource( @@ -493,6 +498,7 @@ class TestIdentityProviderSet(TestIdentityProvider): Set Identity Provider's ``enabled`` attribute to True. """ + def prepare(self): """Prepare fake return objects before the test is executed""" self.new_remote_id = 'new_entity' @@ -538,6 +544,7 @@ class TestIdentityProviderSet(TestIdentityProvider): Set Identity Provider's ``enabled`` attribute to True. """ + def prepare(self): """Prepare fake return objects before the test is executed""" self.new_remote_id = 'new_entity' diff --git a/openstackclient/tests/identity/v3/test_mappings.py b/openstackclient/tests/identity/v3/test_mappings.py index f6e88885..e811c0b6 100644 --- a/openstackclient/tests/identity/v3/test_mappings.py +++ b/openstackclient/tests/identity/v3/test_mappings.py @@ -33,71 +33,74 @@ class TestMapping(identity_fakes.TestFederatedIdentity): class TestMappingCreate(TestMapping): - def setUp(self): - super(TestMappingCreate, self).setUp() - self.mapping_mock.create.return_value = fakes.FakeResource( - None, - copy.deepcopy(identity_fakes.MAPPING_RESPONSE), - loaded=True - ) - self.cmd = mapping.CreateMapping(self.app, None) - - def test_create_mapping(self): - arglist = [ - '--rules', identity_fakes.mapping_rules_file_path, - identity_fakes.mapping_id - ] - verifylist = [ - ('mapping', identity_fakes.mapping_id), - ('rules', identity_fakes.mapping_rules_file_path) - ] - - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - mocker = mock.Mock() - mocker.return_value = identity_fakes.MAPPING_RULES - with mock.patch("openstackclient.identity.v3.mapping." - "CreateMapping._read_rules", mocker): - columns, data = self.cmd.take_action(parsed_args) - - self.mapping_mock.create.assert_called_with( - mapping_id=identity_fakes.mapping_id, - rules=identity_fakes.MAPPING_RULES) - - collist = ('id', 'rules') - self.assertEqual(collist, columns) - - datalist = (identity_fakes.mapping_id, - identity_fakes.MAPPING_RULES) - self.assertEqual(datalist, data) + + def setUp(self): + super(TestMappingCreate, self).setUp() + self.mapping_mock.create.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.MAPPING_RESPONSE), + loaded=True + ) + self.cmd = mapping.CreateMapping(self.app, None) + + def test_create_mapping(self): + arglist = [ + '--rules', identity_fakes.mapping_rules_file_path, + identity_fakes.mapping_id + ] + verifylist = [ + ('mapping', identity_fakes.mapping_id), + ('rules', identity_fakes.mapping_rules_file_path) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + mocker = mock.Mock() + mocker.return_value = identity_fakes.MAPPING_RULES + with mock.patch("openstackclient.identity.v3.mapping." + "CreateMapping._read_rules", mocker): + columns, data = self.cmd.take_action(parsed_args) + + self.mapping_mock.create.assert_called_with( + mapping_id=identity_fakes.mapping_id, + rules=identity_fakes.MAPPING_RULES) + + collist = ('id', 'rules') + self.assertEqual(collist, columns) + + datalist = (identity_fakes.mapping_id, + identity_fakes.MAPPING_RULES) + self.assertEqual(datalist, data) class TestMappingDelete(TestMapping): - def setUp(self): - super(TestMappingDelete, self).setUp() - self.mapping_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(identity_fakes.MAPPING_RESPONSE), - loaded=True) - self.mapping_mock.delete.return_value = None - self.cmd = mapping.DeleteMapping(self.app, None) + def setUp(self): + super(TestMappingDelete, self).setUp() + self.mapping_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.MAPPING_RESPONSE), + loaded=True) - def test_delete_mapping(self): - arglist = [ - identity_fakes.mapping_id - ] - verifylist = [ - ('mapping', identity_fakes.mapping_id) - ] + self.mapping_mock.delete.return_value = None + self.cmd = mapping.DeleteMapping(self.app, None) - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.cmd.take_action(parsed_args) - self.mapping_mock.delete.assert_called_with( - identity_fakes.mapping_id) + def test_delete_mapping(self): + arglist = [ + identity_fakes.mapping_id + ] + verifylist = [ + ('mapping', identity_fakes.mapping_id) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + self.mapping_mock.delete.assert_called_with( + identity_fakes.mapping_id) class TestMappingList(TestMapping): + def setUp(self): super(TestMappingList, self).setUp() self.mapping_mock.get.return_value = fakes.FakeResource( @@ -141,6 +144,7 @@ class TestMappingList(TestMapping): class TestMappingShow(TestMapping): + def setUp(self): super(TestMappingShow, self).setUp() diff --git a/openstackclient/tests/identity/v3/test_project.py b/openstackclient/tests/identity/v3/test_project.py index 36540201..b834e943 100644 --- a/openstackclient/tests/identity/v3/test_project.py +++ b/openstackclient/tests/identity/v3/test_project.py @@ -83,7 +83,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -125,7 +127,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -159,7 +163,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -225,7 +231,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -258,7 +266,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -290,7 +300,9 @@ class TestProjectCreate(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -464,7 +476,9 @@ class TestProjectList(TestProject): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.projects_mock.list.assert_called_with() @@ -480,7 +494,9 @@ class TestProjectList(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.projects_mock.list.assert_called_with() @@ -511,7 +527,9 @@ class TestProjectList(TestProject): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.projects_mock.list.assert_called_with( domain=identity_fakes.domain_id) @@ -737,7 +755,9 @@ class TestProjectShow(TestProject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.projects_mock.get.assert_called_with( identity_fakes.project_id, diff --git a/openstackclient/tests/identity/v3/test_region.py b/openstackclient/tests/identity/v3/test_region.py index 9ac9ddf8..f5f50793 100644 --- a/openstackclient/tests/identity/v3/test_region.py +++ b/openstackclient/tests/identity/v3/test_region.py @@ -64,7 +64,9 @@ class TestRegionCreate(TestRegion): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -89,7 +91,9 @@ class TestRegionCreate(TestRegion): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -116,7 +120,9 @@ class TestRegionCreate(TestRegion): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -193,7 +199,9 @@ class TestRegionList(TestRegion): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.regions_mock.list.assert_called_with() @@ -209,7 +217,9 @@ class TestRegionList(TestRegion): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.regions_mock.list.assert_called_with( parent_region_id=identity_fakes.region_parent_region_id) @@ -316,7 +326,9 @@ class TestRegionShow(TestRegion): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.regions_mock.get.assert_called_with( identity_fakes.region_id, diff --git a/openstackclient/tests/identity/v3/test_role.py b/openstackclient/tests/identity/v3/test_role.py index 1910c874..f3661324 100644 --- a/openstackclient/tests/identity/v3/test_role.py +++ b/openstackclient/tests/identity/v3/test_role.py @@ -258,7 +258,9 @@ class TestRoleCreate(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -304,7 +306,6 @@ class TestRoleDelete(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) self.roles_mock.delete.assert_called_with( @@ -365,7 +366,9 @@ class TestRoleList(TestRole): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.roles_mock.list.assert_called_with() @@ -384,7 +387,9 @@ class TestRoleList(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -410,7 +415,9 @@ class TestRoleList(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -438,7 +445,9 @@ class TestRoleList(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -473,7 +482,9 @@ class TestRoleList(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -508,7 +519,9 @@ class TestRoleList(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -543,7 +556,9 @@ class TestRoleList(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -625,7 +640,6 @@ class TestRoleRemove(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -658,7 +672,6 @@ class TestRoleRemove(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -692,7 +705,6 @@ class TestRoleRemove(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -725,7 +737,6 @@ class TestRoleRemove(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -767,7 +778,6 @@ class TestRoleSet(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -804,7 +814,9 @@ class TestRoleShow(TestRole): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # RoleManager.get(role) diff --git a/openstackclient/tests/identity/v3/test_role_assignment.py b/openstackclient/tests/identity/v3/test_role_assignment.py index 5723a334..8956b74f 100644 --- a/openstackclient/tests/identity/v3/test_role_assignment.py +++ b/openstackclient/tests/identity/v3/test_role_assignment.py @@ -86,7 +86,9 @@ class TestRoleAssignmentList(TestRoleAssignment): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.role_assignments_mock.list.assert_called_with( @@ -96,7 +98,8 @@ class TestRoleAssignmentList(TestRoleAssignment): role=None, user=None, project=None, - os_inherit_extension_inherited_to=None) + os_inherit_extension_inherited_to=None, + include_names=False) self.assertEqual(self.columns, columns) datalist = (( @@ -143,10 +146,13 @@ class TestRoleAssignmentList(TestRoleAssignment): ('role', None), ('effective', False), ('inherited', False), + ('names', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.role_assignments_mock.list.assert_called_with( @@ -156,7 +162,8 @@ class TestRoleAssignmentList(TestRoleAssignment): project=None, role=None, effective=False, - os_inherit_extension_inherited_to=None) + os_inherit_extension_inherited_to=None, + include_names=False) self.assertEqual(self.columns, columns) datalist = (( @@ -203,10 +210,13 @@ class TestRoleAssignmentList(TestRoleAssignment): ('role', None), ('effective', False), ('inherited', False), + ('names', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.role_assignments_mock.list.assert_called_with( @@ -216,7 +226,8 @@ class TestRoleAssignmentList(TestRoleAssignment): project=None, role=None, user=None, - os_inherit_extension_inherited_to=None) + os_inherit_extension_inherited_to=None, + include_names=False) self.assertEqual(self.columns, columns) datalist = (( @@ -263,10 +274,13 @@ class TestRoleAssignmentList(TestRoleAssignment): ('role', None), ('effective', False), ('inherited', False), + ('names', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.role_assignments_mock.list.assert_called_with( @@ -276,7 +290,8 @@ class TestRoleAssignmentList(TestRoleAssignment): project=None, role=None, user=None, - os_inherit_extension_inherited_to=None) + os_inherit_extension_inherited_to=None, + include_names=False) self.assertEqual(self.columns, columns) datalist = (( @@ -323,10 +338,13 @@ class TestRoleAssignmentList(TestRoleAssignment): ('role', None), ('effective', False), ('inherited', False), + ('names', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.role_assignments_mock.list.assert_called_with( @@ -336,7 +354,8 @@ class TestRoleAssignmentList(TestRoleAssignment): project=self.projects_mock.get(), role=None, user=None, - os_inherit_extension_inherited_to=None) + os_inherit_extension_inherited_to=None, + include_names=False) self.assertEqual(self.columns, columns) datalist = (( @@ -381,10 +400,13 @@ class TestRoleAssignmentList(TestRoleAssignment): ('role', None), ('effective', True), ('inherited', False), + ('names', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.role_assignments_mock.list.assert_called_with( @@ -394,7 +416,8 @@ class TestRoleAssignmentList(TestRoleAssignment): project=None, role=None, user=None, - os_inherit_extension_inherited_to=None) + os_inherit_extension_inherited_to=None, + include_names=False) self.assertEqual(self.columns, columns) datalist = (( @@ -441,10 +464,13 @@ class TestRoleAssignmentList(TestRoleAssignment): ('role', None), ('effective', False), ('inherited', True), + ('names', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.role_assignments_mock.list.assert_called_with( @@ -454,7 +480,8 @@ class TestRoleAssignmentList(TestRoleAssignment): project=None, role=None, user=None, - os_inherit_extension_inherited_to='projects') + os_inherit_extension_inherited_to='projects', + include_names=False) self.assertEqual(self.columns, columns) datalist = (( @@ -472,3 +499,72 @@ class TestRoleAssignmentList(TestRoleAssignment): True ),) self.assertEqual(datalist, tuple(data)) + + def test_role_assignment_list_include_names(self): + + self.role_assignments_mock.list.return_value = [ + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes + .ASSIGNMENT_WITH_PROJECT_ID_AND_USER_ID_INCLUDE_NAMES), + loaded=True, + ), + fakes.FakeResource( + None, + copy.deepcopy( + identity_fakes + .ASSIGNMENT_WITH_DOMAIN_ID_AND_USER_ID_INCLUDE_NAMES), + loaded=True, + ), + ] + + arglist = ['--names'] + verifylist = [ + ('user', None), + ('group', None), + ('domain', None), + ('project', None), + ('role', None), + ('effective', False), + ('inherited', False), + ('names', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + + # This test will not run correctly until the patch in the python + # client is merged. Once that is done 'data' should return the + # correct information + columns, data = self.cmd.take_action(parsed_args) + + self.role_assignments_mock.list.assert_called_with( + domain=None, + group=None, + effective=False, + project=None, + role=None, + user=None, + os_inherit_extension_inherited_to=None, + include_names=True) + + collist = ('Role', 'User', 'Group', 'Project', 'Domain', 'Inherited') + self.assertEqual(columns, collist) + + datalist1 = (( + identity_fakes.role_name, + '@'.join([identity_fakes.user_name, identity_fakes.domain_name]), + '', + '@'.join([identity_fakes.project_name, + identity_fakes.domain_name]), + '', + False + ), (identity_fakes.role_name, + '@'.join([identity_fakes.user_name, identity_fakes.domain_name]), + '', + '', + identity_fakes.domain_name, + False + ),) + self.assertEqual(tuple(data), datalist1) diff --git a/openstackclient/tests/identity/v3/test_service.py b/openstackclient/tests/identity/v3/test_service.py index c609142c..2bc5927f 100644 --- a/openstackclient/tests/identity/v3/test_service.py +++ b/openstackclient/tests/identity/v3/test_service.py @@ -73,7 +73,9 @@ class TestServiceCreate(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ServiceManager.create(name=, type=, enabled=, **kwargs) @@ -101,7 +103,9 @@ class TestServiceCreate(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ServiceManager.create(name=, type=, enabled=, **kwargs) @@ -129,7 +133,9 @@ class TestServiceCreate(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ServiceManager.create(name=, type=, enabled=, **kwargs) @@ -157,7 +163,9 @@ class TestServiceCreate(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ServiceManager.create(name=, type=, enabled=, **kwargs) @@ -225,7 +233,9 @@ class TestServiceList(TestService): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.services_mock.list.assert_called_with() @@ -248,7 +258,9 @@ class TestServiceList(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.services_mock.list.assert_called_with() @@ -465,7 +477,9 @@ class TestServiceShow(TestService): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ServiceManager.get(id) diff --git a/openstackclient/tests/identity/v3/test_service_provider.py b/openstackclient/tests/identity/v3/test_service_provider.py index 24fa7c7b..39f779d0 100644 --- a/openstackclient/tests/identity/v3/test_service_provider.py +++ b/openstackclient/tests/identity/v3/test_service_provider.py @@ -220,7 +220,9 @@ class TestServiceProviderList(TestServiceProvider): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.service_providers_mock.list.assert_called_with() @@ -303,6 +305,7 @@ class TestServiceProviderSet(TestServiceProvider): Set Service Provider's ``enabled`` attribute to False. """ + def prepare(self): """Prepare fake return objects before the test is executed""" updated_sp = copy.deepcopy(service_fakes.SERVICE_PROVIDER) @@ -341,6 +344,7 @@ class TestServiceProviderSet(TestServiceProvider): Set Service Provider's ``enabled`` attribute to True. """ + def prepare(self): """Prepare fake return objects before the test is executed""" resources = fakes.FakeResource( diff --git a/openstackclient/tests/identity/v3/test_token.py b/openstackclient/tests/identity/v3/test_token.py index 6ad4845d..80c397bc 100644 --- a/openstackclient/tests/identity/v3/test_token.py +++ b/openstackclient/tests/identity/v3/test_token.py @@ -44,7 +44,9 @@ class TestTokenIssue(TestToken): self.sc_mock.get_token.return_value = \ identity_fakes.TOKEN_WITH_PROJECT_ID - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.sc_mock.get_token.assert_called_with() @@ -66,7 +68,9 @@ class TestTokenIssue(TestToken): self.sc_mock.get_token.return_value = \ identity_fakes.TOKEN_WITH_DOMAIN_ID - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.sc_mock.get_token.assert_called_with() @@ -80,3 +84,45 @@ class TestTokenIssue(TestToken): identity_fakes.user_id, ) self.assertEqual(datalist, data) + + def test_token_issue_with_unscoped(self): + arglist = [] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.sc_mock.get_token.return_value = \ + identity_fakes.UNSCOPED_TOKEN + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + self.sc_mock.get_token.assert_called_with() + + collist = ('expires', 'id', 'user_id') + self.assertEqual(collist, columns) + datalist = ( + identity_fakes.token_expires, + identity_fakes.token_id, + identity_fakes.user_id, + ) + self.assertEqual(datalist, data) + + +class TestTokenRevoke(TestToken): + + TOKEN = 'fob' + + def setUp(self): + super(TestTokenRevoke, self).setUp() + self.tokens_mock = self.app.client_manager.identity.tokens + self.tokens_mock.reset_mock() + self.tokens_mock.revoke_token.return_value = True + self.cmd = token.RevokeToken(self.app, None) + + def test_token_revoke(self): + arglist = [self.TOKEN] + verifylist = [('token', self.TOKEN)] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + self.tokens_mock.revoke_token.assert_called_with(self.TOKEN) diff --git a/openstackclient/tests/identity/v3/test_trust.py b/openstackclient/tests/identity/v3/test_trust.py index b90e7815..2a748872 100644 --- a/openstackclient/tests/identity/v3/test_trust.py +++ b/openstackclient/tests/identity/v3/test_trust.py @@ -81,7 +81,9 @@ class TestTrustCreate(TestTrust): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -167,7 +169,9 @@ class TestTrustList(TestTrust): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.trusts_mock.list.assert_called_with() @@ -209,7 +213,9 @@ class TestTrustShow(TestTrust): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.trusts_mock.get.assert_called_with(identity_fakes.trust_id) diff --git a/openstackclient/tests/identity/v3/test_unscoped_saml.py b/openstackclient/tests/identity/v3/test_unscoped_saml.py index 6a799094..c2f14493 100644 --- a/openstackclient/tests/identity/v3/test_unscoped_saml.py +++ b/openstackclient/tests/identity/v3/test_unscoped_saml.py @@ -52,7 +52,9 @@ class TestProjectList(TestUnscopedSAML): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.projects_mock.list.assert_called_with() @@ -101,7 +103,9 @@ class TestDomainList(TestUnscopedSAML): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.domains_mock.list.assert_called_with() diff --git a/openstackclient/tests/identity/v3/test_user.py b/openstackclient/tests/identity/v3/test_user.py index 1871ed18..3757c5f8 100644 --- a/openstackclient/tests/identity/v3/test_user.py +++ b/openstackclient/tests/identity/v3/test_user.py @@ -104,7 +104,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -141,7 +143,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -176,7 +180,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. mocker = mock.Mock() mocker.return_value = 'abc123' with mock.patch("openstackclient.common.utils.get_password", mocker): @@ -214,7 +220,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -264,7 +272,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -324,7 +334,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -367,7 +379,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -401,7 +415,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -435,7 +451,9 @@ class TestUserCreate(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -481,7 +499,6 @@ class TestUserDelete(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) self.users_mock.delete.assert_called_with( @@ -553,7 +570,9 @@ class TestUserList(TestUser): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -578,7 +597,9 @@ class TestUserList(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -603,7 +624,9 @@ class TestUserList(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -628,7 +651,9 @@ class TestUserList(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -673,7 +698,9 @@ class TestUserList(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) kwargs = { @@ -746,7 +773,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -778,7 +804,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -810,7 +835,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples mocker = mock.Mock() mocker.return_value = 'abc123' with mock.patch("openstackclient.common.utils.get_password", mocker): @@ -844,7 +868,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -875,7 +898,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -908,7 +930,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -939,7 +960,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -969,7 +989,6 @@ class TestUserSet(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -1072,7 +1091,9 @@ class TestUserShow(TestUser): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.users_mock.get.assert_called_with(identity_fakes.user_id) diff --git a/openstackclient/tests/image/v1/fakes.py b/openstackclient/tests/image/v1/fakes.py index 95a8a39c..1e49f173 100644 --- a/openstackclient/tests/image/v1/fakes.py +++ b/openstackclient/tests/image/v1/fakes.py @@ -53,6 +53,7 @@ IMAGE_data = tuple((IMAGE_output[x] for x in sorted(IMAGE_output))) class FakeImagev1Client(object): + def __init__(self, **kwargs): self.images = mock.Mock() self.images.resource_class = fakes.FakeResource(None, {}) @@ -61,6 +62,7 @@ class FakeImagev1Client(object): class TestImagev1(utils.TestCommand): + def setUp(self): super(TestImagev1, self).setUp() diff --git a/openstackclient/tests/image/v1/test_image.py b/openstackclient/tests/image/v1/test_image.py index 1e0b29aa..201105a4 100644 --- a/openstackclient/tests/image/v1/test_image.py +++ b/openstackclient/tests/image/v1/test_image.py @@ -73,7 +73,9 @@ class TestImageCreate(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ImageManager.create(name=, **) @@ -120,7 +122,9 @@ class TestImageCreate(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ImageManager.create(name=, **) @@ -172,7 +176,9 @@ class TestImageCreate(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Ensure input file is opened @@ -230,7 +236,6 @@ class TestImageDelete(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) self.images_mock.delete.assert_called_with( @@ -274,7 +279,9 @@ class TestImageList(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with( detailed=True, @@ -295,7 +302,9 @@ class TestImageList(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with( detailed=True, @@ -317,7 +326,9 @@ class TestImageList(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with( detailed=True, @@ -337,7 +348,9 @@ class TestImageList(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with( detailed=True, @@ -386,7 +399,9 @@ class TestImageList(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with( detailed=True, @@ -412,7 +427,9 @@ class TestImageList(TestImage): verifylist = [('sort', 'name:asc')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with( detailed=True, @@ -456,7 +473,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Verify update() was not called, if it was show the args @@ -517,7 +533,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -545,7 +560,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -570,7 +584,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -669,7 +682,9 @@ class TestImageShow(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.images_mock.get.assert_called_with( image_fakes.image_id, diff --git a/openstackclient/tests/image/v2/fakes.py b/openstackclient/tests/image/v2/fakes.py index 5441a3e2..3555d2d4 100644 --- a/openstackclient/tests/image/v2/fakes.py +++ b/openstackclient/tests/image/v2/fakes.py @@ -148,6 +148,7 @@ IMAGE_schema = { class FakeImagev2Client(object): + def __init__(self, **kwargs): self.images = mock.Mock() self.images.resource_class = fakes.FakeResource(None, {}) @@ -158,6 +159,7 @@ class FakeImagev2Client(object): class TestImagev2(utils.TestCommand): + def setUp(self): super(TestImagev2, self).setUp() diff --git a/openstackclient/tests/image/v2/test_image.py b/openstackclient/tests/image/v2/test_image.py index d399c9ed..b8e137f8 100644 --- a/openstackclient/tests/image/v2/test_image.py +++ b/openstackclient/tests/image/v2/test_image.py @@ -95,7 +95,9 @@ class TestImageCreate(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ImageManager.create(name=, **) @@ -156,7 +158,9 @@ class TestImageCreate(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ImageManager.create(name=, **) @@ -288,7 +292,9 @@ class TestImageCreate(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ImageManager.create(name=, **) @@ -375,14 +381,16 @@ class TestAddProjectToImage(TestImage): arglist = [ image_fakes.image_id, identity_fakes.project_id, - ] + ] verifylist = [ ('image', image_fakes.image_id), ('project', identity_fakes.project_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.image_members_mock.create.assert_called_with( image_fakes.image_id, @@ -404,7 +412,9 @@ class TestAddProjectToImage(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.image_members_mock.create.assert_called_with( image_fakes.image_id, @@ -435,7 +445,6 @@ class TestImageDelete(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) self.images_mock.delete.assert_called_with( @@ -496,7 +505,9 @@ class TestImageList(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with() @@ -515,7 +526,9 @@ class TestImageList(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with( public=True, @@ -536,7 +549,9 @@ class TestImageList(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with( private=True, @@ -557,7 +572,9 @@ class TestImageList(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with( shared=True, @@ -575,7 +592,9 @@ class TestImageList(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with() @@ -621,7 +640,9 @@ class TestImageList(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with() sf_mock.assert_called_with( @@ -644,7 +665,9 @@ class TestImageList(TestImage): verifylist = [('sort', 'name:asc')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with() si_mock.assert_called_with( @@ -730,7 +753,6 @@ class TestRemoveProjectImage(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) self.image_members_mock.delete.assert_called_with( image_fakes.image_id, @@ -750,7 +772,6 @@ class TestRemoveProjectImage(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) self.image_members_mock.delete.assert_called_with( image_fakes.image_id, @@ -808,7 +829,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -876,7 +896,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -904,7 +923,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -929,7 +947,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -963,7 +980,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -991,7 +1007,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -1015,7 +1030,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -1044,7 +1058,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -1075,7 +1088,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -1101,7 +1113,6 @@ class TestImageSet(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) kwargs = { @@ -1155,7 +1166,9 @@ class TestImageShow(TestImage): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.images_mock.get.assert_called_with( image_fakes.image_id, diff --git a/openstackclient/tests/network/test_common.py b/openstackclient/tests/network/test_common.py index a3396b9d..48608734 100644 --- a/openstackclient/tests/network/test_common.py +++ b/openstackclient/tests/network/test_common.py @@ -18,57 +18,107 @@ from openstackclient.network import common from openstackclient.tests import utils +def _add_common_argument(parser): + parser.add_argument( + 'common', + metavar='<common>', + help='Common argument', + ) + return parser + + +def _add_network_argument(parser): + parser.add_argument( + 'network', + metavar='<network>', + help='Network argument', + ) + return parser + + +def _add_compute_argument(parser): + parser.add_argument( + 'compute', + metavar='<compute>', + help='Compute argument', + ) + return parser + + class FakeNetworkAndComputeCommand(common.NetworkAndComputeCommand): + def update_parser_common(self, parser): - parser.add_argument( - 'common', - metavar='<common>', - help='Common argument', - ) - return parser + return _add_common_argument(parser) + + def update_parser_network(self, parser): + return _add_network_argument(parser) + + def update_parser_compute(self, parser): + return _add_compute_argument(parser) + + def take_action_network(self, client, parsed_args): + return client.network_action(parsed_args) + + def take_action_compute(self, client, parsed_args): + return client.compute_action(parsed_args) + + +class FakeNetworkAndComputeLister(common.NetworkAndComputeLister): + + def update_parser_common(self, parser): + return _add_common_argument(parser) + + def update_parser_network(self, parser): + return _add_network_argument(parser) + + def update_parser_compute(self, parser): + return _add_compute_argument(parser) + + def take_action_network(self, client, parsed_args): + return client.network_action(parsed_args) + + def take_action_compute(self, client, parsed_args): + return client.compute_action(parsed_args) + + +class FakeNetworkAndComputeShowOne(common.NetworkAndComputeShowOne): + + def update_parser_common(self, parser): + return _add_common_argument(parser) def update_parser_network(self, parser): - parser.add_argument( - 'network', - metavar='<network>', - help='Network argument', - ) - return parser + return _add_network_argument(parser) def update_parser_compute(self, parser): - parser.add_argument( - 'compute', - metavar='<compute>', - help='Compute argument', - ) - return parser + return _add_compute_argument(parser) def take_action_network(self, client, parsed_args): - client.network_action(parsed_args) - return 'take_action_network' + return client.network_action(parsed_args) def take_action_compute(self, client, parsed_args): - client.compute_action(parsed_args) - return 'take_action_compute' + return client.compute_action(parsed_args) + +class TestNetworkAndCompute(utils.TestCommand): -class TestNetworkAndComputeCommand(utils.TestCommand): def setUp(self): - super(TestNetworkAndComputeCommand, self).setUp() + super(TestNetworkAndCompute, self).setUp() self.namespace = argparse.Namespace() # Create network client mocks. self.app.client_manager.network = mock.Mock() self.network = self.app.client_manager.network - self.network.network_action = mock.Mock(return_value=None) + self.network.network_action = mock.Mock( + return_value='take_action_network') # Create compute client mocks. self.app.client_manager.compute = mock.Mock() self.compute = self.app.client_manager.compute - self.compute.compute_action = mock.Mock(return_value=None) + self.compute.compute_action = mock.Mock( + return_value='take_action_compute') - # Get the command object to test + # Subclasses can override the command object to test. self.cmd = FakeNetworkAndComputeCommand(self.app, self.namespace) def test_take_action_network(self): @@ -101,3 +151,24 @@ class TestNetworkAndComputeCommand(utils.TestCommand): result = self.cmd.take_action(parsed_args) self.compute.compute_action.assert_called_with(parsed_args) self.assertEqual('take_action_compute', result) + + +class TestNetworkAndComputeCommand(TestNetworkAndCompute): + + def setUp(self): + super(TestNetworkAndComputeCommand, self).setUp() + self.cmd = FakeNetworkAndComputeCommand(self.app, self.namespace) + + +class TestNetworkAndComputeLister(TestNetworkAndCompute): + + def setUp(self): + super(TestNetworkAndComputeLister, self).setUp() + self.cmd = FakeNetworkAndComputeLister(self.app, self.namespace) + + +class TestNetworkAndComputeShowOne(TestNetworkAndCompute): + + def setUp(self): + super(TestNetworkAndComputeShowOne, self).setUp() + self.cmd = FakeNetworkAndComputeShowOne(self.app, self.namespace) diff --git a/openstackclient/tests/network/v2/fakes.py b/openstackclient/tests/network/v2/fakes.py index 516995eb..cfd05729 100644 --- a/openstackclient/tests/network/v2/fakes.py +++ b/openstackclient/tests/network/v2/fakes.py @@ -51,11 +51,13 @@ def create_extension(): class FakeNetworkV2Client(object): + def __init__(self, **kwargs): self.extensions = mock.Mock(return_value=[create_extension()]) class TestNetworkV2(utils.TestCommand): + def setUp(self): super(TestNetworkV2, self).setUp() @@ -138,12 +140,11 @@ class FakeNetwork(object): router_external, status, subnets, tenant_id """ # Set default attributes. - project_id = 'project-id-' + uuid.uuid4().hex network_attrs = { 'id': 'network-id-' + uuid.uuid4().hex, 'name': 'network-name-' + uuid.uuid4().hex, 'status': 'ACTIVE', - 'tenant_id': project_id, + 'tenant_id': 'project-id-' + uuid.uuid4().hex, 'admin_state_up': True, 'shared': False, 'subnets': ['a', 'b'], @@ -169,7 +170,9 @@ class FakeNetwork(object): network = fakes.FakeResource(info=copy.deepcopy(network_attrs), methods=copy.deepcopy(network_methods), loaded=True) - network.project_id = project_id + + # Set attributes with special mapping in OpenStack SDK. + network.project_id = network_attrs['tenant_id'] return network @@ -226,7 +229,6 @@ class FakePort(object): :return: A FakeResource object, with id, name, etc. """ - # Set default attributes. port_attrs = { 'admin_state_up': True, @@ -274,7 +276,7 @@ class FakePort(object): methods=copy.deepcopy(port_methods), loaded=True) - # Set attributes with special mappings. + # Set attributes with special mappings in OpenStack SDK. port.project_id = port_attrs['tenant_id'] port.binding_host_id = port_attrs['binding:host_id'] port.binding_profile = port_attrs['binding:profile'] @@ -463,28 +465,82 @@ class FakeSecurityGroup(object): security_groups = [] for i in range(0, count): security_groups.append( - FakeRouter.create_one_security_group(attrs, methods)) + FakeSecurityGroup.create_one_security_group(attrs, methods)) return security_groups + +class FakeSecurityGroupRule(object): + """Fake one or more security group rules.""" + @staticmethod - def get_security_groups(security_groups=None, count=2): - """Get an iterable MagicMock object with a list of faked security groups. + def create_one_security_group_rule(attrs={}, methods={}): + """Create a fake security group rule. - If security group list is provided, then initialize the Mock object - with the list. Otherwise create one. + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods + :return: + A FakeResource object, with id, etc. + """ + # Set default attributes. + security_group_rule_attrs = { + 'direction': 'ingress', + 'ethertype': 'IPv4', + 'id': 'security-group-rule-id-' + uuid.uuid4().hex, + 'port_range_max': None, + 'port_range_min': None, + 'protocol': None, + 'remote_group_id': 'remote-security-group-id-' + uuid.uuid4().hex, + 'remote_ip_prefix': None, + 'security_group_id': 'security-group-id-' + uuid.uuid4().hex, + 'tenant_id': 'project-id-' + uuid.uuid4().hex, + } + + # Overwrite default attributes. + security_group_rule_attrs.update(attrs) + + # Set default methods. + security_group_rule_methods = { + 'keys': ['direction', 'ethertype', 'id', 'port_range_max', + 'port_range_min', 'protocol', 'remote_group_id', + 'remote_ip_prefix', 'security_group_id', 'tenant_id'], + } + + # Overwrite default methods. + security_group_rule_methods.update(methods) + + security_group_rule = fakes.FakeResource( + info=copy.deepcopy(security_group_rule_attrs), + methods=copy.deepcopy(security_group_rule_methods), + loaded=True) + + # Set attributes with special mappings. + security_group_rule.project_id = security_group_rule_attrs['tenant_id'] + + return security_group_rule - :param List security groups: - A list of FakeResource objects faking security groups + @staticmethod + def create_security_group_rules(attrs={}, methods={}, count=2): + """Create multiple fake security group rules. + + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods :param int count: - The number of security groups to fake + The number of security group rules to fake :return: - An iterable Mock object with side_effect set to a list of faked - security groups + A list of FakeResource objects faking the security group rules """ - if security_groups is None: - security_groups = FakeRouter.create_security_groups(count) - return mock.MagicMock(side_effect=security_groups) + security_group_rules = [] + for i in range(0, count): + security_group_rules.append( + FakeSecurityGroupRule.create_one_security_group_rule( + attrs, methods)) + + return security_group_rules class FakeSubnet(object): @@ -502,18 +558,22 @@ class FakeSubnet(object): A FakeResource object faking the subnet """ # Set default attributes. + project_id = 'project-id-' + uuid.uuid4().hex subnet_attrs = { 'id': 'subnet-id-' + uuid.uuid4().hex, 'name': 'subnet-name-' + uuid.uuid4().hex, 'network_id': 'network-id-' + uuid.uuid4().hex, 'cidr': '10.10.10.0/24', - 'tenant_id': 'project-id-' + uuid.uuid4().hex, + 'tenant_id': project_id, 'enable_dhcp': True, 'dns_nameservers': [], 'allocation_pools': [], 'host_routes': [], 'ip_version': '4', 'gateway_ip': '10.10.10.1', + 'ipv6_address_mode': 'None', + 'ipv6_ra_mode': 'None', + 'subnetpool_id': 'None', } # Overwrite default attributes. @@ -523,7 +583,8 @@ class FakeSubnet(object): subnet_methods = { 'keys': ['id', 'name', 'network_id', 'cidr', 'enable_dhcp', 'allocation_pools', 'dns_nameservers', 'gateway_ip', - 'host_routes', 'ip_version', 'tenant_id'] + 'host_routes', 'ip_version', 'tenant_id', + 'ipv6_address_mode', 'ipv6_ra_mode', 'subnetpool_id'] } # Overwrite default methods. @@ -532,6 +593,8 @@ class FakeSubnet(object): subnet = fakes.FakeResource(info=copy.deepcopy(subnet_attrs), methods=copy.deepcopy(subnet_methods), loaded=True) + # Set attributes with special mappings in OpenStack SDK. + subnet.project_id = subnet_attrs['tenant_id'] return subnet @@ -553,3 +616,173 @@ class FakeSubnet(object): subnets.append(FakeSubnet.create_one_subnet(attrs, methods)) return subnets + + +class FakeFloatingIP(object): + """Fake one or more floating ip.""" + + @staticmethod + def create_one_floating_ip(attrs={}, methods={}): + """Create a fake floating ip. + + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods + :return: + A FakeResource object, with id, ip, and so on + """ + # Set default attributes. + floating_ip_attrs = { + 'id': 'floating-ip-id-' + uuid.uuid4().hex, + 'floating_ip_address': '1.0.9.0', + 'fixed_ip_address': '2.0.9.0', + 'dns_domain': None, + 'dns_name': None, + 'status': 'DOWN', + 'floating_network_id': 'network-id-' + uuid.uuid4().hex, + 'router_id': 'router-id-' + uuid.uuid4().hex, + 'port_id': 'port-id-' + uuid.uuid4().hex, + 'tenant_id': 'project-id-' + uuid.uuid4().hex, + } + + # Overwrite default attributes. + floating_ip_attrs.update(attrs) + + # Set default methods. + floating_ip_methods = { + 'keys': ['id', 'floating_ip_address', 'fixed_ip_address', + 'dns_domain', 'dns_name', 'status', 'router_id', + 'floating_network_id', 'port_id', 'tenant_id'] + } + + # Overwrite default methods. + floating_ip_methods.update(methods) + + floating_ip = fakes.FakeResource( + info=copy.deepcopy(floating_ip_attrs), + methods=copy.deepcopy(floating_ip_methods), + loaded=True + ) + + # Set attributes with special mappings in OpenStack SDK. + floating_ip.project_id = floating_ip_attrs['tenant_id'] + + return floating_ip + + @staticmethod + def create_floating_ips(attrs={}, methods={}, count=2): + """Create multiple fake floating ips. + + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods + :param int count: + The number of floating ips to fake + :return: + A list of FakeResource objects faking the floating ips + """ + floating_ips = [] + for i in range(0, count): + floating_ips.append(FakeFloatingIP.create_one_floating_ip( + attrs, + methods + )) + return floating_ips + + @staticmethod + def get_floating_ips(floating_ips=None, count=2): + """Get an iterable MagicMock object with a list of faked floating ips. + + If floating_ips list is provided, then initialize the Mock object + with the list. Otherwise create one. + + :param List floating ips: + A list of FakeResource objects faking floating ips + :param int count: + The number of floating ips to fake + :return: + An iterable Mock object with side_effect set to a list of faked + floating ips + """ + if floating_ips is None: + floating_ips = FakeFloatingIP.create_floating_ips(count) + return mock.MagicMock(side_effect=floating_ips) + + +class FakeSubnetPool(object): + """Fake one or more subnet pools.""" + + @staticmethod + def create_one_subnet_pool(attrs={}, methods={}): + """Create a fake subnet pool. + + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods + :return: + A FakeResource object faking the subnet pool + """ + # Set default attributes. + subnet_pool_attrs = { + 'id': 'subnet-pool-id-' + uuid.uuid4().hex, + 'name': 'subnet-pool-name-' + uuid.uuid4().hex, + 'prefixes': ['10.0.0.0/24', '10.1.0.0/24'], + 'default_prefixlen': 8, + 'address_scope_id': 'address-scope-id-' + uuid.uuid4().hex, + 'tenant_id': 'project-id-' + uuid.uuid4().hex, + 'is_default': False, + 'shared': False, + 'max_prefixlen': 32, + 'min_prefixlen': 8, + 'default_quota': None, + 'ip_version': 4, + } + + # Overwrite default attributes. + subnet_pool_attrs.update(attrs) + + # Set default methods. + subnet_pool_methods = { + 'keys': ['id', 'name', 'prefixes', 'default_prefixlen', + 'address_scope_id', 'tenant_id', 'is_default', + 'shared', 'max_prefixlen', 'min_prefixlen', + 'default_quota', 'ip_version'] + } + + # Overwrite default methods. + subnet_pool_methods.update(methods) + + subnet_pool = fakes.FakeResource( + info=copy.deepcopy(subnet_pool_attrs), + methods=copy.deepcopy(subnet_pool_methods), + loaded=True + ) + + # Set attributes with special mapping in OpenStack SDK. + subnet_pool.project_id = subnet_pool_attrs['tenant_id'] + + return subnet_pool + + @staticmethod + def create_subnet_pools(attrs={}, methods={}, count=2): + """Create multiple fake subnet pools. + + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods + :param int count: + The number of subnet pools to fake + :return: + A list of FakeResource objects faking the subnet pools + """ + subnet_pools = [] + for i in range(0, count): + subnet_pools.append( + FakeSubnetPool.create_one_subnet_pool(attrs, methods) + ) + + return subnet_pools diff --git a/openstackclient/tests/network/v2/test_floating_ip.py b/openstackclient/tests/network/v2/test_floating_ip.py new file mode 100644 index 00000000..1c1088a3 --- /dev/null +++ b/openstackclient/tests/network/v2/test_floating_ip.py @@ -0,0 +1,296 @@ +# 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. +# + +import mock + +from openstackclient.network.v2 import floating_ip +from openstackclient.tests.compute.v2 import fakes as compute_fakes +from openstackclient.tests.network.v2 import fakes as network_fakes + + +# Tests for Neutron network +# +class TestFloatingIPNetwork(network_fakes.TestNetworkV2): + + def setUp(self): + super(TestFloatingIPNetwork, self).setUp() + + # Get a shortcut to the network client + self.network = self.app.client_manager.network + + +class TestDeleteFloatingIPNetwork(TestFloatingIPNetwork): + + # The floating ip to be deleted. + floating_ip = network_fakes.FakeFloatingIP.create_one_floating_ip() + + def setUp(self): + super(TestDeleteFloatingIPNetwork, self).setUp() + + self.network.delete_ip = mock.Mock(return_value=None) + self.network.find_ip = mock.Mock(return_value=self.floating_ip) + + # Get the command object to test + self.cmd = floating_ip.DeleteFloatingIP(self.app, self.namespace) + + def test_floating_ip_delete(self): + arglist = [ + self.floating_ip.id, + ] + verifylist = [ + ('floating_ip', self.floating_ip.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.network.find_ip.assert_called_with(self.floating_ip.id) + self.network.delete_ip.assert_called_with(self.floating_ip) + self.assertIsNone(result) + + +class TestListFloatingIPNetwork(TestFloatingIPNetwork): + + # The floating ips to list up + floating_ips = network_fakes.FakeFloatingIP.create_floating_ips(count=3) + + columns = ( + 'ID', + 'Floating IP Address', + 'Fixed IP Address', + 'Port', + ) + + data = [] + for ip in floating_ips: + data.append(( + ip.id, + ip.floating_ip_address, + ip.fixed_ip_address, + ip.port_id, + )) + + def setUp(self): + super(TestListFloatingIPNetwork, self).setUp() + + self.network.ips = mock.Mock(return_value=self.floating_ips) + + # Get the command object to test + self.cmd = floating_ip.ListFloatingIP(self.app, self.namespace) + + def test_floating_ip_list(self): + arglist = [] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.ips.assert_called_with(**{}) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + +class TestShowFloatingIPNetwork(TestFloatingIPNetwork): + + # The floating ip to display. + floating_ip = network_fakes.FakeFloatingIP.create_one_floating_ip() + + columns = ( + 'dns_domain', + 'dns_name', + 'fixed_ip_address', + 'floating_ip_address', + 'floating_network_id', + 'id', + 'port_id', + 'project_id', + 'router_id', + 'status', + ) + + data = ( + floating_ip.dns_domain, + floating_ip.dns_name, + floating_ip.fixed_ip_address, + floating_ip.floating_ip_address, + floating_ip.floating_network_id, + floating_ip.id, + floating_ip.port_id, + floating_ip.tenant_id, + floating_ip.router_id, + floating_ip.status, + ) + + def setUp(self): + super(TestShowFloatingIPNetwork, self).setUp() + + self.network.find_ip = mock.Mock(return_value=self.floating_ip) + + # Get the command object to test + self.cmd = floating_ip.ShowFloatingIP(self.app, self.namespace) + + def test_floating_ip_show(self): + arglist = [ + self.floating_ip.id, + ] + verifylist = [ + ('floating_ip', self.floating_ip.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.find_ip.assert_called_with( + self.floating_ip.id, + ignore_missing=False + ) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + +# Tests for Nova network +# +class TestFloatingIPCompute(compute_fakes.TestComputev2): + + def setUp(self): + super(TestFloatingIPCompute, self).setUp() + + # Get a shortcut to the compute client + self.compute = self.app.client_manager.compute + + +class TestDeleteFloatingIPCompute(TestFloatingIPCompute): + + # The floating ip to be deleted. + floating_ip = compute_fakes.FakeFloatingIP.create_one_floating_ip() + + def setUp(self): + super(TestDeleteFloatingIPCompute, self).setUp() + + self.app.client_manager.network_endpoint_enabled = False + + self.compute.floating_ips.delete.return_value = None + + # Return value of utils.find_resource() + self.compute.floating_ips.get.return_value = self.floating_ip + + # Get the command object to test + self.cmd = floating_ip.DeleteFloatingIP(self.app, None) + + def test_floating_ip_delete(self): + arglist = [ + self.floating_ip.id, + ] + verifylist = [ + ('floating_ip', self.floating_ip.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.compute.floating_ips.delete.assert_called_with( + self.floating_ip.id + ) + self.assertIsNone(result) + + +class TestListFloatingIPCompute(TestFloatingIPCompute): + + # The floating ips to be list up + floating_ips = compute_fakes.FakeFloatingIP.create_floating_ips(count=3) + + columns = ( + 'ID', + 'Floating IP Address', + 'Fixed IP Address', + 'Server', + 'Pool', + ) + + data = [] + for ip in floating_ips: + data.append(( + ip.id, + ip.ip, + ip.fixed_ip, + ip.instance_id, + ip.pool, + )) + + def setUp(self): + super(TestListFloatingIPCompute, self).setUp() + + self.app.client_manager.network_endpoint_enabled = False + + self.compute.floating_ips.list.return_value = self.floating_ips + + # Get the command object to test + self.cmd = floating_ip.ListFloatingIP(self.app, None) + + def test_floating_ip_list(self): + arglist = [] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.compute.floating_ips.list.assert_called_with() + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + +class TestShowFloatingIPCompute(TestFloatingIPCompute): + + # The floating ip to display. + floating_ip = compute_fakes.FakeFloatingIP.create_one_floating_ip() + + columns = ( + 'fixed_ip', + 'id', + 'instance_id', + 'ip', + 'pool', + ) + + data = ( + floating_ip.fixed_ip, + floating_ip.id, + floating_ip.instance_id, + floating_ip.ip, + floating_ip.pool, + ) + + def setUp(self): + super(TestShowFloatingIPCompute, self).setUp() + + self.app.client_manager.network_endpoint_enabled = False + + # Return value of utils.find_resource() + self.compute.floating_ips.get.return_value = self.floating_ip + + # Get the command object to test + self.cmd = floating_ip.ShowFloatingIP(self.app, None) + + def test_floating_ip_show(self): + arglist = [ + self.floating_ip.id, + ] + verifylist = [ + ('floating_ip', self.floating_ip.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) diff --git a/openstackclient/tests/network/v2/test_network.py b/openstackclient/tests/network/v2/test_network.py index f96497a4..26a9da40 100644 --- a/openstackclient/tests/network/v2/test_network.py +++ b/openstackclient/tests/network/v2/test_network.py @@ -17,6 +17,7 @@ import mock from openstackclient.common import exceptions from openstackclient.common import utils from openstackclient.network.v2 import network +from openstackclient.tests.compute.v2 import fakes as compute_fakes from openstackclient.tests import fakes from openstackclient.tests.identity.v2_0 import fakes as identity_fakes_v2 from openstackclient.tests.identity.v3 import fakes as identity_fakes_v3 @@ -24,6 +25,8 @@ from openstackclient.tests.network.v2 import fakes as network_fakes from openstackclient.tests import utils as tests_utils +# Tests for Neutron network +# class TestNetwork(network_fakes.TestNetworkV2): def setUp(self): @@ -103,11 +106,9 @@ class TestCreateNetworkIdentityV3(TestNetwork): arglist = [] verifylist = [] - try: - # Missing required args should bail here - self.check_parser(self.cmd, arglist, verifylist) - except tests_utils.ParserException: - pass + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) def test_create_default_options(self): arglist = [ @@ -380,7 +381,9 @@ class TestListNetwork(TestNetwork): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.network.networks.assert_called_with() @@ -397,7 +400,9 @@ class TestListNetwork(TestNetwork): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.network.networks.assert_called_with( @@ -416,7 +421,9 @@ class TestListNetwork(TestNetwork): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.network.networks.assert_called_with() @@ -447,7 +454,7 @@ class TestSetNetwork(TestNetwork): '--share', ] verifylist = [ - ('identifier', self._network.name), + ('network', self._network.name), ('admin_state', True), ('name', 'noob'), ('shared', True), @@ -471,7 +478,7 @@ class TestSetNetwork(TestNetwork): '--no-share', ] verifylist = [ - ('identifier', self._network.name), + ('network', self._network.name), ('admin_state', False), ('shared', False), ] @@ -488,7 +495,7 @@ class TestSetNetwork(TestNetwork): def test_set_nothing(self): arglist = [self._network.name, ] - verifylist = [('identifier', self._network.name), ] + verifylist = [('network', self._network.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises(exceptions.CommandError, self.cmd.take_action, @@ -497,7 +504,7 @@ class TestSetNetwork(TestNetwork): class TestShowNetwork(TestNetwork): - # The network to set. + # The network to show. _network = network_fakes.FakeNetwork.create_one_network() columns = ( @@ -536,18 +543,16 @@ class TestShowNetwork(TestNetwork): arglist = [] verifylist = [] - try: - # Missing required args should bail here - self.check_parser(self.cmd, arglist, verifylist) - except tests_utils.ParserException: - pass + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) def test_show_all_options(self): arglist = [ self._network.name, ] verifylist = [ - ('identifier', self._network.name), + ('network', self._network.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -558,3 +563,203 @@ class TestShowNetwork(TestNetwork): self.assertEqual(tuple(self.columns), columns) self.assertEqual(list(self.data), list(data)) + + +# Tests for Nova network +# +class TestNetworkCompute(compute_fakes.TestComputev2): + + def setUp(self): + super(TestNetworkCompute, self).setUp() + + # Get a shortcut to the compute client + self.compute = self.app.client_manager.compute + + +class TestDeleteNetworkCompute(TestNetworkCompute): + + # The network to delete. + _network = compute_fakes.FakeNetwork.create_one_network() + + def setUp(self): + super(TestDeleteNetworkCompute, self).setUp() + + self.app.client_manager.network_endpoint_enabled = False + + self.compute.networks.delete.return_value = None + + # Return value of utils.find_resource() + self.compute.networks.get.return_value = self._network + + # Get the command object to test + self.cmd = network.DeleteNetwork(self.app, None) + + def test_network_delete(self): + arglist = [ + self._network.label, + ] + verifylist = [ + ('network', [self._network.label]), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.compute.networks.delete.assert_called_with(self._network.id) + self.assertIsNone(result) + + +class TestListNetworkCompute(TestNetworkCompute): + + # The networks going to be listed up. + _networks = compute_fakes.FakeNetwork.create_networks(count=3) + + columns = ( + 'ID', + 'Name', + 'Subnet', + ) + + data = [] + for net in _networks: + data.append(( + net.id, + net.label, + net.cidr, + )) + + def setUp(self): + super(TestListNetworkCompute, self).setUp() + + self.app.client_manager.network_endpoint_enabled = False + + self.compute.networks.list.return_value = self._networks + + # Get the command object to test + self.cmd = network.ListNetwork(self.app, None) + + def test_network_list_no_options(self): + arglist = [] + verifylist = [ + ('external', False), + ('long', False), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. + columns, data = self.cmd.take_action(parsed_args) + + self.compute.networks.list.assert_called_with() + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + +class TestShowNetworkCompute(TestNetworkCompute): + + # The network to show. + _network = compute_fakes.FakeNetwork.create_one_network() + + columns = ( + 'bridge', + 'bridge_interface', + 'broadcast', + 'cidr', + 'cidr_v6', + 'created_at', + 'deleted', + 'deleted_at', + 'dhcp_server', + 'dhcp_start', + 'dns1', + 'dns2', + 'enable_dhcp', + 'gateway', + 'gateway_v6', + 'host', + 'id', + 'injected', + 'label', + 'mtu', + 'multi_host', + 'netmask', + 'netmask_v6', + 'priority', + 'project_id', + 'rxtx_base', + 'share_address', + 'updated_at', + 'vlan', + 'vpn_private_address', + 'vpn_public_address', + 'vpn_public_port', + ) + + data = ( + _network.bridge, + _network.bridge_interface, + _network.broadcast, + _network.cidr, + _network.cidr_v6, + _network.created_at, + _network.deleted, + _network.deleted_at, + _network.dhcp_server, + _network.dhcp_start, + _network.dns1, + _network.dns2, + _network.enable_dhcp, + _network.gateway, + _network.gateway_v6, + _network.host, + _network.id, + _network.injected, + _network.label, + _network.mtu, + _network.multi_host, + _network.netmask, + _network.netmask_v6, + _network.priority, + _network.project_id, + _network.rxtx_base, + _network.share_address, + _network.updated_at, + _network.vlan, + _network.vpn_private_address, + _network.vpn_public_address, + _network.vpn_public_port, + ) + + def setUp(self): + super(TestShowNetworkCompute, self).setUp() + + self.app.client_manager.network_endpoint_enabled = False + + # Return value of utils.find_resource() + self.compute.networks.get.return_value = self._network + + # Get the command object to test + self.cmd = network.ShowNetwork(self.app, None) + + def test_show_no_options(self): + arglist = [] + verifylist = [] + + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_show_all_options(self): + arglist = [ + self._network.label, + ] + verifylist = [ + ('network', self._network.label), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.assertEqual(self.columns, tuple(columns)) + self.assertEqual(self.data, data) diff --git a/openstackclient/tests/network/v2/test_router.py b/openstackclient/tests/network/v2/test_router.py index 98e9f17a..05bb7857 100644 --- a/openstackclient/tests/network/v2/test_router.py +++ b/openstackclient/tests/network/v2/test_router.py @@ -63,10 +63,9 @@ class TestCreateRouter(TestRouter): arglist = [] verifylist = [] - try: - self.check_parser(self.cmd, arglist, verifylist) - except tests_utils.ParserException: - pass + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) def test_create_default_options(self): arglist = [ @@ -201,7 +200,9 @@ class TestListRouter(TestRouter): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.network.routers.assert_called_with() @@ -217,7 +218,9 @@ class TestListRouter(TestRouter): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.network.routers.assert_called_with() @@ -299,11 +302,9 @@ class TestSetRouter(TestRouter): ('distributed', False), ] - try: - # Argument parse failing should bail here - self.check_parser(self.cmd, arglist, verifylist) - except tests_utils.ParserException: - pass + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) def test_set_nothing(self): arglist = [self._router.name, ] @@ -349,11 +350,9 @@ class TestShowRouter(TestRouter): arglist = [] verifylist = [] - try: - # Missing required args should bail here - self.check_parser(self.cmd, arglist, verifylist) - except tests_utils.ParserException: - pass + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) def test_show_all_options(self): arglist = [ diff --git a/openstackclient/tests/network/v2/test_security_group.py b/openstackclient/tests/network/v2/test_security_group.py index 98388ec7..72da1400 100644 --- a/openstackclient/tests/network/v2/test_security_group.py +++ b/openstackclient/tests/network/v2/test_security_group.py @@ -61,7 +61,7 @@ class TestDeleteSecurityGroupNetwork(TestSecurityGroup): self.network.delete_security_group.assert_called_with( self._security_group) - self.assertEqual(None, result) + self.assertIsNone(result) class TestDeleteSecurityGroupCompute(TestSecurityGroup): @@ -96,4 +96,4 @@ class TestDeleteSecurityGroupCompute(TestSecurityGroup): self.compute.security_groups.delete.assert_called_with( self._security_group.id) - self.assertEqual(None, result) + self.assertIsNone(result) diff --git a/openstackclient/tests/network/v2/test_security_group_rule.py b/openstackclient/tests/network/v2/test_security_group_rule.py new file mode 100644 index 00000000..db15d0e2 --- /dev/null +++ b/openstackclient/tests/network/v2/test_security_group_rule.py @@ -0,0 +1,212 @@ +# 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. +# + +import copy +import mock + +from openstackclient.network.v2 import security_group_rule +from openstackclient.tests.compute.v2 import fakes as compute_fakes +from openstackclient.tests import fakes +from openstackclient.tests.network.v2 import fakes as network_fakes +from openstackclient.tests import utils as tests_utils + + +class TestSecurityGroupRuleNetwork(network_fakes.TestNetworkV2): + + def setUp(self): + super(TestSecurityGroupRuleNetwork, self).setUp() + + # Get a shortcut to the network client + self.network = self.app.client_manager.network + + +class TestSecurityGroupRuleCompute(compute_fakes.TestComputev2): + + def setUp(self): + super(TestSecurityGroupRuleCompute, self).setUp() + + # Get a shortcut to the network client + self.compute = self.app.client_manager.compute + + +class TestDeleteSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): + + # The security group rule to be deleted. + _security_group_rule = \ + network_fakes.FakeSecurityGroupRule.create_one_security_group_rule() + + def setUp(self): + super(TestDeleteSecurityGroupRuleNetwork, self).setUp() + + self.network.delete_security_group_rule = mock.Mock(return_value=None) + + self.network.find_security_group_rule = mock.Mock( + return_value=self._security_group_rule) + + # Get the command object to test + self.cmd = security_group_rule.DeleteSecurityGroupRule( + self.app, self.namespace) + + def test_security_group_rule_delete(self): + arglist = [ + self._security_group_rule.id, + ] + verifylist = [ + ('rule', self._security_group_rule.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.network.delete_security_group_rule.assert_called_with( + self._security_group_rule) + self.assertIsNone(result) + + +class TestDeleteSecurityGroupRuleCompute(TestSecurityGroupRuleCompute): + + # The security group rule to be deleted. + _security_group_rule = \ + compute_fakes.FakeSecurityGroupRule.create_one_security_group_rule() + + def setUp(self): + super(TestDeleteSecurityGroupRuleCompute, self).setUp() + + self.app.client_manager.network_endpoint_enabled = False + + # Get the command object to test + self.cmd = security_group_rule.DeleteSecurityGroupRule(self.app, None) + + def test_security_group_rule_delete(self): + arglist = [ + self._security_group_rule.id, + ] + verifylist = [ + ('rule', self._security_group_rule.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.compute.security_group_rules.delete.assert_called_with( + self._security_group_rule.id) + self.assertIsNone(result) + + +class TestShowSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): + + # The security group rule to be shown. + _security_group_rule = \ + network_fakes.FakeSecurityGroupRule.create_one_security_group_rule() + + columns = ( + 'direction', + 'ethertype', + 'id', + 'port_range_max', + 'port_range_min', + 'project_id', + 'protocol', + 'remote_group_id', + 'remote_ip_prefix', + 'security_group_id', + ) + + data = ( + _security_group_rule.direction, + _security_group_rule.ethertype, + _security_group_rule.id, + _security_group_rule.port_range_max, + _security_group_rule.port_range_min, + _security_group_rule.project_id, + _security_group_rule.protocol, + _security_group_rule.remote_group_id, + _security_group_rule.remote_ip_prefix, + _security_group_rule.security_group_id, + ) + + def setUp(self): + super(TestShowSecurityGroupRuleNetwork, self).setUp() + + self.network.find_security_group_rule = mock.Mock( + return_value=self._security_group_rule) + + # Get the command object to test + self.cmd = security_group_rule.ShowSecurityGroupRule( + self.app, self.namespace) + + def test_show_no_options(self): + self.assertRaises(tests_utils.ParserException, + self.check_parser, self.cmd, [], []) + + def test_show_all_options(self): + arglist = [ + self._security_group_rule.id, + ] + verifylist = [ + ('rule', self._security_group_rule.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.find_security_group_rule.assert_called_with( + self._security_group_rule.id, ignore_missing=False) + self.assertEqual(tuple(self.columns), columns) + self.assertEqual(self.data, data) + + +class TestShowSecurityGroupRuleCompute(TestSecurityGroupRuleCompute): + + # The security group rule to be shown. + _security_group_rule = \ + compute_fakes.FakeSecurityGroupRule.create_one_security_group_rule() + + columns, data = \ + security_group_rule._format_security_group_rule_show( + _security_group_rule._info) + + def setUp(self): + super(TestShowSecurityGroupRuleCompute, self).setUp() + + self.app.client_manager.network_endpoint_enabled = False + + # Build a security group fake customized for this test. + security_group_rules = [self._security_group_rule._info] + security_group = fakes.FakeResource( + info=copy.deepcopy({'rules': security_group_rules}), + loaded=True) + security_group.rules = security_group_rules + self.compute.security_groups.list.return_value = [security_group] + + # Get the command object to test + self.cmd = security_group_rule.ShowSecurityGroupRule(self.app, None) + + def test_show_no_options(self): + self.assertRaises(tests_utils.ParserException, + self.check_parser, self.cmd, [], []) + + def test_show_all_options(self): + arglist = [ + self._security_group_rule.id, + ] + verifylist = [ + ('rule', self._security_group_rule.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.compute.security_groups.list.assert_called_with() + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) diff --git a/openstackclient/tests/network/v2/test_subnet.py b/openstackclient/tests/network/v2/test_subnet.py index 5fca5edd..e1e663f4 100644 --- a/openstackclient/tests/network/v2/test_subnet.py +++ b/openstackclient/tests/network/v2/test_subnet.py @@ -16,9 +16,11 @@ import mock from openstackclient.common import utils from openstackclient.network.v2 import subnet as subnet_v2 from openstackclient.tests.network.v2 import fakes as network_fakes +from openstackclient.tests import utils as tests_utils class TestSubnet(network_fakes.TestNetworkV2): + def setUp(self): super(TestSubnet, self).setUp() @@ -106,3 +108,76 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_with() self.assertEqual(self.columns_long, columns) self.assertEqual(self.data_long, list(data)) + + +class TestShowSubnet(TestSubnet): + # The subnets to be shown + _subnet = network_fakes.FakeSubnet.create_one_subnet() + + columns = ( + 'allocation_pools', + 'cidr', + 'dns_nameservers', + 'enable_dhcp', + 'gateway_ip', + 'host_routes', + 'id', + 'ip_version', + 'ipv6_address_mode', + 'ipv6_ra_mode', + 'name', + 'network_id', + 'project_id', + 'subnetpool_id', + ) + + data = ( + subnet_v2._format_allocation_pools(_subnet.allocation_pools), + _subnet.cidr, + utils.format_list(_subnet.dns_nameservers), + _subnet.enable_dhcp, + _subnet.gateway_ip, + utils.format_list(_subnet.host_routes), + _subnet.id, + _subnet.ip_version, + _subnet.ipv6_address_mode, + _subnet.ipv6_ra_mode, + _subnet.name, + _subnet.network_id, + _subnet.tenant_id, + _subnet.subnetpool_id, + ) + + def setUp(self): + super(TestShowSubnet, self).setUp() + + # Get the command object to test + self.cmd = subnet_v2.ShowSubnet(self.app, self.namespace) + + self.network.find_subnet = mock.Mock(return_value=self._subnet) + + def test_show_no_options(self): + arglist = [] + verifylist = [] + + # Testing that a call without the required argument will fail and + # throw a "ParserExecption" + self.assertRaises(tests_utils.ParserException, + self.check_parser, self.cmd, arglist, verifylist) + + def test_show_all_options(self): + arglist = [ + self._subnet.name, + ] + verifylist = [ + ('subnet', self._subnet.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.find_subnet.assert_called_with(self._subnet.name, + ignore_missing=False) + + self.assertEqual(self.columns, columns) + self.assertEqual(list(self.data), list(data)) diff --git a/openstackclient/tests/network/v2/test_subnet_pool.py b/openstackclient/tests/network/v2/test_subnet_pool.py new file mode 100644 index 00000000..c4e3340d --- /dev/null +++ b/openstackclient/tests/network/v2/test_subnet_pool.py @@ -0,0 +1,202 @@ +# 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. +# + +import mock + +from openstackclient.common import utils +from openstackclient.network.v2 import subnet_pool +from openstackclient.tests.network.v2 import fakes as network_fakes +from openstackclient.tests import utils as tests_utils + + +class TestSubnetPool(network_fakes.TestNetworkV2): + + def setUp(self): + super(TestSubnetPool, self).setUp() + + # Get a shortcut to the network client + self.network = self.app.client_manager.network + + +class TestDeleteSubnetPool(TestSubnetPool): + + # The subnet pool to delete. + _subnet_pool = network_fakes.FakeSubnetPool.create_one_subnet_pool() + + def setUp(self): + super(TestDeleteSubnetPool, self).setUp() + + self.network.delete_subnet_pool = mock.Mock(return_value=None) + + self.network.find_subnet_pool = mock.Mock( + return_value=self._subnet_pool + ) + + # Get the command object to test + self.cmd = subnet_pool.DeleteSubnetPool(self.app, self.namespace) + + def test_delete(self): + arglist = [ + self._subnet_pool.name, + ] + verifylist = [ + ('subnet_pool', self._subnet_pool.name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.network.delete_subnet_pool.assert_called_with(self._subnet_pool) + self.assertIsNone(result) + + +class TestListSubnetPool(TestSubnetPool): + # The subnet pools going to be listed up. + _subnet_pools = network_fakes.FakeSubnetPool.create_subnet_pools(count=3) + + columns = ( + 'ID', + 'Name', + 'Prefixes', + ) + columns_long = columns + ( + 'Default Prefix Length', + 'Address Scope', + ) + + data = [] + for pool in _subnet_pools: + data.append(( + pool.id, + pool.name, + pool.prefixes, + )) + + data_long = [] + for pool in _subnet_pools: + data_long.append(( + pool.id, + pool.name, + pool.prefixes, + pool.default_prefixlen, + pool.address_scope_id, + )) + + def setUp(self): + super(TestListSubnetPool, self).setUp() + + # Get the command object to test + self.cmd = subnet_pool.ListSubnetPool(self.app, self.namespace) + + self.network.subnet_pools = mock.Mock(return_value=self._subnet_pools) + + def test_subnet_pool_list_no_option(self): + arglist = [] + verifylist = [ + ('long', False), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.subnet_pools.assert_called_with() + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + def test_subnet_pool_list_long(self): + arglist = [ + '--long', + ] + verifylist = [ + ('long', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.subnet_pools.assert_called_with() + self.assertEqual(self.columns_long, columns) + self.assertEqual(self.data_long, list(data)) + + +class TestShowSubnetPool(TestSubnetPool): + + # The subnet_pool to set. + _subnet_pool = network_fakes.FakeSubnetPool.create_one_subnet_pool() + + columns = ( + 'address_scope_id', + 'default_prefixlen', + 'default_quota', + 'id', + 'ip_version', + 'is_default', + 'max_prefixlen', + 'min_prefixlen', + 'name', + 'prefixes', + 'project_id', + 'shared', + ) + + data = ( + _subnet_pool.address_scope_id, + _subnet_pool.default_prefixlen, + _subnet_pool.default_quota, + _subnet_pool.id, + _subnet_pool.ip_version, + _subnet_pool.is_default, + _subnet_pool.max_prefixlen, + _subnet_pool.min_prefixlen, + _subnet_pool.name, + utils.format_list(_subnet_pool.prefixes), + _subnet_pool.tenant_id, + _subnet_pool.shared, + ) + + def setUp(self): + super(TestShowSubnetPool, self).setUp() + + self.network.find_subnet_pool = mock.Mock( + return_value=self._subnet_pool + ) + + # Get the command object to test + self.cmd = subnet_pool.ShowSubnetPool(self.app, self.namespace) + + def test_show_no_options(self): + arglist = [] + verifylist = [] + + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_show_all_options(self): + arglist = [ + self._subnet_pool.name, + ] + verifylist = [ + ('subnet_pool', self._subnet_pool.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.find_subnet_pool.assert_called_with( + self._subnet_pool.name, + ignore_missing=False + ) + + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) diff --git a/openstackclient/tests/object/v1/fakes.py b/openstackclient/tests/object/v1/fakes.py index 986ab2f3..b9e86db7 100644 --- a/openstackclient/tests/object/v1/fakes.py +++ b/openstackclient/tests/object/v1/fakes.py @@ -76,6 +76,7 @@ OBJECT_2 = { class TestObjectv1(utils.TestCommand): + def setUp(self): super(TestObjectv1, self).setUp() diff --git a/openstackclient/tests/object/v1/test_container.py b/openstackclient/tests/object/v1/test_container.py index d34d73e2..41bc6e8c 100644 --- a/openstackclient/tests/object/v1/test_container.py +++ b/openstackclient/tests/object/v1/test_container.py @@ -26,6 +26,7 @@ AUTH_URL = "http://0.0.0.0" class FakeClient(object): + def __init__(self, endpoint=None, **kwargs): self.endpoint = AUTH_URL self.token = AUTH_TOKEN @@ -67,7 +68,7 @@ class TestContainerDelete(TestContainer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertEqual(None, self.cmd.take_action(parsed_args)) + self.assertIsNone(self.cmd.take_action(parsed_args)) kwargs = {} c_mock.assert_called_with( @@ -92,7 +93,7 @@ class TestContainerDelete(TestContainer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertEqual(None, self.cmd.take_action(parsed_args)) + self.assertIsNone(self.cmd.take_action(parsed_args)) kwargs = {} c_mock.assert_called_with( @@ -120,7 +121,7 @@ class TestContainerDelete(TestContainer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertEqual(None, self.cmd.take_action(parsed_args)) + self.assertIsNone(self.cmd.take_action(parsed_args)) kwargs = {} c_mock.assert_called_with( @@ -156,7 +157,9 @@ class TestContainerList(TestContainer): verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -188,7 +191,9 @@ class TestContainerList(TestContainer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -222,7 +227,9 @@ class TestContainerList(TestContainer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -255,7 +262,9 @@ class TestContainerList(TestContainer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -287,7 +296,9 @@ class TestContainerList(TestContainer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -328,7 +339,9 @@ class TestContainerList(TestContainer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -370,7 +383,9 @@ class TestContainerShow(TestContainer): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values diff --git a/openstackclient/tests/object/v1/test_container_all.py b/openstackclient/tests/object/v1/test_container_all.py index c2dd02a5..95e12f47 100644 --- a/openstackclient/tests/object/v1/test_container_all.py +++ b/openstackclient/tests/object/v1/test_container_all.py @@ -57,7 +57,9 @@ class TestContainerCreate(TestContainerAll): )] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) @@ -91,7 +93,9 @@ class TestContainerCreate(TestContainerAll): )] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) @@ -312,7 +316,9 @@ class TestContainerShow(TestContainerAll): )] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) collist = ( diff --git a/openstackclient/tests/object/v1/test_object.py b/openstackclient/tests/object/v1/test_object.py index f0d62f6e..e11f78a1 100644 --- a/openstackclient/tests/object/v1/test_object.py +++ b/openstackclient/tests/object/v1/test_object.py @@ -26,6 +26,7 @@ AUTH_URL = "http://0.0.0.0" class TestObject(object_fakes.TestObjectv1): + def setUp(self): super(TestObject, self).setUp() self.app.client_manager.object_store = object_store.APIv1( @@ -67,7 +68,9 @@ class TestObjectList(TestObject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) o_mock.assert_called_with( @@ -96,7 +99,9 @@ class TestObjectList(TestObject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -126,7 +131,9 @@ class TestObjectList(TestObject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -156,7 +163,9 @@ class TestObjectList(TestObject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -186,7 +195,9 @@ class TestObjectList(TestObject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -216,7 +227,9 @@ class TestObjectList(TestObject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -247,7 +260,9 @@ class TestObjectList(TestObject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -294,7 +309,9 @@ class TestObjectList(TestObject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) # Set expected values @@ -338,7 +355,9 @@ class TestObjectShow(TestObject): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Set expected values diff --git a/openstackclient/tests/object/v1/test_object_all.py b/openstackclient/tests/object/v1/test_object_all.py index a90e5b65..2a1bf059 100644 --- a/openstackclient/tests/object/v1/test_object_all.py +++ b/openstackclient/tests/object/v1/test_object_all.py @@ -20,6 +20,7 @@ from openstackclient.tests.object.v1 import fakes as object_fakes class TestObjectAll(object_fakes.TestObjectv1): + def setUp(self): super(TestObjectAll, self).setUp() @@ -102,7 +103,9 @@ class TestObjectList(TestObjectAll): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class Lister in cliff, abstract method take_action() + # returns a tuple containing the column names and an iterable + # containing the data to be listed. columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) @@ -150,7 +153,9 @@ class TestObjectShow(TestObjectAll): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) collist = ( diff --git a/openstackclient/tests/test_shell.py b/openstackclient/tests/test_shell.py index 101aadd1..ea3c6fe2 100644 --- a/openstackclient/tests/test_shell.py +++ b/openstackclient/tests/test_shell.py @@ -162,6 +162,7 @@ def fake_execute(shell, cmd): class TestShell(utils.TestCase): + def setUp(self): super(TestShell, self).setUp() patch = "openstackclient.shell.OpenStackShell.run_subcommand" @@ -281,6 +282,7 @@ class TestShell(utils.TestCase): class TestShellHelp(TestShell): """Test the deferred help flag""" + def setUp(self): super(TestShellHelp, self).setUp() self.orig_env, os.environ = os.environ, {} @@ -305,6 +307,7 @@ class TestShellHelp(TestShell): class TestShellOptions(TestShell): + def setUp(self): super(TestShellOptions, self).setUp() self.orig_env, os.environ = os.environ, {} @@ -318,7 +321,7 @@ class TestShellOptions(TestShell): if not test_opts[opt][1]: continue key = opt2attr(opt) - if type(test_opts[opt][0]) is str: + if isinstance(test_opts[opt][0], str): cmd = opt + " " + test_opts[opt][0] else: cmd = opt @@ -332,7 +335,7 @@ class TestShellOptions(TestShell): if not test_opts[opt][1]: continue key = opt2attr(opt) - if type(test_opts[opt][0]) is str: + if isinstance(test_opts[opt][0], str): cmd = opt + " " + test_opts[opt][0] else: cmd = opt @@ -392,6 +395,7 @@ class TestShellOptions(TestShell): class TestShellTokenAuthEnv(TestShell): + def setUp(self): super(TestShellTokenAuthEnv, self).setUp() env = { @@ -439,6 +443,7 @@ class TestShellTokenAuthEnv(TestShell): class TestShellTokenEndpointAuthEnv(TestShell): + def setUp(self): super(TestShellTokenEndpointAuthEnv, self).setUp() env = { @@ -486,6 +491,7 @@ class TestShellTokenEndpointAuthEnv(TestShell): class TestShellCli(TestShell): + def setUp(self): super(TestShellCli, self).setUp() env = { @@ -707,6 +713,7 @@ class TestShellCli(TestShell): class TestShellCliEnv(TestShell): + def setUp(self): super(TestShellCliEnv, self).setUp() env = { diff --git a/openstackclient/tests/utils.py b/openstackclient/tests/utils.py index d9abd572..d3f3853f 100644 --- a/openstackclient/tests/utils.py +++ b/openstackclient/tests/utils.py @@ -28,6 +28,7 @@ class ParserException(Exception): class TestCase(testtools.TestCase): + def setUp(self): testtools.TestCase.setUp(self) diff --git a/openstackclient/tests/volume/v1/fakes.py b/openstackclient/tests/volume/v1/fakes.py index c6b4f0b8..42673efa 100644 --- a/openstackclient/tests/volume/v1/fakes.py +++ b/openstackclient/tests/volume/v1/fakes.py @@ -130,11 +130,13 @@ QOS_WITH_ASSOCIATIONS = { class FakeImagev1Client(object): + def __init__(self, **kwargs): self.images = mock.Mock() class FakeVolumev1Client(object): + def __init__(self, **kwargs): self.volumes = mock.Mock() self.volumes.resource_class = fakes.FakeResource(None, {}) @@ -151,6 +153,7 @@ class FakeVolumev1Client(object): class TestVolumev1(utils.TestCommand): + def setUp(self): super(TestVolumev1, self).setUp() diff --git a/openstackclient/tests/volume/v1/test_qos_specs.py b/openstackclient/tests/volume/v1/test_qos_specs.py index 7ecc8ee8..1a6c0fa4 100644 --- a/openstackclient/tests/volume/v1/test_qos_specs.py +++ b/openstackclient/tests/volume/v1/test_qos_specs.py @@ -34,6 +34,7 @@ class TestQos(volume_fakes.TestVolumev1): class TestQosAssociate(TestQos): + def setUp(self): super(TestQosAssociate, self).setUp() @@ -183,6 +184,7 @@ class TestQosCreate(TestQos): class TestQosDelete(TestQos): + def setUp(self): super(TestQosDelete, self).setUp() @@ -223,6 +225,7 @@ class TestQosDelete(TestQos): class TestQosDisassociate(TestQos): + def setUp(self): super(TestQosDisassociate, self).setUp() @@ -277,6 +280,7 @@ class TestQosDisassociate(TestQos): class TestQosList(TestQos): + def setUp(self): super(TestQosList, self).setUp() @@ -323,6 +327,7 @@ class TestQosList(TestQos): class TestQosSet(TestQos): + def setUp(self): super(TestQosSet, self).setUp() @@ -354,6 +359,7 @@ class TestQosSet(TestQos): class TestQosShow(TestQos): + def setUp(self): super(TestQosShow, self).setUp() @@ -405,6 +411,7 @@ class TestQosShow(TestQos): class TestQosUnset(TestQos): + def setUp(self): super(TestQosUnset, self).setUp() diff --git a/openstackclient/tests/volume/v1/test_volume.py b/openstackclient/tests/volume/v1/test_volume.py index 33255aac..00c509b5 100644 --- a/openstackclient/tests/volume/v1/test_volume.py +++ b/openstackclient/tests/volume/v1/test_volume.py @@ -95,7 +95,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # VolumeManager.create(size, snapshot_id=, source_volid=, @@ -136,7 +138,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # VolumeManager.create(size, snapshot_id=, source_volid=, @@ -189,7 +193,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # VolumeManager.create(size, snapshot_id=, source_volid=, @@ -242,7 +248,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # VolumeManager.create(size, snapshot_id=, source_volid=, @@ -281,7 +289,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # VolumeManager.create(size, snapshot_id=, source_volid=, @@ -325,7 +335,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # VolumeManager.create(size, snapshot_id=, source_volid=, @@ -369,7 +381,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) # VolumeManager.create(size, snapshot_id=, source_volid=, @@ -582,7 +596,6 @@ class TestVolumeSet(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -608,7 +621,6 @@ class TestVolumeSet(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -634,7 +646,6 @@ class TestVolumeSet(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values @@ -700,7 +711,6 @@ class TestVolumeSet(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples self.cmd.take_action(parsed_args) # Set expected values diff --git a/openstackclient/tests/volume/v2/fakes.py b/openstackclient/tests/volume/v2/fakes.py index 2fc5c8ff..61d9df3a 100644 --- a/openstackclient/tests/volume/v2/fakes.py +++ b/openstackclient/tests/volume/v2/fakes.py @@ -17,6 +17,7 @@ import mock import random import uuid +from openstackclient.common import utils as common_utils from openstackclient.tests import fakes from openstackclient.tests.identity.v3 import fakes as identity_fakes from openstackclient.tests.image.v2 import fakes as image_fakes @@ -56,8 +57,31 @@ VOLUME = { "attachments": volume_attachments } -VOLUME_columns = tuple(sorted(VOLUME)) -VOLUME_data = tuple((VOLUME[x] for x in sorted(VOLUME))) +VOLUME_columns = ( + "attachments", + "availability_zone", + "description", + "id", + "name", + "properties", + "size", + "snapshot_id", + "status", + "type" +) + +VOLUME_data = ( + volume_attachments, + volume_availability_zone, + volume_description, + volume_id, + volume_name, + common_utils.format_dict(volume_metadata), + volume_size, + volume_snapshot_id, + volume_status, + volume_type +) snapshot_id = "cb2d364e-4d1c-451a-8c68-b5bbcb340fb2" @@ -189,6 +213,7 @@ IMAGE = { class FakeVolumeClient(object): + def __init__(self, **kwargs): self.volumes = mock.Mock() self.volumes.resource_class = fakes.FakeResource(None, {}) @@ -209,6 +234,7 @@ class FakeVolumeClient(object): class TestVolume(utils.TestCommand): + def setUp(self): super(TestVolume, self).setUp() diff --git a/openstackclient/tests/volume/v2/test_backup.py b/openstackclient/tests/volume/v2/test_backup.py index dc1d7877..edb4eb8e 100644 --- a/openstackclient/tests/volume/v2/test_backup.py +++ b/openstackclient/tests/volume/v2/test_backup.py @@ -33,6 +33,7 @@ class TestBackup(volume_fakes.TestVolume): class TestBackupCreate(TestBackup): + def setUp(self): super(TestBackupCreate, self).setUp() @@ -78,6 +79,7 @@ class TestBackupCreate(TestBackup): class TestBackupShow(TestBackup): + def setUp(self): super(TestBackupShow, self).setUp() @@ -105,6 +107,7 @@ class TestBackupShow(TestBackup): class TestBackupDelete(TestBackup): + def setUp(self): super(TestBackupDelete, self).setUp() @@ -132,6 +135,7 @@ class TestBackupDelete(TestBackup): class TestBackupRestore(TestBackup): + def setUp(self): super(TestBackupRestore, self).setUp() diff --git a/openstackclient/tests/volume/v2/test_qos_specs.py b/openstackclient/tests/volume/v2/test_qos_specs.py index 403634a3..c826925f 100644 --- a/openstackclient/tests/volume/v2/test_qos_specs.py +++ b/openstackclient/tests/volume/v2/test_qos_specs.py @@ -34,6 +34,7 @@ class TestQos(volume_fakes.TestVolume): class TestQosAssociate(TestQos): + def setUp(self): super(TestQosAssociate, self).setUp() @@ -184,6 +185,7 @@ class TestQosCreate(TestQos): class TestQosDelete(TestQos): + def setUp(self): super(TestQosDelete, self).setUp() @@ -224,6 +226,7 @@ class TestQosDelete(TestQos): class TestQosDisassociate(TestQos): + def setUp(self): super(TestQosDisassociate, self).setUp() @@ -278,6 +281,7 @@ class TestQosDisassociate(TestQos): class TestQosList(TestQos): + def setUp(self): super(TestQosList, self).setUp() @@ -324,6 +328,7 @@ class TestQosList(TestQos): class TestQosSet(TestQos): + def setUp(self): super(TestQosSet, self).setUp() @@ -355,6 +360,7 @@ class TestQosSet(TestQos): class TestQosShow(TestQos): + def setUp(self): super(TestQosShow, self).setUp() @@ -406,6 +412,7 @@ class TestQosShow(TestQos): class TestQosUnset(TestQos): + def setUp(self): super(TestQosUnset, self).setUp() diff --git a/openstackclient/tests/volume/v2/test_snapshot.py b/openstackclient/tests/volume/v2/test_snapshot.py index 1c1dd437..b4fb004b 100644 --- a/openstackclient/tests/volume/v2/test_snapshot.py +++ b/openstackclient/tests/volume/v2/test_snapshot.py @@ -31,6 +31,7 @@ class TestSnapshot(volume_fakes.TestVolume): class TestSnapshotCreate(TestSnapshot): + def setUp(self): super(TestSnapshotCreate, self).setUp() @@ -76,6 +77,7 @@ class TestSnapshotCreate(TestSnapshot): class TestSnapshotShow(TestSnapshot): + def setUp(self): super(TestSnapshotShow, self).setUp() @@ -103,6 +105,7 @@ class TestSnapshotShow(TestSnapshot): class TestSnapshotDelete(TestSnapshot): + def setUp(self): super(TestSnapshotDelete, self).setUp() @@ -130,6 +133,7 @@ class TestSnapshotDelete(TestSnapshot): class TestSnapshotSet(TestSnapshot): + def setUp(self): super(TestSnapshotSet, self).setUp() @@ -171,6 +175,7 @@ class TestSnapshotSet(TestSnapshot): class TestSnapshotUnset(TestSnapshot): + def setUp(self): super(TestSnapshotUnset, self).setUp() @@ -247,7 +252,7 @@ class TestSnapshotList(TestSnapshot): volume_fakes.snapshot_description, "available", volume_fakes.snapshot_size - ),) + ),) self.assertEqual(datalist, tuple(data)) def test_snapshot_list_with_options(self): diff --git a/openstackclient/tests/volume/v2/test_type.py b/openstackclient/tests/volume/v2/test_type.py index 9bf60363..f394aff3 100644 --- a/openstackclient/tests/volume/v2/test_type.py +++ b/openstackclient/tests/volume/v2/test_type.py @@ -147,7 +147,7 @@ class TestTypeList(TestType): datalist = (( volume_fakes.type_id, volume_fakes.type_name, - ),) + ),) self.assertEqual(datalist, tuple(data)) def test_type_list_with_options(self): @@ -166,11 +166,12 @@ class TestTypeList(TestType): volume_fakes.type_name, volume_fakes.type_description, "foo='bar'" - ),) + ),) self.assertEqual(datalist, tuple(data)) class TestTypeShow(TestType): + def setUp(self): super(TestTypeShow, self).setUp() @@ -314,6 +315,7 @@ class TestTypeUnset(TestType): class TestTypeDelete(TestType): + def setUp(self): super(TestTypeDelete, self).setUp() diff --git a/openstackclient/tests/volume/v2/test_volume.py b/openstackclient/tests/volume/v2/test_volume.py index 76c7a27a..cbca09b2 100644 --- a/openstackclient/tests/volume/v2/test_volume.py +++ b/openstackclient/tests/volume/v2/test_volume.py @@ -24,6 +24,7 @@ from openstackclient.volume.v2 import volume class TestVolume(volume_fakes.TestVolume): + def setUp(self): super(TestVolume, self).setUp() @@ -96,7 +97,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.volumes_mock.create.assert_called_with( @@ -133,7 +136,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.volumes_mock.create.assert_called_with( @@ -181,7 +186,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.volumes_mock.create.assert_called_with( @@ -229,7 +236,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.volumes_mock.create.assert_called_with( @@ -263,7 +272,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.volumes_mock.create.assert_called_with( @@ -302,7 +313,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.volumes_mock.create.assert_called_with( @@ -341,7 +354,9 @@ class TestVolumeCreate(TestVolume): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # DisplayCommandBase.take_action() returns two tuples + # In base command class ShowOne in cliff, abstract method take_action() + # returns a two-part tuple with a tuple of column names and a tuple of + # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.volumes_mock.create.assert_called_with( @@ -363,6 +378,7 @@ class TestVolumeCreate(TestVolume): class TestVolumeDelete(TestVolume): + def setUp(self): super(TestVolumeDelete, self).setUp() @@ -712,6 +728,7 @@ class TestVolumeList(TestVolume): class TestVolumeShow(TestVolume): + def setUp(self): super(TestVolumeShow, self).setUp() diff --git a/openstackclient/volume/v2/volume.py b/openstackclient/volume/v2/volume.py index 436ec689..8f2122eb 100644 --- a/openstackclient/volume/v2/volume.py +++ b/openstackclient/volume/v2/volume.py @@ -267,7 +267,7 @@ class ListVolume(command.Lister): 'Status', 'Size', 'Attachments', - ] + ] column_headers = copy.deepcopy(columns) column_headers[1] = 'Display Name' column_headers[4] = 'Attached to' @@ -394,6 +394,16 @@ class ShowVolume(command.ShowOne): volume_client = self.app.client_manager.volume volume = utils.find_resource(volume_client.volumes, parsed_args.volume) + # Special mapping for columns to make the output easier to read: + # 'metadata' --> 'properties' + # 'volume_type' --> 'type' + volume._info.update( + { + 'properties': utils.format_dict(volume._info.pop('metadata')), + 'type': volume._info.pop('volume_type'), + }, + ) + # Remove key links from being displayed volume._info.pop("links", None) return zip(*sorted(six.iteritems(volume._info))) |
