Support error handling for "port delete" command

"Port delete" command supported deleting multi ports
before but didn't support error handing, This patch
add the error handling following the rules in
doc/source/command-errors.rst.

Change-Id: I4ea69f2279763626d6a27cad1ca0ee99822d016d
Partially-Implements: blueprint multi-argument-network
This commit is contained in:
Huanxuan Ao 2016-06-03 17:29:41 +08:00
parent 48ffd8cf4b
commit eb421f6dab
2 changed files with 76 additions and 9 deletions
openstackclient
network/v2
tests/network/v2

@ -284,10 +284,23 @@ class DeletePort(command.Command):
def take_action(self, parsed_args):
client = self.app.client_manager.network
result = 0
for port in parsed_args.port:
res = client.find_port(port)
client.delete_port(res)
try:
obj = client.find_port(port, ignore_missing=False)
client.delete_port(obj)
except Exception as e:
result += 1
self.app.log.error(_("Failed to delete port with "
"name or ID '%(port)s': %(e)s")
% {'port': port, 'e': e})
if result > 0:
total = len(parsed_args.port)
msg = (_("%(result)s of %(total)s ports failed "
"to delete.") % {'result': result, 'total': total})
raise exceptions.CommandError(msg)
class ListPort(command.Lister):

@ -13,6 +13,8 @@
import mock
from mock import call
from openstackclient.common import exceptions
from openstackclient.common import utils
from openstackclient.network.v2 import port
from openstackclient.tests.network.v2 import fakes as network_fakes
@ -174,30 +176,82 @@ class TestCreatePort(TestPort):
class TestDeletePort(TestPort):
# The port to delete.
_port = network_fakes.FakePort.create_one_port()
# Ports to delete.
_ports = network_fakes.FakePort.create_ports(count=2)
def setUp(self):
super(TestDeletePort, self).setUp()
self.network.delete_port = mock.Mock(return_value=None)
self.network.find_port = mock.Mock(return_value=self._port)
self.network.find_port = network_fakes.FakePort.get_ports(
ports=self._ports)
# Get the command object to test
self.cmd = port.DeletePort(self.app, self.namespace)
def test_delete(self):
def test_port_delete(self):
arglist = [
self._port.name,
self._ports[0].name,
]
verifylist = [
('port', [self._port.name]),
('port', [self._ports[0].name]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.network.delete_port.assert_called_once_with(self._port)
self.network.find_port.assert_called_once_with(
self._ports[0].name, ignore_missing=False)
self.network.delete_port.assert_called_once_with(self._ports[0])
self.assertIsNone(result)
def test_multi_ports_delete(self):
arglist = []
verifylist = []
for p in self._ports:
arglist.append(p.name)
verifylist = [
('port', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
calls = []
for p in self._ports:
calls.append(call(p))
self.network.delete_port.assert_has_calls(calls)
self.assertIsNone(result)
def test_multi_ports_delete_with_exception(self):
arglist = [
self._ports[0].name,
'unexist_port',
]
verifylist = [
('port',
[self._ports[0].name, 'unexist_port']),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self._ports[0], exceptions.CommandError]
self.network.find_port = (
mock.MagicMock(side_effect=find_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 ports failed to delete.', str(e))
self.network.find_port.assert_any_call(
self._ports[0].name, ignore_missing=False)
self.network.find_port.assert_any_call(
'unexist_port', ignore_missing=False)
self.network.delete_port.assert_called_once_with(
self._ports[0]
)
class TestListPort(TestPort):