summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/backwards-incompatible.rst54
-rw-r--r--doc/source/command-objects/backup.rst11
-rw-r--r--doc/source/command-objects/compute-agent.rst4
-rw-r--r--doc/source/command-objects/compute-service.rst10
-rw-r--r--doc/source/command-objects/host.rst4
-rw-r--r--doc/source/command-objects/keypair.rst6
-rw-r--r--doc/source/command-objects/network.rst4
-rw-r--r--doc/source/command-objects/subnet.rst7
-rw-r--r--doc/source/commands.rst9
-rw-r--r--doc/source/humaninterfaceguide.rst2
-rw-r--r--functional/tests/image/v2/test_image.py3
-rw-r--r--openstackclient/compute/v2/agent.py6
-rw-r--r--openstackclient/compute/v2/host.py4
-rw-r--r--openstackclient/compute/v2/keypair.py27
-rw-r--r--openstackclient/compute/v2/service.py24
-rw-r--r--openstackclient/network/v2/network.py2
-rw-r--r--openstackclient/network/v2/subnet.py8
-rw-r--r--openstackclient/tests/compute/v2/fakes.py19
-rw-r--r--openstackclient/tests/compute/v2/test_keypair.py62
-rw-r--r--openstackclient/tests/compute/v2/test_service.py55
-rw-r--r--openstackclient/tests/identity/v2_0/fakes.py70
-rw-r--r--openstackclient/tests/identity/v2_0/test_endpoint.py6
-rw-r--r--openstackclient/tests/identity/v2_0/test_role.py227
-rw-r--r--openstackclient/tests/identity/v2_0/test_service.py121
-rw-r--r--openstackclient/tests/identity/v2_0/test_token.py9
-rw-r--r--openstackclient/tests/identity/v2_0/test_user.py269
-rw-r--r--openstackclient/tests/volume/v2/test_backup.py8
-rw-r--r--openstackclient/volume/v1/backup.py6
-rw-r--r--openstackclient/volume/v2/backup.py11
-rw-r--r--releasenotes/notes/bp-multi-argument-compute-0bc4522f6edca355.yaml4
-rw-r--r--releasenotes/notes/bug-1596443-9e2af267e91d1643.yaml6
31 files changed, 592 insertions, 466 deletions
diff --git a/doc/source/backwards-incompatible.rst b/doc/source/backwards-incompatible.rst
index f86cfce4..da3c1b64 100644
--- a/doc/source/backwards-incompatible.rst
+++ b/doc/source/backwards-incompatible.rst
@@ -124,7 +124,7 @@ Releases Before 3.0
8. `region` commands no longer support `url`
- The Keystone team removed support for thr `url` attribute from the client
+ The Keystone team removed support for the `url` attribute from the client
and server side. Changes to the `create`, `set` and `list` commands for
regions have been affected.
@@ -184,27 +184,41 @@ Releases Before 3.0
14. Output of `ip floating list` command has changed.
- When using Compute v2, the original output of `ip floating list` command is:
- +----+--------+------------+----------+-------------+
- | ID | Pool | IP | Fixed IP | Instance ID |
- +----+--------+-----------------------+-------------+
- | 1 | public | 172.24.4.1 | None | None |
- +----+--------+------------+----------+-------------+
+ When using Compute v2, the original output is:
+
+ .. code-block:: bash
+
+ # ip floating list
+
+ +----+--------+------------+----------+-------------+
+ | ID | Pool | IP | Fixed IP | Instance ID |
+ +----+--------+-----------------------+-------------+
+ | 1 | public | 172.24.4.1 | None | None |
+ +----+--------+------------+----------+-------------+
Now it changes to:
- +----+---------------------+------------------+-----------+--------+
- | ID | Floating IP Address | Fixed IP Address | Server ID | Pool |
- +----+---------------------+------------------+-----------+--------+
- | 1 | 172.24.4.1 | None | None | public |
- +----+---------------------+------------------+-----------+--------+
-
- When using Network v2, the output of `ip floating list` command is:
- +--------------------------------------+---------------------+------------------+------+
- | ID | Floating IP Address | Fixed IP Address | Port |
- +--------------------------------------+---------------------+------------------+------+
- | 1976df86-e66a-4f96-81bd-c6ffee6407f1 | 172.24.4.3 | None | None |
- +--------------------------------------+---------------------+------------------+------+
- which is different from Compute v2.
+
+ .. code-block:: bash
+
+ # ip floating list
+
+ +----+---------------------+------------------+-----------+--------+
+ | ID | Floating IP Address | Fixed IP Address | Server ID | Pool |
+ +----+---------------------+------------------+-----------+--------+
+ | 1 | 172.24.4.1 | None | None | public |
+ +----+---------------------+------------------+-----------+--------+
+
+ When using Network v2, which is different from Compute v2. The output is:
+
+ .. code-block:: bash
+
+ # ip floating list
+
+ +--------------------------------------+---------------------+------------------+------+
+ | ID | Floating IP Address | Fixed IP Address | Port |
+ +--------------------------------------+---------------------+------------------+------+
+ | 1976df86-e66a-4f96-81bd-c6ffee6407f1 | 172.24.4.3 | None | None |
+ +--------------------------------------+---------------------+------------------+------+
* In favor of: Use `ip floating list` command
* As of: NA
diff --git a/doc/source/command-objects/backup.rst b/doc/source/command-objects/backup.rst
index 9d7fb95d..8e657b32 100644
--- a/doc/source/command-objects/backup.rst
+++ b/doc/source/command-objects/backup.rst
@@ -16,6 +16,7 @@ Create new backup
[--container <container>]
[--name <name>]
[--description <description>]
+ [--force]
<volume>
.. option:: --container <container>
@@ -30,6 +31,10 @@ Create new backup
Description of the backup
+.. option:: --force
+
+ Allow to back up an in-use volume
+
.. _backup_create-backup:
.. describe:: <volume>
@@ -49,7 +54,7 @@ Delete backup(s)
.. _backup_delete-backup:
.. describe:: <backup>
- Backup(s) to delete (ID only)
+ Backup(s) to delete (name or ID)
backup list
-----------
@@ -81,7 +86,7 @@ Restore backup
.. _backup_restore-backup:
.. describe:: <backup>
- Backup to restore (ID only)
+ Backup to restore (name or ID)
.. describe:: <volume>
@@ -101,4 +106,4 @@ Display backup details
.. _backup_show-backup:
.. describe:: <backup>
- Backup to display (ID only)
+ Backup to display (name or ID)
diff --git a/doc/source/command-objects/compute-agent.rst b/doc/source/command-objects/compute-agent.rst
index b00a981d..ae057dc9 100644
--- a/doc/source/command-objects/compute-agent.rst
+++ b/doc/source/command-objects/compute-agent.rst
@@ -59,7 +59,7 @@ Delete compute agent(s)
compute agent list
------------------
-List compute agent command
+List compute agents
.. program:: compute agent list
.. code:: bash
@@ -74,7 +74,7 @@ List compute agent command
compute agent set
-----------------
-Set compute agent command
+Set compute agent properties
.. program:: agent set
.. code:: bash
diff --git a/doc/source/command-objects/compute-service.rst b/doc/source/command-objects/compute-service.rst
index f43b5fa6..57dd2ba5 100644
--- a/doc/source/command-objects/compute-service.rst
+++ b/doc/source/command-objects/compute-service.rst
@@ -7,23 +7,23 @@ Compute v2
compute service delete
----------------------
-Delete service command
+Delete compute service(s)
.. program:: compute service delete
.. code:: bash
os compute service delete
- <service>
+ <service> [<service> ...]
.. _compute-service-delete:
.. describe:: <service>
- Compute service to delete (ID only)
+ Compute service(s) to delete (ID only)
compute service list
--------------------
-List service command
+List compute services
.. program:: compute service list
.. code:: bash
@@ -50,7 +50,7 @@ List service command
compute service set
-------------------
-Set service command
+Set compute service properties
.. program:: compute service set
.. code:: bash
diff --git a/doc/source/command-objects/host.rst b/doc/source/command-objects/host.rst
index 8c34d3fb..409b834b 100644
--- a/doc/source/command-objects/host.rst
+++ b/doc/source/command-objects/host.rst
@@ -9,7 +9,7 @@ The physical computer running a hypervisor.
host list
---------
-List all hosts
+List hosts
.. program:: host list
.. code:: bash
@@ -24,7 +24,7 @@ List all hosts
host set
--------
-Set host command
+Set host properties
.. program:: host set
.. code:: bash
diff --git a/doc/source/command-objects/keypair.rst b/doc/source/command-objects/keypair.rst
index 6638b8c9..64cc20cd 100644
--- a/doc/source/command-objects/keypair.rst
+++ b/doc/source/command-objects/keypair.rst
@@ -30,17 +30,17 @@ Create new public key
keypair delete
--------------
-Delete public key
+Delete public key(s)
.. program:: keypair delete
.. code:: bash
os keypair delete
- <key>
+ <key> [<key> ...]
.. describe:: <key>
- Public key to delete (name only)
+ Public key(s) to delete (name only)
keypair list
------------
diff --git a/doc/source/command-objects/network.rst b/doc/source/command-objects/network.rst
index 1cf442f2..0c472e7f 100644
--- a/doc/source/command-objects/network.rst
+++ b/doc/source/command-objects/network.rst
@@ -108,7 +108,7 @@ Create new network
.. option:: --provider-network-type <provider-network-type>
The physical mechanism by which the virtual network is implemented.
- The supported options are: flat, geneve, gre, local, vlan, vxlan
+ The supported options are: flat, geneve, gre, local, vlan, vxlan.
*Network version 2 only*
@@ -238,7 +238,7 @@ Set network properties
.. option:: --provider-network-type <provider-network-type>
The physical mechanism by which the virtual network is implemented.
- The supported options are: flat, gre, local, vlan, vxlan
+ The supported options are: flat, gre, local, vlan, vxlan.
.. option:: --provider-physical-network <provider-physical-network>
diff --git a/doc/source/command-objects/subnet.rst b/doc/source/command-objects/subnet.rst
index fe77ccfd..1137940f 100644
--- a/doc/source/command-objects/subnet.rst
+++ b/doc/source/command-objects/subnet.rst
@@ -83,7 +83,7 @@ Create new subnet
'auto': Gateway address should automatically be chosen from
within the subnet itself, 'none': This subnet will not use
a gateway, e.g.: ``--gateway 192.168.9.1``, ``--gateway auto``,
- ``--gateway none`` (default is 'auto')
+ ``--gateway none`` (default is 'auto').
.. option:: --host-route destination=<subnet>,gateway=<ip-address>
@@ -158,7 +158,8 @@ List subnets
.. option:: --ip-version {4, 6}
- List only subnets of given IP version in output
+ List only subnets of given IP version in output.
+ Allowed values for IP version are 4 and 6.
subnet set
----------
@@ -200,7 +201,7 @@ Set subnet properties
Specify a gateway for the subnet. The options are:
<ip-address>: Specific IP address to use as the gateway,
'none': This subnet will not use a gateway,
- e.g.: ``--gateway 192.168.9.1``, ``--gateway none``
+ e.g.: ``--gateway 192.168.9.1``, ``--gateway none``.
.. option:: --host-route destination=<subnet>,gateway=<ip-address>
diff --git a/doc/source/commands.rst b/doc/source/commands.rst
index 9fb0555d..9d8ad6fd 100644
--- a/doc/source/commands.rst
+++ b/doc/source/commands.rst
@@ -8,11 +8,12 @@ Commands take the form::
openstack [<global-options>] <object-1> <action> [<object-2>] [<command-arguments>]
-* All long options names begin with two dashes (``--``) and use a single dash
+.. NOTE::
+
+ All long options names begin with two dashes (``--``) and use a single dash
(``-``) internally between words (``--like-this``). Underscores (``_``) are
not used in option names.
-
Global Options
--------------
@@ -78,7 +79,7 @@ referring to both Compute and Volume quotas.
* ``command``: (**Internal**) installed commands in the OSC process
* ``compute agent``: (**Compute**) a cloud Compute agent available to a hypervisor
* ``compute service``: (**Compute**) a cloud Compute process running on a host
-* ``configuration``: (**Internal**) openstack client configuration
+* ``configuration``: (**Internal**) OpenStack client configuration
* ``console log``: (**Compute**) server console text dump
* ``console url``: (**Compute**) server remote console URL
* ``consumer``: (**Identity**) OAuth-based delegatee
@@ -89,7 +90,7 @@ referring to both Compute and Volume quotas.
* ``endpoint``: (**Identity**) the base URL used to contact a specific service
* ``extension``: (**Compute**, **Identity**, **Network**, **Volume**) OpenStack server API extensions
* ``federation protocol``: (**Identity**) the underlying protocol used while federating identities
-* ``flavor``: (**Compute**) predefined server configurations: ram, root disk, etc
+* ``flavor``: (**Compute**) predefined server configurations: ram, root disk and so on
* ``group``: (**Identity**) a grouping of users
* ``host``: (**Compute**) - the physical computer running compute services
* ``hypervisor``: (**Compute**) the virtual machine manager
diff --git a/doc/source/humaninterfaceguide.rst b/doc/source/humaninterfaceguide.rst
index 9cca5aa7..5d3c48dc 100644
--- a/doc/source/humaninterfaceguide.rst
+++ b/doc/source/humaninterfaceguide.rst
@@ -85,7 +85,7 @@ Simplicity
To best support new users and create straight forward interactions, designs
should be as simple as possible. When crafting new commands, designs should
minimize the amount of noise present in output: large amounts of
-nonessential data, overabundance of possible actions, etc. Designs should
+nonessential data, overabundance of possible actions and so on. Designs should
focus on the intent of the command, requiring only the necessary components
and either removing superfluous elements or making
them accessible through optional arguments. An example of this principle occurs
diff --git a/functional/tests/image/v2/test_image.py b/functional/tests/image/v2/test_image.py
index 6a33ad88..2e2b59bb 100644
--- a/functional/tests/image/v2/test_image.py
+++ b/functional/tests/image/v2/test_image.py
@@ -13,6 +13,8 @@
import os
import uuid
+import testtools
+
from functional.common import test
@@ -66,6 +68,7 @@ class ImageTests(test.TestCase):
raw_output = self.openstack('image show ' + self.NAME + opts)
self.assertEqual(self.NAME + "\na='b', c='d'\n", raw_output)
+ @testtools.skip("skip until bug 1596573 is resolved")
def test_image_unset(self):
opts = self.get_show_opts(["name", "tags", "properties"])
self.openstack('image set --tag 01 ' + self.NAME)
diff --git a/openstackclient/compute/v2/agent.py b/openstackclient/compute/v2/agent.py
index 62be2424..4d923955 100644
--- a/openstackclient/compute/v2/agent.py
+++ b/openstackclient/compute/v2/agent.py
@@ -29,7 +29,7 @@ LOG = logging.getLogger(__name__)
class CreateAgent(command.ShowOne):
- """Create compute agent command"""
+ """Create compute agent"""
def get_parser(self, prog_name):
parser = super(CreateAgent, self).get_parser(prog_name)
@@ -112,7 +112,7 @@ class DeleteAgent(command.Command):
class ListAgent(command.Lister):
- """List compute agent command"""
+ """List compute agents"""
def get_parser(self, prog_name):
parser = super(ListAgent, self).get_parser(prog_name)
@@ -142,7 +142,7 @@ class ListAgent(command.Lister):
class SetAgent(command.Command):
- """Set compute agent command"""
+ """Set compute agent properties"""
def get_parser(self, prog_name):
parser = super(SetAgent, self).get_parser(prog_name)
diff --git a/openstackclient/compute/v2/host.py b/openstackclient/compute/v2/host.py
index 78567589..4785377e 100644
--- a/openstackclient/compute/v2/host.py
+++ b/openstackclient/compute/v2/host.py
@@ -22,7 +22,7 @@ from openstackclient.i18n import _
class ListHost(command.Lister):
- """List host command"""
+ """List hosts"""
def get_parser(self, prog_name):
parser = super(ListHost, self).get_parser(prog_name)
@@ -107,7 +107,7 @@ class SetHost(command.Command):
class ShowHost(command.Lister):
- """Show host command"""
+ """Display host details"""
def get_parser(self, prog_name):
parser = super(ShowHost, self).get_parser(prog_name)
diff --git a/openstackclient/compute/v2/keypair.py b/openstackclient/compute/v2/keypair.py
index 13c0a99c..3725a3a8 100644
--- a/openstackclient/compute/v2/keypair.py
+++ b/openstackclient/compute/v2/keypair.py
@@ -16,6 +16,7 @@
"""Keypair action implementations"""
import io
+import logging
import os
import sys
@@ -27,6 +28,9 @@ import six
from openstackclient.i18n import _
+LOG = logging.getLogger(__name__)
+
+
class CreateKeypair(command.ShowOne):
"""Create new public key"""
@@ -78,20 +82,37 @@ class CreateKeypair(command.ShowOne):
class DeleteKeypair(command.Command):
- """Delete public key"""
+ """Delete public key(s)"""
def get_parser(self, prog_name):
parser = super(DeleteKeypair, self).get_parser(prog_name)
parser.add_argument(
'name',
metavar='<key>',
- help=_("Public key to delete (name only)")
+ nargs='+',
+ help=_("Public key(s) to delete (name only)")
)
return parser
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
- compute_client.keypairs.delete(parsed_args.name)
+ result = 0
+ for n in parsed_args.name:
+ try:
+ data = utils.find_resource(
+ compute_client.keypairs, n)
+ compute_client.keypairs.delete(data.name)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete public key with name "
+ "'%(name)s': %(e)s")
+ % {'name': n, 'e': e})
+
+ if result > 0:
+ total = len(parsed_args.name)
+ msg = (_("%(result)s of %(total)s public keys failed "
+ "to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListKeypair(command.Lister):
diff --git a/openstackclient/compute/v2/service.py b/openstackclient/compute/v2/service.py
index 2e40dd7f..53624f55 100644
--- a/openstackclient/compute/v2/service.py
+++ b/openstackclient/compute/v2/service.py
@@ -29,25 +29,39 @@ LOG = logging.getLogger(__name__)
class DeleteService(command.Command):
- """Delete service command"""
+ """Delete compute service(s)"""
def get_parser(self, prog_name):
parser = super(DeleteService, self).get_parser(prog_name)
parser.add_argument(
"service",
metavar="<service>",
- help=_("Compute service to delete (ID only)")
+ nargs='+',
+ help=_("Compute service(s) to delete (ID only)")
)
return parser
def take_action(self, parsed_args):
compute_client = self.app.client_manager.compute
+ result = 0
+ for s in parsed_args.service:
+ try:
+ compute_client.services.delete(s)
+ except Exception as e:
+ result += 1
+ LOG.error(_("Failed to delete compute service with "
+ "ID '%(service)s': %(e)s")
+ % {'service': s, 'e': e})
- compute_client.services.delete(parsed_args.service)
+ if result > 0:
+ total = len(parsed_args.service)
+ msg = (_("%(result)s of %(total)s compute services failed "
+ "to delete.") % {'result': result, 'total': total})
+ raise exceptions.CommandError(msg)
class ListService(command.Lister):
- """List service command"""
+ """List compute services"""
def get_parser(self, prog_name):
parser = super(ListService, self).get_parser(prog_name)
@@ -101,7 +115,7 @@ class ListService(command.Lister):
class SetService(command.Command):
- """Set service command"""
+ """Set compute service properties"""
def get_parser(self, prog_name):
parser = super(SetService, self).get_parser(prog_name)
diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py
index 41735500..31dfc798 100644
--- a/openstackclient/network/v2/network.py
+++ b/openstackclient/network/v2/network.py
@@ -108,7 +108,7 @@ def _add_additional_network_options(parser):
'vlan', 'vxlan'],
help=_("The physical mechanism by which the virtual network "
"is implemented. The supported options are: "
- "flat, geneve, gre, local, vlan, vxlan"))
+ "flat, geneve, gre, local, vlan, vxlan."))
parser.add_argument(
'--provider-physical-network',
metavar='<provider-physical-network>',
diff --git a/openstackclient/network/v2/subnet.py b/openstackclient/network/v2/subnet.py
index 752923f7..b076d82e 100644
--- a/openstackclient/network/v2/subnet.py
+++ b/openstackclient/network/v2/subnet.py
@@ -235,7 +235,7 @@ class CreateSubnet(command.ShowOne):
"'auto': Gateway address should automatically be chosen "
"from within the subnet itself, 'none': This subnet will "
"not use a gateway, e.g.: --gateway 192.168.9.1, "
- "--gateway auto, --gateway none (default is 'auto')")
+ "--gateway auto, --gateway none (default is 'auto').")
)
parser.add_argument(
'--ip-version',
@@ -244,7 +244,7 @@ class CreateSubnet(command.ShowOne):
choices=[4, 6],
help=_("IP version (default is 4). Note that when subnet pool is "
"specified, IP version is determined from the subnet pool "
- "and this option is ignored")
+ "and this option is ignored.")
)
parser.add_argument(
'--ipv6-ra-mode',
@@ -334,7 +334,7 @@ class ListSubnet(command.Lister):
choices=[4, 6],
metavar='<ip-version>',
dest='ip_version',
- help=_("List only subnets of given IP version in output"
+ help=_("List only subnets of given IP version in output."
"Allowed values for IP version are 4 and 6."),
)
return parser
@@ -395,7 +395,7 @@ class SetSubnet(command.Command):
help=_("Specify a gateway for the subnet. The options are: "
"<ip-address>: Specific IP address to use as the gateway, "
"'none': This subnet will not use a gateway, "
- "e.g.: --gateway 192.168.9.1, --gateway none")
+ "e.g.: --gateway 192.168.9.1, --gateway none.")
)
_get_common_parse_arguments(parser)
return parser
diff --git a/openstackclient/tests/compute/v2/fakes.py b/openstackclient/tests/compute/v2/fakes.py
index b7f17fbc..882d8480 100644
--- a/openstackclient/tests/compute/v2/fakes.py
+++ b/openstackclient/tests/compute/v2/fakes.py
@@ -826,6 +826,25 @@ class FakeKeypair(object):
return keypairs
+ @staticmethod
+ def get_keypairs(keypairs=None, count=2):
+ """Get an iterable MagicMock object with a list of faked keypairs.
+
+ If keypairs list is provided, then initialize the Mock object with the
+ list. Otherwise create one.
+
+ :param List keypairs:
+ A list of FakeResource objects faking keypairs
+ :param int count:
+ The number of keypairs to fake
+ :return:
+ An iterable Mock object with side_effect set to a list of faked
+ keypairs
+ """
+ if keypairs is None:
+ keypairs = FakeKeypair.create_keypairs(count)
+ return mock.MagicMock(side_effect=keypairs)
+
class FakeAvailabilityZone(object):
"""Fake one or more compute availability zones (AZs)."""
diff --git a/openstackclient/tests/compute/v2/test_keypair.py b/openstackclient/tests/compute/v2/test_keypair.py
index a50a5323..25949e31 100644
--- a/openstackclient/tests/compute/v2/test_keypair.py
+++ b/openstackclient/tests/compute/v2/test_keypair.py
@@ -14,6 +14,10 @@
#
import mock
+from mock import call
+
+from osc_lib import exceptions
+from osc_lib import utils
from openstackclient.compute.v2 import keypair
from openstackclient.tests.compute.v2 import fakes as compute_fakes
@@ -114,22 +118,23 @@ class TestKeypairCreate(TestKeypair):
class TestKeypairDelete(TestKeypair):
- keypair = compute_fakes.FakeKeypair.create_one_keypair()
+ keypairs = compute_fakes.FakeKeypair.create_keypairs(count=2)
def setUp(self):
super(TestKeypairDelete, self).setUp()
- self.keypairs_mock.get.return_value = self.keypair
+ self.keypairs_mock.get = compute_fakes.FakeKeypair.get_keypairs(
+ self.keypairs)
self.keypairs_mock.delete.return_value = None
self.cmd = keypair.DeleteKeypair(self.app, None)
def test_keypair_delete(self):
arglist = [
- self.keypair.name
+ self.keypairs[0].name
]
verifylist = [
- ('name', self.keypair.name),
+ ('name', [self.keypairs[0].name]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -137,7 +142,54 @@ class TestKeypairDelete(TestKeypair):
ret = self.cmd.take_action(parsed_args)
self.assertIsNone(ret)
- self.keypairs_mock.delete.assert_called_with(self.keypair.name)
+ self.keypairs_mock.delete.assert_called_with(self.keypairs[0].name)
+
+ def test_delete_multiple_keypairs(self):
+ arglist = []
+ for k in self.keypairs:
+ arglist.append(k.name)
+ verifylist = [
+ ('name', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ calls = []
+ for k in self.keypairs:
+ calls.append(call(k.name))
+ self.keypairs_mock.delete.assert_has_calls(calls)
+ self.assertIsNone(result)
+
+ def test_delete_multiple_keypairs_with_exception(self):
+ arglist = [
+ self.keypairs[0].name,
+ 'unexist_keypair',
+ ]
+ verifylist = [
+ ('name', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ find_mock_result = [self.keypairs[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 public keys failed to delete.',
+ str(e))
+
+ find_mock.assert_any_call(
+ self.keypairs_mock, self.keypairs[0].name)
+ find_mock.assert_any_call(self.keypairs_mock, 'unexist_keypair')
+
+ self.assertEqual(2, find_mock.call_count)
+ self.keypairs_mock.delete.assert_called_once_with(
+ self.keypairs[0].name
+ )
class TestKeypairList(TestKeypair):
diff --git a/openstackclient/tests/compute/v2/test_service.py b/openstackclient/tests/compute/v2/test_service.py
index e41d633a..1599f466 100644
--- a/openstackclient/tests/compute/v2/test_service.py
+++ b/openstackclient/tests/compute/v2/test_service.py
@@ -14,6 +14,7 @@
#
import mock
+from mock import call
from osc_lib import exceptions
@@ -33,32 +34,74 @@ class TestService(compute_fakes.TestComputev2):
class TestServiceDelete(TestService):
+ services = compute_fakes.FakeService.create_services(count=2)
+
def setUp(self):
super(TestServiceDelete, self).setUp()
- self.service = compute_fakes.FakeService.create_one_service()
-
self.service_mock.delete.return_value = None
# Get the command object to test
self.cmd = service.DeleteService(self.app, None)
- def test_service_delete_no_options(self):
+ def test_service_delete(self):
arglist = [
- self.service.binary,
+ self.services[0].binary,
]
verifylist = [
- ('service', self.service.binary),
+ ('service', [self.services[0].binary]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.service_mock.delete.assert_called_with(
- self.service.binary,
+ self.services[0].binary,
)
self.assertIsNone(result)
+ def test_multi_services_delete(self):
+ arglist = []
+ for s in self.services:
+ arglist.append(s.binary)
+ verifylist = [
+ ('service', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ calls = []
+ for s in self.services:
+ calls.append(call(s.binary))
+ self.service_mock.delete.assert_has_calls(calls)
+ self.assertIsNone(result)
+
+ def test_multi_services_delete_with_exception(self):
+ arglist = [
+ self.services[0].binary,
+ 'unexist_service',
+ ]
+ verifylist = [
+ ('service', arglist)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ delete_mock_result = [None, exceptions.CommandError]
+ self.service_mock.delete = (
+ mock.MagicMock(side_effect=delete_mock_result)
+ )
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual(
+ '1 of 2 compute services failed to delete.', str(e))
+
+ self.service_mock.delete.assert_any_call(self.services[0].binary)
+ self.service_mock.delete.assert_any_call('unexist_service')
+
class TestServiceList(TestService):
diff --git a/openstackclient/tests/identity/v2_0/fakes.py b/openstackclient/tests/identity/v2_0/fakes.py
index 10b8b49e..662d56b6 100644
--- a/openstackclient/tests/identity/v2_0/fakes.py
+++ b/openstackclient/tests/identity/v2_0/fakes.py
@@ -76,19 +76,19 @@ USER = {
}
token_expires = '2014-01-01T00:00:00Z'
-token_id = 'tttttttt-tttt-tttt-tttt-tttttttttttt'
+token_id = 'token-id-' + uuid.uuid4().hex
TOKEN = {
'expires': token_expires,
'id': token_id,
- 'tenant_id': project_id,
- 'user_id': user_id,
+ 'tenant_id': 'project-id',
+ 'user_id': 'user-id',
}
UNSCOPED_TOKEN = {
'expires': token_expires,
'id': token_id,
- 'user_id': user_id,
+ 'user_id': 'user-id',
}
endpoint_name = service_name
@@ -110,8 +110,6 @@ ENDPOINT = {
'publicurl': endpoint_publicurl,
'service_id': endpoint_service_id,
}
-SERVICE_NAME = 'service-name-' + uuid.uuid4().hex
-SERVICE_ID = 'service-id-' + uuid.uuid4().hex
def fake_auth_ref(fake_token, fake_service=None):
@@ -244,7 +242,7 @@ class FakeCatalog(object):
# Set default attributes.
catalog_info = {
- 'id': SERVICE_ID,
+ 'id': 'service-id-' + uuid.uuid4().hex,
'type': 'compute',
'name': 'supernova',
'endpoints': [
@@ -295,8 +293,8 @@ class FakeProject(object):
# set default attributes.
project_info = {
- 'id': 'project-id' + uuid.uuid4().hex,
- 'name': 'project-name' + uuid.uuid4().hex,
+ 'id': 'project-id-' + uuid.uuid4().hex,
+ 'name': 'project-name-' + uuid.uuid4().hex,
'description': 'project_description',
'enabled': True,
}
@@ -341,14 +339,14 @@ class FakeEndpoint(object):
# set default attributes.
endpoint_info = {
- 'service_name': SERVICE_NAME,
+ 'service_name': 'service-name-' + uuid.uuid4().hex,
'adminurl': 'http://endpoint_adminurl',
'region': 'endpoint_region',
'internalurl': 'http://endpoint_internalurl',
'service_type': 'service_type',
'id': 'endpoint-id-' + uuid.uuid4().hex,
'publicurl': 'http://endpoint_publicurl',
- 'service_id': SERVICE_ID,
+ 'service_id': 'service-name-' + uuid.uuid4().hex,
}
endpoint_info.update(attrs)
@@ -392,8 +390,8 @@ class FakeService(object):
# set default attributes.
service_info = {
- 'id': SERVICE_ID,
- 'name': SERVICE_NAME,
+ 'id': 'service-id-' + uuid.uuid4().hex,
+ 'name': 'service-name-' + uuid.uuid4().hex,
'description': 'service_description',
'type': 'service_type',
@@ -464,3 +462,49 @@ class FakeRole(object):
roles.append(FakeRole.create_one_role(attrs))
return roles
+
+
+class FakeUser(object):
+ """Fake one or more user."""
+
+ @staticmethod
+ def create_one_user(attrs=None):
+ """Create a fake user.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :return:
+ A FakeResource object, with id, name, and so on
+ """
+ attrs = attrs or {}
+
+ # set default attributes.
+ user_info = {
+ 'id': 'user-id-' + uuid.uuid4().hex,
+ 'name': 'user-name-' + uuid.uuid4().hex,
+ 'tenantId': 'project-id-' + uuid.uuid4().hex,
+ 'email': 'admin@openstack.org',
+ 'enabled': True,
+ }
+ user_info.update(attrs)
+
+ user = fakes.FakeResource(info=copy.deepcopy(user_info),
+ loaded=True)
+ return user
+
+ @staticmethod
+ def create_users(attrs=None, count=2):
+ """Create multiple fake users.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param int count:
+ The number of users to fake
+ :return:
+ A list of FakeResource objects faking the users
+ """
+ users = []
+ for i in range(0, count):
+ users.append(FakeUser.create_one_user(attrs))
+
+ return users
diff --git a/openstackclient/tests/identity/v2_0/test_endpoint.py b/openstackclient/tests/identity/v2_0/test_endpoint.py
index 0b539702..b2b6d0f1 100644
--- a/openstackclient/tests/identity/v2_0/test_endpoint.py
+++ b/openstackclient/tests/identity/v2_0/test_endpoint.py
@@ -17,8 +17,12 @@ from openstackclient.tests.identity.v2_0 import fakes as identity_fakes
class TestEndpoint(identity_fakes.TestIdentityv2):
- fake_endpoint = identity_fakes.FakeEndpoint.create_one_endpoint()
fake_service = identity_fakes.FakeService.create_one_service()
+ attr = {
+ 'service_name': fake_service.name,
+ 'service_id': fake_service.id,
+ }
+ fake_endpoint = identity_fakes.FakeEndpoint.create_one_endpoint(attr)
def setUp(self):
super(TestEndpoint, self).setUp()
diff --git a/openstackclient/tests/identity/v2_0/test_role.py b/openstackclient/tests/identity/v2_0/test_role.py
index 74bd8f27..3d379356 100644
--- a/openstackclient/tests/identity/v2_0/test_role.py
+++ b/openstackclient/tests/identity/v2_0/test_role.py
@@ -13,14 +13,12 @@
# under the License.
#
-import copy
import mock
from keystoneauth1 import exceptions as ks_exc
from osc_lib import exceptions
from openstackclient.identity.v2_0 import role
-from openstackclient.tests import fakes
from openstackclient.tests.identity.v2_0 import fakes as identity_fakes
@@ -34,6 +32,12 @@ class TestRole(identity_fakes.TestIdentityv2):
]
fake_service = identity_fakes.FakeService.create_one_service(attr)
fake_role = identity_fakes.FakeRole.create_one_role()
+ fake_project = identity_fakes.FakeProject.create_one_project()
+ attr = {}
+ attr = {
+ 'tenantId': fake_project.id,
+ }
+ fake_user = identity_fakes.FakeUser.create_one_user(attr)
def setUp(self):
super(TestRole, self).setUp()
@@ -63,42 +67,26 @@ class TestRoleAdd(TestRole):
def setUp(self):
super(TestRoleAdd, self).setUp()
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.fake_project
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.users_mock.get.return_value = self.fake_user
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- )
- self.roles_mock.add_user_role.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- )
+ self.roles_mock.get.return_value = self.fake_role
+ self.roles_mock.add_user_role.return_value = self.fake_role
# Get the command object to test
self.cmd = role.AddRole(self.app, None)
def test_role_add(self):
arglist = [
- '--project', identity_fakes.project_name,
- '--user', identity_fakes.user_name,
- identity_fakes.role_name,
+ '--project', self.fake_project.name,
+ '--user', self.fake_user.name,
+ self.fake_role.name,
]
verifylist = [
- ('project', identity_fakes.project_name),
- ('user', identity_fakes.user_name),
- ('role', identity_fakes.role_name),
+ ('project', self.fake_project.name),
+ ('user', self.fake_user.name),
+ ('role', self.fake_role.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -109,49 +97,46 @@ class TestRoleAdd(TestRole):
# RoleManager.add_user_role(user, role, tenant=None)
self.roles_mock.add_user_role.assert_called_with(
- identity_fakes.user_id,
- identity_fakes.role_id,
- identity_fakes.project_id,
+ self.fake_user.id,
+ self.fake_role.id,
+ self.fake_project.id,
)
collist = ('id', 'name')
self.assertEqual(collist, columns)
datalist = (
- identity_fakes.role_id,
- identity_fakes.role_name,
+ self.fake_role.id,
+ self.fake_role.name,
)
self.assertEqual(datalist, data)
class TestRoleCreate(TestRole):
+ fake_role_c = identity_fakes.FakeRole.create_one_role()
columns = (
'id',
'name'
)
datalist = (
- identity_fakes.role_id,
- identity_fakes.role_name,
+ fake_role_c.id,
+ fake_role_c.name,
)
def setUp(self):
super(TestRoleCreate, self).setUp()
- self.roles_mock.create.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- )
+ self.roles_mock.create.return_value = self.fake_role_c
# Get the command object to test
self.cmd = role.CreateRole(self.app, None)
def test_role_create_no_options(self):
arglist = [
- identity_fakes.role_name,
+ self.fake_role_c.name,
]
verifylist = [
- ('role_name', identity_fakes.role_name),
+ ('role_name', self.fake_role_c.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -162,7 +147,7 @@ class TestRoleCreate(TestRole):
# RoleManager.create(name)
self.roles_mock.create.assert_called_with(
- identity_fakes.role_name,
+ self.fake_role_c.name,
)
self.assertEqual(self.columns, columns)
@@ -175,18 +160,14 @@ class TestRoleCreate(TestRole):
# need to make this throw an exception...
self.roles_mock.create.side_effect = _raise_conflict
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- )
+ self.roles_mock.get.return_value = self.fake_role_c
arglist = [
'--or-show',
- identity_fakes.role_name,
+ self.fake_role_c.name,
]
verifylist = [
- ('role_name', identity_fakes.role_name),
+ ('role_name', self.fake_role_c.name),
('or_show', True),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -197,11 +178,11 @@ class TestRoleCreate(TestRole):
columns, data = self.cmd.take_action(parsed_args)
# RoleManager.get(name, description, enabled)
- self.roles_mock.get.assert_called_with(identity_fakes.role_name)
+ self.roles_mock.get.assert_called_with(self.fake_role_c.name)
# RoleManager.create(name)
self.roles_mock.create.assert_called_with(
- identity_fakes.role_name,
+ self.fake_role_c.name,
)
self.assertEqual(self.columns, columns)
@@ -210,10 +191,10 @@ class TestRoleCreate(TestRole):
def test_role_create_or_show_not_exists(self):
arglist = [
'--or-show',
- identity_fakes.role_name,
+ self.fake_role_c.name,
]
verifylist = [
- ('role_name', identity_fakes.role_name),
+ ('role_name', self.fake_role_c.name),
('or_show', True),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -225,7 +206,7 @@ class TestRoleCreate(TestRole):
# RoleManager.create(name)
self.roles_mock.create.assert_called_with(
- identity_fakes.role_name,
+ self.fake_role_c.name,
)
self.assertEqual(self.columns, columns)
@@ -237,11 +218,7 @@ class TestRoleDelete(TestRole):
def setUp(self):
super(TestRoleDelete, self).setUp()
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- )
+ self.roles_mock.get.return_value = self.fake_role
self.roles_mock.delete.return_value = None
# Get the command object to test
@@ -249,17 +226,17 @@ class TestRoleDelete(TestRole):
def test_role_delete_no_options(self):
arglist = [
- identity_fakes.role_name,
+ self.fake_role.name,
]
verifylist = [
- ('roles', [identity_fakes.role_name]),
+ ('roles', [self.fake_role.name]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.roles_mock.delete.assert_called_with(
- identity_fakes.role_id,
+ self.fake_role.id,
)
self.assertIsNone(result)
@@ -269,13 +246,7 @@ class TestRoleList(TestRole):
def setUp(self):
super(TestRoleList, self).setUp()
- self.roles_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- ),
- ]
+ self.roles_mock.list.return_value = [self.fake_role]
# Get the command object to test
self.cmd = role.ListRole(self.app, None)
@@ -295,8 +266,8 @@ class TestRoleList(TestRole):
collist = ('ID', 'Name')
self.assertEqual(collist, columns)
datalist = ((
- identity_fakes.role_id,
- identity_fakes.role_name,
+ self.fake_role.id,
+ self.fake_role.name,
), )
self.assertEqual(datalist, tuple(data))
@@ -313,25 +284,11 @@ class TestUserRoleList(TestRole):
def setUp(self):
super(TestUserRoleList, self).setUp()
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.fake_project
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.users_mock.get.return_value = self.fake_user
- self.roles_mock.roles_for_user.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- ),
- ]
+ self.roles_mock.roles_for_user.return_value = [self.fake_role]
# Get the command object to test
self.cmd = role.ListUserRole(self.app, None)
@@ -366,17 +323,17 @@ class TestUserRoleList(TestRole):
columns, data = self.cmd.take_action(parsed_args)
self.roles_mock.roles_for_user.assert_called_with(
- identity_fakes.user_id,
- identity_fakes.project_id,
+ self.fake_user.id,
+ self.fake_project.id,
)
collist = ('ID', 'Name', 'Project', 'User')
self.assertEqual(collist, columns)
datalist = ((
- identity_fakes.role_id,
- identity_fakes.role_name,
- identity_fakes.project_name,
- identity_fakes.user_name,
+ self.fake_role.id,
+ self.fake_role.name,
+ self.fake_project.name,
+ self.fake_user.name,
), )
self.assertEqual(datalist, tuple(data))
@@ -388,16 +345,12 @@ class TestUserRoleList(TestRole):
self.ar_mock = mock.PropertyMock(return_value=auth_ref)
type(self.app.client_manager).auth_ref = self.ar_mock
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT_2),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.fake_project
arglist = [
- '--project', identity_fakes.PROJECT_2['name'],
+ '--project', self.fake_project.name,
]
verifylist = [
- ('project', identity_fakes.PROJECT_2['name']),
+ ('project', self.fake_project.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -407,30 +360,26 @@ class TestUserRoleList(TestRole):
columns, data = self.cmd.take_action(parsed_args)
self.roles_mock.roles_for_user.assert_called_with(
- identity_fakes.user_id,
- identity_fakes.PROJECT_2['id'],
+ self.fake_user.id,
+ self.fake_project.id,
)
self.assertEqual(columns, columns)
datalist = ((
- identity_fakes.role_id,
- identity_fakes.role_name,
- identity_fakes.PROJECT_2['name'],
- identity_fakes.user_name,
+ self.fake_role.id,
+ self.fake_role.name,
+ self.fake_project.name,
+ self.fake_user.name,
), )
self.assertEqual(datalist, tuple(data))
def test_user_role_list_project_scoped_token(self):
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT_2),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.fake_project
arglist = [
- '--project', identity_fakes.PROJECT_2['name'],
+ '--project', self.fake_project.name,
]
verifylist = [
- ('project', identity_fakes.PROJECT_2['name']),
+ ('project', self.fake_project.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -440,16 +389,16 @@ class TestUserRoleList(TestRole):
columns, data = self.cmd.take_action(parsed_args)
self.roles_mock.roles_for_user.assert_called_with(
- identity_fakes.user_id,
- identity_fakes.PROJECT_2['id'],
+ self.fake_user.id,
+ self.fake_project.id,
)
self.assertEqual(columns, columns)
datalist = ((
- identity_fakes.role_id,
- identity_fakes.role_name,
- identity_fakes.PROJECT_2['name'],
- identity_fakes.user_name,
+ self.fake_role.id,
+ self.fake_role.name,
+ self.fake_project.name,
+ self.fake_user.name,
), )
self.assertEqual(datalist, tuple(data))
@@ -459,23 +408,11 @@ class TestRoleRemove(TestRole):
def setUp(self):
super(TestRoleRemove, self).setUp()
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.fake_project
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.users_mock.get.return_value = self.fake_user
- self.roles_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.ROLE),
- loaded=True,
- )
+ self.roles_mock.get.return_value = self.fake_role
self.roles_mock.remove_user_role.return_value = None
# Get the command object to test
@@ -483,14 +420,14 @@ class TestRoleRemove(TestRole):
def test_role_remove(self):
arglist = [
- '--project', identity_fakes.project_name,
- '--user', identity_fakes.user_name,
- identity_fakes.role_name,
+ '--project', self.fake_project.name,
+ '--user', self.fake_user.name,
+ self.fake_role.name,
]
verifylist = [
- ('role', identity_fakes.role_name),
- ('project', identity_fakes.project_name),
- ('user', identity_fakes.user_name),
+ ('role', self.fake_role.name),
+ ('project', self.fake_project.name),
+ ('user', self.fake_user.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -498,9 +435,9 @@ class TestRoleRemove(TestRole):
# RoleManager.remove_user_role(user, role, tenant=None)
self.roles_mock.remove_user_role.assert_called_with(
- identity_fakes.user_id,
- identity_fakes.role_id,
- identity_fakes.project_id,
+ self.fake_user.id,
+ self.fake_role.id,
+ self.fake_project.id,
)
self.assertIsNone(result)
diff --git a/openstackclient/tests/identity/v2_0/test_service.py b/openstackclient/tests/identity/v2_0/test_service.py
index ba976f4c..318fa83d 100644
--- a/openstackclient/tests/identity/v2_0/test_service.py
+++ b/openstackclient/tests/identity/v2_0/test_service.py
@@ -13,14 +13,12 @@
# under the License.
#
-import copy
-
from openstackclient.identity.v2_0 import service
-from openstackclient.tests import fakes
from openstackclient.tests.identity.v2_0 import fakes as identity_fakes
class TestService(identity_fakes.TestIdentityv2):
+ fake_service = identity_fakes.FakeService.create_one_service()
def setUp(self):
super(TestService, self).setUp()
@@ -32,6 +30,7 @@ class TestService(identity_fakes.TestIdentityv2):
class TestServiceCreate(TestService):
+ fake_service_c = identity_fakes.FakeService.create_one_service()
columns = (
'description',
'id',
@@ -39,30 +38,26 @@ class TestServiceCreate(TestService):
'type',
)
datalist = (
- identity_fakes.service_description,
- identity_fakes.service_id,
- identity_fakes.service_name,
- identity_fakes.service_type,
+ fake_service_c.description,
+ fake_service_c.id,
+ fake_service_c.name,
+ fake_service_c.type,
)
def setUp(self):
super(TestServiceCreate, self).setUp()
- self.services_mock.create.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.SERVICE),
- loaded=True,
- )
+ self.services_mock.create.return_value = self.fake_service_c
# Get the command object to test
self.cmd = service.CreateService(self.app, None)
def test_service_create_with_type_positional(self):
arglist = [
- identity_fakes.service_type,
+ self.fake_service_c.type,
]
verifylist = [
- ('type_or_name', identity_fakes.service_type),
+ ('type_or_name', self.fake_service_c.type),
('type', None),
('description', None),
('name', None),
@@ -77,7 +72,7 @@ class TestServiceCreate(TestService):
# ServiceManager.create(name, service_type, description)
self.services_mock.create.assert_called_with(
None,
- identity_fakes.service_type,
+ self.fake_service_c.type,
None,
)
@@ -86,12 +81,12 @@ class TestServiceCreate(TestService):
def test_service_create_with_type_option(self):
arglist = [
- '--type', identity_fakes.service_type,
- identity_fakes.service_name,
+ '--type', self.fake_service_c.type,
+ self.fake_service_c.name,
]
verifylist = [
- ('type_or_name', identity_fakes.service_name),
- ('type', identity_fakes.service_type),
+ ('type_or_name', self.fake_service_c.name),
+ ('type', self.fake_service_c.type),
('description', None),
('name', None),
]
@@ -104,8 +99,8 @@ class TestServiceCreate(TestService):
# ServiceManager.create(name, service_type, description)
self.services_mock.create.assert_called_with(
- identity_fakes.service_name,
- identity_fakes.service_type,
+ self.fake_service_c.name,
+ self.fake_service_c.type,
None,
)
@@ -114,14 +109,14 @@ class TestServiceCreate(TestService):
def test_service_create_with_name_option(self):
arglist = [
- '--name', identity_fakes.service_name,
- identity_fakes.service_type,
+ '--name', self.fake_service_c.name,
+ self.fake_service_c.type,
]
verifylist = [
- ('type_or_name', identity_fakes.service_type),
+ ('type_or_name', self.fake_service_c.type),
('type', None),
('description', None),
- ('name', identity_fakes.service_name),
+ ('name', self.fake_service_c.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -132,8 +127,8 @@ class TestServiceCreate(TestService):
# ServiceManager.create(name, service_type, description)
self.services_mock.create.assert_called_with(
- identity_fakes.service_name,
- identity_fakes.service_type,
+ self.fake_service_c.name,
+ self.fake_service_c.type,
None,
)
@@ -142,15 +137,15 @@ class TestServiceCreate(TestService):
def test_service_create_description(self):
arglist = [
- '--name', identity_fakes.service_name,
- '--description', identity_fakes.service_description,
- identity_fakes.service_type,
+ '--name', self.fake_service_c.name,
+ '--description', self.fake_service_c.description,
+ self.fake_service_c.type,
]
verifylist = [
- ('type_or_name', identity_fakes.service_type),
+ ('type_or_name', self.fake_service_c.type),
('type', None),
- ('description', identity_fakes.service_description),
- ('name', identity_fakes.service_name),
+ ('description', self.fake_service_c.description),
+ ('name', self.fake_service_c.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -161,9 +156,9 @@ class TestServiceCreate(TestService):
# ServiceManager.create(name, service_type, description)
self.services_mock.create.assert_called_with(
- identity_fakes.service_name,
- identity_fakes.service_type,
- identity_fakes.service_description,
+ self.fake_service_c.name,
+ self.fake_service_c.type,
+ self.fake_service_c.description,
)
self.assertEqual(self.columns, columns)
@@ -175,11 +170,7 @@ class TestServiceDelete(TestService):
def setUp(self):
super(TestServiceDelete, self).setUp()
- self.services_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.SERVICE),
- loaded=True,
- )
+ self.services_mock.get.return_value = self.fake_service
self.services_mock.delete.return_value = None
# Get the command object to test
@@ -187,17 +178,17 @@ class TestServiceDelete(TestService):
def test_service_delete_no_options(self):
arglist = [
- identity_fakes.service_name,
+ self.fake_service.name,
]
verifylist = [
- ('services', [identity_fakes.service_name]),
+ ('services', [self.fake_service.name]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.services_mock.delete.assert_called_with(
- identity_fakes.service_id,
+ self.fake_service.id,
)
self.assertIsNone(result)
@@ -207,13 +198,7 @@ class TestServiceList(TestService):
def setUp(self):
super(TestServiceList, self).setUp()
- self.services_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.SERVICE),
- loaded=True,
- ),
- ]
+ self.services_mock.list.return_value = [self.fake_service]
# Get the command object to test
self.cmd = service.ListService(self.app, None)
@@ -233,9 +218,9 @@ class TestServiceList(TestService):
collist = ('ID', 'Name', 'Type')
self.assertEqual(collist, columns)
datalist = ((
- identity_fakes.service_id,
- identity_fakes.service_name,
- identity_fakes.service_type,
+ self.fake_service.id,
+ self.fake_service.name,
+ self.fake_service.type,
), )
self.assertEqual(datalist, tuple(data))
@@ -258,10 +243,10 @@ class TestServiceList(TestService):
collist = ('ID', 'Name', 'Type', 'Description')
self.assertEqual(collist, columns)
datalist = ((
- identity_fakes.service_id,
- identity_fakes.service_name,
- identity_fakes.service_type,
- identity_fakes.service_description,
+ self.fake_service.id,
+ self.fake_service.name,
+ self.fake_service.type,
+ self.fake_service.description,
), )
self.assertEqual(datalist, tuple(data))
@@ -271,21 +256,17 @@ class TestServiceShow(TestService):
def setUp(self):
super(TestServiceShow, self).setUp()
- self.services_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.SERVICE),
- loaded=True,
- )
+ self.services_mock.get.return_value = self.fake_service
# Get the command object to test
self.cmd = service.ShowService(self.app, None)
def test_service_show(self):
arglist = [
- identity_fakes.service_name,
+ self.fake_service.name,
]
verifylist = [
- ('service', identity_fakes.service_name),
+ ('service', self.fake_service.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -296,15 +277,15 @@ class TestServiceShow(TestService):
# ServiceManager.get(id)
self.services_mock.get.assert_called_with(
- identity_fakes.service_name,
+ self.fake_service.name,
)
collist = ('description', 'id', 'name', 'type')
self.assertEqual(collist, columns)
datalist = (
- identity_fakes.service_description,
- identity_fakes.service_id,
- identity_fakes.service_name,
- identity_fakes.service_type,
+ self.fake_service.description,
+ self.fake_service.id,
+ self.fake_service.name,
+ self.fake_service.type,
)
self.assertEqual(datalist, data)
diff --git a/openstackclient/tests/identity/v2_0/test_token.py b/openstackclient/tests/identity/v2_0/test_token.py
index 96f08e87..bb776707 100644
--- a/openstackclient/tests/identity/v2_0/test_token.py
+++ b/openstackclient/tests/identity/v2_0/test_token.py
@@ -21,6 +21,9 @@ from openstackclient.tests.identity.v2_0 import fakes as identity_fakes
class TestToken(identity_fakes.TestIdentityv2):
+ fake_user = identity_fakes.FakeUser.create_one_user()
+ fake_project = identity_fakes.FakeProject.create_one_project()
+
def setUp(self):
super(TestToken, self).setUp()
@@ -57,8 +60,8 @@ class TestTokenIssue(TestToken):
datalist = (
auth_ref.expires,
identity_fakes.token_id,
- identity_fakes.project_id,
- identity_fakes.user_id,
+ 'project-id',
+ 'user-id',
)
self.assertEqual(datalist, data)
@@ -85,7 +88,7 @@ class TestTokenIssue(TestToken):
datalist = (
auth_ref.expires,
identity_fakes.token_id,
- identity_fakes.user_id,
+ 'user-id',
)
self.assertEqual(datalist, data)
diff --git a/openstackclient/tests/identity/v2_0/test_user.py b/openstackclient/tests/identity/v2_0/test_user.py
index f7a7b08c..ba871247 100644
--- a/openstackclient/tests/identity/v2_0/test_user.py
+++ b/openstackclient/tests/identity/v2_0/test_user.py
@@ -13,19 +13,23 @@
# under the License.
#
-import copy
import mock
from keystoneauth1 import exceptions as ks_exc
from osc_lib import exceptions
from openstackclient.identity.v2_0 import user
-from openstackclient.tests import fakes
from openstackclient.tests.identity.v2_0 import fakes as identity_fakes
class TestUser(identity_fakes.TestIdentityv2):
+ fake_project = identity_fakes.FakeProject.create_one_project()
+ attr = {
+ 'tenantId': fake_project.id,
+ }
+ fake_user = identity_fakes.FakeUser.create_one_user(attr)
+
def setUp(self):
super(TestUser, self).setUp()
@@ -40,6 +44,12 @@ class TestUser(identity_fakes.TestIdentityv2):
class TestUserCreate(TestUser):
+ fake_project_c = identity_fakes.FakeProject.create_one_project()
+ attr = {
+ 'tenantId': fake_project_c.id,
+ }
+ fake_user_c = identity_fakes.FakeUser.create_one_user(attr)
+
columns = (
'email',
'enabled',
@@ -48,39 +58,31 @@ class TestUserCreate(TestUser):
'project_id',
)
datalist = (
- identity_fakes.user_email,
+ fake_user_c.email,
True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.project_id,
+ fake_user_c.id,
+ fake_user_c.name,
+ fake_project_c.id,
)
def setUp(self):
super(TestUserCreate, self).setUp()
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.fake_project_c
- self.users_mock.create.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.users_mock.create.return_value = self.fake_user_c
# Get the command object to test
self.cmd = user.CreateUser(self.app, None)
def test_user_create_no_options(self):
arglist = [
- identity_fakes.user_name,
+ self.fake_user_c.name,
]
verifylist = [
('enable', False),
('disable', False),
- ('name', identity_fakes.user_name),
+ ('name', self.fake_user_c.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -96,7 +98,7 @@ class TestUserCreate(TestUser):
}
# UserManager.create(name, password, email, tenant_id=, enabled=)
self.users_mock.create.assert_called_with(
- identity_fakes.user_name,
+ self.fake_user_c.name,
None,
None,
**kwargs
@@ -108,10 +110,10 @@ class TestUserCreate(TestUser):
def test_user_create_password(self):
arglist = [
'--password', 'secret',
- identity_fakes.user_name,
+ self.fake_user_c.name,
]
verifylist = [
- ('name', identity_fakes.user_name),
+ ('name', self.fake_user_c.name),
('password_prompt', False),
('password', 'secret')
]
@@ -129,7 +131,7 @@ class TestUserCreate(TestUser):
}
# UserManager.create(name, password, email, tenant_id=, enabled=)
self.users_mock.create.assert_called_with(
- identity_fakes.user_name,
+ self.fake_user_c.name,
'secret',
None,
**kwargs
@@ -140,10 +142,10 @@ class TestUserCreate(TestUser):
def test_user_create_password_prompt(self):
arglist = [
'--password-prompt',
- identity_fakes.user_name,
+ self.fake_user_c.name,
]
verifylist = [
- ('name', identity_fakes.user_name),
+ ('name', self.fake_user_c.name),
('password_prompt', True)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -163,7 +165,7 @@ class TestUserCreate(TestUser):
}
# UserManager.create(name, password, email, tenant_id=, enabled=)
self.users_mock.create.assert_called_with(
- identity_fakes.user_name,
+ self.fake_user_c.name,
'abc123',
None,
**kwargs
@@ -175,10 +177,10 @@ class TestUserCreate(TestUser):
def test_user_create_email(self):
arglist = [
'--email', 'barney@example.com',
- identity_fakes.user_name,
+ self.fake_user_c.name,
]
verifylist = [
- ('name', identity_fakes.user_name),
+ ('name', self.fake_user_c.name),
('email', 'barney@example.com'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -195,7 +197,7 @@ class TestUserCreate(TestUser):
}
# UserManager.create(name, password, email, tenant_id=, enabled=)
self.users_mock.create.assert_called_with(
- identity_fakes.user_name,
+ self.fake_user_c.name,
None,
'barney@example.com',
**kwargs
@@ -206,27 +208,22 @@ class TestUserCreate(TestUser):
def test_user_create_project(self):
# Return the new project
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT_2),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.fake_project_c
+
# Set up to return an updated user
- USER_2 = copy.deepcopy(identity_fakes.USER)
- USER_2['tenantId'] = identity_fakes.PROJECT_2['id']
- self.users_mock.create.return_value = fakes.FakeResource(
- None,
- USER_2,
- loaded=True,
- )
+ attr = {
+ 'tenantId': self.fake_project_c.id,
+ }
+ user_2 = identity_fakes.FakeUser.create_one_user(attr)
+ self.users_mock.create.return_value = user_2
arglist = [
- '--project', identity_fakes.PROJECT_2['name'],
- identity_fakes.user_name,
+ '--project', self.fake_project_c.name,
+ user_2.name,
]
verifylist = [
- ('name', identity_fakes.user_name),
- ('project', identity_fakes.PROJECT_2['name']),
+ ('name', user_2.name),
+ ('project', self.fake_project_c.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -238,11 +235,11 @@ class TestUserCreate(TestUser):
# Set expected values
kwargs = {
'enabled': True,
- 'tenant_id': identity_fakes.PROJECT_2['id'],
+ 'tenant_id': self.fake_project_c.id,
}
# UserManager.create(name, password, email, tenant_id=, enabled=)
self.users_mock.create.assert_called_with(
- identity_fakes.user_name,
+ user_2.name,
None,
None,
**kwargs
@@ -250,21 +247,21 @@ class TestUserCreate(TestUser):
self.assertEqual(self.columns, columns)
datalist = (
- identity_fakes.user_email,
+ user_2.email,
True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.PROJECT_2['id'],
+ user_2.id,
+ user_2.name,
+ self.fake_project_c.id,
)
self.assertEqual(datalist, data)
def test_user_create_enable(self):
arglist = [
'--enable',
- identity_fakes.user_name,
+ self.fake_user_c.name,
]
verifylist = [
- ('name', identity_fakes.user_name),
+ ('name', self.fake_user_c.name),
('enable', True),
('disable', False),
]
@@ -282,7 +279,7 @@ class TestUserCreate(TestUser):
}
# UserManager.create(name, password, email, tenant_id=, enabled=)
self.users_mock.create.assert_called_with(
- identity_fakes.user_name,
+ self.fake_user_c.name,
None,
None,
**kwargs
@@ -294,10 +291,10 @@ class TestUserCreate(TestUser):
def test_user_create_disable(self):
arglist = [
'--disable',
- identity_fakes.user_name,
+ self.fake_user_c.name,
]
verifylist = [
- ('name', identity_fakes.user_name),
+ ('name', self.fake_user_c.name),
('enable', False),
('disable', True),
]
@@ -315,7 +312,7 @@ class TestUserCreate(TestUser):
}
# UserManager.create(name, password, email, tenant_id=, enabled=)
self.users_mock.create.assert_called_with(
- identity_fakes.user_name,
+ self.fake_user_c.name,
None,
None,
**kwargs
@@ -331,18 +328,14 @@ class TestUserCreate(TestUser):
# need to make this throw an exception...
self.users_mock.create.side_effect = _raise_conflict
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.users_mock.get.return_value = self.fake_user_c
arglist = [
'--or-show',
- identity_fakes.user_name,
+ self.fake_user_c.name,
]
verifylist = [
- ('name', identity_fakes.user_name),
+ ('name', self.fake_user_c.name),
('or_show', True),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -353,7 +346,7 @@ class TestUserCreate(TestUser):
columns, data = self.cmd.take_action(parsed_args)
# UserManager.create(name, password, email, tenant_id=, enabled=)
- self.users_mock.get.assert_called_with(identity_fakes.user_name)
+ self.users_mock.get.assert_called_with(self.fake_user_c.name)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
@@ -361,10 +354,10 @@ class TestUserCreate(TestUser):
def test_user_create_or_show_not_exists(self):
arglist = [
'--or-show',
- identity_fakes.user_name,
+ self.fake_user_c.name,
]
verifylist = [
- ('name', identity_fakes.user_name),
+ ('name', self.fake_user_c.name),
('or_show', True),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -381,7 +374,7 @@ class TestUserCreate(TestUser):
}
# UserManager.create(name, password, email, tenant_id=, enabled=)
self.users_mock.create.assert_called_with(
- identity_fakes.user_name,
+ self.fake_user_c.name,
None,
None,
**kwargs
@@ -396,11 +389,7 @@ class TestUserDelete(TestUser):
super(TestUserDelete, self).setUp()
# This is the return value for utils.find_resource()
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.users_mock.get.return_value = self.fake_user
self.users_mock.delete.return_value = None
# Get the command object to test
@@ -408,57 +397,47 @@ class TestUserDelete(TestUser):
def test_user_delete_no_options(self):
arglist = [
- identity_fakes.user_id,
+ self.fake_user.id,
]
verifylist = [
- ('users', [identity_fakes.user_id]),
+ ('users', [self.fake_user.id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.users_mock.delete.assert_called_with(
- identity_fakes.user_id,
+ self.fake_user.id,
)
self.assertIsNone(result)
class TestUserList(TestUser):
+ fake_project_l = identity_fakes.FakeProject.create_one_project()
+ attr = {
+ 'tenantId': fake_project_l.id,
+ }
+ fake_user_l = identity_fakes.FakeUser.create_one_user(attr)
+
columns = (
'ID',
'Name',
)
datalist = (
(
- identity_fakes.user_id,
- identity_fakes.user_name,
+ fake_user_l.id,
+ fake_user_l.name,
),
)
def setUp(self):
super(TestUserList, self).setUp()
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT_2),
- loaded=True,
- )
- self.projects_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- ),
- ]
+ self.projects_mock.get.return_value = self.fake_project_l
+ self.projects_mock.list.return_value = [self.fake_project_l]
- self.users_mock.list.return_value = [
- fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- ),
- ]
+ self.users_mock.list.return_value = [self.fake_user_l]
# Get the command object to test
self.cmd = user.ListUser(self.app, None)
@@ -480,13 +459,13 @@ class TestUserList(TestUser):
def test_user_list_project(self):
arglist = [
- '--project', identity_fakes.project_id,
+ '--project', self.fake_project_l.id,
]
verifylist = [
- ('project', identity_fakes.project_id),
+ ('project', self.fake_project_l.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- project_id = identity_fakes.PROJECT_2['id']
+ project_id = self.fake_project_l.id
# In base command class Lister in cliff, abstract method take_action()
# returns a tuple containing the column names and an iterable
@@ -517,10 +496,10 @@ class TestUserList(TestUser):
collist = ('ID', 'Name', 'Project', 'Email', 'Enabled')
self.assertEqual(collist, columns)
datalist = ((
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.project_name,
- identity_fakes.user_email,
+ self.fake_user_l.id,
+ self.fake_user_l.name,
+ self.fake_project_l.name,
+ self.fake_user_l.email,
True,
), )
self.assertEqual(datalist, tuple(data))
@@ -531,23 +510,15 @@ class TestUserSet(TestUser):
def setUp(self):
super(TestUserSet, self).setUp()
- self.projects_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.PROJECT),
- loaded=True,
- )
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.projects_mock.get.return_value = self.fake_project
+ self.users_mock.get.return_value = self.fake_user
# Get the command object to test
self.cmd = user.SetUser(self.app, None)
def test_user_set_no_options(self):
arglist = [
- identity_fakes.user_name,
+ self.fake_user.name,
]
verifylist = [
('name', None),
@@ -556,7 +527,7 @@ class TestUserSet(TestUser):
('project', None),
('enable', False),
('disable', False),
- ('user', identity_fakes.user_name),
+ ('user', self.fake_user.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -588,7 +559,7 @@ class TestUserSet(TestUser):
def test_user_set_name(self):
arglist = [
'--name', 'qwerty',
- identity_fakes.user_name,
+ self.fake_user.name,
]
verifylist = [
('name', 'qwerty'),
@@ -597,7 +568,7 @@ class TestUserSet(TestUser):
('project', None),
('enable', False),
('disable', False),
- ('user', identity_fakes.user_name),
+ ('user', self.fake_user.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -610,7 +581,7 @@ class TestUserSet(TestUser):
}
# UserManager.update(user, **kwargs)
self.users_mock.update.assert_called_with(
- identity_fakes.user_id,
+ self.fake_user.id,
**kwargs
)
self.assertIsNone(result)
@@ -618,7 +589,7 @@ class TestUserSet(TestUser):
def test_user_set_password(self):
arglist = [
'--password', 'secret',
- identity_fakes.user_name,
+ self.fake_user.name,
]
verifylist = [
('name', None),
@@ -628,7 +599,7 @@ class TestUserSet(TestUser):
('project', None),
('enable', False),
('disable', False),
- ('user', identity_fakes.user_name),
+ ('user', self.fake_user.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -636,7 +607,7 @@ class TestUserSet(TestUser):
# UserManager.update_password(user, password)
self.users_mock.update_password.assert_called_with(
- identity_fakes.user_id,
+ self.fake_user.id,
'secret',
)
self.assertIsNone(result)
@@ -644,7 +615,7 @@ class TestUserSet(TestUser):
def test_user_set_password_prompt(self):
arglist = [
'--password-prompt',
- identity_fakes.user_name,
+ self.fake_user.name,
]
verifylist = [
('name', None),
@@ -654,7 +625,7 @@ class TestUserSet(TestUser):
('project', None),
('enable', False),
('disable', False),
- ('user', identity_fakes.user_name),
+ ('user', self.fake_user.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -665,7 +636,7 @@ class TestUserSet(TestUser):
# UserManager.update_password(user, password)
self.users_mock.update_password.assert_called_with(
- identity_fakes.user_id,
+ self.fake_user.id,
'abc123',
)
self.assertIsNone(result)
@@ -673,7 +644,7 @@ class TestUserSet(TestUser):
def test_user_set_email(self):
arglist = [
'--email', 'barney@example.com',
- identity_fakes.user_name,
+ self.fake_user.name,
]
verifylist = [
('name', None),
@@ -682,7 +653,7 @@ class TestUserSet(TestUser):
('project', None),
('enable', False),
('disable', False),
- ('user', identity_fakes.user_name),
+ ('user', self.fake_user.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -695,24 +666,24 @@ class TestUserSet(TestUser):
}
# UserManager.update(user, **kwargs)
self.users_mock.update.assert_called_with(
- identity_fakes.user_id,
+ self.fake_user.id,
**kwargs
)
self.assertIsNone(result)
def test_user_set_project(self):
arglist = [
- '--project', identity_fakes.project_id,
- identity_fakes.user_name,
+ '--project', self.fake_project.id,
+ self.fake_user.name,
]
verifylist = [
('name', None),
('password', None),
('email', None),
- ('project', identity_fakes.project_id),
+ ('project', self.fake_project.id),
('enable', False),
('disable', False),
- ('user', identity_fakes.user_name),
+ ('user', self.fake_user.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -720,15 +691,15 @@ class TestUserSet(TestUser):
# UserManager.update_tenant(user, tenant)
self.users_mock.update_tenant.assert_called_with(
- identity_fakes.user_id,
- identity_fakes.project_id,
+ self.fake_user.id,
+ self.fake_project.id,
)
self.assertIsNone(result)
def test_user_set_enable(self):
arglist = [
'--enable',
- identity_fakes.user_name,
+ self.fake_user.name,
]
verifylist = [
('name', None),
@@ -737,7 +708,7 @@ class TestUserSet(TestUser):
('project', None),
('enable', True),
('disable', False),
- ('user', identity_fakes.user_name),
+ ('user', self.fake_user.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -749,7 +720,7 @@ class TestUserSet(TestUser):
}
# UserManager.update(user, **kwargs)
self.users_mock.update.assert_called_with(
- identity_fakes.user_id,
+ self.fake_user.id,
**kwargs
)
self.assertIsNone(result)
@@ -757,7 +728,7 @@ class TestUserSet(TestUser):
def test_user_set_disable(self):
arglist = [
'--disable',
- identity_fakes.user_name,
+ self.fake_user.name,
]
verifylist = [
('name', None),
@@ -766,7 +737,7 @@ class TestUserSet(TestUser):
('project', None),
('enable', False),
('disable', True),
- ('user', identity_fakes.user_name),
+ ('user', self.fake_user.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -778,7 +749,7 @@ class TestUserSet(TestUser):
}
# UserManager.update(user, **kwargs)
self.users_mock.update.assert_called_with(
- identity_fakes.user_id,
+ self.fake_user.id,
**kwargs
)
self.assertIsNone(result)
@@ -789,21 +760,17 @@ class TestUserShow(TestUser):
def setUp(self):
super(TestUserShow, self).setUp()
- self.users_mock.get.return_value = fakes.FakeResource(
- None,
- copy.deepcopy(identity_fakes.USER),
- loaded=True,
- )
+ self.users_mock.get.return_value = self.fake_user
# Get the command object to test
self.cmd = user.ShowUser(self.app, None)
def test_user_show(self):
arglist = [
- identity_fakes.user_id,
+ self.fake_user.id,
]
verifylist = [
- ('user', identity_fakes.user_id),
+ ('user', self.fake_user.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -812,15 +779,15 @@ class TestUserShow(TestUser):
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
- self.users_mock.get.assert_called_with(identity_fakes.user_id)
+ self.users_mock.get.assert_called_with(self.fake_user.id)
collist = ('email', 'enabled', 'id', 'name', 'project_id')
self.assertEqual(collist, columns)
datalist = (
- identity_fakes.user_email,
+ self.fake_user.email,
True,
- identity_fakes.user_id,
- identity_fakes.user_name,
- identity_fakes.project_id,
+ self.fake_user.id,
+ self.fake_user.name,
+ self.fake_project.id,
)
self.assertEqual(datalist, data)
diff --git a/openstackclient/tests/volume/v2/test_backup.py b/openstackclient/tests/volume/v2/test_backup.py
index 8a151a91..ba0f1c18 100644
--- a/openstackclient/tests/volume/v2/test_backup.py
+++ b/openstackclient/tests/volume/v2/test_backup.py
@@ -72,12 +72,14 @@ class TestBackupCreate(TestBackup):
"--name", self.new_backup.name,
"--description", self.new_backup.description,
"--container", self.new_backup.container,
+ "--force",
self.new_backup.volume_id,
]
verifylist = [
("name", self.new_backup.name),
("description", self.new_backup.description),
("container", self.new_backup.container),
+ ("force", True),
("volume", self.new_backup.volume_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -88,7 +90,8 @@ class TestBackupCreate(TestBackup):
self.new_backup.volume_id,
container=self.new_backup.container,
name=self.new_backup.name,
- description=self.new_backup.description
+ description=self.new_backup.description,
+ force=True,
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
@@ -112,7 +115,8 @@ class TestBackupCreate(TestBackup):
self.new_backup.volume_id,
container=self.new_backup.container,
name=None,
- description=self.new_backup.description
+ description=self.new_backup.description,
+ force=False,
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
diff --git a/openstackclient/volume/v1/backup.py b/openstackclient/volume/v1/backup.py
index 212c74ef..5f34a2c5 100644
--- a/openstackclient/volume/v1/backup.py
+++ b/openstackclient/volume/v1/backup.py
@@ -76,7 +76,7 @@ class DeleteBackup(command.Command):
'backups',
metavar='<backup>',
nargs="+",
- help=_('Backup(s) to delete (ID only)'),
+ help=_('Backup(s) to delete (name or ID)'),
)
return parser
@@ -150,7 +150,7 @@ class RestoreBackup(command.Command):
parser.add_argument(
'backup',
metavar='<backup>',
- help=_('Backup to restore (ID only)')
+ help=_('Backup to restore (name or ID)')
)
parser.add_argument(
'volume',
@@ -177,7 +177,7 @@ class ShowBackup(command.ShowOne):
parser.add_argument(
'backup',
metavar='<backup>',
- help=_('Backup to display (ID only)')
+ help=_('Backup to display (name or ID)')
)
return parser
diff --git a/openstackclient/volume/v2/backup.py b/openstackclient/volume/v2/backup.py
index 6a44e30c..519913a9 100644
--- a/openstackclient/volume/v2/backup.py
+++ b/openstackclient/volume/v2/backup.py
@@ -48,6 +48,12 @@ class CreateBackup(command.ShowOne):
metavar="<container>",
help=_("Optional backup container name")
)
+ parser.add_argument(
+ '--force',
+ action='store_true',
+ default=False,
+ help=_("Allow to back up an in-use volume")
+ )
return parser
def take_action(self, parsed_args):
@@ -58,7 +64,8 @@ class CreateBackup(command.ShowOne):
volume_id,
container=parsed_args.container,
name=parsed_args.name,
- description=parsed_args.description
+ description=parsed_args.description,
+ force=parsed_args.force,
)
backup._info.pop("links", None)
return zip(*sorted(six.iteritems(backup._info)))
@@ -147,7 +154,7 @@ class RestoreBackup(command.ShowOne):
parser.add_argument(
"backup",
metavar="<backup>",
- help=_("Backup to restore (ID only)")
+ help=_("Backup to restore (name or ID)")
)
parser.add_argument(
"volume",
diff --git a/releasenotes/notes/bp-multi-argument-compute-0bc4522f6edca355.yaml b/releasenotes/notes/bp-multi-argument-compute-0bc4522f6edca355.yaml
index 286dc7ea..2e129dfa 100644
--- a/releasenotes/notes/bp-multi-argument-compute-0bc4522f6edca355.yaml
+++ b/releasenotes/notes/bp-multi-argument-compute-0bc4522f6edca355.yaml
@@ -1,5 +1,5 @@
---
features:
- - Support bulk deletion and error handling for ``aggregate delete`` and
- ``flavor delete`` commands.
+ - Support bulk deletion and error handling for ``aggregate delete``,
+ ``flavor delete``, ``keypair delete`` and ``service delete`` commands.
[Blueprint `multi-argument-compute <https://blueprints.launchpad.net/python-openstackclient/+spec/multi-argument-compute>`_]
diff --git a/releasenotes/notes/bug-1596443-9e2af267e91d1643.yaml b/releasenotes/notes/bug-1596443-9e2af267e91d1643.yaml
new file mode 100644
index 00000000..cf4e85c0
--- /dev/null
+++ b/releasenotes/notes/bug-1596443-9e2af267e91d1643.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Add ``--force`` option to ``backup create`` command to allow users to
+ back up an in-use volume.
+ [Bug `1596443 <https://bugs.launchpad.net/bugs/1596443>`_]