summaryrefslogtreecommitdiff
path: root/openstackclient/tests
diff options
context:
space:
mode:
authorHuanxuan Ao <huanxuan.ao@easystack.cn>2016-06-20 15:42:40 +0800
committerHuanxuan Ao <huanxuan.ao@easystack.cn>2016-06-21 11:04:13 +0800
commit640014fa91b939e802f261346473d3ec025f2acb (patch)
tree98af9ac80e7458d29772dd4e892bbf31485015c8 /openstackclient/tests
parentba825a4d5c04e2e6fd8a82ebbfb2f71a85e683aa (diff)
downloadpython-openstackclient-640014fa91b939e802f261346473d3ec025f2acb.tar.gz
Support bulk deletion for "flavor/aggregate delete"
Support bulk deletion and error handling for "aggregate delete" and "flavor delete" commands. Change-Id: I3f6105cbeeab1c9f8cd571c63ce0e7ac3d4252b3 Partially-Implements: blueprint multi-argument-compute Partial-Bug: #1592906
Diffstat (limited to 'openstackclient/tests')
-rw-r--r--openstackclient/tests/compute/v2/fakes.py38
-rw-r--r--openstackclient/tests/compute/v2/test_aggregate.py65
-rw-r--r--openstackclient/tests/compute/v2/test_flavor.py58
3 files changed, 140 insertions, 21 deletions
diff --git a/openstackclient/tests/compute/v2/fakes.py b/openstackclient/tests/compute/v2/fakes.py
index 60abb8ef..8416b630 100644
--- a/openstackclient/tests/compute/v2/fakes.py
+++ b/openstackclient/tests/compute/v2/fakes.py
@@ -87,6 +87,42 @@ class FakeAggregate(object):
loaded=True)
return aggregate
+ @staticmethod
+ def create_aggregates(attrs=None, count=2):
+ """Create multiple fake aggregates.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param int count:
+ The number of aggregates to fake
+ :return:
+ A list of FakeResource objects faking the aggregates
+ """
+ aggregates = []
+ for i in range(0, count):
+ aggregates.append(FakeAggregate.create_one_aggregate(attrs))
+
+ return aggregates
+
+ @staticmethod
+ def get_aggregates(aggregates=None, count=2):
+ """Get an iterable MagicMock object with a list of faked aggregates.
+
+ If aggregates list is provided, then initialize the Mock object
+ with the list. Otherwise create one.
+
+ :param List aggregates:
+ A list of FakeResource objects faking aggregates
+ :param int count:
+ The number of aggregates to fake
+ :return:
+ An iterable Mock object with side_effect set to a list of faked
+ aggregates
+ """
+ if aggregates is None:
+ aggregates = FakeAggregate.create_aggregates(count)
+ return mock.MagicMock(side_effect=aggregates)
+
class FakeComputev2Client(object):
@@ -732,7 +768,7 @@ class FakeFlavor(object):
flavors
"""
if flavors is None:
- flavors = FakeServer.create_flavors(count)
+ flavors = FakeFlavor.create_flavors(count)
return mock.MagicMock(side_effect=flavors)
diff --git a/openstackclient/tests/compute/v2/test_aggregate.py b/openstackclient/tests/compute/v2/test_aggregate.py
index 58dd7755..3ebca35f 100644
--- a/openstackclient/tests/compute/v2/test_aggregate.py
+++ b/openstackclient/tests/compute/v2/test_aggregate.py
@@ -13,6 +13,12 @@
# under the License.
#
+import mock
+from mock import call
+
+from osc_lib import exceptions
+from osc_lib import utils
+
from openstackclient.compute.v2 import aggregate
from openstackclient.tests.compute.v2 import fakes as compute_fakes
from openstackclient.tests import utils as tests_utils
@@ -135,25 +141,74 @@ class TestAggregateCreate(TestAggregate):
class TestAggregateDelete(TestAggregate):
+ fake_ags = compute_fakes.FakeAggregate.create_aggregates(count=2)
+
def setUp(self):
super(TestAggregateDelete, self).setUp()
- self.aggregate_mock.get.return_value = self.fake_ag
+ self.aggregate_mock.get = (
+ compute_fakes.FakeAggregate.get_aggregates(self.fake_ags))
self.cmd = aggregate.DeleteAggregate(self.app, None)
def test_aggregate_delete(self):
arglist = [
- 'ag1',
+ self.fake_ags[0].id
]
verifylist = [
- ('aggregate', 'ag1'),
+ ('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(parsed_args.aggregate)
- self.aggregate_mock.delete.assert_called_once_with(self.fake_ag.id)
+ 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)
+ def test_delete_multiple_aggregates(self):
+ arglist = []
+ for a in self.fake_ags:
+ arglist.append(a.id)
+ verifylist = [
+ ('aggregate', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = 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)
+
+ def test_delete_multiple_agggregates_with_exception(self):
+ arglist = [
+ self.fake_ags[0].id,
+ 'unexist_aggregate',
+ ]
+ verifylist = [
+ ('aggregate', arglist),
+ ]
+
+ 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.assertEqual(2, find_mock.call_count)
+ self.aggregate_mock.delete.assert_called_once_with(
+ self.fake_ags[0].id
+ )
+
class TestAggregateList(TestAggregate):
diff --git a/openstackclient/tests/compute/v2/test_flavor.py b/openstackclient/tests/compute/v2/test_flavor.py
index 4365a540..d8d02e11 100644
--- a/openstackclient/tests/compute/v2/test_flavor.py
+++ b/openstackclient/tests/compute/v2/test_flavor.py
@@ -14,6 +14,8 @@
#
import copy
+import mock
+from mock import call
from osc_lib import exceptions
from osc_lib import utils
@@ -204,47 +206,73 @@ class TestFlavorCreate(TestFlavor):
class TestFlavorDelete(TestFlavor):
- flavor = compute_fakes.FakeFlavor.create_one_flavor()
+ flavors = compute_fakes.FakeFlavor.create_flavors(count=2)
def setUp(self):
super(TestFlavorDelete, self).setUp()
- self.flavors_mock.get.return_value = self.flavor
+ self.flavors_mock.get = (
+ compute_fakes.FakeFlavor.get_flavors(self.flavors))
self.flavors_mock.delete.return_value = None
self.cmd = flavor.DeleteFlavor(self.app, None)
def test_flavor_delete(self):
arglist = [
- self.flavor.id
+ self.flavors[0].id
]
verifylist = [
- ('flavor', self.flavor.id),
+ ('flavor', [self.flavors[0].id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
- self.flavors_mock.delete.assert_called_with(self.flavor.id)
+ self.flavors_mock.delete.assert_called_with(self.flavors[0].id)
self.assertIsNone(result)
- def test_flavor_delete_with_unexist_flavor(self):
- self.flavors_mock.get.side_effect = exceptions.NotFound(None)
- self.flavors_mock.find.side_effect = exceptions.NotFound(None)
+ def test_delete_multiple_flavors(self):
+ arglist = []
+ for f in self.flavors:
+ arglist.append(f.id)
+ verifylist = [
+ ('flavor', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ 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)
+ self.assertIsNone(result)
+
+ def test_multi_flavors_delete_with_exception(self):
arglist = [
- 'unexist_flavor'
+ self.flavors[0].id,
+ 'unexist_flavor',
]
verifylist = [
- ('flavor', 'unexist_flavor'),
+ ('flavor', [self.flavors[0].id, 'unexist_flavor'])
]
-
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- self.assertRaises(
- exceptions.CommandError,
- self.cmd.take_action,
- parsed_args)
+ find_mock_result = [self.flavors[0], exceptions.CommandError]
+ self.flavors_mock.get = (
+ mock.MagicMock(side_effect=find_mock_result)
+ )
+ self.flavors_mock.find.side_effect = exceptions.NotFound(None)
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ 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)
class TestFlavorList(TestFlavor):