diff options
58 files changed, 1452 insertions, 968 deletions
@@ -76,25 +76,63 @@ Configuration The CLI is configured via environment variables and command-line options as listed in https://docs.openstack.org/python-openstackclient/latest/cli/authentication.html. -Authentication using username/password is most commonly used:: - - export OS_AUTH_URL=<url-to-openstack-identity> - export OS_IDENTITY_API_VERSION=3 - export OS_PROJECT_NAME=<project-name> - export OS_PROJECT_DOMAIN_NAME=<project-domain-name> - export OS_USERNAME=<username> - export OS_USER_DOMAIN_NAME=<user-domain-name> - export OS_PASSWORD=<password> # (optional) - -The corresponding command-line options look very similar:: - - --os-auth-url <url> - --os-identity-api-version 3 - --os-project-name <project-name> - --os-project-domain-name <project-domain-name> - --os-username <username> - --os-user-domain-name <user-domain-name> - [--os-password <password>] +Authentication using username/password is most commonly used: + +- For a local user, your configuration will look like the one below:: + + export OS_AUTH_URL=<url-to-openstack-identity> + export OS_IDENTITY_API_VERSION=3 + export OS_PROJECT_NAME=<project-name> + export OS_PROJECT_DOMAIN_NAME=<project-domain-name> + export OS_USERNAME=<username> + export OS_USER_DOMAIN_NAME=<user-domain-name> + export OS_PASSWORD=<password> # (optional) + + The corresponding command-line options look very similar:: + + --os-auth-url <url> + --os-identity-api-version 3 + --os-project-name <project-name> + --os-project-domain-name <project-domain-name> + --os-username <username> + --os-user-domain-name <user-domain-name> + [--os-password <password>] + +- For a federated user, your configuration will look the so:: + + export OS_PROJECT_NAME=<project-name> + export OS_PROJECT_DOMAIN_NAME=<project-domain-name> + export OS_AUTH_URL=<url-to-openstack-identity> + export OS_IDENTITY_API_VERSION=3 + export OS_AUTH_PLUGIN=openid + export OS_AUTH_TYPE=v3oidcpassword + export OS_USERNAME=<username-in-idp> + export OS_PASSWORD=<password-in-idp> + export OS_IDENTITY_PROVIDER=<the-desired-idp-in-keystone> + export OS_CLIENT_ID=<the-client-id-configured-in-the-idp> + export OS_CLIENT_SECRET=<the-client-secred-configured-in-the-idp> + export OS_OPENID_SCOPE=<the-scopes-of-desired-attributes-to-claim-from-idp> + export OS_PROTOCOL=<the-protocol-used-in-the-apache2-oidc-proxy> + export OS_ACCESS_TOKEN_TYPE=<the-access-token-type-used-by-your-idp> + export OS_DISCOVERY_ENDPOINT=<the-well-known-endpoint-of-the-idp> + + The corresponding command-line options look very similar:: + + --os-project-name <project-name> + --os-project-domain-name <project-domain-name> + --os-auth-url <url-to-openstack-identity> + --os-identity-api-version 3 + --os-auth-plugin openid + --os-auth-type v3oidcpassword + --os-username <username-in-idp> + --os-password <password-in-idp> + --os-identity-provider <the-desired-idp-in-keystone> + --os-client-id <the-client-id-configured-in-the-idp> + --os-client-secret <the-client-secred-configured-in-the-idp> + --os-openid-scope <the-scopes-of-desired-attributes-to-claim-from-idp> + --os-protocol <the-protocol-used-in-the-apache2-oidc-proxy> + --os-access-token-type <the-access-token-type-used-by-your-idp> + --os-discovery-endpoint <the-well-known-endpoint-of-the-idp> If a password is not provided above (in plaintext), you will be interactively prompted to provide one securely. diff --git a/doc/requirements.txt b/doc/requirements.txt index 962b0e26..28030ca4 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -26,7 +26,6 @@ python-neutronclient>=6.7.0 # Apache-2.0 python-octaviaclient>=1.11.0 # Apache-2.0 python-rsdclient>=1.0.1 # Apache-2.0 python-saharaclient>=1.4.0 # Apache-2.0 -python-searchlightclient>=1.0.0 #Apache-2.0 python-senlinclient>=1.1.0 # Apache-2.0 python-troveclient>=3.1.0 # Apache-2.0 python-watcherclient>=2.5.0 # Apache-2.0 diff --git a/doc/source/cli/authentication.rst b/doc/source/cli/authentication.rst index 3b404bce..2e9148c3 100644 --- a/doc/source/cli/authentication.rst +++ b/doc/source/cli/authentication.rst @@ -133,3 +133,17 @@ Thus, a minimal set of environment variables would be: $ export OS_USERNAME=admin $ export OS_PASSWORD=secret $ export OS_PROJECT_NAME=admin + +Federated users support +----------------------- + +The OpenStackClient also allows the use of Federated users to log in. +It enables one to use the identity providers credentials such as Google or +Facebook to log in the OpenStackClient instead of using the Keystone +credentials. + +This is useful in a Federated environment where one credential give access +to many applications/services that the Federation supports. To check how to +configure the OpenStackClient to allow Federated users to log in, please check +the +:ref:`Authentication using federation. <manpage>` diff --git a/doc/source/cli/man/openstack.rst b/doc/source/cli/man/openstack.rst index 687e39eb..dc327a66 100644 --- a/doc/source/cli/man/openstack.rst +++ b/doc/source/cli/man/openstack.rst @@ -44,6 +44,7 @@ command line. The primary difference is the use of 'project' in the name of the * ``token``: Authentication with a token * ``password``: Authentication with a username and a password +* ``openid`` : Authentication using the protocol OpenID Connect Refer to the keystoneclient library documentation for more details about these plugins and their options, and for a complete list of available plugins. Please bear in mind that some plugins might not support all of the functionalities of :program:`openstack`; for example the v3unscopedsaml plugin can deliver only unscoped tokens, some commands might not be available through this authentication method. @@ -53,6 +54,31 @@ Additionally, it is possible to use Keystone's service token to authenticate, by .. NOTE:: To use the ``v3unscopedsaml`` method, the lxml package will need to be installed. +AUTHENTICATION USING FEDERATION +------------------------------- + +To use federated authentication, your configuration file needs the following: + +:: + + export OS_PROJECT_NAME=<project-name> + export OS_PROJECT_DOMAIN_NAME=<project-domain-name> + export OS_AUTH_URL=<url-to-openstack-identity> + export OS_IDENTITY_API_VERSION=3 + export OS_AUTH_PLUGIN=openid + export OS_AUTH_TYPE=v3oidcpassword + export OS_USERNAME=<username-in-idp> + export OS_PASSWORD=<password-in-idp> + export OS_IDENTITY_PROVIDER=<the-desired-idp> + export OS_CLIENT_ID=<the-client-id-configured-in-the-idp> + export OS_CLIENT_SECRET=<the-client-secred-configured-in-the-idp> + export OS_OPENID_SCOPE=<the-scopes-of-desired-attributes-to-claim-from-idp> + export OS_PROTOCOL=<the-protocol-used-in-the-apache2-oidc-proxy> + export OS_ACCESS_TOKEN_TYPE=<the-access-token-type-used-by-your-idp> + export OS_DISCOVERY_ENDPOINT=<the-well-known-endpoint-of-the-idp> + export OS_ACCESS_TOKEN_ENDPOINT=<the-idp-access-token-url> + + OPTIONS ======= @@ -356,6 +382,24 @@ Show the detailed information for server ``appweb01``:: --os-auth-url http://localhost:5000:/v2.0 \ server show appweb01 +The same but using openid to authenticate in keystone:: + + openstack \ + --os-project-name ExampleCo \ + --os-auth-url http://localhost:5000:/v2.0 \ + --os-auth-plugin openid \ + --os-auth-type v3oidcpassword \ + --os-username demo-idp \ + --os-password secret-idp \ + --os-identity-provider google \ + --os-client-id the-id-assigned-to-keystone-in-google \ + --os-client-secret 3315162f-2b28-4809-9369-cb54730ac837 \ + --os-openid-scope 'openid email profile'\ + --os-protocol openid \ + --os-access-token-type access_token \ + --os-discovery-endpoint https://accounts.google.com/.well-known/openid-configuration \ + server show appweb01 + The same command if the auth environment variables (:envvar:`OS_AUTH_URL`, :envvar:`OS_PROJECT_NAME`, :envvar:`OS_USERNAME`, :envvar:`OS_PASSWORD`) are set:: @@ -404,6 +448,24 @@ The following environment variables can be set to alter the behaviour of :progra Authentication URL +.. envvar:: OS_AUTH_TYPE + + Define the authentication plugin that will be used to handle the + authentication process. One of the following: + + - ``v2password`` + - ``v2token`` + - ``v3password`` + - ``v3token`` + - ``v3oidcclientcredentials`` + - ``v3oidcpassword`` + - ``v3oidcauthorizationcode`` + - ``v3oidcaccesstoken`` + - ``v3totp`` + - ``v3tokenlessauth`` + - ``v3applicationcredential`` + - ``v3multifactor`` + .. envvar:: OS_URL Service URL (when using the service token) @@ -473,6 +535,56 @@ The following environment variables can be set to alter the behaviour of :progra Interface type. Valid options are `public`, `admin` and `internal`. +.. envvar:: OS_PROTOCOL + + Define the protocol that is used to execute the federated authentication + process. It is used in the Keystone authentication URL generation process. + +.. envvar:: OS_IDENTITY_PROVIDER + + Define the identity provider of your federation that will be used. It is + used by the Keystone authentication URL generation process. The available + Identity Providers can be listed using the + :program:`openstack identity provider list` command + +.. envvar:: OS_CLIENT_ID + + Configure the ``CLIENT_ID`` that the CLI will use to authenticate the + application (OpenStack) in the Identity Provider. This value is defined on + the identity provider side. Do not confuse with the user ID. + +.. envvar:: OS_CLIENT_SECRET + + Configure the OS_CLIENT_SECRET that the CLI will use to authenticate the + CLI (OpenStack secret in the identity provider). + +.. envvar:: OS_OPENID_SCOPE + + Configure the attribute scopes that will be claimed by the Service Provider + (SP), in this case OpenStack, from the identity provider. These scopes and + which attributes each scope contains are defined in the identity provider + side. This parameter can receive multiple values separated by space. + +.. envvar:: OS_ACCESS_TOKEN_TYPE + + Define the type of access token that is used in the token introspection + process. + This variable can assume only one of the states ("access_token" or + "id_token"). + +.. envvar:: OS_DISCOVERY_ENDPOINT + + Configure the identity provider's discovery URL. This URL will provide a + discover document that contains metadata describing the identity provider + endpoints. This variable is optional if the variable + ``OS_ACCESS_TOKEN_ENDPOINT`` is defined. + +.. envvar:: OS_ACCESS_TOKEN_ENDPOINT + + Overrides the value presented in the discovery document retrieved from + ``OS_DISCOVERY_ENDPOINT`` URL request. This variable is optional if the + ``OS_DISCOVERY_ENDPOINT`` is configured. + .. NOTE:: If you switch to openstackclient from project specified clients, like: novaclient, neutronclient and so on, please use `OS_INTERFACE` instead of diff --git a/doc/source/cli/plugin-commands/index.rst b/doc/source/cli/plugin-commands/index.rst index 33a8fe06..8c9c5c13 100644 --- a/doc/source/cli/plugin-commands/index.rst +++ b/doc/source/cli/plugin-commands/index.rst @@ -22,7 +22,6 @@ Plugin Commands placement rsd sahara - searchlight senlin trove watcher diff --git a/doc/source/cli/plugin-commands/searchlight.rst b/doc/source/cli/plugin-commands/searchlight.rst deleted file mode 100644 index be934aeb..00000000 --- a/doc/source/cli/plugin-commands/searchlight.rst +++ /dev/null @@ -1,4 +0,0 @@ -searchlight ------------ - -.. autoprogram-cliff:: openstack.search.v1 diff --git a/doc/source/conf.py b/doc/source/conf.py index 2216ddd7..4b60ce4a 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -263,6 +263,9 @@ autoprogram_cliff_ignored = [ '--help', '--format', '--column', '--max-width', '--fit-width', '--print-empty', '--prefix', '--noindent', '--quote'] +# Prevent cliff from generating "This command is provided by the +# python-openstackclient plugin." +autoprogram_cliff_app_dist_name = 'python-openstackclient' # -- Options for sphinxcontrib.apidoc ---------------------------------------- diff --git a/doc/source/contributor/plugins.rst b/doc/source/contributor/plugins.rst index 7ea48edd..fe2cc14a 100644 --- a/doc/source/contributor/plugins.rst +++ b/doc/source/contributor/plugins.rst @@ -37,7 +37,6 @@ The following is a list of projects that are an OpenStackClient plugin. - python-octaviaclient - python-rsdclient - python-saharaclient -- python-searchlightclient - python-senlinclient - python-tripleoclient\*\* - python-troveclient diff --git a/lower-constraints.txt b/lower-constraints.txt index b489501b..287f7d45 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -1,21 +1,17 @@ amqp==2.1.1 -aodhclient==0.9.0 appdirs==1.3.0 asn1crypto==0.23.0 -bandit==1.1.0 +Babel==2.6.0 +bcrypt==3.2.0 cachetools==2.0.0 cffi==1.14.0 -cliff==3.4.0 +cliff==3.5.0 cmd2==0.8.0 -contextlib2==0.4.0 coverage==4.0 -cryptography==2.1 +cryptography==2.7 ddt==1.0.1 debtcollector==1.2.0 decorator==4.4.1 -deprecation==1.0 -docker-pycreds==0.2.1 -docker==2.4.2 dogpile.cache==0.6.5 eventlet==0.18.2 extras==1.0.0 @@ -23,12 +19,8 @@ fasteners==0.7.0 fixtures==3.0.0 future==0.16.0 futurist==2.1.0 -gitdb==0.6.4 -GitPython==1.0.1 -gnocchiclient==3.3.1 greenlet==0.4.15 -httplib2==0.9.1 -idna==2.6 +importlib-metadata==3.1.1 iso8601==0.1.11 Jinja2==2.10 jmespath==0.9.0 @@ -39,17 +31,18 @@ keystoneauth1==3.18.0 kombu==4.0.0 linecache2==1.0.0 MarkupSafe==1.1.1 +mock==4.0.2 monotonic==0.6 mox3==0.20.0 msgpack-python==0.4.0 munch==2.1.0 netaddr==0.7.18 netifaces==0.10.4 -openstacksdk==0.51.0 +openstacksdk==0.52.0 +os-client-config==2.1.0 os-service-types==1.7.0 os-testr==1.0.0 -osc-lib==2.2.0 -osc-placement==1.7.0 +osc-lib==2.3.0 oslo.concurrency==3.26.0 oslo.config==5.2.0 oslo.context==2.19.2 @@ -66,71 +59,41 @@ paramiko==2.7.1 Paste==2.0.2 PasteDeploy==1.5.0 pbr==2.0.0 -pika-pool==0.1.3 pika==0.10.0 -ply==3.10 -positional==1.2.1 +pika-pool==0.1.3 prettytable==0.7.2 -pyasn1==0.1.8 -pycodestyle==2.0.0 pycparser==2.18 pyinotify==0.9.6 -pyOpenSSL==17.1.0 +PyNaCl==1.4.0 pyparsing==2.1.0 pyperclip==1.5.27 -python-barbicanclient==4.5.2 python-cinderclient==3.3.0 python-dateutil==2.5.3 -python-designateclient==2.7.0 -python-glanceclient==2.8.0 -python-heatclient==1.10.0 -python-ironic-inspector-client==1.5.0 -python-ironicclient==2.3.0 -python-karborclient==0.6.0 python-keystoneclient==3.22.0 python-mimeparse==1.6.0 -python-mistralclient==3.1.0 -python-muranoclient==0.8.2 -python-neutronclient==6.7.0 python-novaclient==15.1.0 -python-octaviaclient==1.11.0 -python-rsdclient==1.0.1 -python-saharaclient==1.4.0 -python-searchlightclient==1.0.0 -python-senlinclient==1.1.0 python-subunit==1.0.0 -python-swiftclient==3.2.0 -python-troveclient==3.1.0 -python-watcherclient==2.5.0 -python-zaqarclient==1.0.0 -python-zunclient==3.6.0 pytz==2013.6 -PyYAML==3.12 +PyYAML==3.13 repoze.lru==0.7 -requests-mock==1.2.0 requests==2.14.2 +requests-mock==1.2.0 requestsexceptions==1.2.0 rfc3986==0.3.1 Routes==2.3.1 -rsd-lib==0.1.0 simplejson==3.5.1 -smmap==0.9.0 +six==1.15.0 statsd==3.2.1 stestr==1.0.0 stevedore==2.0.1 -sushy==0.1.0 tempest==17.1.0 tenacity==3.2.1 testrepository==0.0.18 testtools==2.2.0 traceback2==1.4.0 -ujson==1.35 unittest2==1.1.0 urllib3==1.21.1 -validictory==1.1.1 vine==1.1.4 -warlock==1.2.0 WebOb==1.7.1 -websocket-client==0.44.0 wrapt==1.7.0 -yaql==1.1.3 +zipp==3.4.0 diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py index 11de986b..643cb4e4 100644 --- a/openstackclient/common/quota.py +++ b/openstackclient/common/quota.py @@ -161,6 +161,13 @@ class BaseQuota(object): raise return quota._info + def _network_quota_to_dict(self, network_quota): + if type(network_quota) is not dict: + dict_quota = network_quota.to_dict() + else: + dict_quota = network_quota + return {k: v for k, v in dict_quota.items() if v is not None} + def get_network_quota(self, parsed_args): quota_class = ( parsed_args.quota_class if 'quota_class' in parsed_args else False) @@ -174,13 +181,11 @@ class BaseQuota(object): client = self.app.client_manager.network if default: network_quota = client.get_quota_default(project) - if type(network_quota) is not dict: - network_quota = network_quota.to_dict() + network_quota = self._network_quota_to_dict(network_quota) else: network_quota = client.get_quota(project, details=detail) - if type(network_quota) is not dict: - network_quota = network_quota.to_dict() + network_quota = self._network_quota_to_dict(network_quota) if detail: # NOTE(slaweq): Neutron returns values with key "used" but # Nova for example returns same data with key "in_use" diff --git a/openstackclient/compute/v2/aggregate.py b/openstackclient/compute/v2/aggregate.py index 599659a3..8b70f426 100644 --- a/openstackclient/compute/v2/aggregate.py +++ b/openstackclient/compute/v2/aggregate.py @@ -18,6 +18,7 @@ import logging +from openstack import utils as sdk_utils from osc_lib.cli import format_columns from osc_lib.cli import parseractions from osc_lib.command import command @@ -30,6 +31,25 @@ from openstackclient.i18n import _ LOG = logging.getLogger(__name__) +_aggregate_formatters = { + 'Hosts': format_columns.ListColumn, + 'Metadata': format_columns.DictColumn, + 'hosts': format_columns.ListColumn, + 'metadata': format_columns.DictColumn, +} + + +def _get_aggregate_columns(item): + # To maintain backwards compatibility we need to rename sdk props to + # whatever OSC was using before + column_map = { + 'metadata': 'properties', + } + hidden_columns = ['links', 'location'] + return utils.get_osc_show_columns_for_sdk_resource( + item, column_map, hidden_columns) + + class AddAggregateHost(command.ShowOne): _description = _("Add host to aggregate") @@ -48,26 +68,18 @@ class AddAggregateHost(command.ShowOne): return parser def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute + compute_client = self.app.client_manager.sdk_connection.compute - aggregate = utils.find_resource( - compute_client.aggregates, - parsed_args.aggregate, - ) - data = compute_client.aggregates.add_host(aggregate, parsed_args.host) - - info = {} - info.update(data._info) - - # Special mapping for columns to make the output easier to read: - # 'metadata' --> 'properties' - info.update( - { - 'hosts': format_columns.ListColumn(info.pop('hosts')), - 'properties': format_columns.DictColumn(info.pop('metadata')), - }, - ) - return zip(*sorted(info.items())) + aggregate = compute_client.find_aggregate( + parsed_args.aggregate, ignore_missing=False) + + aggregate = compute_client.add_host_to_aggregate( + aggregate.id, parsed_args.host) + + display_columns, columns = _get_aggregate_columns(aggregate) + data = utils.get_item_properties( + aggregate, columns, formatters=_aggregate_formatters) + return (display_columns, data) class CreateAggregate(command.ShowOne): @@ -95,36 +107,25 @@ class CreateAggregate(command.ShowOne): return parser def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute + compute_client = self.app.client_manager.sdk_connection.compute - info = {} - data = compute_client.aggregates.create( - parsed_args.name, - parsed_args.zone, - ) - info.update(data._info) + attrs = {'name': parsed_args.name} + + if parsed_args.zone: + attrs['availability_zone'] = parsed_args.zone + + aggregate = compute_client.create_aggregate(**attrs) if parsed_args.property: - info.update(compute_client.aggregates.set_metadata( - data, + aggregate = compute_client.set_aggregate_metadata( + aggregate.id, parsed_args.property, - )._info) - - # Special mapping for columns to make the output easier to read: - # 'metadata' --> 'properties' - hosts = None - properties = None - if 'hosts' in info.keys(): - hosts = format_columns.ListColumn(info.pop('hosts')) - if 'metadata' in info.keys(): - properties = format_columns.DictColumn(info.pop('metadata')) - info.update( - { - 'hosts': hosts, - 'properties': properties, - }, - ) - return zip(*sorted(info.items())) + ) + + display_columns, columns = _get_aggregate_columns(aggregate) + data = utils.get_item_properties( + aggregate, columns, formatters=_aggregate_formatters) + return (display_columns, data) class DeleteAggregate(command.Command): @@ -141,13 +142,14 @@ class DeleteAggregate(command.Command): return parser def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute + compute_client = self.app.client_manager.sdk_connection.compute result = 0 for a in parsed_args.aggregate: try: - data = utils.find_resource( - compute_client.aggregates, a) - compute_client.aggregates.delete(data.id) + aggregate = compute_client.find_aggregate( + a, ignore_missing=False) + compute_client.delete_aggregate( + aggregate.id, ignore_missing=False) except Exception as e: result += 1 LOG.error(_("Failed to delete aggregate with name or " @@ -175,15 +177,15 @@ class ListAggregate(command.Lister): return parser def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute + compute_client = self.app.client_manager.sdk_connection.compute - data = compute_client.aggregates.list() + aggregates = list(compute_client.aggregates()) if parsed_args.long: # Remove availability_zone from metadata because Nova doesn't - for d in data: - if 'availability_zone' in d.metadata: - d.metadata.pop('availability_zone') + for aggregate in aggregates: + if 'availability_zone' in aggregate.metadata: + aggregate.metadata.pop('availability_zone') # This is the easiest way to change column headers column_headers = ( "ID", @@ -204,14 +206,11 @@ class ListAggregate(command.Lister): "Availability Zone", ) - return (column_headers, - (utils.get_item_properties( - s, columns, - formatters={ - 'Hosts': format_columns.ListColumn, - 'Metadata': format_columns.DictColumn, - }, - ) for s in data)) + data = ( + utils.get_item_properties( + s, columns, formatters=_aggregate_formatters + ) for s in aggregates) + return (column_headers, data) class RemoveAggregateHost(command.ShowOne): @@ -232,29 +231,18 @@ class RemoveAggregateHost(command.ShowOne): return parser def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute + compute_client = self.app.client_manager.sdk_connection.compute - aggregate = utils.find_resource( - compute_client.aggregates, - parsed_args.aggregate, - ) - data = compute_client.aggregates.remove_host( - aggregate, - parsed_args.host, - ) + aggregate = compute_client.find_aggregate( + parsed_args.aggregate, ignore_missing=False) - info = {} - info.update(data._info) + aggregate = compute_client.remove_host_from_aggregate( + aggregate.id, parsed_args.host) - # Special mapping for columns to make the output easier to read: - # 'metadata' --> 'properties' - info.update( - { - 'hosts': format_columns.ListColumn(info.pop('hosts')), - 'properties': format_columns.DictColumn(info.pop('metadata')), - }, - ) - return zip(*sorted(info.items())) + display_columns, columns = _get_aggregate_columns(aggregate) + data = utils.get_item_properties( + aggregate, columns, formatters=_aggregate_formatters) + return (display_columns, data) class SetAggregate(command.Command): @@ -296,11 +284,9 @@ class SetAggregate(command.Command): def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute - aggregate = utils.find_resource( - compute_client.aggregates, - parsed_args.aggregate, - ) + compute_client = self.app.client_manager.sdk_connection.compute + aggregate = compute_client.find_aggregate( + parsed_args.aggregate, ignore_missing=False) kwargs = {} if parsed_args.name: @@ -308,18 +294,12 @@ class SetAggregate(command.Command): if parsed_args.zone: kwargs['availability_zone'] = parsed_args.zone if kwargs: - compute_client.aggregates.update( - aggregate, - kwargs - ) + compute_client.update_aggregate(aggregate.id, **kwargs) set_property = {} if parsed_args.no_property: - # NOTE(RuiChen): "availability_zone" is removed from response of - # aggregate show and create commands, don't see it - # anywhere, so pop it, avoid the unexpected server - # exception(can't unset the availability zone from - # aggregate metadata in nova). + # NOTE(RuiChen): "availability_zone" can not be unset from + # properties. It is already excluded from show and create output. set_property.update({key: None for key in aggregate.metadata.keys() if key != 'availability_zone'}) @@ -327,8 +307,8 @@ class SetAggregate(command.Command): set_property.update(parsed_args.property) if set_property: - compute_client.aggregates.set_metadata( - aggregate, + compute_client.set_aggregate_metadata( + aggregate.id, set_property ) @@ -347,31 +327,18 @@ class ShowAggregate(command.ShowOne): def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute - data = utils.find_resource( - compute_client.aggregates, - parsed_args.aggregate, - ) + compute_client = self.app.client_manager.sdk_connection.compute + aggregate = compute_client.find_aggregate( + parsed_args.aggregate, ignore_missing=False) + # Remove availability_zone from metadata because Nova doesn't - if 'availability_zone' in data.metadata: - data.metadata.pop('availability_zone') - - # Special mapping for columns to make the output easier to read: - # 'metadata' --> 'properties' - data._info.update( - { - 'hosts': format_columns.ListColumn( - data._info.pop('hosts') - ), - 'properties': format_columns.DictColumn( - data._info.pop('metadata') - ), - }, - ) + if 'availability_zone' in aggregate.metadata: + aggregate.metadata.pop('availability_zone') - info = {} - info.update(data._info) - return zip(*sorted(info.items())) + display_columns, columns = _get_aggregate_columns(aggregate) + data = utils.get_item_properties( + aggregate, columns, formatters=_aggregate_formatters) + return (display_columns, data) class UnsetAggregate(command.Command): @@ -394,14 +361,56 @@ class UnsetAggregate(command.Command): return parser def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute - aggregate = utils.find_resource( - compute_client.aggregates, - parsed_args.aggregate) + compute_client = self.app.client_manager.sdk_connection.compute + aggregate = compute_client.find_aggregate( + parsed_args.aggregate, ignore_missing=False) unset_property = {} if parsed_args.property: unset_property.update({key: None for key in parsed_args.property}) if unset_property: - compute_client.aggregates.set_metadata(aggregate, - unset_property) + compute_client.set_aggregate_metadata( + aggregate, unset_property) + + +class CacheImageForAggregate(command.Command): + _description = _("Request image caching for aggregate") + # NOTE(gtema): According to stephenfin and dansmith there is no and will + # not be anything to return. + + def get_parser(self, prog_name): + parser = super(CacheImageForAggregate, self).get_parser(prog_name) + parser.add_argument( + 'aggregate', + metavar='<aggregate>', + help=_("Aggregate (name or ID)") + ) + parser.add_argument( + 'image', + metavar='<image>', + nargs='+', + help=_("Image ID to request caching for aggregate (name or ID). " + "May be specified multiple times.") + ) + return parser + + def take_action(self, parsed_args): + compute_client = self.app.client_manager.sdk_connection.compute + + if not sdk_utils.supports_microversion(compute_client, '2.81'): + msg = _( + 'This operation requires server support for ' + 'API microversion 2.81' + ) + raise exceptions.CommandError(msg) + + aggregate = compute_client.find_aggregate( + parsed_args.aggregate, ignore_missing=False) + + images = [] + for img in parsed_args.image: + image = self.app.client_manager.sdk_connection.image.find_image( + img, ignore_missing=False) + images.append(image.id) + + compute_client.aggregate_precache_images(aggregate.id, images) diff --git a/openstackclient/compute/v2/flavor.py b/openstackclient/compute/v2/flavor.py index 00431b7b..8477e8ef 100644 --- a/openstackclient/compute/v2/flavor.py +++ b/openstackclient/compute/v2/flavor.py @@ -17,7 +17,8 @@ import logging -from novaclient import api_versions +from openstack import exceptions as sdk_exceptions +from openstack import utils as sdk_utils from osc_lib.cli import format_columns from osc_lib.cli import parseractions from osc_lib.command import command @@ -33,10 +34,7 @@ LOG = logging.getLogger(__name__) _formatters = { 'extra_specs': format_columns.DictColumn, - # Unless we finish switch to use SDK resources this need to be doubled this - # way - 'properties': format_columns.DictColumn, - 'Properties': format_columns.DictColumn + 'properties': format_columns.DictColumn } @@ -51,29 +49,10 @@ def _get_flavor_columns(item): } hidden_columns = ['links', 'location'] - return utils.get_osc_show_columns_for_sdk_resource( item, column_map, hidden_columns) -def _find_flavor(compute_client, flavor): - try: - return compute_client.flavors.get(flavor) - except Exception as ex: - if type(ex).__name__ == 'NotFound': - pass - else: - raise - try: - return compute_client.flavors.find(name=flavor, is_public=None) - except Exception as ex: - if type(ex).__name__ == 'NotFound': - msg = _("No flavor with a name or ID of '%s' exists.") % flavor - raise exceptions.CommandError(msg) - else: - raise - - class CreateFlavor(command.ShowOne): _description = _("Create new flavor") @@ -87,9 +66,7 @@ class CreateFlavor(command.ShowOne): parser.add_argument( "--id", metavar="<id>", - default='auto', - help=_("Unique flavor ID; 'auto' creates a UUID " - "(default: auto)") + help=_("Unique flavor ID") ) parser.add_argument( "--ram", @@ -170,32 +147,36 @@ class CreateFlavor(command.ShowOne): return parser def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute + compute_client = self.app.client_manager.sdk_connection.compute identity_client = self.app.client_manager.identity if parsed_args.project and parsed_args.public: msg = _("--project is only allowed with --private") raise exceptions.CommandError(msg) + args = { + 'name': parsed_args.name, + 'ram': parsed_args.ram, + 'vcpus': parsed_args.vcpus, + 'disk': parsed_args.disk, + 'id': parsed_args.id, + 'ephemeral': parsed_args.ephemeral, + 'swap': parsed_args.swap, + 'rxtx_factor': parsed_args.rxtx_factor, + 'is_public': parsed_args.public, + } + if parsed_args.description: - if compute_client.api_version < api_versions.APIVersion("2.55"): - msg = _("--os-compute-api-version 2.55 or later is required") + if not sdk_utils.supports_microversion(compute_client, '2.55'): + msg = _( + 'The --description parameter requires server support for ' + 'API microversion 2.55' + ) raise exceptions.CommandError(msg) - args = ( - parsed_args.name, - parsed_args.ram, - parsed_args.vcpus, - parsed_args.disk, - parsed_args.id, - parsed_args.ephemeral, - parsed_args.swap, - parsed_args.rxtx_factor, - parsed_args.public, - parsed_args.description - ) + args['description'] = parsed_args.description - flavor = compute_client.flavors.create(*args) + flavor = compute_client.create_flavor(**args) if parsed_args.project: try: @@ -204,7 +185,7 @@ class CreateFlavor(command.ShowOne): parsed_args.project, parsed_args.project_domain, ).id - compute_client.flavor_access.add_tenant_access( + compute_client.flavor_add_tenant_access( flavor.id, project_id) except Exception as e: msg = _("Failed to add project %(project)s access to " @@ -212,19 +193,14 @@ class CreateFlavor(command.ShowOne): LOG.error(msg, {'project': parsed_args.project, 'e': e}) if parsed_args.property: try: - flavor.set_keys(parsed_args.property) + flavor = compute_client.create_flavor_extra_specs( + flavor, parsed_args.property) except Exception as e: LOG.error(_("Failed to set flavor property: %s"), e) - flavor_info = flavor._info.copy() - flavor_info['properties'] = flavor.get_keys() - - display_columns, columns = _get_flavor_columns(flavor_info) - data = utils.get_dict_properties( - flavor_info, columns, - formatters=_formatters, - mixed_case_fields=['OS-FLV-DISABLED:disabled', - 'OS-FLV-EXT-DATA:ephemeral']) + display_columns, columns = _get_flavor_columns(flavor) + data = utils.get_dict_properties(flavor, columns, + formatters=_formatters) return (display_columns, data) @@ -243,12 +219,12 @@ class DeleteFlavor(command.Command): return parser def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute + compute_client = self.app.client_manager.sdk_connection.compute result = 0 for f in parsed_args.flavor: try: - flavor = _find_flavor(compute_client, f) - compute_client.flavors.delete(flavor.id) + flavor = compute_client.find_flavor(f, ignore_missing=False) + compute_client.delete_flavor(flavor.id) except Exception as e: result += 1 LOG.error(_("Failed to delete flavor with name or " @@ -307,37 +283,63 @@ class ListFlavor(command.Lister): return parser def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute + compute_client = self.app.client_manager.sdk_connection.compute + # is_public is ternary - None means give all flavors, + # True is public only and False is private only + # By default Nova assumes True and gives admins public flavors + # and flavors from their own projects only. + is_public = None if parsed_args.all else parsed_args.public + + query_attrs = { + 'is_public': is_public + } + if parsed_args.marker: + query_attrs['marker'] = parsed_args.marker + if parsed_args.limit: + query_attrs['limit'] = parsed_args.limit + if parsed_args.limit or parsed_args.marker: + # User passed explicit pagination request, switch off SDK + # pagination + query_attrs['paginated'] = False + + data = list(compute_client.flavors(**query_attrs)) + # Even if server supports 2.61 some policy might stop it sending us + # extra_specs. So try to fetch them if they are absent + for f in data: + if not f.extra_specs: + compute_client.fetch_flavor_extra_specs(f) + columns = ( + "id", + "name", + "ram", + "disk", + "ephemeral", + "vcpus", + "is_public" + ) + if parsed_args.long: + columns += ( + "swap", + "rxtx_factor", + "extra_specs", + ) + + column_headers = ( "ID", "Name", "RAM", "Disk", "Ephemeral", "VCPUs", - "Is Public", + "Is Public" ) - - # is_public is ternary - None means give all flavors, - # True is public only and False is private only - # By default Nova assumes True and gives admins public flavors - # and flavors from their own projects only. - is_public = None if parsed_args.all else parsed_args.public - - data = compute_client.flavors.list(is_public=is_public, - marker=parsed_args.marker, - limit=parsed_args.limit) - if parsed_args.long: - columns = columns + ( + column_headers += ( "Swap", "RXTX Factor", "Properties", ) - for f in data: - f.properties = f.get_keys() - - column_headers = columns return (column_headers, (utils.get_item_properties( @@ -387,24 +389,42 @@ class SetFlavor(command.Command): return parser def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute + compute_client = self.app.client_manager.sdk_connection.compute identity_client = self.app.client_manager.identity - flavor = _find_flavor(compute_client, parsed_args.flavor) + try: + flavor = compute_client.find_flavor( + parsed_args.flavor, + get_extra_specs=True, + ignore_missing=False) + except sdk_exceptions.ResourceNotFound as e: + raise exceptions.CommandError(e.message) + + if parsed_args.description: + if not sdk_utils.supports_microversion(compute_client, '2.55'): + msg = _( + 'The --description parameter requires server support for ' + 'API microversion 2.55' + ) + raise exceptions.CommandError(msg) + + compute_client.update_flavor( + flavor=flavor.id, description=parsed_args.description) result = 0 - key_list = [] if parsed_args.no_property: try: - for key in flavor.get_keys().keys(): - key_list.append(key) - flavor.unset_keys(key_list) + for key in flavor.extra_specs.keys(): + compute_client.delete_flavor_extra_specs_property( + flavor.id, key) except Exception as e: LOG.error(_("Failed to clear flavor property: %s"), e) result += 1 + if parsed_args.property: try: - flavor.set_keys(parsed_args.property) + compute_client.create_flavor_extra_specs( + flavor.id, parsed_args.property) except Exception as e: LOG.error(_("Failed to set flavor property: %s"), e) result += 1 @@ -420,7 +440,7 @@ class SetFlavor(command.Command): parsed_args.project, parsed_args.project_domain, ).id - compute_client.flavor_access.add_tenant_access( + compute_client.flavor_add_tenant_access( flavor.id, project_id) except Exception as e: LOG.error(_("Failed to set flavor access to project: %s"), e) @@ -430,13 +450,6 @@ class SetFlavor(command.Command): raise exceptions.CommandError(_("Command Failed: One or more of" " the operations failed")) - if parsed_args.description: - if compute_client.api_version < api_versions.APIVersion("2.55"): - msg = _("--os-compute-api-version 2.55 or later is required") - raise exceptions.CommandError(msg) - compute_client.flavors.update(flavor=flavor.id, - description=parsed_args.description) - class ShowFlavor(command.ShowOne): _description = _("Display flavor details") @@ -451,35 +464,32 @@ class ShowFlavor(command.ShowOne): return parser def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute - resource_flavor = _find_flavor(compute_client, parsed_args.flavor) + compute_client = self.app.client_manager.sdk_connection.compute + flavor = compute_client.find_flavor( + parsed_args.flavor, get_extra_specs=True, ignore_missing=False) access_projects = None # get access projects list of this flavor - if not resource_flavor.is_public: + if not flavor.is_public: try: - flavor_access = compute_client.flavor_access.list( - flavor=resource_flavor.id) - access_projects = [utils.get_field(access, 'tenant_id') - for access in flavor_access] + flavor_access = compute_client.get_flavor_access( + flavor=flavor.id) + access_projects = [ + utils.get_field(access, 'tenant_id') + for access in flavor_access] except Exception as e: msg = _("Failed to get access projects list " "for flavor '%(flavor)s': %(e)s") LOG.error(msg, {'flavor': parsed_args.flavor, 'e': e}) - flavor = resource_flavor._info.copy() - flavor.update({ - 'access_project_ids': access_projects - }) - - flavor['properties'] = resource_flavor.get_keys() + # Since we need to inject "access_project_id" into resource - convert + # it to dict and treat it respectively + flavor = flavor.to_dict() + flavor['access_project_ids'] = access_projects display_columns, columns = _get_flavor_columns(flavor) data = utils.get_dict_properties( - flavor, columns, - formatters=_formatters, - mixed_case_fields=['OS-FLV-DISABLED:disabled', - 'OS-FLV-EXT-DATA:ephemeral']) + flavor, columns, formatters=_formatters) return (display_columns, data) @@ -512,32 +522,40 @@ class UnsetFlavor(command.Command): return parser def take_action(self, parsed_args): - compute_client = self.app.client_manager.compute + compute_client = self.app.client_manager.sdk_connection.compute identity_client = self.app.client_manager.identity - flavor = _find_flavor(compute_client, parsed_args.flavor) + try: + flavor = compute_client.find_flavor( + parsed_args.flavor, + get_extra_specs=True, + ignore_missing=False) + except sdk_exceptions.ResourceNotFound as e: + raise exceptions.CommandError(_(e.message)) result = 0 if parsed_args.property: - try: - flavor.unset_keys(parsed_args.property) - except Exception as e: - LOG.error(_("Failed to unset flavor property: %s"), e) - result += 1 + for key in parsed_args.property: + try: + compute_client.delete_flavor_extra_specs_property( + flavor.id, key) + except sdk_exceptions.SDKException as e: + LOG.error(_("Failed to unset flavor property: %s"), e) + result += 1 if parsed_args.project: try: if flavor.is_public: msg = _("Cannot remove access for a public flavor") raise exceptions.CommandError(msg) - else: - project_id = identity_common.find_project( - identity_client, - parsed_args.project, - parsed_args.project_domain, - ).id - compute_client.flavor_access.remove_tenant_access( - flavor.id, project_id) + + project_id = identity_common.find_project( + identity_client, + parsed_args.project, + parsed_args.project_domain, + ).id + compute_client.flavor_remove_tenant_access( + flavor.id, project_id) except Exception as e: LOG.error(_("Failed to remove flavor access from project: %s"), e) diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py index c6da0fba..24c09ed1 100644 --- a/openstackclient/compute/v2/server.py +++ b/openstackclient/compute/v2/server.py @@ -711,7 +711,12 @@ class CreateServer(command.ShowOne): parser.add_argument( '--availability-zone', metavar='<zone-name>', - help=_('Select an availability zone for the server'), + help=_('Select an availability zone for the server. ' + 'Host and node are optional parameters. ' + 'Availability zone in the format ' + '<zone-name>:<host-name>:<node-name>, ' + '<zone-name>::<node-name>, <zone-name>:<host-name> ' + 'or <zone-name>'), ) parser.add_argument( '--host', @@ -2443,47 +2448,57 @@ class RebuildServer(command.ShowOne): parser.add_argument( '--image', metavar='<image>', - help=_('Recreate server from the specified image (name or ID).' - ' Defaults to the currently used one.'), + help=_( + 'Recreate server from the specified image (name or ID).' + 'Defaults to the currently used one.' + ), ) parser.add_argument( '--password', metavar='<password>', - help=_("Set the password on the rebuilt instance"), + help=_('Set a password on the rebuilt server'), ) parser.add_argument( '--property', metavar='<key=value>', action=parseractions.KeyValueAction, - help=_('Set a property on the rebuilt instance ' - '(repeat option to set multiple values)'), + help=_( + 'Set a new property on the rebuilt server ' + '(repeat option to set multiple values)' + ), ) parser.add_argument( '--description', metavar='<description>', - help=_('New description for the server (supported by ' - '--os-compute-api-version 2.19 or above'), - ) - parser.add_argument( - '--wait', - action='store_true', - help=_('Wait for rebuild to complete'), + help=_( + 'Set a new description on the rebuilt server ' + '(supported by --os-compute-api-version 2.19 or above)' + ), ) key_group = parser.add_mutually_exclusive_group() key_group.add_argument( '--key-name', metavar='<key-name>', - help=_("Set the key name of key pair on the rebuilt instance." - " Cannot be specified with the '--key-unset' option." - " (Supported by API versions '2.54' - '2.latest')"), + help=_( + 'Set the key name of key pair on the rebuilt server. ' + 'Cannot be specified with the --key-unset option. ' + '(supported by --os-compute-api-version 2.54 or above)' + ), ) key_group.add_argument( '--key-unset', action='store_true', default=False, - help=_("Unset the key name of key pair on the rebuilt instance." - " Cannot be specified with the '--key-name' option." - " (Supported by API versions '2.54' - '2.latest')"), + help=_( + 'Unset the key name of key pair on the rebuilt server. ' + 'Cannot be specified with the --key-name option. ' + '(supported by --os-compute-api-version 2.54 or above)' + ), + ) + parser.add_argument( + '--wait', + action='store_true', + help=_('Wait for rebuild to complete'), ) return parser @@ -2509,24 +2524,38 @@ class RebuildServer(command.ShowOne): image = image_client.get_image(image_id) kwargs = {} + if parsed_args.property: kwargs['meta'] = parsed_args.property + if parsed_args.description: if server.api_version < api_versions.APIVersion("2.19"): - msg = _("Description is not supported for " - "--os-compute-api-version less than 2.19") + msg = _( + '--os-compute-api-version 2.19 or greater is required to ' + 'support the --description option' + ) raise exceptions.CommandError(msg) + kwargs['description'] = parsed_args.description - if parsed_args.key_name or parsed_args.key_unset: + if parsed_args.key_name: + if compute_client.api_version < api_versions.APIVersion('2.54'): + msg = _( + '--os-compute-api-version 2.54 or greater is required to ' + 'support the --key-name option' + ) + raise exceptions.CommandError(msg) + + kwargs['key_name'] = parsed_args.key_name + elif parsed_args.key_unset: if compute_client.api_version < api_versions.APIVersion('2.54'): - msg = _('--os-compute-api-version 2.54 or later is required') + msg = _( + '--os-compute-api-version 2.54 or greater is required to ' + 'support the --no-key-name option' + ) raise exceptions.CommandError(msg) - if parsed_args.key_unset: kwargs['key_name'] = None - if parsed_args.key_name: - kwargs['key_name'] = parsed_args.key_name server = server.rebuild(image, parsed_args.password, **kwargs) if parsed_args.wait: @@ -2537,13 +2566,12 @@ class RebuildServer(command.ShowOne): ): self.app.stdout.write(_('Complete\n')) else: - LOG.error(_('Error rebuilding server: %s'), - server.id) + LOG.error(_('Error rebuilding server: %s'), server.id) self.app.stdout.write(_('Error rebuilding server\n')) raise SystemExit - details = _prep_server_detail(compute_client, image_client, server, - refresh=False) + details = _prep_server_detail( + compute_client, image_client, server, refresh=False) return zip(*sorted(details.items())) diff --git a/openstackclient/identity/v2_0/catalog.py b/openstackclient/identity/v2_0/catalog.py index ccedbf33..05d0e9ae 100644 --- a/openstackclient/identity/v2_0/catalog.py +++ b/openstackclient/identity/v2_0/catalog.py @@ -91,7 +91,7 @@ class ShowCatalog(command.ShowOne): for service in auth_ref.service_catalog.catalog: if (service.get('name') == parsed_args.service or service.get('type') == parsed_args.service): - data = service + data = service.copy() data['endpoints'] = EndpointsColumn(data['endpoints']) if 'endpoints_links' in data: data.pop('endpoints_links') diff --git a/openstackclient/identity/v3/identity_provider.py b/openstackclient/identity/v3/identity_provider.py index 2b2d9d11..7307cea0 100644 --- a/openstackclient/identity/v3/identity_provider.py +++ b/openstackclient/identity/v3/identity_provider.py @@ -143,10 +143,32 @@ class DeleteIdentityProvider(command.Command): class ListIdentityProvider(command.Lister): _description = _("List identity providers") + def get_parser(self, prog_name): + parser = super(ListIdentityProvider, self).get_parser(prog_name) + parser.add_argument( + '--id', + metavar='<id>', + help=_('The Identity Providers’ ID attribute'), + ) + parser.add_argument( + '--enabled', + dest='enabled', + action='store_true', + help=_('The Identity Providers that are enabled will be returned'), + ) + return parser + def take_action(self, parsed_args): columns = ('ID', 'Enabled', 'Domain ID', 'Description') identity_client = self.app.client_manager.identity - data = identity_client.federation.identity_providers.list() + + kwargs = {} + if parsed_args.id: + kwargs['id'] = parsed_args.id + if parsed_args.enabled: + kwargs['enabled'] = True + + data = identity_client.federation.identity_providers.list(**kwargs) return (columns, (utils.get_item_properties( s, columns, diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py index cf1d6817..64aa3fcd 100644 --- a/openstackclient/image/v1/image.py +++ b/openstackclient/image/v1/image.py @@ -478,7 +478,11 @@ class SaveImage(command.Command): image_client = self.app.client_manager.image image = image_client.find_image(parsed_args.image) - image_client.download_image(image.id, output=parsed_args.file) + output_file = parsed_args.file + if output_file is None: + output_file = getattr(sys.stdout, "buffer", sys.stdout) + + image_client.download_image(image.id, stream=True, output=output_file) class SetImage(command.Command): diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py index 4f3e9d0b..58d92f51 100644 --- a/openstackclient/image/v2/image.py +++ b/openstackclient/image/v2/image.py @@ -803,7 +803,11 @@ class SaveImage(command.Command): image_client = self.app.client_manager.image image = image_client.find_image(parsed_args.image) - image_client.download_image(image.id, output=parsed_args.file) + output_file = parsed_args.file + if output_file is None: + output_file = getattr(sys.stdout, "buffer", sys.stdout) + + image_client.download_image(image.id, stream=True, output=output_file) class SetImage(command.Command): diff --git a/openstackclient/tests/unit/common/test_quota.py b/openstackclient/tests/unit/common/test_quota.py index 6504c5b0..8771359c 100644 --- a/openstackclient/tests/unit/common/test_quota.py +++ b/openstackclient/tests/unit/common/test_quota.py @@ -1087,3 +1087,26 @@ class TestQuotaShow(TestQuota): identity_fakes.project_id, details=False ) self.assertNotCalled(self.network.get_quota_default) + + def test_network_quota_show_remove_empty(self): + arglist = [ + self.projects[0].name, + ] + verifylist = [ + ('project', self.projects[0].name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # First check that all regular values are returned + result = self.cmd.get_network_quota(parsed_args) + self.assertEqual(len(network_fakes.QUOTA), len(result)) + + # set 1 of the values to None, and verify it is not returned + orig_get_quota = self.network.get_quota + network_quotas = copy.copy(network_fakes.QUOTA) + network_quotas['healthmonitor'] = None + self.network.get_quota = mock.Mock(return_value=network_quotas) + result = self.cmd.get_network_quota(parsed_args) + self.assertEqual(len(network_fakes.QUOTA) - 1, len(result)) + # Go back to default mock + self.network.get_quota = orig_get_quota diff --git a/openstackclient/tests/unit/compute/v2/fakes.py b/openstackclient/tests/unit/compute/v2/fakes.py index 3a06d271..d3d037a9 100644 --- a/openstackclient/tests/unit/compute/v2/fakes.py +++ b/openstackclient/tests/unit/compute/v2/fakes.py @@ -19,6 +19,7 @@ from unittest import mock import uuid from novaclient import api_versions +from openstack.compute.v2 import flavor as _flavor from openstackclient.api import compute_v2 from openstackclient.tests.unit import fakes @@ -164,7 +165,6 @@ class FakeComputev2Client(object): self.extensions.resource_class = fakes.FakeResource(None, {}) self.flavors = mock.Mock() - self.flavors.resource_class = fakes.FakeResource(None, {}) self.flavor_access = mock.Mock() self.flavor_access.resource_class = fakes.FakeResource(None, {}) @@ -777,27 +777,13 @@ class FakeFlavor(object): 'os-flavor-access:is_public': True, 'description': 'description', 'OS-FLV-EXT-DATA:ephemeral': 0, - 'properties': {'property': 'value'}, + 'extra_specs': {'property': 'value'}, } # Overwrite default attributes. flavor_info.update(attrs) - # Set default methods. - flavor_methods = { - 'set_keys': None, - 'unset_keys': None, - 'get_keys': {'property': 'value'}, - } - - flavor = fakes.FakeResource(info=copy.deepcopy(flavor_info), - methods=flavor_methods, - 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'] + flavor = _flavor.Flavor(**flavor_info) return flavor diff --git a/openstackclient/tests/unit/compute/v2/test_aggregate.py b/openstackclient/tests/unit/compute/v2/test_aggregate.py index cd0c1525..e12edd0f 100644 --- a/openstackclient/tests/unit/compute/v2/test_aggregate.py +++ b/openstackclient/tests/unit/compute/v2/test_aggregate.py @@ -16,12 +16,14 @@ from unittest import mock from unittest.mock import call +from openstack import exceptions as sdk_exceptions +from openstack import utils as sdk_utils from osc_lib.cli import format_columns from osc_lib import exceptions -from osc_lib import utils from openstackclient.compute.v2 import aggregate from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes +from openstackclient.tests.unit.image.v2 import fakes as image_fakes class TestAggregate(compute_fakes.TestComputev2): @@ -48,8 +50,17 @@ class TestAggregate(compute_fakes.TestComputev2): super(TestAggregate, self).setUp() # Get a shortcut to the AggregateManager Mock - self.aggregate_mock = self.app.client_manager.compute.aggregates - self.aggregate_mock.reset_mock() + self.app.client_manager.sdk_connection = mock.Mock() + self.app.client_manager.sdk_connection.compute = mock.Mock() + self.sdk_client = self.app.client_manager.sdk_connection.compute + self.sdk_client.aggregates = mock.Mock() + self.sdk_client.find_aggregate = mock.Mock() + self.sdk_client.create_aggregate = mock.Mock() + self.sdk_client.update_aggregate = mock.Mock() + self.sdk_client.update_aggregate = mock.Mock() + self.sdk_client.set_aggregate_metadata = mock.Mock() + self.sdk_client.add_host_to_aggregate = mock.Mock() + self.sdk_client.remove_host_from_aggregate = mock.Mock() class TestAggregateAddHost(TestAggregate): @@ -57,8 +68,8 @@ class TestAggregateAddHost(TestAggregate): def setUp(self): super(TestAggregateAddHost, self).setUp() - self.aggregate_mock.get.return_value = self.fake_ag - self.aggregate_mock.add_host.return_value = self.fake_ag + self.sdk_client.find_aggregate.return_value = self.fake_ag + self.sdk_client.add_host_to_aggregate.return_value = self.fake_ag self.cmd = aggregate.AddAggregateHost(self.app, None) def test_aggregate_add_host(self): @@ -72,11 +83,12 @@ class TestAggregateAddHost(TestAggregate): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate) - self.aggregate_mock.add_host.assert_called_once_with(self.fake_ag, - parsed_args.host) + self.sdk_client.find_aggregate.assert_called_once_with( + parsed_args.aggregate, ignore_missing=False) + self.sdk_client.add_host_to_aggregate.assert_called_once_with( + self.fake_ag.id, parsed_args.host) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) class TestAggregateCreate(TestAggregate): @@ -84,8 +96,8 @@ class TestAggregateCreate(TestAggregate): def setUp(self): super(TestAggregateCreate, self).setUp() - self.aggregate_mock.create.return_value = self.fake_ag - self.aggregate_mock.set_metadata.return_value = self.fake_ag + self.sdk_client.create_aggregate.return_value = self.fake_ag + self.sdk_client.set_aggregate_metadata.return_value = self.fake_ag self.cmd = aggregate.CreateAggregate(self.app, None) def test_aggregate_create(self): @@ -97,10 +109,10 @@ class TestAggregateCreate(TestAggregate): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.aggregate_mock.create.assert_called_once_with(parsed_args.name, - None) + self.sdk_client.create_aggregate.assert_called_once_with( + name=parsed_args.name) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_aggregate_create_with_zone(self): arglist = [ @@ -114,10 +126,10 @@ class TestAggregateCreate(TestAggregate): parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.aggregate_mock.create.assert_called_once_with(parsed_args.name, - parsed_args.zone) + self.sdk_client.create_aggregate.assert_called_once_with( + name=parsed_args.name, availability_zone=parsed_args.zone) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_aggregate_create_with_property(self): arglist = [ @@ -131,12 +143,12 @@ class TestAggregateCreate(TestAggregate): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.aggregate_mock.create.assert_called_once_with(parsed_args.name, - None) - self.aggregate_mock.set_metadata.assert_called_once_with( - self.fake_ag, parsed_args.property) + self.sdk_client.create_aggregate.assert_called_once_with( + name=parsed_args.name) + self.sdk_client.set_aggregate_metadata.assert_called_once_with( + self.fake_ag.id, parsed_args.property) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) class TestAggregateDelete(TestAggregate): @@ -146,7 +158,7 @@ class TestAggregateDelete(TestAggregate): def setUp(self): super(TestAggregateDelete, self).setUp() - self.aggregate_mock.get = ( + self.sdk_client.find_aggregate = ( compute_fakes.FakeAggregate.get_aggregates(self.fake_ags)) self.cmd = aggregate.DeleteAggregate(self.app, None) @@ -158,10 +170,11 @@ class TestAggregateDelete(TestAggregate): ('aggregate', [self.fake_ags[0].id]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - result = self.cmd.take_action(parsed_args) - self.aggregate_mock.get.assert_called_once_with(self.fake_ags[0].id) - self.aggregate_mock.delete.assert_called_once_with(self.fake_ags[0].id) - self.assertIsNone(result) + self.cmd.take_action(parsed_args) + self.sdk_client.find_aggregate.assert_called_once_with( + self.fake_ags[0].id, ignore_missing=False) + self.sdk_client.delete_aggregate.assert_called_once_with( + self.fake_ags[0].id, ignore_missing=False) def test_delete_multiple_aggregates(self): arglist = [] @@ -172,13 +185,13 @@ class TestAggregateDelete(TestAggregate): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - result = self.cmd.take_action(parsed_args) + self.cmd.take_action(parsed_args) calls = [] for a in self.fake_ags: - calls.append(call(a.id)) - self.aggregate_mock.delete.assert_has_calls(calls) - self.assertIsNone(result) + calls.append(call(a.id, ignore_missing=False)) + self.sdk_client.find_aggregate.assert_has_calls(calls) + self.sdk_client.delete_aggregate.assert_has_calls(calls) def test_delete_multiple_agggregates_with_exception(self): arglist = [ @@ -191,23 +204,21 @@ class TestAggregateDelete(TestAggregate): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - find_mock_result = [self.fake_ags[0], exceptions.CommandError] - with mock.patch.object(utils, 'find_resource', - side_effect=find_mock_result) as find_mock: - try: - self.cmd.take_action(parsed_args) - self.fail('CommandError should be raised.') - except exceptions.CommandError as e: - self.assertEqual('1 of 2 aggregates failed to delete.', - str(e)) - - find_mock.assert_any_call(self.aggregate_mock, self.fake_ags[0].id) - find_mock.assert_any_call(self.aggregate_mock, 'unexist_aggregate') + self.sdk_client.find_aggregate.side_effect = [ + self.fake_ags[0], sdk_exceptions.NotFoundException] + try: + self.cmd.take_action(parsed_args) + self.fail('CommandError should be raised.') + except exceptions.CommandError as e: + self.assertEqual('1 of 2 aggregates failed to delete.', + str(e)) - self.assertEqual(2, find_mock.call_count) - self.aggregate_mock.delete.assert_called_once_with( - self.fake_ags[0].id - ) + calls = [] + for a in arglist: + calls.append(call(a, ignore_missing=False)) + self.sdk_client.find_aggregate.assert_has_calls(calls) + self.sdk_client.delete_aggregate.assert_called_with( + self.fake_ags[0].id, ignore_missing=False) class TestAggregateList(TestAggregate): @@ -245,7 +256,7 @@ class TestAggregateList(TestAggregate): def setUp(self): super(TestAggregateList, self).setUp() - self.aggregate_mock.list.return_value = [self.fake_ag] + self.sdk_client.aggregates.return_value = [self.fake_ag] self.cmd = aggregate.ListAggregate(self.app, None) def test_aggregate_list(self): @@ -254,7 +265,7 @@ class TestAggregateList(TestAggregate): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.list_columns, columns) - self.assertItemEqual(self.list_data, tuple(data)) + self.assertItemsEqual(self.list_data, tuple(data)) def test_aggregate_list_with_long(self): arglist = [ @@ -267,7 +278,7 @@ class TestAggregateList(TestAggregate): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.list_columns_long, columns) - self.assertListItemEqual(self.list_data_long, tuple(data)) + self.assertItemsEqual(self.list_data_long, tuple(data)) class TestAggregateRemoveHost(TestAggregate): @@ -275,11 +286,11 @@ class TestAggregateRemoveHost(TestAggregate): def setUp(self): super(TestAggregateRemoveHost, self).setUp() - self.aggregate_mock.get.return_value = self.fake_ag - self.aggregate_mock.remove_host.return_value = self.fake_ag + self.sdk_client.find_aggregate.return_value = self.fake_ag + self.sdk_client.remove_host_from_aggregate.return_value = self.fake_ag self.cmd = aggregate.RemoveAggregateHost(self.app, None) - def test_aggregate_add_host(self): + def test_aggregate_remove_host(self): arglist = [ 'ag1', 'host1', @@ -290,11 +301,12 @@ class TestAggregateRemoveHost(TestAggregate): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate) - self.aggregate_mock.remove_host.assert_called_once_with( - self.fake_ag, parsed_args.host) + self.sdk_client.find_aggregate.assert_called_once_with( + parsed_args.aggregate, ignore_missing=False) + self.sdk_client.remove_host_from_aggregate.assert_called_once_with( + self.fake_ag.id, parsed_args.host) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) class TestAggregateSet(TestAggregate): @@ -302,7 +314,7 @@ class TestAggregateSet(TestAggregate): def setUp(self): super(TestAggregateSet, self).setUp() - self.aggregate_mock.get.return_value = self.fake_ag + self.sdk_client.find_aggregate.return_value = self.fake_ag self.cmd = aggregate.SetAggregate(self.app, None) def test_aggregate_set_no_option(self): @@ -315,9 +327,10 @@ class TestAggregateSet(TestAggregate): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate) - self.assertNotCalled(self.aggregate_mock.update) - self.assertNotCalled(self.aggregate_mock.set_metadata) + self.sdk_client.find_aggregate.assert_called_once_with( + parsed_args.aggregate, ignore_missing=False) + self.assertNotCalled(self.sdk_client.update_aggregate) + self.assertNotCalled(self.sdk_client.set_aggregate_metadata) self.assertIsNone(result) def test_aggregate_set_with_name(self): @@ -332,10 +345,11 @@ class TestAggregateSet(TestAggregate): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate) - self.aggregate_mock.update.assert_called_once_with( - self.fake_ag, {'name': parsed_args.name}) - self.assertNotCalled(self.aggregate_mock.set_metadata) + self.sdk_client.find_aggregate.assert_called_once_with( + parsed_args.aggregate, ignore_missing=False) + self.sdk_client.update_aggregate.assert_called_once_with( + self.fake_ag.id, name=parsed_args.name) + self.assertNotCalled(self.sdk_client.set_aggregate_metadata) self.assertIsNone(result) def test_aggregate_set_with_zone(self): @@ -350,10 +364,11 @@ class TestAggregateSet(TestAggregate): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate) - self.aggregate_mock.update.assert_called_once_with( - self.fake_ag, {'availability_zone': parsed_args.zone}) - self.assertNotCalled(self.aggregate_mock.set_metadata) + self.sdk_client.find_aggregate.assert_called_once_with( + parsed_args.aggregate, ignore_missing=False) + self.sdk_client.update_aggregate.assert_called_once_with( + self.fake_ag.id, availability_zone=parsed_args.zone) + self.assertNotCalled(self.sdk_client.set_aggregate_metadata) self.assertIsNone(result) def test_aggregate_set_with_property(self): @@ -369,10 +384,11 @@ class TestAggregateSet(TestAggregate): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate) - self.assertNotCalled(self.aggregate_mock.update) - self.aggregate_mock.set_metadata.assert_called_once_with( - self.fake_ag, parsed_args.property) + self.sdk_client.find_aggregate.assert_called_once_with( + parsed_args.aggregate, ignore_missing=False) + self.assertNotCalled(self.sdk_client.update_aggregate) + self.sdk_client.set_aggregate_metadata.assert_called_once_with( + self.fake_ag.id, parsed_args.property) self.assertIsNone(result) def test_aggregate_set_with_no_property_and_property(self): @@ -388,10 +404,11 @@ class TestAggregateSet(TestAggregate): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate) - self.assertNotCalled(self.aggregate_mock.update) - self.aggregate_mock.set_metadata.assert_called_once_with( - self.fake_ag, {'key1': None, 'key2': 'value2'}) + self.sdk_client.find_aggregate.assert_called_once_with( + parsed_args.aggregate, ignore_missing=False) + self.assertNotCalled(self.sdk_client.update_aggregate) + self.sdk_client.set_aggregate_metadata.assert_called_once_with( + self.fake_ag.id, {'key1': None, 'key2': 'value2'}) self.assertIsNone(result) def test_aggregate_set_with_no_property(self): @@ -405,10 +422,11 @@ class TestAggregateSet(TestAggregate): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate) - self.assertNotCalled(self.aggregate_mock.update) - self.aggregate_mock.set_metadata.assert_called_once_with( - self.fake_ag, {'key1': None}) + self.sdk_client.find_aggregate.assert_called_once_with( + parsed_args.aggregate, ignore_missing=False) + self.assertNotCalled(self.sdk_client.update_aggregate) + self.sdk_client.set_aggregate_metadata.assert_called_once_with( + self.fake_ag.id, {'key1': None}) self.assertIsNone(result) def test_aggregate_set_with_zone_and_no_property(self): @@ -424,11 +442,12 @@ class TestAggregateSet(TestAggregate): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate) - self.aggregate_mock.update.assert_called_once_with( - self.fake_ag, {'availability_zone': parsed_args.zone}) - self.aggregate_mock.set_metadata.assert_called_once_with( - self.fake_ag, {'key1': None}) + self.sdk_client.find_aggregate.assert_called_once_with( + parsed_args.aggregate, ignore_missing=False) + self.sdk_client.update_aggregate.assert_called_once_with( + self.fake_ag.id, availability_zone=parsed_args.zone) + self.sdk_client.set_aggregate_metadata.assert_called_once_with( + self.fake_ag.id, {'key1': None}) self.assertIsNone(result) @@ -457,7 +476,7 @@ class TestAggregateShow(TestAggregate): def setUp(self): super(TestAggregateShow, self).setUp() - self.aggregate_mock.get.return_value = self.fake_ag + self.sdk_client.find_aggregate.return_value = self.fake_ag self.cmd = aggregate.ShowAggregate(self.app, None) def test_aggregate_show(self): @@ -469,10 +488,11 @@ class TestAggregateShow(TestAggregate): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.aggregate_mock.get.assert_called_once_with(parsed_args.aggregate) + self.sdk_client.find_aggregate.assert_called_once_with( + parsed_args.aggregate, ignore_missing=False) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, tuple(data)) + self.assertItemsEqual(self.data, tuple(data)) class TestAggregateUnset(TestAggregate): @@ -480,7 +500,7 @@ class TestAggregateUnset(TestAggregate): def setUp(self): super(TestAggregateUnset, self).setUp() - self.aggregate_mock.get.return_value = self.fake_ag + self.sdk_client.find_aggregate.return_value = self.fake_ag self.cmd = aggregate.UnsetAggregate(self.app, None) def test_aggregate_unset(self): @@ -495,7 +515,7 @@ class TestAggregateUnset(TestAggregate): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.aggregate_mock.set_metadata.assert_called_once_with( + self.sdk_client.set_aggregate_metadata.assert_called_once_with( self.fake_ag, {'unset_key': None}) self.assertIsNone(result) @@ -512,7 +532,7 @@ class TestAggregateUnset(TestAggregate): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.aggregate_mock.set_metadata.assert_called_once_with( + self.sdk_client.set_aggregate_metadata.assert_called_once_with( self.fake_ag, {'unset_key1': None, 'unset_key2': None}) self.assertIsNone(result) @@ -526,5 +546,72 @@ class TestAggregateUnset(TestAggregate): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.assertNotCalled(self.aggregate_mock.set_metadata) + self.assertNotCalled(self.sdk_client.set_aggregate_metadata) self.assertIsNone(result) + + +class TestAggregateCacheImage(TestAggregate): + + images = image_fakes.FakeImage.create_images(count=2) + + def setUp(self): + super(TestAggregateCacheImage, self).setUp() + + self.sdk_client.find_aggregate.return_value = self.fake_ag + self.find_image_mock = mock.Mock(side_effect=self.images) + self.app.client_manager.sdk_connection.image.find_image = \ + self.find_image_mock + + self.cmd = aggregate.CacheImageForAggregate(self.app, None) + + @mock.patch.object(sdk_utils, 'supports_microversion', return_value=False) + def test_aggregate_not_supported(self, sm_mock): + arglist = [ + 'ag1', + 'im1' + ] + verifylist = [ + ('aggregate', 'ag1'), + ('image', ['im1']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises( + exceptions.CommandError, + self.cmd.take_action, + parsed_args + ) + + @mock.patch.object(sdk_utils, 'supports_microversion', return_value=True) + def test_aggregate_add_single_image(self, sm_mock): + arglist = [ + 'ag1', + 'im1' + ] + verifylist = [ + ('aggregate', 'ag1'), + ('image', ['im1']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + self.sdk_client.find_aggregate.assert_called_once_with( + parsed_args.aggregate, ignore_missing=False) + self.sdk_client.aggregate_precache_images.assert_called_once_with( + self.fake_ag.id, [self.images[0].id]) + + @mock.patch.object(sdk_utils, 'supports_microversion', return_value=True) + def test_aggregate_add_multiple_images(self, sm_mock): + arglist = [ + 'ag1', + 'im1', + 'im2', + ] + verifylist = [ + ('aggregate', 'ag1'), + ('image', ['im1', 'im2']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + self.sdk_client.find_aggregate.assert_called_once_with( + parsed_args.aggregate, ignore_missing=False) + self.sdk_client.aggregate_precache_images.assert_called_once_with( + self.fake_ag.id, [self.images[0].id, self.images[1].id]) diff --git a/openstackclient/tests/unit/compute/v2/test_flavor.py b/openstackclient/tests/unit/compute/v2/test_flavor.py index 2828d74e..4c4882ec 100644 --- a/openstackclient/tests/unit/compute/v2/test_flavor.py +++ b/openstackclient/tests/unit/compute/v2/test_flavor.py @@ -12,11 +12,11 @@ # License for the specific language governing permissions and limitations # under the License. # - from unittest import mock -from unittest.mock import call -import novaclient +from openstack.compute.v2 import flavor as _flavor +from openstack import exceptions as sdk_exceptions +from openstack import utils as sdk_utils from osc_lib.cli import format_columns from osc_lib import exceptions @@ -31,13 +31,19 @@ class TestFlavor(compute_fakes.TestComputev2): def setUp(self): super(TestFlavor, self).setUp() - # Get a shortcut to the FlavorManager Mock - self.flavors_mock = self.app.client_manager.compute.flavors - self.flavors_mock.reset_mock() - - # Get a shortcut to the FlavorAccessManager Mock - self.flavor_access_mock = self.app.client_manager.compute.flavor_access - self.flavor_access_mock.reset_mock() + # SDK mock + self.app.client_manager.sdk_connection = mock.Mock() + self.app.client_manager.sdk_connection.compute = mock.Mock() + self.sdk_client = self.app.client_manager.sdk_connection.compute + self.sdk_client.flavors = mock.Mock() + self.sdk_client.find_flavor = mock.Mock() + self.sdk_client.delete_flavor = mock.Mock() + self.sdk_client.update_flavor = mock.Mock() + self.sdk_client.flavor_add_tenant_access = mock.Mock() + self.sdk_client.flavor_remove_tenant_access = mock.Mock() + self.sdk_client.create_flavor_extra_specs = mock.Mock() + self.sdk_client.update_flavor_extra_specs_property = mock.Mock() + self.sdk_client.delete_flavor_extra_specs_property = mock.Mock() self.projects_mock = self.app.client_manager.identity.projects self.projects_mock.reset_mock() @@ -48,6 +54,7 @@ class TestFlavorCreate(TestFlavor): flavor = compute_fakes.FakeFlavor.create_one_flavor( attrs={'links': 'flavor-links'}) project = identity_fakes.FakeProject.create_one_project() + columns = ( 'OS-FLV-DISABLED:disabled', 'OS-FLV-EXT-DATA:ephemeral', @@ -60,17 +67,32 @@ class TestFlavorCreate(TestFlavor): 'ram', 'rxtx_factor', 'swap', - 'vcpus', + 'vcpus' ) + data = ( - flavor.disabled, + flavor.is_disabled, flavor.ephemeral, flavor.description, flavor.disk, flavor.id, flavor.name, flavor.is_public, - format_columns.DictColumn(flavor.properties), + format_columns.DictColumn(flavor.extra_specs), + flavor.ram, + flavor.rxtx_factor, + flavor.swap, + flavor.vcpus, + ) + data_private = ( + flavor.is_disabled, + flavor.ephemeral, + flavor.description, + flavor.disk, + flavor.id, + flavor.name, + False, + format_columns.DictColumn(flavor.extra_specs), flavor.ram, flavor.rxtx_factor, flavor.swap, @@ -82,7 +104,7 @@ class TestFlavorCreate(TestFlavor): # Return a project self.projects_mock.get.return_value = self.project - self.flavors_mock.create.return_value = self.flavor + self.sdk_client.create_flavor.return_value = self.flavor self.cmd = flavor.CreateFlavor(self.app, None) def test_flavor_create_default_options(self): @@ -95,23 +117,23 @@ class TestFlavorCreate(TestFlavor): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - default_args = ( - self.flavor.name, - 256, - 1, - 0, - 'auto', - 0, - 0, - 1.0, - True, - None, - ) + default_args = { + 'name': self.flavor.name, + 'ram': 256, + 'vcpus': 1, + 'disk': 0, + 'id': None, + 'ephemeral': 0, + 'swap': 0, + 'rxtx_factor': 1.0, + 'is_public': True, + } + columns, data = self.cmd.take_action(parsed_args) - self.flavors_mock.create.assert_called_once_with(*default_args) + self.sdk_client.create_flavor.assert_called_once_with(**default_args) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_flavor_create_all_options(self): @@ -143,29 +165,44 @@ class TestFlavorCreate(TestFlavor): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - args = ( - self.flavor.name, - self.flavor.ram, - self.flavor.vcpus, - self.flavor.disk, - self.flavor.id, - self.flavor.ephemeral, - self.flavor.swap, - self.flavor.rxtx_factor, - self.flavor.is_public, - self.flavor.description, - ) - self.app.client_manager.compute.api_version = 2.55 - with mock.patch.object(novaclient.api_versions, - 'APIVersion', - return_value=2.55): + args = { + 'name': self.flavor.name, + 'ram': self.flavor.ram, + 'vcpus': self.flavor.vcpus, + 'disk': self.flavor.disk, + 'id': self.flavor.id, + 'ephemeral': self.flavor.ephemeral, + 'swap': self.flavor.swap, + 'rxtx_factor': self.flavor.rxtx_factor, + 'is_public': self.flavor.is_public, + 'description': self.flavor.description + } + + props = {'property': 'value'} + + # SDK updates the flavor object instance. In order to make the + # verification clear and preciese let's create new flavor and change + # expected props this way + create_flavor = _flavor.Flavor(**self.flavor) + expected_flavor = _flavor.Flavor(**self.flavor) + expected_flavor.extra_specs = props + # convert expected data tuple to list to be able to modify it + cmp_data = list(self.data) + cmp_data[7] = format_columns.DictColumn(props) + self.sdk_client.create_flavor.return_value = create_flavor + self.sdk_client.create_flavor_extra_specs.return_value = \ + expected_flavor + + with mock.patch.object(sdk_utils, 'supports_microversion', + return_value=True): columns, data = self.cmd.take_action(parsed_args) - self.flavors_mock.create.assert_called_once_with(*args) - self.flavor.set_keys.assert_called_once_with({'property': 'value'}) - self.flavor.get_keys.assert_called_once_with() + self.sdk_client.create_flavor.assert_called_once_with(**args) + self.sdk_client.create_flavor_extra_specs.assert_called_once_with( + create_flavor, props) + self.sdk_client.get_flavor_access.assert_not_called() self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(tuple(cmp_data), data) def test_flavor_create_other_options(self): @@ -200,33 +237,47 @@ class TestFlavorCreate(TestFlavor): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - args = ( - self.flavor.name, - self.flavor.ram, - self.flavor.vcpus, - self.flavor.disk, - 'auto', - self.flavor.ephemeral, - self.flavor.swap, - self.flavor.rxtx_factor, - self.flavor.is_public, - self.flavor.description, - ) - self.app.client_manager.compute.api_version = 2.55 - with mock.patch.object(novaclient.api_versions, - 'APIVersion', - return_value=2.55): + args = { + 'name': self.flavor.name, + 'ram': self.flavor.ram, + 'vcpus': self.flavor.vcpus, + 'disk': self.flavor.disk, + 'id': 'auto', + 'ephemeral': self.flavor.ephemeral, + 'swap': self.flavor.swap, + 'rxtx_factor': self.flavor.rxtx_factor, + 'is_public': False, + 'description': self.flavor.description + } + + props = {'key1': 'value1', 'key2': 'value2'} + + # SDK updates the flavor object instance. In order to make the + # verification clear and preciese let's create new flavor and change + # expected props this way + create_flavor = _flavor.Flavor(**self.flavor) + expected_flavor = _flavor.Flavor(**self.flavor) + expected_flavor.extra_specs = props + expected_flavor.is_public = False + # convert expected data tuple to list to be able to modify it + cmp_data = list(self.data_private) + cmp_data[7] = format_columns.DictColumn(props) + self.sdk_client.create_flavor.return_value = create_flavor + self.sdk_client.create_flavor_extra_specs.return_value = \ + expected_flavor + + with mock.patch.object(sdk_utils, 'supports_microversion', + return_value=True): columns, data = self.cmd.take_action(parsed_args) - self.flavors_mock.create.assert_called_once_with(*args) - self.flavor_access_mock.add_tenant_access.assert_called_with( + self.sdk_client.create_flavor.assert_called_once_with(**args) + self.sdk_client.flavor_add_tenant_access.assert_called_with( self.flavor.id, self.project.id, ) - self.flavor.set_keys.assert_called_with( - {'key1': 'value1', 'key2': 'value2'}) - self.flavor.get_keys.assert_called_with() + self.sdk_client.create_flavor_extra_specs.assert_called_with( + create_flavor, props) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(cmp_data, data) def test_public_flavor_create_with_project(self): arglist = [ @@ -278,29 +329,28 @@ class TestFlavorCreate(TestFlavor): ('name', self.flavor.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.app.client_manager.compute.api_version = 2.55 - with mock.patch.object(novaclient.api_versions, - 'APIVersion', - return_value=2.55): + with mock.patch.object(sdk_utils, 'supports_microversion', + return_value=True): + columns, data = self.cmd.take_action(parsed_args) - args = ( - self.flavor.name, - self.flavor.ram, - self.flavor.vcpus, - self.flavor.disk, - self.flavor.id, - self.flavor.ephemeral, - self.flavor.swap, - self.flavor.rxtx_factor, - False, - 'fake description', - ) + args = { + 'name': self.flavor.name, + 'ram': self.flavor.ram, + 'vcpus': self.flavor.vcpus, + 'disk': self.flavor.disk, + 'id': self.flavor.id, + 'ephemeral': self.flavor.ephemeral, + 'swap': self.flavor.swap, + 'rxtx_factor': self.flavor.rxtx_factor, + 'is_public': self.flavor.is_public, + 'description': 'fake description' + } - self.flavors_mock.create.assert_called_once_with(*args) + self.sdk_client.create_flavor.assert_called_once_with(**args) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data_private, data) def test_flavor_create_with_description_api_older(self): arglist = [ @@ -318,10 +368,8 @@ class TestFlavorCreate(TestFlavor): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.app.client_manager.compute.api_version = 2.54 - with mock.patch.object(novaclient.api_versions, - 'APIVersion', - return_value=2.55): + with mock.patch.object(sdk_utils, 'supports_microversion', + return_value=False): self.assertRaises(exceptions.CommandError, self.cmd.take_action, parsed_args) @@ -333,9 +381,7 @@ class TestFlavorDelete(TestFlavor): def setUp(self): super(TestFlavorDelete, self).setUp() - self.flavors_mock.get = ( - compute_fakes.FakeFlavor.get_flavors(self.flavors)) - self.flavors_mock.delete.return_value = None + self.sdk_client.delete_flavor.return_value = None self.cmd = flavor.DeleteFlavor(self.app, None) @@ -348,9 +394,13 @@ class TestFlavorDelete(TestFlavor): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.sdk_client.find_flavor.return_value = self.flavors[0] + result = self.cmd.take_action(parsed_args) - self.flavors_mock.delete.assert_called_with(self.flavors[0].id) + self.sdk_client.find_flavor.assert_called_with(self.flavors[0].id, + ignore_missing=False) + self.sdk_client.delete_flavor.assert_called_with(self.flavors[0].id) self.assertIsNone(result) def test_delete_multiple_flavors(self): @@ -362,12 +412,17 @@ class TestFlavorDelete(TestFlavor): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.sdk_client.find_flavor.side_effect = self.flavors + result = self.cmd.take_action(parsed_args) - calls = [] - for f in self.flavors: - calls.append(call(f.id)) - self.flavors_mock.delete.assert_has_calls(calls) + find_calls = [ + mock.call(i.id, ignore_missing=False) for i in self.flavors + ] + delete_calls = [mock.call(i.id) for i in self.flavors] + self.sdk_client.find_flavor.assert_has_calls(find_calls) + self.sdk_client.delete_flavor.assert_has_calls(delete_calls) self.assertIsNone(result) def test_multi_flavors_delete_with_exception(self): @@ -380,11 +435,10 @@ class TestFlavorDelete(TestFlavor): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - find_mock_result = [self.flavors[0], exceptions.CommandError] - self.flavors_mock.get = ( - mock.Mock(side_effect=find_mock_result) - ) - self.flavors_mock.find.side_effect = exceptions.NotFound(None) + self.sdk_client.find_flavor.side_effect = [ + self.flavors[0], + sdk_exceptions.ResourceNotFound + ] try: self.cmd.take_action(parsed_args) @@ -392,15 +446,18 @@ class TestFlavorDelete(TestFlavor): except exceptions.CommandError as e: self.assertEqual('1 of 2 flavors failed to delete.', str(e)) - self.flavors_mock.get.assert_any_call(self.flavors[0].id) - self.flavors_mock.get.assert_any_call('unexist_flavor') - self.flavors_mock.delete.assert_called_once_with(self.flavors[0].id) + find_calls = [ + mock.call(self.flavors[0].id, ignore_missing=False), + mock.call('unexist_flavor', ignore_missing=False), + ] + delete_calls = [mock.call(self.flavors[0].id)] + self.sdk_client.find_flavor.assert_has_calls(find_calls) + self.sdk_client.delete_flavor.assert_has_calls(delete_calls) class TestFlavorList(TestFlavor): - # Return value of self.flavors_mock.list(). - flavors = compute_fakes.FakeFlavor.create_flavors(count=1) + _flavor = compute_fakes.FakeFlavor.create_one_flavor() columns = ( 'ID', @@ -418,24 +475,27 @@ class TestFlavorList(TestFlavor): ) data = (( - flavors[0].id, - flavors[0].name, - flavors[0].ram, - flavors[0].disk, - flavors[0].ephemeral, - flavors[0].vcpus, - flavors[0].is_public, - ), ) + _flavor.id, + _flavor.name, + _flavor.ram, + _flavor.disk, + _flavor.ephemeral, + _flavor.vcpus, + _flavor.is_public, + ),) data_long = (data[0] + ( - flavors[0].swap, - flavors[0].rxtx_factor, - format_columns.DictColumn(flavors[0].properties) + _flavor.swap, + _flavor.rxtx_factor, + format_columns.DictColumn(_flavor.extra_specs) ), ) def setUp(self): super(TestFlavorList, self).setUp() - self.flavors_mock.list.return_value = self.flavors + self.api_mock = mock.Mock() + self.api_mock.side_effect = [[self._flavor], [], ] + + self.sdk_client.flavors = self.api_mock # Get the command object to test self.cmd = flavor.ListFlavor(self.app, None) @@ -458,16 +518,14 @@ class TestFlavorList(TestFlavor): # Set expected values kwargs = { 'is_public': True, - 'limit': None, - 'marker': None } - self.flavors_mock.list.assert_called_with( + self.sdk_client.flavors.assert_called_with( **kwargs ) self.assertEqual(self.columns, columns) - self.assertEqual(tuple(self.data), tuple(data)) + self.assertEqual(self.data, tuple(data)) def test_flavor_list_all_flavors(self): arglist = [ @@ -487,16 +545,14 @@ class TestFlavorList(TestFlavor): # Set expected values kwargs = { 'is_public': None, - 'limit': None, - 'marker': None } - self.flavors_mock.list.assert_called_with( + self.sdk_client.flavors.assert_called_with( **kwargs ) self.assertEqual(self.columns, columns) - self.assertEqual(tuple(self.data), tuple(data)) + self.assertEqual(self.data, tuple(data)) def test_flavor_list_private_flavors(self): arglist = [ @@ -516,16 +572,14 @@ class TestFlavorList(TestFlavor): # Set expected values kwargs = { 'is_public': False, - 'limit': None, - 'marker': None } - self.flavors_mock.list.assert_called_with( + self.sdk_client.flavors.assert_called_with( **kwargs ) self.assertEqual(self.columns, columns) - self.assertEqual(tuple(self.data), tuple(data)) + self.assertEqual(self.data, tuple(data)) def test_flavor_list_public_flavors(self): arglist = [ @@ -545,16 +599,14 @@ class TestFlavorList(TestFlavor): # Set expected values kwargs = { 'is_public': True, - 'limit': None, - 'marker': None } - self.flavors_mock.list.assert_called_with( + self.sdk_client.flavors.assert_called_with( **kwargs ) self.assertEqual(self.columns, columns) - self.assertEqual(tuple(self.data), tuple(data)) + self.assertEqual(self.data, tuple(data)) def test_flavor_list_long(self): arglist = [ @@ -574,21 +626,19 @@ class TestFlavorList(TestFlavor): # Set expected values kwargs = { 'is_public': True, - 'limit': None, - 'marker': None } - self.flavors_mock.list.assert_called_with( + self.sdk_client.flavors.assert_called_with( **kwargs ) self.assertEqual(self.columns_long, columns) - self.assertListItemEqual(self.data_long, tuple(data)) + self.assertItemsEqual(self.data_long, tuple(data)) class TestFlavorSet(TestFlavor): - # Return value of self.flavors_mock.find(). + # Return value of self.sdk_client.find_flavor(). flavor = compute_fakes.FakeFlavor.create_one_flavor( attrs={'os-flavor-access:is_public': False}) project = identity_fakes.FakeProject.create_one_project() @@ -596,8 +646,7 @@ class TestFlavorSet(TestFlavor): def setUp(self): super(TestFlavorSet, self).setUp() - self.flavors_mock.find.return_value = self.flavor - self.flavors_mock.get.side_effect = exceptions.NotFound(None) + self.sdk_client.find_flavor.return_value = self.flavor # Return a project self.projects_mock.get.return_value = self.project self.cmd = flavor.SetFlavor(self.app, None) @@ -614,9 +663,14 @@ class TestFlavorSet(TestFlavor): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.flavors_mock.find.assert_called_with(name=parsed_args.flavor, - is_public=None) - self.flavor.set_keys.assert_called_with({'FOO': '"B A R"'}) + self.sdk_client.find_flavor.assert_called_with( + parsed_args.flavor, + get_extra_specs=True, + ignore_missing=False + ) + self.sdk_client.create_flavor_extra_specs.assert_called_with( + self.flavor.id, + {'FOO': '"B A R"'}) self.assertIsNone(result) def test_flavor_set_no_property(self): @@ -631,9 +685,13 @@ class TestFlavorSet(TestFlavor): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.flavors_mock.find.assert_called_with(name=parsed_args.flavor, - is_public=None) - self.flavor.unset_keys.assert_called_with(['property']) + self.sdk_client.find_flavor.assert_called_with( + parsed_args.flavor, + get_extra_specs=True, + ignore_missing=False + ) + self.sdk_client.delete_flavor_extra_specs_property.assert_called_with( + self.flavor.id, 'property') self.assertIsNone(result) def test_flavor_set_project(self): @@ -649,13 +707,16 @@ class TestFlavorSet(TestFlavor): result = self.cmd.take_action(parsed_args) - self.flavors_mock.find.assert_called_with(name=parsed_args.flavor, - is_public=None) - self.flavor_access_mock.add_tenant_access.assert_called_with( + self.sdk_client.find_flavor.assert_called_with( + parsed_args.flavor, + get_extra_specs=True, + ignore_missing=False + ) + self.sdk_client.flavor_add_tenant_access.assert_called_with( self.flavor.id, self.project.id, ) - self.flavor.set_keys.assert_not_called() + self.sdk_client.create_flavor_extra_specs.assert_not_called() self.assertIsNone(result) def test_flavor_set_no_project(self): @@ -681,8 +742,9 @@ class TestFlavorSet(TestFlavor): self.cmd, arglist, verifylist) def test_flavor_set_with_unexist_flavor(self): - self.flavors_mock.get.side_effect = exceptions.NotFound(None) - self.flavors_mock.find.side_effect = exceptions.NotFound(None) + self.sdk_client.find_flavor.side_effect = [ + sdk_exceptions.ResourceNotFound() + ] arglist = [ '--project', self.project.id, @@ -708,9 +770,12 @@ class TestFlavorSet(TestFlavor): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.flavors_mock.find.assert_called_with(name=parsed_args.flavor, - is_public=None) - self.flavor_access_mock.add_tenant_access.assert_not_called() + self.sdk_client.find_flavor.assert_called_with( + parsed_args.flavor, + get_extra_specs=True, + ignore_missing=False + ) + self.sdk_client.flavor_add_tenant_access.assert_not_called() self.assertIsNone(result) def test_flavor_set_description_api_newer(self): @@ -724,11 +789,11 @@ class TestFlavorSet(TestFlavor): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.app.client_manager.compute.api_version = 2.55 - with mock.patch.object(novaclient.api_versions, - 'APIVersion', - return_value=2.55): + with mock.patch.object(sdk_utils, + 'supports_microversion', + return_value=True): result = self.cmd.take_action(parsed_args) - self.flavors_mock.update.assert_called_with( + self.sdk_client.update_flavor.assert_called_with( flavor=self.flavor.id, description='description') self.assertIsNone(result) @@ -743,9 +808,9 @@ class TestFlavorSet(TestFlavor): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.app.client_manager.compute.api_version = 2.54 - with mock.patch.object(novaclient.api_versions, - 'APIVersion', - return_value=2.55): + with mock.patch.object(sdk_utils, + 'supports_microversion', + return_value=False): self.assertRaises(exceptions.CommandError, self.cmd.take_action, parsed_args) @@ -760,11 +825,12 @@ class TestFlavorSet(TestFlavor): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.app.client_manager.compute.api_version = 2.55 - with mock.patch.object(novaclient.api_versions, - 'APIVersion', - return_value=2.55): + + with mock.patch.object(sdk_utils, + 'supports_microversion', + return_value=True): result = self.cmd.take_action(parsed_args) - self.flavors_mock.update.assert_called_with( + self.sdk_client.update_flavor.assert_called_with( flavor=self.flavor.id, description='description') self.assertIsNone(result) @@ -779,16 +845,17 @@ class TestFlavorSet(TestFlavor): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.app.client_manager.compute.api_version = 2.54 - with mock.patch.object(novaclient.api_versions, - 'APIVersion', - return_value=2.55): + + with mock.patch.object(sdk_utils, + 'supports_microversion', + return_value=False): self.assertRaises(exceptions.CommandError, self.cmd.take_action, parsed_args) class TestFlavorShow(TestFlavor): - # Return value of self.flavors_mock.find(). + # Return value of self.sdk_client.find_flavor(). flavor_access = compute_fakes.FakeFlavorAccess.create_one_flavor_access() flavor = compute_fakes.FakeFlavor.create_one_flavor() @@ -805,11 +872,11 @@ class TestFlavorShow(TestFlavor): 'ram', 'rxtx_factor', 'swap', - 'vcpus', + 'vcpus' ) data = ( - flavor.disabled, + flavor.is_disabled, flavor.ephemeral, None, flavor.description, @@ -817,7 +884,7 @@ class TestFlavorShow(TestFlavor): flavor.id, flavor.name, flavor.is_public, - format_columns.DictColumn(flavor.get_keys()), + format_columns.DictColumn(flavor.extra_specs), flavor.ram, flavor.rxtx_factor, flavor.swap, @@ -828,9 +895,8 @@ class TestFlavorShow(TestFlavor): super(TestFlavorShow, self).setUp() # Return value of _find_resource() - self.flavors_mock.find.return_value = self.flavor - self.flavors_mock.get.side_effect = exceptions.NotFound(None) - self.flavor_access_mock.list.return_value = [self.flavor_access] + self.sdk_client.find_flavor.return_value = self.flavor + self.sdk_client.get_flavor_access.return_value = [self.flavor_access] self.cmd = flavor.ShowFlavor(self.app, None) def test_show_no_options(self): @@ -854,7 +920,7 @@ class TestFlavorShow(TestFlavor): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_private_flavor_show(self): private_flavor = compute_fakes.FakeFlavor.create_one_flavor( @@ -862,7 +928,7 @@ class TestFlavorShow(TestFlavor): 'os-flavor-access:is_public': False, } ) - self.flavors_mock.find.return_value = private_flavor + self.sdk_client.find_flavor.return_value = private_flavor arglist = [ private_flavor.name, @@ -872,7 +938,7 @@ class TestFlavorShow(TestFlavor): ] data_with_project = ( - private_flavor.disabled, + private_flavor.is_disabled, private_flavor.ephemeral, [self.flavor_access.tenant_id], private_flavor.description, @@ -880,7 +946,7 @@ class TestFlavorShow(TestFlavor): private_flavor.id, private_flavor.name, private_flavor.is_public, - format_columns.DictColumn(private_flavor.get_keys()), + format_columns.DictColumn(private_flavor.extra_specs), private_flavor.ram, private_flavor.rxtx_factor, private_flavor.swap, @@ -891,15 +957,15 @@ class TestFlavorShow(TestFlavor): columns, data = self.cmd.take_action(parsed_args) - self.flavor_access_mock.list.assert_called_with( + self.sdk_client.get_flavor_access.assert_called_with( flavor=private_flavor.id) self.assertEqual(self.columns, columns) - self.assertItemEqual(data_with_project, data) + self.assertItemsEqual(data_with_project, data) class TestFlavorUnset(TestFlavor): - # Return value of self.flavors_mock.find(). + # Return value of self.sdk_client.find_flavor(). flavor = compute_fakes.FakeFlavor.create_one_flavor( attrs={'os-flavor-access:is_public': False}) project = identity_fakes.FakeProject.create_one_project() @@ -907,12 +973,13 @@ class TestFlavorUnset(TestFlavor): def setUp(self): super(TestFlavorUnset, self).setUp() - self.flavors_mock.find.return_value = self.flavor - self.flavors_mock.get.side_effect = exceptions.NotFound(None) + self.sdk_client.find_flavor.return_value = self.flavor # Return a project self.projects_mock.get.return_value = self.project self.cmd = flavor.UnsetFlavor(self.app, None) + self.mock_shortcut = self.sdk_client.delete_flavor_extra_specs_property + def test_flavor_unset_property(self): arglist = [ '--property', 'property', @@ -925,12 +992,49 @@ class TestFlavorUnset(TestFlavor): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.flavors_mock.find.assert_called_with(name=parsed_args.flavor, - is_public=None) - self.flavor.unset_keys.assert_called_with(['property']) - self.flavor_access_mock.remove_tenant_access.assert_not_called() + self.sdk_client.find_flavor.assert_called_with( + parsed_args.flavor, + get_extra_specs=True, + ignore_missing=False) + self.mock_shortcut.assert_called_with( + self.flavor.id, 'property') + self.sdk_client.flavor_remove_tenant_access.assert_not_called() self.assertIsNone(result) + def test_flavor_unset_properties(self): + arglist = [ + '--property', 'property1', + '--property', 'property2', + 'baremetal' + ] + verifylist = [ + ('property', ['property1', 'property2']), + ('flavor', 'baremetal'), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + self.sdk_client.find_flavor.assert_called_with( + parsed_args.flavor, + get_extra_specs=True, + ignore_missing=False) + calls = [ + mock.call(self.flavor.id, 'property1'), + mock.call(self.flavor.id, 'property2') + ] + self.mock_shortcut.assert_has_calls( + calls) + + # A bit tricky way to ensure we do not unset other properties + calls.append(mock.call(self.flavor.id, 'property')) + self.assertRaises( + AssertionError, + self.mock_shortcut.assert_has_calls, + calls + ) + + self.sdk_client.flavor_remove_tenant_access.assert_not_called() + def test_flavor_unset_project(self): arglist = [ '--project', self.project.id, @@ -945,13 +1049,14 @@ class TestFlavorUnset(TestFlavor): result = self.cmd.take_action(parsed_args) self.assertIsNone(result) - self.flavors_mock.find.assert_called_with(name=parsed_args.flavor, - is_public=None) - self.flavor_access_mock.remove_tenant_access.assert_called_with( + self.sdk_client.find_flavor.assert_called_with( + parsed_args.flavor, get_extra_specs=True, + ignore_missing=False) + self.sdk_client.flavor_remove_tenant_access.assert_called_with( self.flavor.id, self.project.id, ) - self.flavor.unset_keys.assert_not_called() + self.sdk_client.delete_flavor_extra_specs_proerty.assert_not_called() self.assertIsNone(result) def test_flavor_unset_no_project(self): @@ -977,8 +1082,9 @@ class TestFlavorUnset(TestFlavor): self.cmd, arglist, verifylist) def test_flavor_unset_with_unexist_flavor(self): - self.flavors_mock.get.side_effect = exceptions.NotFound(None) - self.flavors_mock.find.side_effect = exceptions.NotFound(None) + self.sdk_client.find_flavor.side_effect = [ + sdk_exceptions.ResourceNotFound + ] arglist = [ '--project', self.project.id, @@ -1004,4 +1110,4 @@ class TestFlavorUnset(TestFlavor): result = self.cmd.take_action(parsed_args) self.assertIsNone(result) - self.flavor_access_mock.remove_tenant_access.assert_not_called() + self.sdk_client.flavor_remove_tenant_access.assert_not_called() diff --git a/openstackclient/tests/unit/compute/v2/test_server_backup.py b/openstackclient/tests/unit/compute/v2/test_server_backup.py index 5cdc2080..753db9cd 100644 --- a/openstackclient/tests/unit/compute/v2/test_server_backup.py +++ b/openstackclient/tests/unit/compute/v2/test_server_backup.py @@ -139,7 +139,7 @@ class TestServerBackupCreate(TestServerBackup): ) self.assertEqual(self.image_columns(images[0]), columns) - self.assertItemEqual(self.image_data(images[0]), data) + self.assertItemsEqual(self.image_data(images[0]), data) def test_server_backup_create_options(self): servers = self.setup_servers_mock(count=1) @@ -173,7 +173,7 @@ class TestServerBackupCreate(TestServerBackup): ) self.assertEqual(self.image_columns(images[0]), columns) - self.assertItemEqual(self.image_data(images[0]), data) + self.assertItemsEqual(self.image_data(images[0]), data) @mock.patch.object(common_utils, 'wait_for_status', return_value=False) def test_server_backup_wait_fail(self, mock_wait_for_status): @@ -269,4 +269,4 @@ class TestServerBackupCreate(TestServerBackup): ) self.assertEqual(self.image_columns(images[0]), columns) - self.assertItemEqual(self.image_data(images[0]), data) + self.assertItemsEqual(self.image_data(images[0]), data) diff --git a/openstackclient/tests/unit/compute/v2/test_server_image.py b/openstackclient/tests/unit/compute/v2/test_server_image.py index 1cec5b68..06f6017c 100644 --- a/openstackclient/tests/unit/compute/v2/test_server_image.py +++ b/openstackclient/tests/unit/compute/v2/test_server_image.py @@ -133,7 +133,7 @@ class TestServerImageCreate(TestServerImage): ) self.assertEqual(self.image_columns(images[0]), columns) - self.assertItemEqual(self.image_data(images[0]), data) + self.assertItemsEqual(self.image_data(images[0]), data) def test_server_image_create_options(self): servers = self.setup_servers_mock(count=1) @@ -161,7 +161,7 @@ class TestServerImageCreate(TestServerImage): ) self.assertEqual(self.image_columns(images[0]), columns) - self.assertItemEqual(self.image_data(images[0]), data) + self.assertItemsEqual(self.image_data(images[0]), data) @mock.patch.object(common_utils, 'wait_for_status', return_value=False) def test_server_create_image_wait_fail(self, mock_wait_for_status): @@ -229,4 +229,4 @@ class TestServerImageCreate(TestServerImage): ) self.assertEqual(self.image_columns(images[0]), columns) - self.assertItemEqual(self.image_data(images[0]), data) + self.assertItemsEqual(self.image_data(images[0]), data) diff --git a/openstackclient/tests/unit/identity/v2_0/test_catalog.py b/openstackclient/tests/unit/identity/v2_0/test_catalog.py index 17355074..e2c56ba1 100644 --- a/openstackclient/tests/unit/identity/v2_0/test_catalog.py +++ b/openstackclient/tests/unit/identity/v2_0/test_catalog.py @@ -71,9 +71,10 @@ class TestCatalogList(TestCatalog): datalist = (( 'supernova', 'compute', - catalog.EndpointsColumn(self.service_catalog['endpoints']), + catalog.EndpointsColumn( + auth_ref.service_catalog.catalog[0]['endpoints']), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) def test_catalog_list_with_endpoint_url(self): attr = { @@ -113,9 +114,10 @@ class TestCatalogList(TestCatalog): datalist = (( 'supernova', 'compute', - catalog.EndpointsColumn(service_catalog['endpoints']), + catalog.EndpointsColumn( + auth_ref.service_catalog.catalog[0]['endpoints']), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) class TestCatalogShow(TestCatalog): @@ -150,16 +152,17 @@ class TestCatalogShow(TestCatalog): collist = ('endpoints', 'id', 'name', 'type') self.assertEqual(collist, columns) datalist = ( - catalog.EndpointsColumn(self.service_catalog['endpoints']), + catalog.EndpointsColumn( + auth_ref.service_catalog.catalog[0]['endpoints']), self.service_catalog.id, 'supernova', 'compute', ) - self.assertItemEqual(datalist, data) + self.assertItemsEqual(datalist, data) class TestFormatColumns(TestCatalog): - def test_endpoints_column_human_readabale(self): + def test_endpoints_column_human_readable(self): col = catalog.EndpointsColumn(self.service_catalog['endpoints']) self.assertEqual( 'one\n publicURL: https://public.one.example.com\n ' diff --git a/openstackclient/tests/unit/identity/v2_0/test_project.py b/openstackclient/tests/unit/identity/v2_0/test_project.py index cd8c825d..766d5dab 100644 --- a/openstackclient/tests/unit/identity/v2_0/test_project.py +++ b/openstackclient/tests/unit/identity/v2_0/test_project.py @@ -643,7 +643,7 @@ class TestProjectShow(TestProject): self.fake_proj_show.name, format_columns.DictColumn({}), ) - self.assertItemEqual(datalist, data) + self.assertItemsEqual(datalist, data) class TestProjectUnset(TestProject): diff --git a/openstackclient/tests/unit/identity/v2_0/test_user.py b/openstackclient/tests/unit/identity/v2_0/test_user.py index 4308b05d..dd300478 100644 --- a/openstackclient/tests/unit/identity/v2_0/test_user.py +++ b/openstackclient/tests/unit/identity/v2_0/test_user.py @@ -482,7 +482,7 @@ class TestUserList(TestUser): self.users_mock.list.assert_called_with(tenant_id=None) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) def test_user_list_project(self): arglist = [ @@ -502,7 +502,7 @@ class TestUserList(TestUser): self.users_mock.list.assert_called_with(tenant_id=project_id) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) def test_user_list_long(self): arglist = [ @@ -531,7 +531,7 @@ class TestUserList(TestUser): self.fake_user_l.email, True, ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) class TestUserSet(TestUser): @@ -819,4 +819,4 @@ class TestUserShow(TestUser): self.fake_user.name, self.fake_project.id, ) - self.assertItemEqual(datalist, data) + self.assertItemsEqual(datalist, data) diff --git a/openstackclient/tests/unit/identity/v3/test_catalog.py b/openstackclient/tests/unit/identity/v3/test_catalog.py index 3630ccb6..97ce48f6 100644 --- a/openstackclient/tests/unit/identity/v3/test_catalog.py +++ b/openstackclient/tests/unit/identity/v3/test_catalog.py @@ -91,9 +91,10 @@ class TestCatalogList(TestCatalog): datalist = (( 'supernova', 'compute', - catalog.EndpointsColumn(self.fake_service['endpoints']), + catalog.EndpointsColumn( + auth_ref.service_catalog.catalog[0]['endpoints']), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) class TestCatalogShow(TestCatalog): @@ -128,12 +129,13 @@ class TestCatalogShow(TestCatalog): collist = ('endpoints', 'id', 'name', 'type') self.assertEqual(collist, columns) datalist = ( - catalog.EndpointsColumn(self.fake_service['endpoints']), + catalog.EndpointsColumn( + auth_ref.service_catalog.catalog[0]['endpoints']), 'qwertyuiop', 'supernova', 'compute', ) - self.assertItemEqual(datalist, data) + self.assertItemsEqual(datalist, data) class TestFormatColumns(TestCatalog): diff --git a/openstackclient/tests/unit/identity/v3/test_identity_provider.py b/openstackclient/tests/unit/identity/v3/test_identity_provider.py index a419a9bc..5aff2b1b 100644 --- a/openstackclient/tests/unit/identity/v3/test_identity_provider.py +++ b/openstackclient/tests/unit/identity/v3/test_identity_provider.py @@ -89,7 +89,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_create_identity_provider_description(self): arglist = [ @@ -117,7 +117,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_create_identity_provider_remote_id(self): arglist = [ @@ -145,7 +145,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_create_identity_provider_remote_ids_multiple(self): arglist = [ @@ -174,7 +174,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_create_identity_provider_remote_ids_file(self): arglist = [ @@ -207,7 +207,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_create_identity_provider_disabled(self): @@ -250,7 +250,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): identity_fakes.idp_id, identity_fakes.formatted_idp_remote_ids ) - self.assertItemEqual(datalist, data) + self.assertItemsEqual(datalist, data) def test_create_identity_provider_domain_name(self): arglist = [ @@ -278,7 +278,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_create_identity_provider_domain_id(self): arglist = [ @@ -306,7 +306,7 @@ class TestIdentityProviderCreate(TestIdentityProvider): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) class TestIdentityProviderDelete(TestIdentityProvider): @@ -382,7 +382,62 @@ class TestIdentityProviderList(TestIdentityProvider): identity_fakes.domain_id, identity_fakes.idp_description, ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) + + def test_identity_provider_list_ID_option(self): + arglist = ['--id', + identity_fakes.idp_id] + verifylist = [ + ('id', identity_fakes.idp_id) + ] + 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) + + kwargs = { + 'id': identity_fakes.idp_id + } + self.identity_providers_mock.list.assert_called_with(**kwargs) + + collist = ('ID', 'Enabled', 'Domain ID', 'Description') + self.assertEqual(collist, columns) + datalist = (( + identity_fakes.idp_id, + True, + identity_fakes.domain_id, + identity_fakes.idp_description, + ), ) + self.assertItemsEqual(datalist, tuple(data)) + + def test_identity_provider_list_enabled_option(self): + arglist = ['--enabled'] + verifylist = [ + ('enabled', True) + ] + 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) + + kwargs = { + 'enabled': True + } + self.identity_providers_mock.list.assert_called_with(**kwargs) + + collist = ('ID', 'Enabled', 'Domain ID', 'Description') + self.assertEqual(collist, columns) + datalist = (( + identity_fakes.idp_id, + True, + identity_fakes.domain_id, + identity_fakes.idp_description, + ), ) + self.assertItemsEqual(datalist, tuple(data)) class TestIdentityProviderSet(TestIdentityProvider): @@ -667,4 +722,4 @@ class TestIdentityProviderShow(TestIdentityProvider): identity_fakes.idp_id, identity_fakes.formatted_idp_remote_ids ) - self.assertItemEqual(datalist, data) + self.assertItemsEqual(datalist, data) diff --git a/openstackclient/tests/unit/image/v1/test_image.py b/openstackclient/tests/unit/image/v1/test_image.py index 2f190a7a..db64983c 100644 --- a/openstackclient/tests/unit/image/v1/test_image.py +++ b/openstackclient/tests/unit/image/v1/test_image.py @@ -100,7 +100,7 @@ class TestImageCreate(TestImage): self.assertEqual(self.client.update_image.call_args_list, []) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) @mock.patch('sys.stdin', side_effect=[None]) def test_image_reserve_options(self, raw_input): @@ -149,7 +149,7 @@ class TestImageCreate(TestImage): self.assertEqual(self.client.update_image.call_args_list, []) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) @mock.patch('openstackclient.image.v1.image.io.open', name='Open') def test_image_create_file(self, mock_open): @@ -205,7 +205,7 @@ class TestImageCreate(TestImage): self.assertEqual(self.client.update_image.call_args_list, []) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) class TestImageDelete(TestImage): @@ -386,7 +386,7 @@ class TestImageList(TestImage): format_columns.DictColumn( {'Alpha': 'a', 'Beta': 'b', 'Gamma': 'g'}), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) @mock.patch('osc_lib.api.utils.simple_filter') def test_image_list_property_option(self, sf_mock): @@ -737,7 +737,7 @@ class TestImageShow(TestImage): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_image_show_human_readable(self): arglist = [ diff --git a/openstackclient/tests/unit/image/v2/test_image.py b/openstackclient/tests/unit/image/v2/test_image.py index b094817e..b72e9835 100644 --- a/openstackclient/tests/unit/image/v2/test_image.py +++ b/openstackclient/tests/unit/image/v2/test_image.py @@ -111,7 +111,7 @@ class TestImageCreate(TestImage): self.assertEqual( self.expected_columns, columns) - self.assertItemEqual( + self.assertItemsEqual( self.expected_data, data) @@ -166,7 +166,7 @@ class TestImageCreate(TestImage): self.assertEqual( self.expected_columns, columns) - self.assertItemEqual( + self.assertItemsEqual( self.expected_data, data) @@ -255,7 +255,7 @@ class TestImageCreate(TestImage): self.assertEqual( self.expected_columns, columns) - self.assertItemEqual( + self.assertItemsEqual( self.expected_data, data) @@ -513,7 +513,7 @@ class TestImageList(TestImage): ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) def test_image_list_public_option(self): arglist = [ @@ -537,7 +537,7 @@ class TestImageList(TestImage): ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) def test_image_list_private_option(self): arglist = [ @@ -561,7 +561,7 @@ class TestImageList(TestImage): ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) def test_image_list_community_option(self): arglist = [ @@ -609,7 +609,7 @@ class TestImageList(TestImage): ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) def test_image_list_shared_member_status_option(self): arglist = [ @@ -697,7 +697,7 @@ class TestImageList(TestImage): self._image.owner_id, format_columns.ListColumn(self._image.tags), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) @mock.patch('osc_lib.api.utils.simple_filter') def test_image_list_property_option(self, sf_mock): @@ -725,7 +725,7 @@ class TestImageList(TestImage): ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) @mock.patch('osc_lib.utils.sort_items') def test_image_list_sort_option(self, si_mock): @@ -747,7 +747,7 @@ class TestImageList(TestImage): str, ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) def test_image_list_limit_option(self): ret_limit = 1 @@ -1472,7 +1472,7 @@ class TestImageShow(TestImage): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_image_show_human_readable(self): self.client.find_image.return_value = self.new_image @@ -1618,7 +1618,7 @@ class TestImageSave(TestImage): verifylist = [ ('file', '/path/to/file'), - ('image', self.image.id) + ('image', self.image.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1626,6 +1626,7 @@ class TestImageSave(TestImage): self.client.download_image.assert_called_once_with( self.image.id, + stream=True, output='/path/to/file') diff --git a/openstackclient/tests/unit/network/v2/test_ip_availability.py b/openstackclient/tests/unit/network/v2/test_ip_availability.py index 9a712704..ade57837 100644 --- a/openstackclient/tests/unit/network/v2/test_ip_availability.py +++ b/openstackclient/tests/unit/network/v2/test_ip_availability.py @@ -75,7 +75,7 @@ class TestListIPAvailability(TestIPAvailability): self.network.network_ip_availabilities.assert_called_once_with( **filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_list_ip_version(self): arglist = [ @@ -93,7 +93,7 @@ class TestListIPAvailability(TestIPAvailability): self.network.network_ip_availabilities.assert_called_once_with( **filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_list_project(self): arglist = [ @@ -113,7 +113,7 @@ class TestListIPAvailability(TestIPAvailability): self.network.network_ip_availabilities.assert_called_once_with( **filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) class TestShowIPAvailability(TestIPAvailability): @@ -176,4 +176,4 @@ class TestShowIPAvailability(TestIPAvailability): self._ip_availability.network_name, ignore_missing=False) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) diff --git a/openstackclient/tests/unit/network/v2/test_network.py b/openstackclient/tests/unit/network/v2/test_network.py index 5f8eed67..e29b72c7 100644 --- a/openstackclient/tests/unit/network/v2/test_network.py +++ b/openstackclient/tests/unit/network/v2/test_network.py @@ -146,7 +146,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): }) self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_all_options(self): arglist = [ @@ -211,7 +211,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'dns_domain': 'example.org.', }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_other_options(self): arglist = [ @@ -238,7 +238,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'port_security_enabled': False, }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def _test_create_with_tag(self, add_tags=True): arglist = [self._network.name] @@ -270,7 +270,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): else: self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_tags(self): self._test_create_with_tag(add_tags=True) @@ -385,7 +385,7 @@ class TestCreateNetworkIdentityV2(TestNetwork): }) self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_domain_identityv2(self): arglist = [ @@ -577,7 +577,7 @@ class TestListNetwork(TestNetwork): self.network.networks.assert_called_once_with() self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_list_external(self): arglist = [ @@ -598,7 +598,7 @@ class TestListNetwork(TestNetwork): **{'router:external': True, 'is_router_external': True} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_list_internal(self): arglist = [ @@ -615,7 +615,7 @@ class TestListNetwork(TestNetwork): **{'router:external': False, 'is_router_external': False} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_list_long(self): arglist = [ @@ -634,7 +634,7 @@ class TestListNetwork(TestNetwork): self.network.networks.assert_called_once_with() self.assertEqual(self.columns_long, columns) - self.assertListItemEqual(self.data_long, list(data)) + self.assertItemsEqual(self.data_long, list(data)) def test_list_name(self): test_name = "fakename" @@ -653,7 +653,7 @@ class TestListNetwork(TestNetwork): **{'name': test_name} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_list_enable(self): arglist = [ @@ -671,7 +671,7 @@ class TestListNetwork(TestNetwork): **{'admin_state_up': True, 'is_admin_state_up': True} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_list_disable(self): arglist = [ @@ -689,7 +689,7 @@ class TestListNetwork(TestNetwork): **{'admin_state_up': False, 'is_admin_state_up': False} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_list_project(self): project = identity_fakes_v3.FakeProject.create_one_project() @@ -708,7 +708,7 @@ class TestListNetwork(TestNetwork): ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_list_project_domain(self): project = identity_fakes_v3.FakeProject.create_one_project() @@ -727,7 +727,7 @@ class TestListNetwork(TestNetwork): self.network.networks.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_list_share(self): arglist = [ @@ -744,7 +744,7 @@ class TestListNetwork(TestNetwork): **{'shared': True, 'is_shared': True} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_list_no_share(self): arglist = [ @@ -761,7 +761,7 @@ class TestListNetwork(TestNetwork): **{'shared': False, 'is_shared': False} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_list_status(self): choices = ['ACTIVE', 'BUILD', 'DOWN', 'ERROR'] @@ -780,7 +780,7 @@ class TestListNetwork(TestNetwork): **{'status': test_status} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_list_provider_network_type(self): network_type = self._network[0].provider_network_type @@ -798,7 +798,7 @@ class TestListNetwork(TestNetwork): 'provider_network_type': network_type} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_list_provider_physical_network(self): physical_network = self._network[0].provider_physical_network @@ -816,7 +816,7 @@ class TestListNetwork(TestNetwork): 'provider_physical_network': physical_network} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_list_provider_segment(self): segmentation_id = self._network[0].provider_segmentation_id @@ -834,7 +834,7 @@ class TestListNetwork(TestNetwork): 'provider_segmentation_id': segmentation_id} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_list_dhcp_agent(self): arglist = [ @@ -853,7 +853,7 @@ class TestListNetwork(TestNetwork): *attrs) self.assertEqual(self.columns, columns) - self.assertListItemEqual(list(data), list(self.data)) + self.assertItemsEqual(list(data), list(self.data)) def test_list_with_tag_options(self): arglist = [ @@ -878,7 +878,7 @@ class TestListNetwork(TestNetwork): 'not_any_tags': 'black,white'} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) class TestSetNetwork(TestNetwork): @@ -1111,7 +1111,7 @@ class TestShowNetwork(TestNetwork): self._network.name, ignore_missing=False) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) class TestUnsetNetwork(TestNetwork): diff --git a/openstackclient/tests/unit/network/v2/test_network_agent.py b/openstackclient/tests/unit/network/v2/test_network_agent.py index 3181ee78..fceac68e 100644 --- a/openstackclient/tests/unit/network/v2/test_network_agent.py +++ b/openstackclient/tests/unit/network/v2/test_network_agent.py @@ -246,7 +246,7 @@ class TestListNetworkAgent(TestNetworkAgent): self.network.agents.assert_called_once_with(**{}) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_agents_list_agent_type(self): arglist = [ @@ -263,7 +263,7 @@ class TestListNetworkAgent(TestNetworkAgent): 'agent_type': 'DHCP agent', }) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_agents_list_host(self): arglist = [ @@ -280,7 +280,7 @@ class TestListNetworkAgent(TestNetworkAgent): 'host': self.network_agents[0].host, }) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_agents_list_networks(self): arglist = [ @@ -298,7 +298,7 @@ class TestListNetworkAgent(TestNetworkAgent): self.network.network_hosting_dhcp_agents.assert_called_once_with( *attrs) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_agents_list_routers(self): arglist = [ @@ -318,7 +318,7 @@ class TestListNetworkAgent(TestNetworkAgent): *attrs) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_network_agents_list_routers_with_long_option(self): arglist = [ @@ -343,7 +343,7 @@ class TestListNetworkAgent(TestNetworkAgent): router_agent_data = [d + ('',) for d in self.data] self.assertEqual(router_agent_columns, columns) - self.assertListItemEqual(router_agent_data, list(data)) + self.assertItemsEqual(router_agent_data, list(data)) class TestRemoveNetworkFromAgent(TestNetworkAgent): @@ -571,4 +571,4 @@ class TestShowNetworkAgent(TestNetworkAgent): self.network.get_agent.assert_called_once_with( self._network_agent.id) self.assertEqual(self.columns, columns) - self.assertItemEqual(list(self.data), list(data)) + self.assertItemsEqual(list(self.data), list(data)) diff --git a/openstackclient/tests/unit/network/v2/test_port.py b/openstackclient/tests/unit/network/v2/test_port.py index f7685f46..e21f9d01 100644 --- a/openstackclient/tests/unit/network/v2/test_port.py +++ b/openstackclient/tests/unit/network/v2/test_port.py @@ -151,7 +151,7 @@ class TestCreatePort(TestPort): self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_full_options(self): arglist = [ @@ -209,7 +209,7 @@ class TestCreatePort(TestPort): }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_invalid_json_binding_profile(self): arglist = [ @@ -260,7 +260,7 @@ class TestCreatePort(TestPort): }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_security_group(self): secgroup = network_fakes.FakeSecurityGroup.create_one_security_group() @@ -289,7 +289,7 @@ class TestCreatePort(TestPort): }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_port_with_dns_name(self): arglist = [ @@ -315,7 +315,7 @@ class TestCreatePort(TestPort): }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_security_groups(self): sg_1 = network_fakes.FakeSecurityGroup.create_one_security_group() @@ -345,7 +345,7 @@ class TestCreatePort(TestPort): }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_no_security_groups(self): arglist = [ @@ -371,7 +371,7 @@ class TestCreatePort(TestPort): }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_no_fixed_ips(self): arglist = [ @@ -397,7 +397,7 @@ class TestCreatePort(TestPort): }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_port_with_allowed_address_pair_ipaddr(self): pairs = [{'ip_address': '192.168.1.123'}, @@ -427,7 +427,7 @@ class TestCreatePort(TestPort): }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_port_with_allowed_address_pair(self): pairs = [{'ip_address': '192.168.1.123', @@ -463,7 +463,7 @@ class TestCreatePort(TestPort): }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_port_with_qos(self): qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy() @@ -491,7 +491,7 @@ class TestCreatePort(TestPort): }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_port_security_enabled(self): arglist = [ @@ -600,7 +600,7 @@ class TestCreatePort(TestPort): self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_tags(self): self._test_create_with_tag(add_tags=True, add_tags_in_post=True) @@ -643,7 +643,7 @@ class TestCreatePort(TestPort): }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_uplink_status_propagation_enabled(self): self._test_create_with_uplink_status_propagation(enable=True) @@ -723,7 +723,7 @@ class TestCreatePort(TestPort): self.network.create_port.assert_called_once_with(**create_args) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_numa_affinity_policy_required(self): self._test_create_with_numa_affinity_policy(policy='required') @@ -890,7 +890,7 @@ class TestListPort(TestPort): self.network.ports.assert_called_once_with( fields=LIST_FIELDS_TO_RETRIEVE) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_port_list_router_opt(self): arglist = [ @@ -910,7 +910,7 @@ class TestListPort(TestPort): 'fields': LIST_FIELDS_TO_RETRIEVE, }) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) @mock.patch.object(utils, 'find_resource') def test_port_list_with_server_option(self, mock_find): @@ -931,7 +931,7 @@ class TestListPort(TestPort): fields=LIST_FIELDS_TO_RETRIEVE) mock_find.assert_called_once_with(mock.ANY, 'fake-server-name') self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_port_list_device_id_opt(self): arglist = [ @@ -951,7 +951,7 @@ class TestListPort(TestPort): 'fields': LIST_FIELDS_TO_RETRIEVE, }) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_port_list_device_owner_opt(self): arglist = [ @@ -971,7 +971,7 @@ class TestListPort(TestPort): 'fields': LIST_FIELDS_TO_RETRIEVE, }) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_port_list_all_opt(self): arglist = [ @@ -1000,7 +1000,7 @@ class TestListPort(TestPort): 'fields': LIST_FIELDS_TO_RETRIEVE, }) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_port_list_mac_address_opt(self): arglist = [ @@ -1020,7 +1020,7 @@ class TestListPort(TestPort): 'fields': LIST_FIELDS_TO_RETRIEVE, }) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_port_list_fixed_ip_opt_ip_address(self): ip_address = self._ports[0].fixed_ips[0]['ip_address'] @@ -1040,7 +1040,7 @@ class TestListPort(TestPort): 'fields': LIST_FIELDS_TO_RETRIEVE, }) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_port_list_fixed_ip_opt_ip_address_substr(self): ip_address_ss = self._ports[0].fixed_ips[0]['ip_address'][:-1] @@ -1060,7 +1060,7 @@ class TestListPort(TestPort): 'fields': LIST_FIELDS_TO_RETRIEVE, }) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_port_list_fixed_ip_opt_subnet_id(self): subnet_id = self._ports[0].fixed_ips[0]['subnet_id'] @@ -1082,7 +1082,7 @@ class TestListPort(TestPort): 'fields': LIST_FIELDS_TO_RETRIEVE, }) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_port_list_fixed_ip_opts(self): subnet_id = self._ports[0].fixed_ips[0]['subnet_id'] @@ -1108,7 +1108,7 @@ class TestListPort(TestPort): 'fields': LIST_FIELDS_TO_RETRIEVE, }) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_port_list_fixed_ips(self): subnet_id = self._ports[0].fixed_ips[0]['subnet_id'] @@ -1136,7 +1136,7 @@ class TestListPort(TestPort): 'fields': LIST_FIELDS_TO_RETRIEVE, }) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_list_port_with_long(self): arglist = [ @@ -1154,7 +1154,7 @@ class TestListPort(TestPort): self.network.ports.assert_called_once_with( fields=LIST_FIELDS_TO_RETRIEVE + LIST_FIELDS_TO_RETRIEVE_LONG) self.assertEqual(self.columns_long, columns) - self.assertListItemEqual(self.data_long, list(data)) + self.assertItemsEqual(self.data_long, list(data)) def test_port_list_host(self): arglist = [ @@ -1173,7 +1173,7 @@ class TestListPort(TestPort): self.network.ports.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_port_list_project(self): project = identity_fakes.FakeProject.create_one_project() @@ -1195,7 +1195,7 @@ class TestListPort(TestPort): self.network.ports.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_port_list_project_domain(self): project = identity_fakes.FakeProject.create_one_project() @@ -1219,7 +1219,7 @@ class TestListPort(TestPort): self.network.ports.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_list_with_tag_options(self): arglist = [ @@ -1245,7 +1245,7 @@ class TestListPort(TestPort): 'fields': LIST_FIELDS_TO_RETRIEVE} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) class TestSetPort(TestPort): @@ -1845,7 +1845,7 @@ class TestShowPort(TestPort): self._port.name, ignore_missing=False) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) class TestUnsetPort(TestPort): diff --git a/openstackclient/tests/unit/network/v2/test_router.py b/openstackclient/tests/unit/network/v2/test_router.py index 09b4957c..323c9198 100644 --- a/openstackclient/tests/unit/network/v2/test_router.py +++ b/openstackclient/tests/unit/network/v2/test_router.py @@ -184,7 +184,7 @@ class TestCreateRouter(TestRouter): }) self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def _test_create_with_ha_options(self, option, ha): arglist = [ @@ -208,7 +208,7 @@ class TestCreateRouter(TestRouter): 'ha': ha, }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_ha_option(self): self._test_create_with_ha_options('--ha', True) @@ -237,7 +237,7 @@ class TestCreateRouter(TestRouter): 'distributed': distributed, }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_distributed_option(self): self._test_create_with_distributed_options('--distributed', True) @@ -268,7 +268,7 @@ class TestCreateRouter(TestRouter): }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def _test_create_with_tag(self, add_tags=True): arglist = [self.new_router.name] @@ -301,7 +301,7 @@ class TestCreateRouter(TestRouter): else: self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_tags(self): self._test_create_with_tag(add_tags=True) @@ -494,7 +494,7 @@ class TestListRouter(TestRouter): self.network.routers.assert_called_once_with() self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_router_list_no_ha_no_distributed(self): _routers = network_fakes.FakeRouter.create_routers({ @@ -531,7 +531,7 @@ class TestListRouter(TestRouter): self.network.routers.assert_called_once_with() self.assertEqual(self.columns_long, columns) - self.assertListItemEqual(self.data_long, list(data)) + self.assertItemsEqual(self.data_long, list(data)) def test_router_list_long_no_az(self): arglist = [ @@ -552,7 +552,7 @@ class TestListRouter(TestRouter): self.network.routers.assert_called_once_with() self.assertEqual(self.columns_long_no_az, columns) - self.assertListItemEqual(self.data_long_no_az, list(data)) + self.assertItemsEqual(self.data_long_no_az, list(data)) def test_list_name(self): test_name = "fakename" @@ -570,7 +570,7 @@ class TestListRouter(TestRouter): **{'name': test_name} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_router_list_enable(self): arglist = [ @@ -587,7 +587,7 @@ class TestListRouter(TestRouter): **{'admin_state_up': True, 'is_admin_state_up': True} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_router_list_disable(self): arglist = [ @@ -605,7 +605,7 @@ class TestListRouter(TestRouter): ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_router_list_project(self): project = identity_fakes_v3.FakeProject.create_one_project() @@ -623,7 +623,7 @@ class TestListRouter(TestRouter): self.network.routers.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_router_list_project_domain(self): project = identity_fakes_v3.FakeProject.create_one_project() @@ -643,7 +643,7 @@ class TestListRouter(TestRouter): self.network.routers.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_router_list_agents_no_args(self): arglist = [ @@ -671,7 +671,7 @@ class TestListRouter(TestRouter): self.network.agent_hosted_routers( *attrs) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_list_with_tag_options(self): arglist = [ @@ -696,7 +696,7 @@ class TestListRouter(TestRouter): 'not_any_tags': 'black,white'} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) class TestRemovePortFromRouter(TestRouter): @@ -1403,7 +1403,7 @@ class TestShowRouter(TestRouter): 'device_id': self._router.id }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_show_no_ha_no_distributed(self): _router = network_fakes.FakeRouter.create_one_router({ diff --git a/openstackclient/tests/unit/network/v2/test_security_group_compute.py b/openstackclient/tests/unit/network/v2/test_security_group_compute.py index b4ddcf80..837c9b21 100644 --- a/openstackclient/tests/unit/network/v2/test_security_group_compute.py +++ b/openstackclient/tests/unit/network/v2/test_security_group_compute.py @@ -88,7 +88,7 @@ class TestCreateSecurityGroupCompute(TestSecurityGroupCompute): self._security_group['name'], ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_security_group_create_all_options(self, sg_mock): sg_mock.return_value = self._security_group @@ -109,7 +109,7 @@ class TestCreateSecurityGroupCompute(TestSecurityGroupCompute): self._security_group['description'], ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) @mock.patch( @@ -255,7 +255,7 @@ class TestListSecurityGroupCompute(TestSecurityGroupCompute): kwargs = {'search_opts': {'all_tenants': False}} sg_mock.assert_called_once_with(**kwargs) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_security_group_list_all_projects(self, sg_mock): sg_mock.return_value = self._security_groups @@ -272,7 +272,7 @@ class TestListSecurityGroupCompute(TestSecurityGroupCompute): kwargs = {'search_opts': {'all_tenants': True}} sg_mock.assert_called_once_with(**kwargs) self.assertEqual(self.columns_all_projects, columns) - self.assertListItemEqual(self.data_all_projects, list(data)) + self.assertItemsEqual(self.data_all_projects, list(data)) @mock.patch( @@ -401,4 +401,4 @@ class TestShowSecurityGroupCompute(TestSecurityGroupCompute): sg_mock.assert_called_once_with(self._security_group['id']) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) diff --git a/openstackclient/tests/unit/network/v2/test_security_group_network.py b/openstackclient/tests/unit/network/v2/test_security_group_network.py index 7c1d7fb6..fe377785 100644 --- a/openstackclient/tests/unit/network/v2/test_security_group_network.py +++ b/openstackclient/tests/unit/network/v2/test_security_group_network.py @@ -96,7 +96,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork): 'name': self._security_group.name, }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_all_options(self): arglist = [ @@ -124,7 +124,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork): 'tenant_id': self.project.id, }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def _test_create_with_tag(self, add_tags=True): arglist = [self._security_group.name] @@ -155,7 +155,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork): else: self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_tags(self): self._test_create_with_tag(add_tags=True) @@ -293,7 +293,7 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork): self.network.security_groups.assert_called_once_with( fields=security_group.ListSecurityGroup.FIELDS_TO_RETRIEVE) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_security_group_list_all_projects(self): arglist = [ @@ -309,7 +309,7 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork): self.network.security_groups.assert_called_once_with( fields=security_group.ListSecurityGroup.FIELDS_TO_RETRIEVE) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_security_group_list_project(self): project = identity_fakes.FakeProject.create_one_project() @@ -329,7 +329,7 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork): self.network.security_groups.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_security_group_list_project_domain(self): project = identity_fakes.FakeProject.create_one_project() @@ -351,7 +351,7 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork): self.network.security_groups.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_list_with_tag_options(self): arglist = [ @@ -539,7 +539,7 @@ class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork): self.network.find_security_group.assert_called_once_with( self._security_group.id, ignore_missing=False) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) class TestUnsetSecurityGroupNetwork(TestSecurityGroupNetwork): diff --git a/openstackclient/tests/unit/network/v2/test_subnet.py b/openstackclient/tests/unit/network/v2/test_subnet.py index 47d0c6b4..1b4bfdad 100644 --- a/openstackclient/tests/unit/network/v2/test_subnet.py +++ b/openstackclient/tests/unit/network/v2/test_subnet.py @@ -255,7 +255,7 @@ class TestCreateSubnet(TestSubnet): }) self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_from_subnet_pool_options(self): # Mock SDK calls for this test. @@ -317,7 +317,7 @@ class TestCreateSubnet(TestSubnet): 'service_types': self._subnet_from_pool.service_types, }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data_subnet_pool, data) + self.assertItemsEqual(self.data_subnet_pool, data) def test_create_options_subnet_range_ipv6(self): # Mock SDK calls for this test. @@ -390,7 +390,7 @@ class TestCreateSubnet(TestSubnet): }) self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data_ipv6, data) + self.assertItemsEqual(self.data_ipv6, data) def test_create_with_network_segment(self): # Mock SDK calls for this test. @@ -424,7 +424,7 @@ class TestCreateSubnet(TestSubnet): }) self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_description(self): # Mock SDK calls for this test. @@ -458,7 +458,7 @@ class TestCreateSubnet(TestSubnet): }) self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def _test_create_with_dns(self, publish_dns=True): arglist = [ @@ -490,7 +490,7 @@ class TestCreateSubnet(TestSubnet): dns_publish_fixed_ip=publish_dns, ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_dns(self): self._test_create_with_dns(publish_dns=True) @@ -535,7 +535,7 @@ class TestCreateSubnet(TestSubnet): else: self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_tags(self): self._test_create_with_tag(add_tags=True) @@ -691,7 +691,7 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_once_with() self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_list_long(self): arglist = [ @@ -706,7 +706,7 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_once_with() self.assertEqual(self.columns_long, columns) - self.assertListItemEqual(self.data_long, list(data)) + self.assertItemsEqual(self.data_long, list(data)) def test_subnet_list_ip_version(self): arglist = [ @@ -722,7 +722,7 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_list_dhcp(self): arglist = [ @@ -738,7 +738,7 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_list_no_dhcp(self): arglist = [ @@ -754,7 +754,7 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_list_service_type(self): arglist = [ @@ -769,7 +769,7 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_list_project(self): project = identity_fakes_v3.FakeProject.create_one_project() @@ -787,7 +787,7 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_list_service_type_multiple(self): arglist = [ @@ -805,7 +805,7 @@ class TestListSubnet(TestSubnet): 'network:floatingip_agent_gateway']} self.network.subnets.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_list_project_domain(self): project = identity_fakes_v3.FakeProject.create_one_project() @@ -825,7 +825,7 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_list_network(self): network = network_fakes.FakeNetwork.create_one_network() @@ -843,7 +843,7 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_list_gateway(self): subnet = network_fakes.FakeSubnet.create_one_subnet() @@ -861,7 +861,7 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_list_name(self): subnet = network_fakes.FakeSubnet.create_one_subnet() @@ -879,7 +879,7 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_list_subnet_range(self): subnet = network_fakes.FakeSubnet.create_one_subnet() @@ -897,7 +897,7 @@ class TestListSubnet(TestSubnet): self.network.subnets.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_list_with_tag_options(self): arglist = [ @@ -1244,7 +1244,7 @@ class TestShowSubnet(TestSubnet): self._subnet.name, ignore_missing=False) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) class TestUnsetSubnet(TestSubnet): diff --git a/openstackclient/tests/unit/network/v2/test_subnet_pool.py b/openstackclient/tests/unit/network/v2/test_subnet_pool.py index eb454646..243fc76d 100644 --- a/openstackclient/tests/unit/network/v2/test_subnet_pool.py +++ b/openstackclient/tests/unit/network/v2/test_subnet_pool.py @@ -133,7 +133,7 @@ class TestCreateSubnetPool(TestSubnetPool): }) self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_prefixlen_options(self): arglist = [ @@ -163,7 +163,7 @@ class TestCreateSubnetPool(TestSubnetPool): 'name': self._subnet_pool.name, }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_len_negative(self): arglist = [ @@ -201,7 +201,7 @@ class TestCreateSubnetPool(TestSubnetPool): 'name': self._subnet_pool.name, }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_address_scope_option(self): arglist = [ @@ -224,7 +224,7 @@ class TestCreateSubnetPool(TestSubnetPool): 'name': self._subnet_pool.name, }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_default_and_shared_options(self): arglist = [ @@ -250,7 +250,7 @@ class TestCreateSubnetPool(TestSubnetPool): 'shared': True, }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_description(self): arglist = [ @@ -273,7 +273,7 @@ class TestCreateSubnetPool(TestSubnetPool): 'description': self._subnet_pool.description, }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_default_quota(self): arglist = [ @@ -294,7 +294,7 @@ class TestCreateSubnetPool(TestSubnetPool): 'default_quota': 10, }) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def _test_create_with_tag(self, add_tags=True): arglist = [ @@ -328,7 +328,7 @@ class TestCreateSubnetPool(TestSubnetPool): else: self.assertFalse(self.network.set_tags.called) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_create_with_tags(self): self._test_create_with_tag(add_tags=True) @@ -476,7 +476,7 @@ class TestListSubnetPool(TestSubnetPool): self.network.subnet_pools.assert_called_once_with() self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_pool_list_long(self): arglist = [ @@ -491,7 +491,7 @@ class TestListSubnetPool(TestSubnetPool): self.network.subnet_pools.assert_called_once_with() self.assertEqual(self.columns_long, columns) - self.assertListItemEqual(self.data_long, list(data)) + self.assertItemsEqual(self.data_long, list(data)) def test_subnet_pool_list_no_share(self): arglist = [ @@ -507,7 +507,7 @@ class TestListSubnetPool(TestSubnetPool): self.network.subnet_pools.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_pool_list_share(self): arglist = [ @@ -523,7 +523,7 @@ class TestListSubnetPool(TestSubnetPool): self.network.subnet_pools.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_pool_list_no_default(self): arglist = [ @@ -539,7 +539,7 @@ class TestListSubnetPool(TestSubnetPool): self.network.subnet_pools.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_pool_list_default(self): arglist = [ @@ -555,7 +555,7 @@ class TestListSubnetPool(TestSubnetPool): self.network.subnet_pools.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_pool_list_project(self): project = identity_fakes_v3.FakeProject.create_one_project() @@ -573,7 +573,7 @@ class TestListSubnetPool(TestSubnetPool): self.network.subnet_pools.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_pool_list_project_domain(self): project = identity_fakes_v3.FakeProject.create_one_project() @@ -593,7 +593,7 @@ class TestListSubnetPool(TestSubnetPool): self.network.subnet_pools.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_pool_list_name(self): subnet_pool = network_fakes.FakeSubnetPool.create_one_subnet_pool() @@ -611,7 +611,7 @@ class TestListSubnetPool(TestSubnetPool): self.network.subnet_pools.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_subnet_pool_list_address_scope(self): addr_scope = network_fakes.FakeAddressScope.create_one_address_scope() @@ -629,7 +629,7 @@ class TestListSubnetPool(TestSubnetPool): self.network.subnet_pools.assert_called_once_with(**filters) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_list_with_tag_options(self): arglist = [ @@ -654,7 +654,7 @@ class TestListSubnetPool(TestSubnetPool): 'not_any_tags': 'black,white'} ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) class TestSetSubnetPool(TestSubnetPool): @@ -1008,7 +1008,7 @@ class TestShowSubnetPool(TestSubnetPool): ignore_missing=False ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) class TestUnsetSubnetPool(TestSubnetPool): diff --git a/openstackclient/tests/unit/utils.py b/openstackclient/tests/unit/utils.py index 4130f18e..39cb5614 100644 --- a/openstackclient/tests/unit/utils.py +++ b/openstackclient/tests/unit/utils.py @@ -17,7 +17,6 @@ from io import StringIO import os -from cliff import columns as cliff_columns import fixtures import testtools @@ -85,18 +84,3 @@ class TestCommand(TestCase): self.assertIn(attr, parsed_args) self.assertEqual(value, getattr(parsed_args, attr)) return parsed_args - - def assertListItemEqual(self, expected, actual): - self.assertEqual(len(expected), len(actual)) - for item_expected, item_actual in zip(expected, actual): - self.assertItemEqual(item_expected, item_actual) - - def assertItemEqual(self, expected, actual): - self.assertEqual(len(expected), len(actual)) - for col_expected, col_actual in zip(expected, actual): - if isinstance(col_expected, cliff_columns.FormattableColumn): - self.assertIsInstance(col_actual, col_expected.__class__) - self.assertEqual(col_expected.human_readable(), - col_actual.human_readable()) - else: - self.assertEqual(col_expected, col_actual) diff --git a/openstackclient/tests/unit/volume/v1/test_qos_specs.py b/openstackclient/tests/unit/volume/v1/test_qos_specs.py index 83c533b6..5500438b 100644 --- a/openstackclient/tests/unit/volume/v1/test_qos_specs.py +++ b/openstackclient/tests/unit/volume/v1/test_qos_specs.py @@ -109,7 +109,7 @@ class TestQosCreate(TestQos): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_qos_create_with_consumer(self): arglist = [ @@ -129,7 +129,7 @@ class TestQosCreate(TestQos): {'consumer': self.new_qos_spec.consumer} ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_qos_create_with_properties(self): arglist = [ @@ -155,7 +155,7 @@ class TestQosCreate(TestQos): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) class TestQosDelete(TestQos): @@ -350,7 +350,7 @@ class TestQosList(TestQos): self.qos_mock.list.assert_called_with() self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_qos_list_no_association(self): self.qos_mock.reset_mock() @@ -377,7 +377,7 @@ class TestQosList(TestQos): format_columns.ListColumn(None), format_columns.DictColumn(self.qos_specs[1].specs), ) - self.assertListItemEqual(ex_data, list(data)) + self.assertItemsEqual(ex_data, list(data)) class TestQosSet(TestQos): @@ -454,7 +454,7 @@ class TestQosShow(TestQos): self.qos_spec.name, format_columns.DictColumn(self.qos_spec.specs), ) - self.assertItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) class TestQosUnset(TestQos): diff --git a/openstackclient/tests/unit/volume/v1/test_type.py b/openstackclient/tests/unit/volume/v1/test_type.py index 8bee5747..f1d46914 100644 --- a/openstackclient/tests/unit/volume/v1/test_type.py +++ b/openstackclient/tests/unit/volume/v1/test_type.py @@ -78,7 +78,7 @@ class TestTypeCreate(TestType): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_type_create_with_encryption(self): encryption_info = { @@ -139,7 +139,7 @@ class TestTypeCreate(TestType): body, ) self.assertEqual(encryption_columns, columns) - self.assertItemEqual(encryption_data, data) + self.assertItemsEqual(encryption_data, data) class TestTypeDelete(TestType): @@ -270,7 +270,7 @@ class TestTypeList(TestType): columns, data = self.cmd.take_action(parsed_args) self.types_mock.list.assert_called_once_with() self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_type_list_with_options(self): arglist = [ @@ -284,7 +284,7 @@ class TestTypeList(TestType): columns, data = self.cmd.take_action(parsed_args) self.types_mock.list.assert_called_once_with() self.assertEqual(self.columns_long, columns) - self.assertListItemEqual(self.data_long, list(data)) + self.assertItemsEqual(self.data_long, list(data)) def test_type_list_with_encryption(self): encryption_type = volume_fakes.FakeType.create_one_encryption_type( @@ -328,7 +328,7 @@ class TestTypeList(TestType): self.encryption_types_mock.list.assert_called_once_with() self.types_mock.list.assert_called_once_with() self.assertEqual(encryption_columns, columns) - self.assertListItemEqual(encryption_data, list(data)) + self.assertItemsEqual(encryption_data, list(data)) class TestTypeSet(TestType): @@ -469,7 +469,7 @@ class TestTypeShow(TestType): self.types_mock.get.assert_called_with(self.volume_type.id) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_type_show_with_encryption(self): encryption_type = volume_fakes.FakeType.create_one_encryption_type() @@ -513,7 +513,7 @@ class TestTypeShow(TestType): self.types_mock.get.assert_called_with(self.volume_type.id) self.encryption_types_mock.get.assert_called_with(self.volume_type.id) self.assertEqual(encryption_columns, columns) - self.assertItemEqual(encryption_data, data) + self.assertItemsEqual(encryption_data, data) class TestTypeUnset(TestType): diff --git a/openstackclient/tests/unit/volume/v1/test_volume.py b/openstackclient/tests/unit/volume/v1/test_volume.py index 25cdf92a..704a66da 100644 --- a/openstackclient/tests/unit/volume/v1/test_volume.py +++ b/openstackclient/tests/unit/volume/v1/test_volume.py @@ -135,7 +135,7 @@ class TestVolumeCreate(TestVolume): None, ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_options(self): arglist = [ @@ -179,7 +179,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_user_project_id(self): # Return a project @@ -226,7 +226,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_user_project_name(self): # Return a project @@ -273,7 +273,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_properties(self): arglist = [ @@ -314,7 +314,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_image_id(self): image = image_fakes.FakeImage.create_one_image() @@ -357,7 +357,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_image_name(self): image = image_fakes.FakeImage.create_one_image() @@ -400,7 +400,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_with_source(self): self.volumes_mock.get.return_value = self.new_volume @@ -430,7 +430,7 @@ class TestVolumeCreate(TestVolume): None, ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_with_bootable_and_readonly(self): arglist = [ @@ -468,7 +468,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) self.volumes_mock.set_bootable.assert_called_with( self.new_volume.id, True) self.volumes_mock.update_readonly_flag.assert_called_with( @@ -510,7 +510,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) self.volumes_mock.set_bootable.assert_called_with( self.new_volume.id, False) self.volumes_mock.update_readonly_flag.assert_called_with( @@ -562,7 +562,7 @@ class TestVolumeCreate(TestVolume): self.assertEqual(2, mock_error.call_count) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) self.volumes_mock.set_bootable.assert_called_with( self.new_volume.id, True) self.volumes_mock.update_readonly_flag.assert_called_with( @@ -765,7 +765,7 @@ class TestVolumeList(TestVolume): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) def test_volume_list_name(self): arglist = [ @@ -782,7 +782,7 @@ class TestVolumeList(TestVolume): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, tuple(columns)) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) def test_volume_list_status(self): arglist = [ @@ -799,7 +799,7 @@ class TestVolumeList(TestVolume): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, tuple(columns)) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) def test_volume_list_all_projects(self): arglist = [ @@ -816,7 +816,7 @@ class TestVolumeList(TestVolume): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, tuple(columns)) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) def test_volume_list_long(self): arglist = [ @@ -856,7 +856,7 @@ class TestVolumeList(TestVolume): volume.AttachmentsColumn(self._volume.attachments), format_columns.DictColumn(self._volume.metadata), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) def test_volume_list_with_limit(self): arglist = [ @@ -881,7 +881,7 @@ class TestVolumeList(TestVolume): 'all_tenants': False, } ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.datalist, tuple(data)) + self.assertItemsEqual(self.datalist, tuple(data)) def test_volume_list_negative_limit(self): arglist = [ @@ -1272,7 +1272,7 @@ class TestVolumeShow(TestVolume): self.volumes_mock.get.assert_called_with(self._volume.id) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_show_backward_compatibility(self): arglist = [ diff --git a/openstackclient/tests/unit/volume/v1/test_volume_backup.py b/openstackclient/tests/unit/volume/v1/test_volume_backup.py index 20aadcd3..a7131550 100644 --- a/openstackclient/tests/unit/volume/v1/test_volume_backup.py +++ b/openstackclient/tests/unit/volume/v1/test_volume_backup.py @@ -100,7 +100,7 @@ class TestBackupCreate(TestBackup): self.new_backup.description, ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_backup_create_without_name(self): arglist = [ @@ -124,7 +124,7 @@ class TestBackupCreate(TestBackup): self.new_backup.description, ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) class TestBackupDelete(TestBackup): @@ -277,7 +277,7 @@ class TestBackupList(TestBackup): search_opts=search_opts, ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_backup_list_with_options(self): arglist = [ @@ -309,7 +309,7 @@ class TestBackupList(TestBackup): search_opts=search_opts, ) self.assertEqual(self.columns_long, columns) - self.assertListItemEqual(self.data_long, list(data)) + self.assertItemsEqual(self.data_long, list(data)) class TestBackupRestore(TestBackup): @@ -391,4 +391,4 @@ class TestBackupShow(TestBackup): self.backups_mock.get.assert_called_with(self.backup.id) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) diff --git a/openstackclient/tests/unit/volume/v2/test_consistency_group.py b/openstackclient/tests/unit/volume/v2/test_consistency_group.py index c3bd71e3..6bb6c029 100644 --- a/openstackclient/tests/unit/volume/v2/test_consistency_group.py +++ b/openstackclient/tests/unit/volume/v2/test_consistency_group.py @@ -251,7 +251,7 @@ class TestConsistencyGroupCreate(TestConsistencyGroup): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_consistency_group_create_from_source(self): arglist = [ @@ -279,7 +279,7 @@ class TestConsistencyGroupCreate(TestConsistencyGroup): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_consistency_group_create_from_snapshot(self): arglist = [ @@ -307,7 +307,7 @@ class TestConsistencyGroupCreate(TestConsistencyGroup): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) class TestConsistencyGroupDelete(TestConsistencyGroup): @@ -463,7 +463,7 @@ class TestConsistencyGroupList(TestConsistencyGroup): self.consistencygroups_mock.list.assert_called_once_with( detailed=True, search_opts={'all_tenants': False}) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_consistency_group_list_with_all_project(self): arglist = [ @@ -480,7 +480,7 @@ class TestConsistencyGroupList(TestConsistencyGroup): self.consistencygroups_mock.list.assert_called_once_with( detailed=True, search_opts={'all_tenants': True}) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_consistency_group_list_with_long(self): arglist = [ @@ -497,7 +497,7 @@ class TestConsistencyGroupList(TestConsistencyGroup): self.consistencygroups_mock.list.assert_called_once_with( detailed=True, search_opts={'all_tenants': False}) self.assertEqual(self.columns_long, columns) - self.assertListItemEqual(self.data_long, list(data)) + self.assertItemsEqual(self.data_long, list(data)) class TestConsistencyGroupRemoveVolume(TestConsistencyGroup): @@ -705,4 +705,4 @@ class TestConsistencyGroupShow(TestConsistencyGroup): self.consistencygroups_mock.get.assert_called_once_with( self.consistency_group.id) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) diff --git a/openstackclient/tests/unit/volume/v2/test_qos_specs.py b/openstackclient/tests/unit/volume/v2/test_qos_specs.py index 073ec570..bc4cee8b 100644 --- a/openstackclient/tests/unit/volume/v2/test_qos_specs.py +++ b/openstackclient/tests/unit/volume/v2/test_qos_specs.py @@ -112,7 +112,7 @@ class TestQosCreate(TestQos): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_qos_create_with_consumer(self): arglist = [ @@ -133,7 +133,7 @@ class TestQosCreate(TestQos): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_qos_create_with_properties(self): arglist = [ @@ -159,7 +159,7 @@ class TestQosCreate(TestQos): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) class TestQosDelete(TestQos): @@ -342,7 +342,7 @@ class TestQosList(TestQos): self.qos_mock.list.assert_called_with() self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_qos_list_no_association(self): self.qos_mock.reset_mock() @@ -369,7 +369,7 @@ class TestQosList(TestQos): format_columns.ListColumn(None), format_columns.DictColumn(self.qos_specs[1].specs), ) - self.assertListItemEqual(ex_data, list(data)) + self.assertItemsEqual(ex_data, list(data)) class TestQosSet(TestQos): @@ -449,7 +449,7 @@ class TestQosShow(TestQos): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, tuple(data)) + self.assertItemsEqual(self.data, tuple(data)) class TestQosUnset(TestQos): diff --git a/openstackclient/tests/unit/volume/v2/test_type.py b/openstackclient/tests/unit/volume/v2/test_type.py index f13d0851..000464c5 100644 --- a/openstackclient/tests/unit/volume/v2/test_type.py +++ b/openstackclient/tests/unit/volume/v2/test_type.py @@ -93,7 +93,7 @@ class TestTypeCreate(TestType): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_type_create_private(self): arglist = [ @@ -119,7 +119,7 @@ class TestTypeCreate(TestType): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_public_type_create_with_project(self): arglist = [ @@ -196,7 +196,7 @@ class TestTypeCreate(TestType): body, ) self.assertEqual(encryption_columns, columns) - self.assertItemEqual(encryption_data, data) + self.assertItemsEqual(encryption_data, data) class TestTypeDelete(TestType): @@ -330,7 +330,7 @@ class TestTypeList(TestType): columns, data = self.cmd.take_action(parsed_args) self.types_mock.list.assert_called_once_with(is_public=None) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_type_list_with_options(self): arglist = [ @@ -348,7 +348,7 @@ class TestTypeList(TestType): columns, data = self.cmd.take_action(parsed_args) self.types_mock.list.assert_called_once_with(is_public=True) self.assertEqual(self.columns_long, columns) - self.assertListItemEqual(self.data_long, list(data)) + self.assertItemsEqual(self.data_long, list(data)) def test_type_list_with_private_option(self): arglist = [ @@ -365,7 +365,7 @@ class TestTypeList(TestType): columns, data = self.cmd.take_action(parsed_args) self.types_mock.list.assert_called_once_with(is_public=False) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_type_list_with_default_option(self): arglist = [ @@ -383,7 +383,7 @@ class TestTypeList(TestType): columns, data = self.cmd.take_action(parsed_args) self.types_mock.default.assert_called_once_with() self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data_with_default_type, list(data)) + self.assertItemsEqual(self.data_with_default_type, list(data)) def test_type_list_with_encryption(self): encryption_type = volume_fakes.FakeType.create_one_encryption_type( @@ -427,7 +427,7 @@ class TestTypeList(TestType): self.encryption_types_mock.list.assert_called_once_with() self.types_mock.list.assert_called_once_with(is_public=None) self.assertEqual(encryption_columns, columns) - self.assertListItemEqual(encryption_data, list(data)) + self.assertItemsEqual(encryption_data, list(data)) class TestTypeSet(TestType): @@ -713,7 +713,7 @@ class TestTypeShow(TestType): self.types_mock.get.assert_called_with(self.volume_type.id) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.data, data) + self.assertItemsEqual(self.data, data) def test_type_show_with_access(self): arglist = [ @@ -746,7 +746,7 @@ class TestTypeShow(TestType): private_type.name, format_columns.DictColumn(private_type.extra_specs) ) - self.assertItemEqual(private_type_data, data) + self.assertItemsEqual(private_type_data, data) def test_type_show_with_list_access_exec(self): arglist = [ @@ -778,7 +778,7 @@ class TestTypeShow(TestType): private_type.name, format_columns.DictColumn(private_type.extra_specs) ) - self.assertItemEqual(private_type_data, data) + self.assertItemsEqual(private_type_data, data) def test_type_show_with_encryption(self): encryption_type = volume_fakes.FakeType.create_one_encryption_type() @@ -824,7 +824,7 @@ class TestTypeShow(TestType): self.types_mock.get.assert_called_with(self.volume_type.id) self.encryption_types_mock.get.assert_called_with(self.volume_type.id) self.assertEqual(encryption_columns, columns) - self.assertItemEqual(encryption_data, data) + self.assertItemsEqual(encryption_data, data) class TestTypeUnset(TestType): diff --git a/openstackclient/tests/unit/volume/v2/test_volume.py b/openstackclient/tests/unit/volume/v2/test_volume.py index 4e204ad1..b9fe4e83 100644 --- a/openstackclient/tests/unit/volume/v2/test_volume.py +++ b/openstackclient/tests/unit/volume/v2/test_volume.py @@ -136,7 +136,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_options(self): consistency_group = ( @@ -182,7 +182,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_properties(self): arglist = [ @@ -218,7 +218,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_image_id(self): image = image_fakes.FakeImage.create_one_image() @@ -256,7 +256,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_image_name(self): image = image_fakes.FakeImage.create_one_image() @@ -294,7 +294,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_with_snapshot(self): snapshot = volume_fakes.FakeSnapshot.create_one_snapshot() @@ -331,7 +331,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) def test_volume_create_with_bootable_and_readonly(self): arglist = [ @@ -369,7 +369,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) self.volumes_mock.set_bootable.assert_called_with( self.new_volume.id, True) self.volumes_mock.update_readonly_flag.assert_called_with( @@ -411,7 +411,7 @@ class TestVolumeCreate(TestVolume): ) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) self.volumes_mock.set_bootable.assert_called_with( self.new_volume.id, False) self.volumes_mock.update_readonly_flag.assert_called_with( @@ -463,7 +463,7 @@ class TestVolumeCreate(TestVolume): self.assertEqual(2, mock_error.call_count) self.assertEqual(self.columns, columns) - self.assertItemEqual(self.datalist, data) + self.assertItemsEqual(self.datalist, data) self.volumes_mock.set_bootable.assert_called_with( self.new_volume.id, True) self.volumes_mock.update_readonly_flag.assert_called_with( @@ -680,7 +680,7 @@ class TestVolumeList(TestVolume): self.mock_volume.size, volume.AttachmentsColumn(self.mock_volume.attachments), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) def test_volume_list_project(self): arglist = [ @@ -720,7 +720,7 @@ class TestVolumeList(TestVolume): self.mock_volume.size, volume.AttachmentsColumn(self.mock_volume.attachments), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) def test_volume_list_project_domain(self): arglist = [ @@ -762,7 +762,7 @@ class TestVolumeList(TestVolume): self.mock_volume.size, volume.AttachmentsColumn(self.mock_volume.attachments), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) def test_volume_list_user(self): arglist = [ @@ -801,7 +801,7 @@ class TestVolumeList(TestVolume): self.mock_volume.size, volume.AttachmentsColumn(self.mock_volume.attachments), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) def test_volume_list_user_domain(self): arglist = [ @@ -843,7 +843,7 @@ class TestVolumeList(TestVolume): self.mock_volume.size, volume.AttachmentsColumn(self.mock_volume.attachments), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) def test_volume_list_name(self): arglist = [ @@ -883,7 +883,7 @@ class TestVolumeList(TestVolume): self.mock_volume.size, volume.AttachmentsColumn(self.mock_volume.attachments), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) def test_volume_list_status(self): arglist = [ @@ -923,7 +923,7 @@ class TestVolumeList(TestVolume): self.mock_volume.size, volume.AttachmentsColumn(self.mock_volume.attachments), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) def test_volume_list_all_projects(self): arglist = [ @@ -963,7 +963,7 @@ class TestVolumeList(TestVolume): self.mock_volume.size, volume.AttachmentsColumn(self.mock_volume.attachments), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) def test_volume_list_long(self): arglist = [ @@ -1017,7 +1017,7 @@ class TestVolumeList(TestVolume): volume.AttachmentsColumn(self.mock_volume.attachments), format_columns.DictColumn(self.mock_volume.metadata), ), ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) def test_volume_list_with_marker_and_limit(self): arglist = [ @@ -1056,7 +1056,7 @@ class TestVolumeList(TestVolume): 'name': None, 'all_tenants': False, } ) - self.assertListItemEqual(datalist, tuple(data)) + self.assertItemsEqual(datalist, tuple(data)) def test_volume_list_negative_limit(self): arglist = [ @@ -1450,7 +1450,7 @@ class TestVolumeShow(TestVolume): volume_fakes.FakeVolume.get_volume_columns(self._volume), columns) - self.assertItemEqual( + self.assertItemsEqual( volume_fakes.FakeVolume.get_volume_data(self._volume), data) diff --git a/openstackclient/tests/unit/volume/v2/test_volume_backup.py b/openstackclient/tests/unit/volume/v2/test_volume_backup.py index 4e1f7ee1..13513ed8 100644 --- a/openstackclient/tests/unit/volume/v2/test_volume_backup.py +++ b/openstackclient/tests/unit/volume/v2/test_volume_backup.py @@ -314,7 +314,7 @@ class TestBackupList(TestBackup): limit=None, ) self.assertEqual(self.columns, columns) - self.assertListItemEqual(self.data, list(data)) + self.assertItemsEqual(self.data, list(data)) def test_backup_list_with_options(self): arglist = [ @@ -353,7 +353,7 @@ class TestBackupList(TestBackup): limit=3, ) self.assertEqual(self.columns_long, columns) - self.assertListItemEqual(self.data_long, list(data)) + self.assertItemsEqual(self.data_long, list(data)) class TestBackupRestore(TestBackup): diff --git a/releasenotes/notes/add_id_and_enabled_to_list_identity_provider-e0981063a2dc5961.yaml b/releasenotes/notes/add_id_and_enabled_to_list_identity_provider-e0981063a2dc5961.yaml new file mode 100644 index 00000000..fccd0a63 --- /dev/null +++ b/releasenotes/notes/add_id_and_enabled_to_list_identity_provider-e0981063a2dc5961.yaml @@ -0,0 +1,3 @@ +--- +features: + - Add ``--id`` and ``--enabled`` option to ``identity provider list`` command.
\ No newline at end of file diff --git a/releasenotes/notes/fix-openstak-image-save-sdk-port-eb160e8ffc92e514.yaml b/releasenotes/notes/fix-openstak-image-save-sdk-port-eb160e8ffc92e514.yaml new file mode 100644 index 00000000..857f3c50 --- /dev/null +++ b/releasenotes/notes/fix-openstak-image-save-sdk-port-eb160e8ffc92e514.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - Stream image download to avoid buffering data in memory which rapidly + exhausts memory resulting in OOM kill or system crash for all but the + smallest of images. Fixes https://storyboard.openstack.org/#!/story/2007672 + - Restore default behavior of 'openstack image save' to send data to stdout + Relates to https://storyboard.openstack.org/#!/story/2007672.
\ No newline at end of file diff --git a/releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml b/releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml new file mode 100644 index 00000000..572e215b --- /dev/null +++ b/releasenotes/notes/remove-nlbaas-quota-8b38e0c91ab113cb.yaml @@ -0,0 +1,4 @@ +--- +other: + - | + Remove deprecated neutron-lbaas results from ``quota show`` command. diff --git a/releasenotes/notes/switch-aggregate-to-sdk-ced451a0f28bf6ea.yaml b/releasenotes/notes/switch-aggregate-to-sdk-ced451a0f28bf6ea.yaml new file mode 100644 index 00000000..0df2d635 --- /dev/null +++ b/releasenotes/notes/switch-aggregate-to-sdk-ced451a0f28bf6ea.yaml @@ -0,0 +1,4 @@ +--- +features: + - Switch aggregate operations to use SDK + - Adds 'aggregate cache image' operation diff --git a/releasenotes/notes/switch-flavor-to-sdk-b874a3c39559815e.yaml b/releasenotes/notes/switch-flavor-to-sdk-b874a3c39559815e.yaml new file mode 100644 index 00000000..7863c323 --- /dev/null +++ b/releasenotes/notes/switch-flavor-to-sdk-b874a3c39559815e.yaml @@ -0,0 +1,4 @@ +--- +features: + - Switch compute.flavor operations from direct API calls (novaclient) to + OpenStackSDK. diff --git a/requirements.txt b/requirements.txt index 9430a7fd..ed55ce37 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,10 +3,10 @@ # process, which may cause wedges in the gate later. pbr!=2.1.0,>=2.0.0 # Apache-2.0 -cliff>=3.4.0 # Apache-2.0 +cliff>=3.5.0 # Apache-2.0 iso8601>=0.1.11 # MIT -openstacksdk>=0.51.0 # Apache-2.0 -osc-lib>=2.2.0 # Apache-2.0 +openstacksdk>=0.52.0 # Apache-2.0 +osc-lib>=2.3.0 # Apache-2.0 oslo.i18n>=3.15.3 # Apache-2.0 python-keystoneclient>=3.22.0 # Apache-2.0 python-novaclient>=15.1.0 # Apache-2.0 @@ -65,6 +65,7 @@ openstack.compute.v2 = aggregate_set = openstackclient.compute.v2.aggregate:SetAggregate aggregate_show = openstackclient.compute.v2.aggregate:ShowAggregate aggregate_unset = openstackclient.compute.v2.aggregate:UnsetAggregate + aggregate_cache_image = openstackclient.compute.v2.aggregate:CacheImageForAggregate compute_service_delete = openstackclient.compute.v2.service:DeleteService compute_service_list = openstackclient.compute.v2.service:ListService diff --git a/test-requirements.txt b/test-requirements.txt index 3dce687b..8b61a5c0 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,10 +1,8 @@ # The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. -hacking>=2.0.0 # Apache-2.0 coverage!=4.4,>=4.0 # Apache-2.0 fixtures>=3.0.0 # Apache-2.0/BSD -flake8-import-order>=0.13 # LGPLv3 oslotest>=3.2.0 # Apache-2.0 requests>=2.14.2 # Apache-2.0 requests-mock>=1.2.0 # Apache-2.0 @@ -12,6 +10,5 @@ stestr>=1.0.0 # Apache-2.0 testtools>=2.2.0 # MIT tempest>=17.1.0 # Apache-2.0 osprofiler>=1.4.0 # Apache-2.0 -bandit!=1.6.0,>=1.1.0 # Apache-2.0 wrapt>=1.7.0 # BSD License ddt>=1.0.1 # MIT @@ -28,9 +28,13 @@ commands = {toxinidir}/tools/fast8.sh [testenv:pep8] +deps = + hacking>=2.0.0 + bandit!=1.6.0,>=1.1.0 + flake8-import-order>=0.13 # LGPLv3 commands = - flake8 - bandit -r openstackclient -x tests -s B105,B106,B107,B401,B404,B603,B606,B607,B110,B605,B101 + flake8 + bandit -r openstackclient -x tests -s B105,B106,B107,B401,B404,B603,B606,B607,B110,B605,B101 [testenv:bandit] # This command runs the bandit security linter against the openstackclient |
